In the app I'm working on, a user can input the form type from a dropdown and create a new form via a directive that is called when a button is clicked. The form created is actually another directive that is compiled to the scope and appended to a wrapper element in the DOM. Here's the code for the click directive that creates the new directive.
(function(){
'use strict';
//on 'add new rule' btn click, a new form is created
function createRuleForm($compile){
function linkFn(scope, element, attrs){
function onClickAddForm(){
var type = scope.rcCtrl.ruleType;
var newDirective = angular.element('<rule-form type="'+type+'"></rule-form>');
var formWrap = document.querySelector('.edit-rc__div--rf-wrapper');
angular.element(formWrap).append(newDirective);
$compile(newDirective)(scope)
}
element.bind('click', onClickAddForm)
}
return{
restrict: 'A',
link: linkFn
}
}
angular.module('ganeshaApp')
.directive('createRuleForm', [
'$compile',
createRuleForm
])
})();
Each new form that is created has an isolate scope as the user needs to be able to work on multiple forms at a time, and save and edit those forms. The 'type' is passed as an attribute to the new form. This is the new directive created on click.
(function(){
'use strict';
function ruleForm(ModalService, CurrentDateService, SaveRule, RULE_PHRASE){
var index = 0;
//directive controller
function RuleFormCtrl($scope, $element, $attrs){
var rfCtrl = this;
//values
rfCtrl.ruleType = $scope.$parent.rcCtrl.ruleType;
rfCtrl.ruleTitle = 'L_' + $attrs.type + index;
rfCtrl.phrase = RULE_PHRASE[$attrs.type]
rfCtrl.fullDate = CurrentDateService.getCurrentDate()
//functions
rfCtrl.saveOneRule = saveOneRule;
rfCtrl.closeRule = closeRule;
//saves one rule on click of save button or on timeout
function saveOneRule(){
rfCtrl.html = $element.find('.edit-rf__div--textdiv').html();
var ruleObject = {
'index' : index,
'ruleText' : rfCtrl.ruleText,
'ruleTitle' : rfCtrl.ruleTitle,
'ruleType' : rfCtrl.ruleType,
'typePhrase' : rfCtrl.phrase,
'html' : rfCtrl.html,
'fullHtml' : rfCtrl.phrase + rfCtrl.html
}
SaveRule.pushRule(ruleObject)
$scope.ruleForm.$setPristine();
index++;
}
function closeRule(){
if($scope.ruleForm.$dirty){
var modal = {
"mssg" : 'You have unsaved changes to this rule. Would you like to save them before closing?',
"confirm" : 'Yes, please.',
"reject" : 'No, thank you.'
}
ModalService.openModal(modal).
then(function(res){
console.log(res)
saveOneRule();
$element.remove();
}).catch(function(err){
console.log(err)
})
}else{
$element.remove();
}
}
}
return{
restrict: 'E',
replace: true,
scope: {},
templateUrl: 'modules/edit/edit-create/ruleForm.html',
controller: RuleFormCtrl,
controllerAs: 'rfCtrl'
};
}
angular.module('ganeshaApp')
.directive('ruleForm', [
'ModalService',
'CurrentDateService',
'SaveRule',
'RULE_PHRASE',
ruleForm
]);
})();
When a form is saved, it is added to a scrollable list in the view.
For creating and saving forms for the first time, everything is working well here. The difficulty I'm having is when the user needs to open a form from the list of forms in the view. Unlike creating a new form where the data passed to the new directive is a simple string 'ruleType', creating a directive for a completed form requires the saved object data to be passed to the new directive.
I'm just wondering if anyone has any experience with this type of situation where a click directive creates an element directive that needs to be packaged with data?
You should be able to add the data to your scope when you compile the element, and then reference it in your html
var type = scope.rcCtrl.ruleType;
var data = {'your': 'data', 'object': 'here'};
//add the data to the scope so that the child element has access to it
scope.data = data;
//pass the data into your rule-form directive using whatever attribute you declared
var newDirective = angular.element('<rule-form type="'+type+'" form-data="data"></rule-form>');
var formWrap = document.querySelector('.edit-rc__div--rf-wrapper');
angular.element(formWrap).append(newDirective);
$compile(newDirective)(scope)
Just make sure your rule-form directive's scope is looking for that form-data attribute
return{
restrict: 'E',
replace: true,
scope: {
formData: '='
},
templateUrl: 'modules/edit/edit-create/ruleForm.html',
controller: RuleFormCtrl,
controllerAs: 'rfCtrl'
};
Then in the RuleFormCtrl, you can access formData
function RuleFormCtrl($scope...){
var data = $scope.formData;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With