Clicking a checkbox using protractor - javascript

There is no unique model, id, label names. How am I suppose to check/click the checkboxes?
The html/code is:
<div ng-repeat="column in $parent.columns.standardMetrics" class="ng-scope">
<label class="ng-binding">
<input type="checkbox" ng-model="column.visible" name="" class="ng-pristine ng-valid">
uCPM
</label>
</div>
</div><div ng-repeat="column in $parent.columns.standardMetrics" class="ng-scope">
<label class="ng-binding">
<input type="checkbox" ng-model="column.visible" name="" class="ng-pristine ng-valid">
CPM
</label>
</div>
There is about 15 of these with the same name besides the label next to the name. I searched everywhere to see if protractor allows you to find elements by label.
My attempts are finding via by.buttonText, by.partialButtonText, by.css and by.binding. I have no luck on this.
My purpose is to pass in a label name that I can toggle the specific checkbox.
So it's like element(by.css(header)).click();
where header is what is passed in.

I strongly recommend using ids. Use a directive to add ids to each checkbox, then you can something like this:
element(by.css('input[myid="checkbox_x"]')); // where x is defined in a loop

I'm sure there will be better answer out there. I just started learning protractor :) You can try clicking on it by index.
3 = position.
element.all(by.repeater('column in $parent.columns.standardMetrics').get(3).element(by.css('[ng-model="column.visible"]')).click();

You can use by.xpath():
element(by.xpath('//input[#ng-model = "column.visible" and following-sibling::text() = "' + label + '"]'));

EDIT: missed that the text belonged to the label and not the input.
This should work:
element(by.xpath("//label[text()='uCPM']/input"));

Assign a dinamic id to the elements:
<div ng-repeat="column in $parent.columns.standardMetrics" class="ng-scope">
<label id="label{{$index}}" class="ng-binding">
<input type="checkbox" ng-model="column.visible" name="" class="ng-pristine ng-valid">
uCPM
</label>
</div>
Then on protractor:
element(by.id('label0')).click();
p.s. Just read that you can't change HTML because the website is not yours. Try this:
var first= element.all(by.repeater('column in $parent.columns.standardMetrics')).get(0);
first.get(0).then(function(el) {
el.click();
});

Related

find html element, without proper class name or id, with javascript

I have this HTML code
<div class="option-wrapper">
<label class="">
<input type="checkbox" name="name" value="1" data-type-xml="select" aria-label="Untitled">
<span lang="" class="option-label active">1</span>
</label>
<label class="">
<input type="checkbox" name="name" value="2" data-type-xml="select" aria-label="Untitled">
<span lang="" class="option-label active">2</span>
</label>
</div>
im trying to find the labels and to set a "style="display: none;"
like this <label class="" style="display: none;>
my problem is, I only need one of the labels in this div. But I don't have a class name or id to find one label. Do u guys know a solution for this?
Use document.getElementsByTagName('label') instead for all end then get them with the array offset. Or - to select the first - use document.getElementByTagName('label'). Notice the singular version of the second selector.
Or, a more general selector which you can use with either classes or tags or any other query string would be document.querySelector('label') or document.querySelectorAll('label')

checkbox is not working properly in html how to fix?

I have this checkbox input that I want it to call a function when its clicked
<div class="checkbox theme-search-results-sidebar-section-checkbox-list-item">
<label class="icheck-label">
<input class="icheck" type="checkbox" onclick="system()">
<span class="icheck-title" >
system is good
</span>
</label>
</div>
I tried different methods the only way that I got it to work was by using the onclick on the span but that would not work if the box gets checked!
Can anyone help me with this?
I can't change the layout because I have a fixed HTML that is like this for a lot of checkboxes.
This appears to be working the way you describe it with a simple "system()" function. The problem may be in your system() function.
function system(){
console.log("inside system")
}
<div class="checkbox theme-search-results-sidebar-section-checkbox-list-item">
<label class="icheck-label">
<input class="icheck" type="checkbox" onclick="system()">
<span class="icheck-title" >
system is good
</span>
</label>
</div>
Try this. First select the check box in JavaScript:
const $checkbox = document.querySelector('.icheck');
Then add a click event listener to it:
$checkbox.addEventListener('click', system);
This will run system when it is clicked.

Save values to an array on checkbox inside ng-repeat in AngularJS

I have a scenario in which I have to put values in array when the checkbox is checked in ng-repeat.
<li ng-repeat="player in team.players">
<div class="row">
<div class="col-md-3 m-t-xs">
<input type="checkbox" ng-model="vm.newEvent.players[$index].selected" ng-change="vm.selectPlayer($index, player)"> {{player.name}}
</div>
<div class="col-md-5 m-t-xs">
<label for="">
<input type="radio" name="{{player.id}}" ng-change="vm.disSelectPlayer($index, player)" ng-model="vm.newEvent.players[$index].casuality.type" value="injured"> Injured
</label>
<label for="">
<input type="radio" name="{{player.id}}" ng-change="vm.disSelectPlayer($index, player)" ng-model="vm.newEvent.players[$index].casuality.type" value="sick"> Sick
</label>
<label for="">
<input type="radio" name="{{player.id}}" ng-change="vm.disSelectPlayer($index, player)" ng-model="vm.newEvent.players[$index].casuality.type" value="other"> Other
</label>
</div>
</div>
</li>
This is how it looks now in browser.
The issue is that when I clicked any of the player name in FC Barcelona Accordion it also selects the same indexed player from FC Bayern Munich Accordion, What I want is to keep all players separate form each-other.
Am i missing something in the binding ??
Use checklist-model, AngularJS directive for list of checkboxes
In Angular one checkbox <input type="checkbox" ng-model="..."> is linked with one model. But in practice we usually want one model to store array of checked values from several checkboxes. Checklist-model solves that task without additional code in controller. You should play with attributes of <input type="checkbox"> tag:
set checklist-model instead of ng-model
set checklist-value - what should be picked as array item
Documentation
This Because of this function: vm.disSelectPlayer($index, player)
I think you have to add index here <li ng-repeat="player in team.players"> in order to give each player different id or index.
Try This :
<li ng-repeat="(key ,player) in team.players">
and use this Key in the function that you call :
vm.disSelectPlayer($index, player , key)
I hope it is useful :)
This is because on on line #4 you wrote
ng-model="vm.newEvent.players[$index].selected".
You have used parents object ie players, instead of this you can use
ng-model="vm.player.selected".
OR
ng-model="vm.team.players[$index].selected".

