Clicking a checkbox with protractor? - javascript

HTML code
<div class="check-box-panel">
<!--
ngRepeat: employee in employees
-->
<div class="ng-scope" ng-repeat="employee in employees">
<div class="action-checkbox ng-binding">
<input id="John" type="checkbox" ng-click="toggleSelection(employee.name)"
ng-checked="selection.indexOf(employee.name) > -1" value="John"></input>
<label for="John">
::before
</label>
<!--
John
end ngRepeat: employee in employees
-->
<div class="ng-scope" ng-repeat="employee in employees">
<div class="action-checkbox ng-binding">
<input id="Jessie" type="checkbox" ng-click="toggleSelection(employee.name)"
ng-checked="selection.indexOf(employee.name) > -1" value="Jessie"></input>
<label for="Jessie"></label>
I tried using jQuery
element(by.repeater('employee in employees')).element(by.id('Jessie')).click();
also,I tried using css
element(by.repeater('employee in employees')).$('[value="Jessie"]').click();
But it didn't do the job. Any other way I can click on the particular Checkbox?

Alright I had a very similar issue where I couldn't click the checkbox. It turned out I had to click the checkbox label. However if you want to do any checks on if the checkbox is selected then you have to check the actual checkbox. I ended up making two variables, one for the label and one for the actual checkbox.
JessieChkbxLabel = element(by.css("label[for='Jessie']"));
JohnChkbxLabel = element(by.css("label[for='John']"));
//Click the Jessie checkbox
JessieChkbxLabel.click();
//Click the John checkbox
JohnChkbxLabel.click();

You should just need to use element(by.id('Jessie')) to grab your object. The issue you might be having is that click() returns a promise, so you need to handle that with a .then. So something along the lines of:
element(by.id('Jessie')).click().then(function(value) {
// fulfillment
}, function(reason) {
// rejection
});

Aside from checking the id directly, you can also filter the desired element checking the employee name:
var employee = element.all(by.repeater('employee in employees')).filter(function (elm) {
return elm.evaluate("employee.name").then(function (name) {
return name === "Jessie";
});
}).first();
employee.element(by.css("input[type=checkbox]")).click();

Related

KO radio works but does not initialise as checked

Here's a snippet from a knockout based answer editor
<!-- ko foreach: Answers -->
<div class="qa-box" data-bindx="event: { mousedown: mouseDown, dragend: dragEnd, dragstart: dragStart }">
<div class="qa-body">
<div class="radio">
<label>
<input type="radio" data-bind="attr: { name: 'Q' + $parentContext.$index(), value: $index }, checked: $parent.CorrectAnswer" /><span></span>
Tick the correct answer
<span data-bind="text:$parent.CorrectAnswer"></span>
</label>
<a href="#" data-bind="click: $parent.remove.bind($parent)">
<i class="fa fa-times"></i>
Remove this answer
</a>
<div class="form-control" contenteditable="true" data-bind="ckeditor: $data, attr: { id: 'Q' + $parentContext.$index() + 'A' + $index() }"></div>
</div>
</div>
</div>
<!-- /ko -->
<div>CorrectAnswer: <span data-bind="text: CorrectAnswer"></span></div>
You'll notice I put a bound span on the end of the radio button label so I can see what happens to the CorrectAnswer observable when I interact with the UI. This is how I know it's correctly bound to the view model. Clicking a radio button or its label changes the value of CorrectAnswer exactly as intended.
This also allows me to know that CorrectAnswer contains the value I expected.
Let's take a closer look at the binding in case it isn't obvious.
attr: { name: 'Q'+$parentContext.$index(), value: $index }, checked: $parent.CorrectAnswer
All the answers for a given question get the same name Qx and a value provided by the item's list position. When an item is clicked its list position is written to CorrectAnswer. This does happen, as evidence by the new value showing up in the telltale div.
So, what could be preventing the UI from initialising as checked when everything else is fine?
It isn't an initialisation problem, it's a type compatibility problem. The value of a radio input is of type string. The value provided by my view model is of type number. Knockout does a strong comparison and does not recognise a match.
See also Radio buttons Knockoutjs

