jQWidgets Forums

jQuery UI Widgets Forums Plugins AngularJS Input fields window content

Tagged: 

This topic contains 2 replies, has 2 voices, and was last updated by  patrick 9 years, 6 months ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
  • Input fields window content #77995

    patrick
    Participant

    Hi,

    I am trying to create an angular directive to display a dynamic form in a window. Basically this directive handles an event which uses the event args to dynamically generate the necessary form fields, update the windows content, compile the windows HTML and finally open it. On the windows close event i reset the windows content. This works great, however when i update the windows content, the previous form fields are still being watched by angular and hence when i recompile i get errors during the $digest cycle related to missing elements for these form fields, TypeError: Cannot read property ‘element’ of undefined at b.fn.jqxProxy (jqx-all.js:7).

    How can i unwatch these old form elements when i clear the windows content. I have tried calling destroy for each but with no effect.

    Input fields window content #77996

    Peter Stoev
    Keymaster

    Hi patrick.fay,

    We remove the watches added by us on destroy. Unfortunately, we do not know why they continue after you call destroy in your case.

    Best Regards,
    Peter Stoev

    jQWidgets Team
    http://www.jqwidgets.com

    Input fields window content #78004

    patrick
    Participant

    Hi Peter,

    The following is a rough example of that error message. Try opening & submitting forms…..

    Patrick

    <html lang=”en” ng-app=”app”>
    <head>
    <meta charset=”utf-8″ />
    <title>Example</title>

    <link href=”jqx.base.css” rel=”stylesheet” />
    <link href=”jqx.arctic.css” rel=”stylesheet” />

    <script src=”jquery-1.11.1.min.js”></script>
    <script src=”angular.min.js”></script>
    <script src=”jqx-all.js”></script>

    <script src=”jqxangular.js” type=”text/javascript”></script>
    </head>
    <body ng-controller=”MainController as main”>

    <div class=”window” window-form></div>

    <button ng-click=”main.form1();”>Open Form2</button>
    <button ng-click=”main.form2();”>Open Form1</button>

    <script type=”text/javascript”>

    var app = angular.module(‘app’, [‘jqwidgets’]);
    app.controller(‘MainController’, MainController);

    MainController.$inject = [‘$rootScope’];
    function MainController($rootScope){
    var vm = this;

    vm.form1 = function(){
    $rootScope.$emit(‘displayForm’, {
    form: {
    title: ‘TestForm1’,
    submit: ‘Submit’,
    rows: [
    { type: ‘String’, label: ‘TestInput4’, key: null, value: null, validators: [{ type: ‘Required’ }] },
    { type: ‘String’, label: ‘TestInput5’, key: null, value: null, validators: [] },
    { type: ‘String’, label: ‘TestInput6’, key: null, value: null, validators: [{ type: ‘Required’ }] }
    ]
    }
    }, vm.submit);
    };
    vm.form2 = function(){
    $rootScope.$emit(‘displayForm’, {
    form: {
    title: ‘TestForm2’,
    submit: ‘Submit’,
    rows: [
    { type: ‘String’, label: ‘TestInput6’, key: null, value: null, validators: [{ type: ‘Required’ }] }
    ]
    }
    }, vm.submit);
    };
    vm.submit = function(results){
    console.log(results);
    }
    }

    app.directive(‘windowForm’, windowForm)

    windowForm.$inject = [‘$compile’, ‘$rootScope’, ‘$timeout’];
    function windowForm ($compile, $rootScope, $timeout) {

    var _window, _settings, _callback, $element = null;

    controller.$inject = [‘$scope’];
    function controller($scope){
    var vm = this;

    vm.submit = function(results){
    _window.close();
    _callback(results);
    };
    vm.reset = function(){
    angular.forEach(_settings.form.rows, function(row){
    vm[row.$key] = null;
    vm[row.$key + ‘Instance’].destroy();
    });
    vm.submitButton.destroy();
    _window.setContent(”);
    };
    }

    function link(scope, element, attrs, ngModel) {
    $element = element;

    var content = generateWindow();
    element.html(content).show();
    element.jqxWindow({
    theme: ‘artic’,
    isModal: true,
    autoOpen: false,
    keyboardCloseKey: ‘esc’,
    draggable: true,
    resizable: false,
    position: ‘center’,
    width: ‘18%’,
    height: ‘auto’,
    maxHeight: 800
    });
    compileForm(element.contents(), scope);
    _window = element.jqxWindow(‘getInstance’);

    element.bind(‘open’, function(){
    if(element && element.find(‘input’))
    element.find(‘input’)[0].focus();
    });
    element.bind(‘close’, function(){
    scope.vm.reset();
    });

    $rootScope.$on(‘displayForm’, function(event, settings, callback){
    _settings = settings;
    _callback = callback;
    init(settings);
    _window.open();
    });

    $rootScope.$on(‘hideForm’, function(event){
    _window.close();
    });

    function init(settings){
    var form = generateForm(settings);
    _window.setContent(form);
    _window.setTitle(settings.form.title);
    compileForm(element.contents(), scope);
    }
    }

    // Generate window HTML
    function generateWindow(config){
    return ‘<div class=”windowTitle”>Default</div>\
    <div class=”windowContent”><\div>’;
    };

    // Generate form HTML
    function generateForm(config){
    return addForm(config);
    }

    // Add form HTML
    function addForm(config){
    config.$formName = config.form.title.replace(‘ ‘, ”);
    return ‘<form name=”vm.’ + config.$formName + ‘” novalidate>’
    + addRows(config) +
    ‘<div class=”windowActionRow”>\
    <div class=”windowContentLeft”></div>\
    <div class=”windowContentRight”>\
    <jqx-button class=”windowActionBtn” jqx-instance=”vm.submitButton” jqx-theme=”\’artic\'” jqx-width=”\’40%\'” jqx-height=”\’100%\'”\
    jqx-template=”\’info\'” ng-click=”vm.submit(‘ + addFormSubmission(config) + ‘)” ng-disabled=”!vm.’ + config.$formName + ‘.$valid”>’ + config.form.submit + ‘</jqx-button>\
    </div>\
    </div>\
    </form>’;
    }

    function addRows(config){
    var html = ”;
    angular.forEach(config.form.rows, function(row){
    html += addRow(config, row);
    });
    return html;
    }

    function addRow(config, row){
    return ‘<div class=”windowContentRow”>\
    <div class=”windowContentLeft”><label>’ + row.label + ‘</label></div>\
    <div class=”windowContentRight”>’
    + addField(row) +
    ‘</div>\
    </div>’
    + addErrors(config, row);
    }

    function addField(row){
    row.$key = !row.key?row.label:row.key;
    switch(row.type){
    case ‘Boolean’:
    break;
    case ‘Double’:
    break;
    case ‘Int’:
    break;
    case ‘String’:
    return ‘<jqx-input jqx-instance=”vm.’ + row.$key + ‘Instance” ng-model=”vm.’ + row.$key + ‘” name=”‘ + row.$key + ‘” jqx-theme=”\’artic\'” jqx-width=”\’100%\'” jqx-height=”\’100%\'” ‘ + addValidators(row) + ‘ autocomplete=”off”></jqx-input>’;
    case ‘SelectValue’:
    break;
    case ‘SelectObject’:
    break;
    }
    }

    function addValidators(row){
    if(!row.validators) return ”;
    var html = ”;
    angular.forEach(row.validators, function(validator){
    html += addValidator(validator)
    });
    return html;
    }

    function addValidator(validator){
    switch(validator.type){
    case ‘Required’:
    return ‘ng-required=”true”‘;
    }
    }

    function addErrors(config, row){
    if(!row.validators) return ”;
    return ‘<div class=”windowContentError” ng-messages=”vm.’ + config.$formName + ‘.’ + row.$key + ‘.$error”>’
    + addErrorMessages(row) +
    ‘</div>’;
    }

    function addErrorMessages(row){
    var html = ”;
    angular.forEach(row.validators, function(validator){
    html += addErrorMessage(validator)
    });
    return html;
    }

    function addErrorMessage(validator){
    switch(validator.type){
    case ‘Required’:
    return ‘<div class=”errorMsg” ng-message=”required”>Required….</div>’
    }
    }

    function compileForm(form, scope){
    $compile(form)(scope)
    }

    function addFormSubmission(config){
    var html = ‘{‘;
    angular.forEach(config.form.rows, function(row){
    html += row.$key + ‘:vm.’ + row.$key + ‘,’
    });
    html = html.substring(0, html.length-1) + ‘}’;
    return html;
    }

    // DDO
    return {
    restrict: ‘EA’,
    scope: {
    //settings: ‘=’,
    // onSubmit: ‘&’
    },
    controller: controller,
    controllerAs: ‘vm’,
    link: link
    };
    }
    </script>

    <style type=”text/css”>
    .windowTitle{
    font-size: 1em;
    }
    .windowContent {
    font-size: 1em;
    margin-top: 0;
    overflow: hidden;
    }
    .windowContent form {
    position: relative;
    width: 99%;
    height: 100%;
    }
    .windowContent label {
    font-weight: bold;
    font-size: 0.8em;
    }
    .windowContentLeft {
    position: relative;
    width: 40%;
    float: left;
    height: 100%;
    }
    .windowContentRight {
    position: relative;
    width: 60%;
    float: left;
    height: 100%;
    }
    .windowActionBtn {
    float: right;
    line-height: 0.5em;
    margin-top: 0;
    }
    .errorMsg {
    font-weight: bold;
    font-size: 0.7em;
    color: red;
    float: right;
    }
    .windowContentRow {
    position: relative;
    width: 100%;
    height: 1.4em;
    margin-bottom: 3px;
    }
    .windowContentError {
    position: relative;
    width: 100%;
    height: 1.2em;
    }
    .windowActionRow {
    position: relative;
    width: 100%;
    height: 1.65em;
    margin-bottom: 3px;
    margin-top: 5px;
    }
    </style>

    </body>
    </html>
    `

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.