javascript - Detach then append AngularJS form change validity status -
you can test in jsfiddle: here (better see on new jsfiddle, see edit part of post)
i think there bug in angularjs or @ least not expected result. if detach form re-append it, it's class ng-invalid
switch ng-valid
on re-append dom. has consequence enable submit button of form data aren't valid. of course, expecting validity status didn't switch.
i think it's angular bug, maybe jquery one. use jquery check on append if form valid or not , forcing form class it's seems not working valid form status of invalid. it's quite weird don't know other workaround without using kind of data saved status form before detaching it.
so has encountered problem? there method (if possible using angularjs directive) rid of bug?
ps: need detach form (and other elements) in single page web application keep dom clean possible.
edit
i've done new jsfiddle illustrating more problem, detaching content on internal site navigation: http://jsfiddle.net/ewvwa/
update
i come temporary solution (thanks caiotoon)
var app = angular.module('plunker', []); app.controller('mainctrl', function($scope) { $scope.name = 'world'; }); app.directive('customvalidation', function() { return { require: ['ngmodel', '^?form'], link: function(scope, element, attr, ctrls) { console.log(ctrls); var ngmodelctrl = ctrls[0], formctrl = ctrls[1]; ngmodelctrl.$parsers.push(function(viewvalue) { if (viewvalue === 'test') { ngmodelctrl.$setvalidity('name', true); formctrl.$setvalidity('name', true); return viewvalue; } else { ngmodelctrl.$setvalidity('name', false); formctrl.$setvalidity('name', false); return undefined; } }); // custom event element.bind('$append', function() { formctrl && formctrl.$addcontrol(ngmodelctrl); /*** test keep form's validation status ***/ formctrl.$setvalidity('name', ngmodelctrl.$valid); //ngmodelctrl.$setvalidity('name', ngmodelctrl.$valid); console.log(formctrl.$valid); }); //binding on element, not scope. element.bind('$destroy', function() { console.log("gone haven"); }); } }; });
this need more testing regarding multiple inputs validation. i'll updating answer when tests done.
the problem happens because input
directive removes form controls when element removed dom. doesn't link ngmodel
, form controller again, input not being considered form anymore.
you have two 3 options:
- change element visibility instead of removing it
- (prefer 1 below)
exposing "relink" function re-add original form - triggering custom event on controls can relink theirselves
changing element visibility means have unnecessary dom elements in domtree. not quite bad, keeping reference $compile element anyway, yet participate $digest
cycles , "dom" modifications.
(after thinking while, new solution better one, don't expose relinking function) exposing relink function quite weird (although functional) , not reliable of solutions. 1 way achieve consists in requiring form controller (require: ['ngmodel', '^?form']
) , binding relinking function element's data:
element.data('relink', function(){ formctrl && formctrl.$addcontrol(ngmodelctrl); });
and when add element screen again, gonna have call controls relink function:
$('.controls').data('relink')();
see example here.
it's not quite reliable, might work case.
triggering custom event pretty same previous, dispatch custom event on elements should relink theirselves. way more organized, still not quite reliable, because form , other links might have been broken (again, should sufice case). listen custom event on directive:
element.bind('$append', function(){ formctrl && formctrl.$addcontrol(ngmodelctrl); });
and after changing form, trigger custom event on controls:
$('.control').triggerhandler('$append');
the reason why 1 better directive still decides when relink component, , event kind of "generic". here working plunker.
as last effort, override jquery.fn.append
, trigger custom event on element children recursively (this angular does when removing elements). organized, impact yoour performance on append
calls.
Comments
Post a Comment