i18next: overwrites nested items

I'm using i18next to translate my form. It works fine but I have problems with nested items, for example:
<div style="margin-bottom: 25px" class="input-group">
<div class="checkbox">
<label class="form" data-i18n="form.checkbox">
<input type="checkbox" name="checkbox" value="true" required>
</label>
</div>
</div>
After applying the translation, the actual HTML code is like this:
<div style="margin-bottom: 25px" class="input-group">
<div class="checkbox">
<label class="form" data-i18n="form.checkbox">
translated value (no more <input> tag!)
</label>
</div>
</div>
It overwrites the innerHTML with the translation string.
Instead I need to "save" existing items and append the translation after them.
What is the correct use of i18next on a checkbox form entry?
I had the same problem and I solved it like this:
$('[data-i18n]').each(function each() {
const el = $(this);
const contents = el.contents();
el.text(i18n.t($(this).attr('data-i18n')))
.append(contents);
});
Edit:
The above is oversimplifying the problem because, as you pointed out, it won't work for custom attributes.
Therefore I searched a bit more and I found out it's already supported by jquery-i18next#append-content like this:
<label class="form" data-i18n="[append]form.checkbox">
<input type="checkbox" name="checkbox" value="true" required>
</label>
You can either specify a custom attribute or one of the special attributes like prepend, append, etc. to specify where you want the translated text to appear. More info on jquery i18next doc
Example on jsfiddle
I solved in this way:
<div class="checkbox">
<label class="form">
<input id="input_flag2" type="checkbox" name="disclaimer2" value="true" required>
<span data-i18n="form.checkbox"></span>
</label>
</div>
The span tag does the trick, embedding the translated content.

Can I concatenate within a directive declaration in AngularJS?

I have a form with an ng-repeat directive. I'm using ng-show to display validation error messages. I'm attempting to add a validation message within the ng-repeat directive, but I'm having trouble. This is what I have so far:
<form name="rentalApp" ng-controller="RentalAppCtrl">
<label for="name">Full Name</label>
<input id="name" name="name" ng-model="app.name">
<div ng-show="rentalApp.name.$invalid">Please enter your name</div>
<div ng-repeat="history in app.history">
<label for="address{{ $index }}">Street Address</label>
<input id="address{{ $index }}" name="address{{ $index }}" ng-model="history.address">
<div ng-show="rentalApp.('address' + $index).$invalid">Please enter an address</div>
</div>
</form>
As you can see, I am using the $index variable to make sure my IDs and names are unique.
In the rest of my form I'm doing something along the lines of:
<div ng-show="rentalApp.whatever.$invald">Error Message</div>
What I'm having trouble with is that within the ng-repeat directive, the indexes are dynamic. I've been fiddling around with this for a while, and the closest I think I've gotten to a solution is this line:
<div ng-show="rentalApp.('address' + $index).$invalid">Please enter an address</div>
However that doesn't work.
How can I properly concatenate the word "address" with the $index variable, to create a string along the lines of address0, which can then be used in my ng-show directive to determine if the form element is invalid? Or, alternatively, am I going about this completely wrong (not the "Angular way")?
EDIT
I'm looking at the rentalApp object from the console, and AngularJS is not evaluating the name attribute as I would expect. Specifically, the rentalApp object contains a address{{ $index }} object, instead of address0. So it looks like I can't use the expression {{ $index }} within the name attribute.
UPDATE
I make a research and find out it is not possible to give dynamic value to name besides create a custom directive for it...
but there is a solution for you to validate dynamic form with ng-form directive for each individual ng-repeat element...
<div ng-repeat="history in app.history">
<ng-form name="addressForm">
<label>Street Address</label>
<input name="address" ng-model="history.address" ng-required="true">
<div ng-show="rentalApp['address' + $index].$invalid">Please enter an address</div>
<span class="alert error" ng-show="addressForm.address.$invalid">Please enter an address</span>
</ng-form>
</div>
and here is your PLUNKER...
Just put:
<input name="{{input.name}}"></input>

Categories

Resources