angular2 ngFor won't work

I'm trying to make some textboxes appear everytime a user clicks a button.
i'm doing this with ngFor.
For some reason, the ngFor won't iterate.
I've tried using slice to change the array reference, but still, the text boxes won't appear.
Any idea what i'm doing wrong??
Below are the HTML and component codes.
Thanks!!!
export class semesterComponent {
subjectsNames = [];
addSubject(subjectName: string) {
if (subjectName) {
this.subjectsNames.push(subjectName);
this.subjectsNames.slice();
console.log(subjectName);
console.log(this.subjectsNames);
}
};
<div class="semester-div">
<ul>
<li ngFor="let subject of subjectsNames">
<span>
<input #subjectName type="text" />
<input id = "subjectGrade" type = "number"/>
<input id = "subjectWeight" type = "number"/>
</span>
</li>
</ul>
<br>
<button (click)="addSubject(subjectName.value)">add</button>
<br>
</div>
You are missing the * in *ngFor
<li *ngFor="let subject of subjectsNames">
The way you have your controls written subjectName does not exist because the array is empty and therefore the *ngFor does not render it. Clicking the Add button results in a exception that the value doesn't exist on undefined where undefined is really subjectName.
Moving it outside of the *ngFor will make things work:
<input #subjectName type="text" />
<ul>
<li *ngFor="let subject of subjectsNames">
<span>
{{subject}}
<input id="subjectGrade" type="number"/>
<input id="subjectWeight" type="number"/>
</span>
</li>
</ul>
I suspect you also want to further bind the data as you iterate over the subject names but that's outside the scope of the question.
Here's a plunker: http://plnkr.co/edit/HVS0QkcLw6oaR4dVzt8p?p=preview
First, you are missing * in *ngFor.
Second put out
<input #subjectName type="text" />
from ngFor, should work.

ng-if and ng-class-even/odd doesn't work well together and won't get expected outout

Here,I am loading a json file and using ng-repeat I display json data into table form.I am adding following features to code.
checkboxes to add the two CSS:
Bubble CSS
text-danger [In built class]
when you click on those check boxes, the CSS is applied only to the even rows in the table.
Using the ng-if or ngHide/Show to display the User-info which have the gender : Male.
I use ng-if to fulfill condition because ng-if will remove elements from DOM. This means that all your handlers or anything else attached to those elements will be lost.
ng-show/ng-hide does not remove the elements from DOM. It uses CSS styles to hide/show elements.
I created Codepen demo for my problem.Here ng-if and ng-class-even doesn't give expected o/p.
HTML:
<body ng-app="module1" ng-controller="module1Ctrl as flight">
<div class="page-header">
<h1>Angular app</h1>
</div>
<div class="checkbox">
<label>
<input type="checkbox" ng-model="danger">
Something's Wrong
</label>
<label>
<input type="checkbox" ng-model="bubble">
Zoom In/Out
</label>
</div>
<table class="table table-striped table-bordered">
<tr>
<th>name</th>
<th>Birthdate</th>
<th>gender</th>
<th>father</th>
<th>mother</th>
</tr>
<tr ng-repeat="x in flightData"
ng-class-even ="{'text-danger':danger,'bubble': bubble}"
ng-if="x.sex=='f'">
<td>{{x.name}}</td>
<td>{{ x.born |date:'yyyy-MM-dd THH:mm:ss'}}</td>
<td>{{x.sex }}</td>
<td>{{x.father}}</td>
<td>{{x.mother}}</td>
</tr>
</table>
</div>
</body>
JS
var app=angular.module('module1',[]);
app.controller('module1Ctrl', function ($scope,$http) {
$scope.getDataFromServer = function () {
$http.get('http://codepen.io/timivey/pen/emQZYY.js').then(
function(res){
console.log(res.data);
$scope.flightData = res.data;
}
,function (err) {
console.log(err.message);
})
};
$scope.getDataFromServer();
$scope.showList='table';
});
Just a small change to Joel's answer. You no need to create a separate filter method.
<tr ng-repeat="x in flightData | filter:{sex:'f'}"
ng-class-even ="{'text-danger':danger,'bubble': bubble}">
There is nothing wrong with your code, but there is a small error with your understanding:
<tr ng-repeat="x in flightData"
ng-class-even ="{'text-danger':danger,'bubble': bubble}"
ng-if="x.sex=='f'">
The ng-if="x.sex == 'f' statement is omitting each <td> from display, but it does not remove them from the flightData array. ng-repeat is run for each item in the array, not for each item that is displayed.
If you add {{$index}} to each row of the table you will see that the order is not 0,1,2,3... it is 1,2,7,11,14...
If you remove the ng-if statement, you will see that every even row has correct class applied.
Instead of using ng-if to remove the males from the list, use a filter instead:
<tr ng-repeat="x in flightData | females"
ng-class-even ="{'text-danger':danger,'bubble': bubble}">
Append this filter to your controller statement in the JS code:
.filter('females', function() {
return function(input) {
var out = [];
angular.forEach(input, function(x) {
if(x.sex == 'f') {
out.push(x);
}
});
return out;
};
})
http://codepen.io/anon/pen/mABJyo
What this does is remove the males from the list before it runs the ng-repeat and will correctly output in the order 0,1,2,3...

how to show/hide div based on drop down selection using angular?

i want to show and hide a div based on selection from the drop down , here is my code, this is my html code for dropdown which fetches the values from the "selectItemsFilterCriteria" json structure
<select ng-model="appointment" ng-change="changeme()" ng-options="item.name for item in selectItemsFilterCriteria">
<option ng-option value="" >Filter Criteria</option>
</select>
this is my changeme() function created inside a controller
$scope.changeme = function() {
$scope.appointment = $scope.items[0];
}
this is code for my div that is to be show or hide , right now my code is working on selection of first option from drop down it is showing me the div but the problem is that its not hiding that div on the selection of any other option from the dropdown list, kindly tell me where i m doing wrong??
<div class="mycontainer" ng-show=appointment >
<div class="left-nav">
<accordion close-others="true">
<accordion-group ng-repeat="item in pagedItems[currentPage] |filter:{name:item.name}| orderBy:sortingOrder:reverse">
<accordion-heading>
<table>
<tr class="odd" ng-click="showDataDetail=!showDataDetail" style="cursor: pointer">
<td><p class="lead-name">{{item.name}}</p>
<p class="call-up-icon">{{item.phoneNo}} </p>
<p>Lead Date : 07/02/2015</p></td>
<td><p></p>
<p class="blue-txt">{{item.trade}}</p>
<p class="fl cstm-wdth">GNU09</p>
<p class="fl">{{item.time}}</p>
<div class="cb"></div>
</td>
<td><p>Today</p>
<p>C#SQL</p>
<p class="blue-remark-icon"></p></td>
</tr>
</table>
</accordion-heading>
<div>{{item.data}}</div>
</accordion-group>
</accordion>
</div>
</div>
items array:
$scope.selectItemsFilterCriteria = [
{id:1 , name:"Appointments Scheduled"},
{id:2 , name:"fresh leads"}
];
Basically the problem is with your ng-change function call,
$scope.changeme = function() {
$scope.appointment = $scope.items[0];
}
You are setting appointment to first value of items array. Hence whenever you change the options, the function sets it back to first option , in turn the div is shown.
Please remove the ng-change function and try.
Remove the $scope.changeme() function. It is not necessary.
Since you are using ng-model on select whatever option you select will get assigned to the ng-model i.e appointment in your case.
Here is the plunkr example

Getting value from input control using jQuery

I am using the teleriks treeview control (asp.net mvc extensions), where I may have up to three children nodes, like so (drumroll...... awesome diagram below):
it has its own formatting, looking a bit like this:
<%=
Html.Telerik().TreeView()
.Name("TreeView")
.BindTo(Model, mappings =>
{
mappings.For<Node1>(binding => binding
.ItemDataBound((item, Node1) =>
{
item.Text = Node1.Property1;
item.Value = Node1.ID.ToString();
})
.Children(Node1 => Node1.AssocProperty));
mappings.For<Node2>(binding => binding
.ItemDataBound((item, Node2) =>
{
item.Text = Node2.Property1;
item.Value = Node2.ID.ToString();
})
.Children(Node2 => Node2.AssocProperty));
mappings.For<Node3>(binding => binding
.ItemDataBound((item, Node3) =>
{
item.Text = Node3.Property1;
item.Value = Node3.ID.ToString();
}));
})
%>
which causes it to render like this. I find it unsual that when I set the value it is rendered in a hidden input ? But anyway:...
<li class="t-item">
<div class="t-mid">
<span class="t-icon t-plus"></span>
<span class="t-in">Node 1</span>
<input class="t-input" name="itemValue" type="hidden" value="6" /></div>
<ul class="t-group" style="display:none">
<li class="t-item t-last">
<div class="t-top t-bot">
<span class="t-icon t-plus"></span>
<span class="t-in">Node 1.1</span>
<input class="t-input" name="itemValue" type="hidden" value="207" />
</div>
<ul class="t-group" style="display:none">
<li class="t-item">
<div class="t-top">
<span class="t-in">Node 1.1.1</span>
<input class="t-input" name="itemValue" type="hidden" value="1452" />
</div>
</li>
<li class="t-item t-last">
<div class="t-bot">
<span class="t-in">Node 1.1.2</span>
<input class="t-input" name="itemValue" type="hidden" value="1453" />
</div>
</li>
</ul>
</li>
</ul>
What I am doing is updating a div after the user clicks on a certain node. But when the user clicks on a node, I want to send the ID not the Node text property. Which means I have to get it out of the value in these type lines <input class="t-input" name="itemValue" type="hidden" value="1453" />, but it can be nested differently each time, so the existing code I ahve doesn't ALWAYS work:
<script type="text/javascript">
function TreeView_onSelect(e) {
//`this` is the DOM element of the treeview
var treeview = $(this).data('tTreeView');
var nodeElement = e.item;
var id = e.item.children[0].children[2].value;
...
</script>
So based on that, what is a better way to get the appropriate id each time with javascript/jquery?
edit:
Sorry to clarify a few things
1) Yes, I am handling clicks to the lis of the tree & want to find the value of the nested hidden input field. As you can see, from the telerik code, setting item.Value = Node2.ID.ToString(); caused it to render in a hidden input field.
I am responding to clicks anywhere in the tree, therefore I cannot use my existing code, which relied on a set relationship (it would work for first nodes (Node 1) not for anything nested below)
What I want is, whenever there is something like this, representing a node, which is then clicked:
<li class="t-item t-last">
<div class="t-bot">
<span class="t-in">Node 1.1.2</span>
<input class="t-input" name="itemValue" type="hidden" value="1453" />
</div>
</li>
I want the ID value out of the input, in this case 1453.
Hope this now makes a lot more sense.
if possible would love to extend this to also store in a variable how nested the element that is clicked is, i.e. if Node 1.1.2 is clicked return 2, Node 1.1 return 1 and node 1 returns 0
It's a little unclear what you're asking, but based on your snippet of JavaScript, I'm guessing that you're handling clicks to the lis of the tree & want to find the value of the nested hidden field? If so, you want something like this:
function TreeView_onSelect(e) {
var id = $(e.item).find(".t-input:first").val();
}
Edit: In answer to your follow-up question, you should be able to get the tree depth with the following:
var depth = $(e.item).parents(".t-item").length;
In jQuery you can return any form element value using .val();
$(this).val(); // would return value of the 'this' element.
I'm not sure why you are using the same hidden input field name "itemValue", but if you can give a little more clarity about what you are asking I'm sure it's not too difficult.
$('.t-input').live('change',function(){
var ID_in_question=$(this).val();
});

Categories

Resources