Angular-formly custom Validation on multiple fields on a repeat section - angularjs

I was trying to create a custom validator for angular-formly repeated section.
The form should be valid only if the sum of the percentage inputs is 100. So for example if repeat section has 2 fields 50 and 50 should be a valid option or 25 and 75 and so on.
While I was working on a JSbin in order to do that I found out that the repeated model is not actually updated onKeydown. Therefore iterating though all the repeat section values and calculating their sum is not possible.
I also tried with modelOptions: { updateOn: 'Keydown' } with no success. It actually makes the validator not to get called at all.
UPDATE
I came up with the following solution from the matching fields example.
Unfortunately it appears that the example its self has a problem.
Play with the following JSbin and see that there are many cases where the validator gets called and returns true but the field/fields still remain red (indicating they have a problem).
Here is the JSBin.

Apologies since I didn't had the time to get back on this one. It has an open issue on GitHub for 2 months now. I fixed it temporary by using 7.1.2 version of angular-formly and just waiting for an update. The updated version of JSBin I have on the question should be working.
UPDATE
Since I had time and fixed this with repeat section (with a hacky way of course) I tough I should post it in case someone else is looking for this.
(note: the solution doesn't depend on formly version)
Working JSBin

You made a typo while using modelOptions: { updateOn: 'Keydown' } the Keydown's k should be small case instead of uppercase, after fixing typo its working as expected. Also the ngModelOptions accept all event name in small case like keydown, keyup, blur, focus, etc.
modelOptions: { updateOn: 'keydown' }
Forked Plunkr

To create your own checks is best used reusable components, for example directive use-form-error.
Look at the example of jsfiddle.
<div ng-form="testForm" use-form-error="sumNot100" use-error-expression="input_1+input_2+input_3!=100">
<label>Sum of all input must be 100</label>
<br>
<label>Input 1</label>
<input ng-model="input_1" type="number" name="input_1">
<label>Input 2</label>
<input ng-model="input_2" type="number" name="input_2">
<label>Input 3</label>
<input ng-model="input_3" type="number" name="input_3">
<div ng-messages="testForm.$error" class="errors">
<div ng-message="sumNot100">
Sum of all input not equal 100
</div>
</div>
<button ng-disabled="testForm.$invalid">
Submit
</button>
</div>

Related

How to keep form error message blank on initial load in AngularJS

I'm trying to learn forms in AngularJS 1.x. But I have error messages that are always on when it first loads. How to develop behaviour such that they are blank on load, and only red after a submit if fields were not entered? Seems to be a few states I have to use the built-in directives for.
All the elements are similar so let's just take apart this bit. Also if different for a radio and dropdown list maybe we can discuss that too.
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required">The first name is required.</span>
</p>
Do I chain a few directives with || or && ?
Behaviour I'm aiming for
How to keep the error messages off when it loads?
when I hit submit, and a field is blank, will it then activate the css red error messages?
I'd like the error messages to clear as I fill in the form without reloading.
Yeah, so any tips greatly appreciated. Doesn't have to be particularly pretty
Thanks
UPDATE 1
gist of current code
Well I took a stab at it. Still really a hot mess at this point. Don't know how to use submit to test for each field and then display the error message if blank. Also seems like a lot of duplication on the testing of field states. Is there a better way to break up that logic? Ugggghhhhh
UPDATE 2
This one's weird, the form now has all text boxes not buttons or checkboxes!? But the HTML hasn't changed. Sigh
ng-if="identification.firstName.$error.required && !$pristine"
Go search more on $pristine and $dirty validator
You can add some other property to your ng-if and set its value to true only when form is submitted.
in your html add this new property
<p>First Name:<input type="text" id="firstName" ng-model="firstName" required/>
<span style="background-color: red" ng-if="identification.firstName.$error.required && running">The first name is required.</span>
</p>
in your controller set this property to true when form is submitted
$scope.submit = function(){
$scope.running = true;
...
}

Why isn't it possible to use VALUE for inputs in a bootstrap modal? (angularjs)

I use a bootstrap modal for a form in my code.
So, I need standard-values for two textfields, and I tried to simply use VALUE like
<input type="text" value="myStandardText" ng-model="something">
I think it's because of the ng-model, but why?
And do you know a way to get the same result as with value, too?
(For now, I use "placeholder" instead, but value would be better)
UPDATE: Ok, i got a step closer.
<input type="text" ng-model="e_uname" ng-init="e_uname = 'a std txt'">
does the trick, but i need now to set a saved value as init-value.
i added "uname" to my scope, but with input it doesn't work.
<input type="text" ng-model="e_uname" ng-init="e_uname = {{uname}}">
I tried also with different quote marks. Any ideas?
Ok guys, I found the answer.
Final solution is:
<input type="text" ng-model="e_uname" ng-value="uname">

angular form validation - set required by code (not working)

if(currentAdmin.target =='new')
{
$('#btnDel').hide();
//Not working !!!
$('#inputPassword1').attr("ng-required","true");
$('#inputPassword2').attr("ng-required","true");
}
else
{
$('#btnDel').show();
$('#inputPassword1').attr("ng-required","true");
$('#inputPassword2').attr("ng-required","true");
}
Well, basically I want to place the ng-required based on the condition. I made a trial using the required (without ng) and it does not works as well.
I inspected the element and injected the required and ng-required into the html and it's not works.
This will always be ignored after rendered. I need to do such thing like "Validator, refresh because it's different now"
any clue ?
Even though I myself hate the kind of answer I am about to give, I feel it is appropriate in this situation: This is not the way to write if using angular...
So what should you do?
place the ng-required in the html code and set the value of the attribute to a bound variable that you set depending on your condition.
Example:
index.html
<form ng-controller="formController">
<input type="password" ng-required="isAdmin">
<input type="password" ng-required="!isAdmin">
</form>
app.js
angular.module('app',[]).controller('formController', function($scope){
$scope.isAdmin=false;
if(currentAdmin.target == 'new'){
$scope.isAdmin=true;
}
});
Not complete code, but hopefully you still understand what I mean.

One form element updating multiple pieces of the model?

I am looking at using angular for a project at work but I have a question first. We have a single page application that's pretty intricate. We do have a basic model set up but some fields in the model are redundant. If I couldn't reduce the redundancy, what steps could I take in angular so that one form element changes two variables in the model?
I've put together a bare bones jsfiddle of what I'm hoping to do:
<div ng-app>
<input type="text" ng-model="yourName" placeholder="Enter a name here" /><br/>
<span>Hello {{yourName}}!</span><br/>
<span>Hello {{altName}}!</span>
</div>
How could I change this around so that the input would assign it's value to both yourName as well as altName? I've tried what I thought would be obvious such as comma or pipe delimiting the ng-model attribute to no avail. Is it possible?
You could set a $watch on the yourname-Variable within your controller and then change the altName in its callback. Should look like this:
$scope.$watch('yourName', function(){
$scope.altName = $scope.newName;
});

ngRepeat breaks the Foundation Switch CSS. How can I fix it?

I'm trying to use the Switch component from Zurb's Foundation.
It works great until you put it inside an ng-repeat. Then, all the switches except the last one are broken--they don't display the labels until you click them.
Here's a JSBin documenting the issue. Anyone know what's up?
You need ng-model on your radios. It works fine in your JSBin if you include an ng-model on each radio button.
According to the docs, value is also required.
Edit:
Okay look at this version, I finally got it to work with both ng-model and ng-value, which I've learned is preferable to value. What do you think, does that work for you?
Apparently ng-repeat created a child scope for each iteration. Using $parent seems to be a way around that.
Found I had to use "ng-checked" in the following fashion for it to work as expected within an "ng-repeat". As long as the ng-clicked var is unique per switch, should work as expected. Make the toggle function something that toggles the visible value between true and false.
<div class="switch" ng-click="toggle()">
<input type="radio" ng-checked="!visible">
<label>Off</label>
<input type="radio" ng-checked="visible">
<label>On</label>
<span></span>
</div>
Hope that helps someone.

Resources