Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs directive which creates new directive with data object inside

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?

like image 662
hughesjmh Avatar asked Apr 08 '26 09:04

hughesjmh


1 Answers

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;
}
like image 194
TwitchBronBron Avatar answered Apr 09 '26 23:04

TwitchBronBron