Validating angular 1.x input checkbox - angularjs

I have the following angular 1.x checkbox:
<input
type="checkbox"
name="fooName"
id="fooId"
ng-model="false"
>
Suppose I do the following in jQuery:
$("#fooId").val()
I always get "on". This is the same result I get from webdriver io.
To reiterate my question:
How do I get the value from a checkbox input?
If there is no way to extract that, is there any other way to validate this from selenium or webdriver io??

For HTML Chekbox, we should check it checked/unchecked status, rather than its value. Its value never change no matter it checked or unchecked.
For example
<input type="checkbox" name="aa" value="true">, $("#fooId").val() will always return "true" no matter you check it or not.
If the check has no attribute value, like <input type="checkbox" name="aa">, you will always get "on" when call $("#fooId").val()
We should check its check status as following:
driver.findElement(By.css('#fooId')).isSelected();

Related

Conditionally add/remove attribute in angularjs

I am trying to disable an input based on a boolean value from a checkbox selected in the form. Sadly this doesn't work -
<input type="number" ng-model="data.age" ng-attr-disabled={data.checked ? 'disabled'}>
How to fix this?
Looking for a pure Angular solution.
Is there a need to use ng-attr-disabled. The simplest option would be to use ng-disabled with your boolean value
<input type="number" ng-model="data.age" ng-disabled="data.checked">
You have also not provided enough information to determine whether the data.checked variable is being correctly set or even exists.

ng-true-value and required in AngularJs

<input type="checkbox" id="acknowledge" name="acknowledge"
ng-model="formData.acknowledge"
ng-true-value="true"
ng-required="formData.acknowledge !='true'"/>
<div ng-show="(peopleworksForm.acknowledge.$dirty || peopleworksForm.submited) && formData.acknowledge !='true'">
Please acknowledge that the information is correct</div>
I feel that something is wrong here with ng-required. Without required or ng- required it works fine. It returns the error message if I don't check the checkbox. But there also a problem: although I check the checkbox, form.$valid = false. That's why I tried using required or ng-required. You may asked me to remove the ng-true-value and use required. I know that also working. But the problem is I load formData.acknowledge = "true" inside my controller, so when the page loads the checkbox has to be checked. So I had to use ng-true-value. Can any one help me?
To restate, you want to show a message when the checkbox acknowledge is not checked by checking the $valid state of the form or the checkbox.
Also, the checkbox should be checked from the controller when assigned "true" - string value, rather than true - boolean value.
You are correct that you need to use ng-true-value to redefine the value given to the model for a checked state. You are using ng-true-value incorrectly, however, because you are not assigning the string value, but rather the boolean.
The correct way is below (notice the double-quotes "' '"):
<input type="checkbox" name="foo"
ng-model="foo" ng-true-value="'true'" required>
In the controller you could assign to "true":
$scope.foo = "true";
plunker
Also, you don't need to use ng-required with an expression - this would make the control required on a conditional basis, and I think you want it to be always "required".
General Pattern
You should be getting any data bindings you need from your controller. If necessary, those pieces of data should come from a service you inject or depend on. It sounds like you're roughly following that.
ng-true-value
You should only need to use ng-true-value if you want something other than true or false, as that is the default behavior.
what's probably wrong
In your controller, you should probably just be defaulting your property to true if that's what you need.
informationAcknowledgeOnlineRegistrationChange = true; // replace value you get from your service
should do everything you need.
As you have answer yourself, you can remove the ng-true-value and use the required:
<input type="checkbox" id="acknowledge" name="acknowledge"
ng-model="formData.acknowledge"
required />
<div ng-show="(peopleworksForm.acknowledge.$dirty || peopleworksForm.submited) && formData.acknowledge">
Please acknowledge that the information is correct</div>
In the controller, the data binding would be:
formData.acknowledge = true; //not 'true' as string
when you don't check the check box no value is provided which goes against ng-required . here what you can do is to set a default value for for the check box when user doesn't provide any value for the checkbox

AngularJS : $pristine for ng-check checked inputs

