Note that there are some explanatory texts on larger screens.

plurals
  1. POAngular (scope?) issues in a Directive that requires the parent FormController
    primarykey
    data
    text
    <p>This is a contrived example, but one that demonstrates an issue I'm encountering.</p> <p>I have a form that has an input that is generated using a directive. The code looks similar to the following. fiddle is here <a href="http://jsfiddle.net/technicolorenvy/CFynn/2/" rel="nofollow">http://jsfiddle.net/technicolorenvy/CFynn/2/</a></p> <p>View</p> <pre><code> &lt;div ng-controller="AppController"&gt; &lt;form name="myForm"&gt; &lt;input name="myInput" id="myInput" ng-model="myInputModel" ng-pattern="/\d+/" my-directive required/&gt; &lt;button type="submit" ng-click="submitForm()"&gt;Submit&lt;/button&gt; &lt;/form&gt; &lt;/div&gt; </code></pre> <p>Controller</p> <pre><code> app.controller('AppController', function ($scope) { $scope.submitForm = function () { console.log('form controller inside AppController submitForm()'); console.log(angular.copy($scope.myForm)); console.log('is the form valid? ' + $scope.myForm.$valid); console.log(' '); }; }); </code></pre> <p>Directive</p> <pre><code> app.directive('myDirective', function () { return { template: '&lt;div&gt;&lt;input/&gt;&lt;/div&gt;', replace: true, restrict: 'A', require: '^form', compile: function (element, attrs) { // some setup here // move the id and ng-model down onto the enclosed input element.removeAttr('id').removeAttr('ng-model').removeAttr('name'); element.find('input').attr('id', attrs.id).attr('ng-model', attrs.ngModel).attr('name', attrs.name); var inputName = attrs.name, $input = element.find('input'); if (attrs.required) { element.removeAttr('required'); $input.attr('required', true); } if (attrs.ngPattern) { element.removeAttr('ng-pattern'); $input.attr('ng-pattern', attrs.ngPattern); } return { pre: function (scope, element, attrs, formCtrl) { var patternErrs, fakeNum = 1234; $input.on('change', function () { patternErrs = formCtrl.$error.pattern; if (patternErrs &amp;&amp; patternErrs.length &gt; 0) { angular.forEach(patternErrs, function (err) { if (err.$name === inputName) { $input.val(fakeNum); formCtrl[inputName].$setViewValue(fakeNum); formCtrl[inputName].$setValidity('pattern', true); } }); } console.log('formCtrl inside directive'); console.log(angular.copy(formCtrl)); console.log('is the form valid? ' + formCtrl.$valid); console.log(' '); }); } }; } } }); </code></pre> <p>In the directive I have an onChange event on the 'generated' input that checks for pattern errors matching this input's name, then if there are any, force the data to be what we need with a fake value, using <code>setViewValue</code> and then set the validity using <code>setValidity</code>.</p> <p>This works... sort of. The problem is, on the FIRST submit, the form is always invalid. You must click submit TWICE for the form to be considered valid. (steps included below)</p> <ol> <li>Enter a string (eg 'abcd') in the input</li> <li>The input fails pattern validation, then gets a valid value (1234)</li> <li>the directive 'myDirective' handles this + sets the input's value and validity</li> <li>On FIRST sumbit, however, the form is invalid</li> <li>On SECOND submit, with no change to input, the form is valid</li> </ol> <p>So How do I make the form valid on the first submit WITHOUT strongarming the form's validity (read, I don't want manually set the form to be valid). This feels like a scoping issue, but if it is, I'm not too sure how to remedy it.</p> <p>Thanks!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload