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

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.

Related

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

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>

AngularJS ng-required better implement from controller?

I'm thinking of a good way to implement ng-required.
Let's say I have a bunch of inputs with ng-required in my app.
<input type="text" id="one" />
<input type="date" id="two" />
<input type="radio" id="three" />
<input type="checkbox" id="four" />
I would like to do something in a controller, where I could pass an array of required fields. I'm thinking that if I made an array of elements such as:
var myEl = angular.element( document.querySelector( '#some-id' ) );
and some how set the required property that way.
I write a directive which would decide from an array if the field is required, if it does not exist in the array, it's not required if it does, it's required.
Ultimately, I would like to have an array that allows passing of fields in such a way:
var reqArray = ('#id', ('#id1' || 'id2')) etc.
Works the same as conditional logic operators:
#id is required
#id1 || #id2 is required, but not both.
Not sure where to begin, or if it's feasible in Angular.
This would make it easier to modify required fields in large applications without having to modify the actual html.
It can be done, but angular already provides its own ways to validate forms. Some brief details:
The form tag must have a novalidate attribute in order to prevent HTML5 validation. <form name="myForm" novalidate>
With that, now angular can take charge of the validation by adding a "required" attribute to your inputs <input ng-model="myModel" type="text" required>
By this point, angular has taken control of your validation, it can also validate other HTML5 attributes like pattern. <input pattern="[0-9][A-Z]{3}" type="text" title="Single digit followed by three uppercase letters."/>
I suggest you take look at this official guide (also take a look at the directives guide on that same site, I wanted to link it but I don't yet have the rep).
That being said, what you are trying to accomplish is also possible, but rather redundant since you would have to add an attribute to your inputs anyway (the directive, and angular is able to validate already) and also require ngModel in the directive.
I made this plunkr to show you how to do it, but take notice of the extra work needed in order to validate something that angular already does natively, I'd leave this kind of work for expanding on validations, like comparing items or models.
Also, querying a selector directly like in your suggestion is not considered "the angular way". A better way would be to add the directive to your form element and access the element through the 'element' parameter in the directive.
Hope this helps.

ng-model not working with typeahead

I am using angular's typeahead, and running into trouble with ngModel.
Here is my typeahead html
<input
type= "text"
ng-model= "symbol"
placeholder= "begin typing"
typeahead= "hit.message for hit in getTypeAheadContents($viewValue)"
typeahead-loading= "loadingSymbols"
typeahead-editable= "false"
typeahead-on-select= "onSelect($item, $model, $label)"
typeahead-min-length= 2
typeahead-wait-ms= 500
class= "form-control"
/>
<input ng-click= "search()" value= "Search!"/>
Here is the code in my controller (quite basic for the time being)
$scope.search = function(){
alert($scope.symbol);
}
Now, the autocomplete code works as expected, but when I click the search button, I get the alert message "undefined"
What's even weirder is that I tried setting
$scope.symbol = "";
at the beginning of my controller, and when I click the search button without typing anything into my typeahead, I get the empty string alerted back to me, as expected. However, when I DO type something into the typeahead and again hit search, I get back "undefined" once again. So clearly, angular's typeahead is not playing very nicely with ng-model, but I'm not sure what to do here.
Advice?
Just set typeahead-editable="true" :-)
Don't know if this is still an issue for you. But I've tried the latest release of angularStrap (2.1.4) and with that I got it working when I set the ng-model to an object on which I set a property.
$scope.selectedPart = {}
<input type="text"
class="form-control"
ng-model="selectedPart.part_id"
data-animation="am-flip-x"
ng-options="part.value as part.name for part in parts"
placeholder="Selecteer onderdeel"
bs-typeahead>
Somewhere in some function (could be a deep $watch)
console.log($scope.selectedPart.part_id)
This doesn't really answer the question, but I sort of got around this issue by setting a different scope variable equal to the user's input inside the getTypeAheadContents function, and then using that variable (instead of 'symbol') inside the search function.

Angular form.fieldName.$invalid not working inside ng-class attribute

I have already solved this problem, but it took me a while to realize what I did wrong. It's a very simple mistake, but I figured I'd post it here in hopes I can save someone else some work in case they run across the same mistake.
I was trying to use simple Angular validation to set a class on an input field based on whether it was valid. I failed to realize it wasn't working because I specified the name of my form with ng-form. So using $scope.form or the actual value of name attribute of the form did not work. Of course, the examples below are simplified and a much larger form could make this mistake much harder to recognize.
Here is a failed example:
<form name="myForm" ng-form="form1">
<input type="text" name="myField" ng-class="error: myForm.myField.$invalid"/>
</form>
Here is a successful example:
<form name="myForm" ng-form="form1">
<input type="text" name="myField" ng-class="error: form1.myField.$invalid"/>
</form>

Binding valid checkbox to enable button angularjs 1.2.x

I'm trying to use Angularjs's built in form validation, but when I add a required field to a checkbox to make sure its checked I get odd results. If I do the opposite of the value I'd like it seems to work fine. The following fiddle will explain it more thoroughly.
This fiddle works great when you're using Angularjs 1.0.4, but if you switch Angular to 1.2.1 it breaks all over the place. Is there a new way of doing this now? or would this be considered a bug?
EDIT
I simplified the code to make it make more sense, check out this fiddle. The key problem here is that it's doing the opposite of what I would like it to do, but if I switch it the entire thing falls apart. I've also replaced the older code I had here with the newer fiddle. You can still see the older fiddle code in the above link.
Here is the html:
<div ng-controller="myCtrl">
<ng-form name="myForm">
<input type="checkbox" ng-model="value.checkbox" name="group-one" ng-true-value="1" ng-false-value="0" ng-required="value.checkbox==1" />
<input type="submit" value="Send" ng-disabled="myForm.$invalid" />
{{choice}}
</ng-form>
</div>
Here is the controller:
function myCtrl($scope) {
$scope.value = {"checkbox":""};
}
This appears the be a bug, though I'm not sure it's the same as your original problem. The required directive is not functioning properly when an ng-true-value is specified.
Found an existing bug report.
If you use ng-click, you should pass $event in and then get the choice from $event. Or you can use ng-checked to get the value directly.
ng-click="updateQuestionValue($event)"
$scope.updateQuestionValue = function($event){
var choice = $event.target;
//...
}

Resources