I have a form with about 100 questions, each with a radio and some checkboxes, so I need the user to be able to save the form and load it later. I need also to check which ones the user changed in this session.
This question solves the problem: How can I denote which input fields have changed in AngularJS
The second answer (storing the old and current values of the model and comparing both) does it. However, if I wanted to go with the $pristine solution I have a problem. Unchecking a ng-checked box does not change it's $pristine value. The $pristine value becomes false only by checking the box again after the uncheck.
I know I'm not suposed to use ng-model with ng-check but I get the answers from the server in values of either 1 or 0. This values used as model do not check the checkboxes.
ng-model="question.answer" //will not check the box
ng-check="question.answer" //does check the box
Value comes as 1 from the server. Unchecking and checking the box changes it to 'true'
<input ng-model="question.answer" ng-checked="question.answer"
type="checkbox" name="{{'answer' + question.id}}"/>
Heres a plnkr: http://plnkr.co/edit/3xcI0Yq9WPZ1IxJJjKGt?p=preview
What you need is to set 1 and 0 to be considered as true and false values respectively. You can use ng-true-value and ng-false-value to have that set up. You dont have to deal with converting 1/0 to true/false and also can get rid of ng-checked and use ng-model itself effectively.
<input ng-model="question.answer"
ng-true-value="1"
ng-false-value="0" type="checkbox" name="{{'answer' + question.id}}" />
Plnkr

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.

How to clear text from AngularUI typeahead input

I have a typeahead input. The input text is set to the option selected on the typeahead. However, I want to clear this text and display the "placeholder" value again on the text box after I select one of the options from typeahead (because I add the selected value to another div in the selectMatch() method.
<input id="searchTextBoxId" type="text"
ng-model="asyncSelected" placeholder="Search addresses..."
typeahead="address for address in getLocation($viewValue) | filter:$viewValue"
typeahead-loading="loadingLocations" class="form-control"
typeahead-on-select="selectMatch(asyncSelected)" typeahead-min-length="3"
typeahead-wait-ms="500">
I tried to set the text value and the placeholder value of the Input element using its Id but that did not work, such as these:
// the input text was still the
$('#searchTextBoxId').attr('placeholder', 'HELLO');
selected result
// the input text was still the selected result
$('#searchTextBoxId').val('');
How can I set or reset the text value ?
I was looking for an answer to this as well, for the longest time. I finally found a resolution that worked for me.
I ended up setting the NgModel to an empty string within the typeahead-on-select attribute:
In your typeahead-on-select attribute add asyncSelected = ''; behind your select function, like so:
<input ...
typeahead-on-select="selectMatch(asyncSelected); asyncSelected = '';" />
Making your final typeahead looking something like:
<input id="searchTextBoxId" type="text"
ng-model="asyncSelected" placeholder="Search addresses..."
typeahead="address for address in getLocation($viewValue) | filter:$viewValue"
typeahead-loading="loadingLocations" class="form-control"
typeahead-on-select="selectMatch(asyncSelected); asyncSelected = '';"
typeahead-min-length="3"
typeahead-wait-ms="500">
Fiddle adding each selection to an array
Actually this problem is not from typeahead. It is common issue about ng-model, scope and dot notation.
Refer
Scope inheritance in Angular
At your situation, you just change the model name like as xx.selected with dot-notation and set xx.selected empty in typeahead-on-select callback.
To set or reset the value, wouldn't you access the ng-model value, which is asyncSelected according to your code? In a controller:
$scope.asyncSelected = '';
#Asok's answer is fine if you need to immediately clear the value, but for myself, and perhaps others who come here based on the question title, #hey's answer may be better (if terse).
I changed the typeahead as follows:
<input id="searchTextBoxId" type="text"
ng-model="myNewVar.asyncSelected" placeholder="Search addresses..."
typeahead="address for address in getLocation($viewValue) | filter:$viewValue"
typeahead-loading="loadingLocations" class="form-control"
typeahead-on-select="selectMatch(myNewVar.asyncSelected)" typeahead-min-length="3"
typeahead-wait-ms="500">
then, whenever i need to clear the input from my controller, i can call
$scope.myNewVar.asyncSelected = '';
I was already doing as jnthnjns's answer suggested and setting the ng-model's value to an empty string, but the selection popup was not going away because I was (intentionally) using typeahead-min-length="0" so that users could easily see the choices.
It wasn't until I noticed that hitting enter to make a selection actually dismissed the box and it was only on clicks that the box remained. Digging into the ui-typeahead code I saw
// return focus to the input element if a match was selected via a mouse click event
// use timeout to avoid $rootScope:inprog error
if (scope.$eval(attrs.typeaheadFocusOnSelect) !== false) {
$timeout(function() { element[0].focus(); }, 0, false);
}
As soon as I set typeahead-focus-on-select="false" then the box dismisses immediately upon selection (and clearing of the model). It seems obvious now, but I had seen that option before but had read it as automatically selecting on focus (or something like that). Putting this as an answer, just in case it helps someone else.

Resources