please provide xpath of the following: - xpath

What should be the xpath for this object?
<td id="searchButtonCol">
<input id="ctl00_m_EmployeeDirectoryEmployee Directory_ctl00_btnSearch"
type="submit"
onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$m$EmployeeDirectoryEmployee Directory$ctl00$btnSearch", "", true, "", "", false, false))"
value="Search"
name="ctl00$m$EmployeeDirectoryEmployee Directory$ctl00$btnSearch">
</td>

Take a look at the XPath 1.0 docs, the id() function.
For the <td> element, do
id('searchButtonCol')
For the <input> element, do
id('ctl00_m_EmployeeDirectoryEmployee Directory_ctl00_btnSearch')

Related

Why "checked" attribute doesn't apply to my Thymeleaf's checkboxes?

I was working with Spring and Thymeleaf when I've encountered the following problem: I need a Form object, which has a list of items (Item) as attribute; I'm using an html form to print the Name of the Item, and to generate a checkbox for each Item (any checkbox's value is the corresponding item's id).
The form works correctly, sending to the Controller a list of item's ids corresponding to the checked checkboxes.
However, now, I'm trying to check some checkbox upon the occurrence of a condition (if itemIds, which is a list, contains the current item's id). For that I'm using:
th:checked="${#lists.contains(itemIds, item.id)}"/>
But it doesn't work (checkbox are all unchecked).
I tried also with a "dummy test":
th:checked="${1 == 1 ? 'checked' : ''}"/>
But, again, all the checkbox remain unchecked; the "checked" attribute is ignored as you can see in this example of the rendered HTML:
<input type="checkbox" value="12" class="chkCheckBox" id="ids1" name="ids">
What am I doing wrong? What am I missing here?
form.html
<form th:action="#{${uriBase}+'/new/' + ${date}}"
method="POST" th:object="${form}">
<div class="table-responsive">
<table class="table">
<thead class=" text-primary">
<tr>
<th>Name</th>
<th><input type="checkbox" th:id="checkAll"/>Check</th>
</tr>
</thead>
<tbody>
<tr th:each="item : ${items}">
<td th:text="${item.name}"></td>
<td>
<input type="checkbox" th:field="*{ids}"
th:value="${item.id}" th:class="chkCheckBox"
th:checked="${#lists.contains(itemIds, item.id)}"/>
</td>
</tr>
</tbody>
</table>
<button type="submit" class="btn btn-primary pull-right">Submit</button>
<div class="clearfix"></div>
</div>
</form>
Form class
public class Form implements Serializable {
private List<Long> ids;
//getter and setter
}
Thank you in advance.
I have been struggling with this as well. If you use the th:field it will override the checked and value options, as Xaltotun mentions, because it is trying to get the value and checked option from the field/form.
If you change it to th:name it should work how you want...
But this forum seems to be helpful for doing it with th:feild.
As far as I understand there are 2 issues in your post:
The dummy example is incorrect.
th:checked="${1 == 1 ? 'checked' : ''}"
In fact the value must true or false not 'checked'. If you try with
th:checked="${1 == 1}"/>
It will work.
If you set th:field="*{ids}" then the checkbox should be trying to get the value from the field item.ids and will not use the "th:checked" or "th:value" properties. Does the item has the field ids?

Select a button on the form of a webpage

I am trying to click on upload button which is inside a <form> tag.
I am using java with selenium. I tried with xpath locator to click on button but unable to identify it.
Html Code:
<form id="sportForm" action="/sportmetadata/saveSport" method="post" enctype="multipart/form-data">
<table>
<tr class="hidden">
<td class="lbl-dialog">Id</font></td>
<td>
<td class="lbl-dialog width200" >Background for Team </td>
<td>
<input type="button" class="btn btn-default btn-command btn-upload" value="Upload" onClick="openFileBrowser('sp_backgroundUploadId')" />
<input id="sp_backgroundUploadId" multiple type="file" class="no-display" name="backgroundUpload" />
<input id="backgroundDelesectUpload" value="Clear" type="button" onclick="clearSelection('sp_backgroundUploadId','sp_backgroundDisplayTableId');" class="btn btn-default btn-command btn-upload" />
</td>
</tr>
Please help
Thanks in advance
Locate Upload button using xpath locator.
//input[#value='Upload'][#type='button']
Explanation:- Use value and type attribute of <input> tag.
Suggestion:- Instead of using absolute xpath, use relative xpath.
OR
Locate Upload button using cssSelector
input[value='Upload'][type='button']
Explanation:- Use value and type attribute of <input> tag.
You should try to avoid XPATH directly copied from browsers as they are not stable ones. When I copy xpath from my browser with the same HTML code I get
//*[#id="sportForm"]/table/tbody/tr/td[4]/input[1] which is different from what you have posted
You should build your xpath more intellegently
This should work
//input[#type='button' and #value='Upload']
You can use cssSelector to identify as follows:
driver.findElement(By.cssSelector("#sportForm > table > tr td:nth-child(3)>input"))

Knockout-Validation - data-bind observable array

I'm trying to do some validation for groups of radio buttons, where each group needs to have a value selected. I'm attempting to use Knockout-Validation to do the validation, but I'm having trouble making this dynamic. I can set up the validation, but getting it to validate each group individually is a challenge. Right now it's treating all groups of questions the same. I have an example on JSFiddle which shows the current situation.
I create the questions dynamically in the back end from a DB, but I could potentially add in a unique identifier for each question, but how do I reference an observable who's name I can't know ahead of time for a number of questions I can't predetermine the number of?
Example code form JSFiddle:
$(function() {
var viewModelQuestionnaire = ko.validatedObservable({
'checkScore': ko.observable().extend({
required: true
}),
submit: function () {
if (this.isValid()) {
alert('Thank you.');
} else {
console.log(this);
alert('Please check your submission.');
this.errors.showAllMessages();
}
}
});
ko.applyBindings(viewModelQuestionnaire);
});
<form action="/Questionnaire/Save" method="post"> <table id="ESAS-questions">
<tr class="esas-question-row">
<td class="esas-best-area">
<div class="esas-best-symptom">No Pain</div>
</td>
<td class="esas-score-area">
<span class="esas-score">0<input type="radio" name="question_id-1" value="0" data-bind="checked: checkScore"/></span>
<span class="esas-score">1<input type="radio" name="question_id-1" value="1" data-bind="checked: checkScore"/></span>
<span class="esas-score">2<input type="radio" name="question_id-1" value="2" data-bind="checked: checkScore"/></span></td>
<td class="esas-worst-area">
<span class="esas-worst-symptom">Worst Possible Pain</span>
</td>
</tr>
<tr class="esas-question-row">
<td class="esas-best-area">
<div class="esas-best-symptom">No Tiredness</div>
<div class="esas-best-subtext">(Tiredness = lack of energy)</div>
</td>
<td class="esas-score-area">
<span class="esas-score">0<input type="radio" name="question_id-2" value="0" data-bind="checked: checkScore"/></span>
<span class="esas-score">1<input type="radio" name="question_id-2" value="1" data-bind="checked: checkScore"/></span>
<span class="esas-score">2<input type="radio" name="question_id-2" value="2" data-bind="checked: checkScore"/></span> </td>
<td class="esas-worst-area">
<span class="esas-worst-symptom">Worst Possible Tiredness</span>
</td>
</tr>
</table>
<p><input type="submit" value="Submit" class="finish" data-bind="click:submit" /></p>
You can avoid multiple error message for that you have to customize the display of your objects validation message by using validationMessage binding and stop the default error message insertion with knockout validation options.
data-bind="validationOptions: { insertMessages: false }" //default validation will not insert
// customize the display of your objects validation message
<p class="invalid" data-bind="validationMessage: checkScore"></p>
You have binded same property to both question so whenever one field is selected it select other one also.You can have list of questions as array of objects in observableArray.
Sample structure for list of questions:-
var questions=[
{
question: "No Pain",
checkScore: ko.observable().extend({
required: true
}),
description: "Worst Possible Pain"
},
{
question: "No Tiredness (Tiredness = lack of energy)",
checkScore: ko.observable().extend({
required: true
}),
description: "Worst Possible Tiredness"
}
]
But for questionList validation you have to enable deep(recursive) validation.
Fiddle Demo

Encounter error when there is if else in mvc view

i am new in mvc and trying to learn.i want to display a form when ViewBag.Success is null or empty but if ViewBag.Success is true then i want to render a partial view.
here is my code
<div id="mydiv">
#if (ViewBag.Success != null && ViewBag.Success == true) //Show the message
{
Html.RenderPartial("Message");
}
else
{
#using (Html.BeginForm("Save", "Game", FormMethod.Post, new { #Id = "Form1" }))
{
<table border="0">
<tr>
<td>
Name :
</td>
<td>
<input name="name" type="text" />
</td>
</tr>
<tr>
<td>
Salary :
</td>
<td>
<input name="salary" type="text" />
</td>
</tr>
<tr>
<td colspan="2">
<input name="btnSubmit" type="submit" value="Save" />
</td>
</tr>
</table>
}
}
</div>
the error message i am getting when i am running like
Expected a "{" but found a "/". Block statements must be enclosed in "{" and "}". You cannot use single-statement control-flow statements in CSHTML pages. For example, the following is not allowed:
what i am doing wrong not being able to understand. please help & guide. thanks
# symbol is only required when your code is contained within an HTML element. The using statement does not need the # because it is a direct decedent of your if else block.
Example:
<div> <!-- html tag -->
#if(something == somethingElse) // requires # because direct decedent of html tag <div>
{
<p>
#for (var i=0; i < len; i++) // requires # because direct decedent of html tag <p>
{
if(i == 1) // doesnt require #, not decedent of any HTML tag, instead direct decedent of another razor statement (for)
{
//do something
}
}
</p>
}
</div>
The # sign is use to distinguish between a simple string / HTML and razor statements. You only need that when you are writing C# code between HTML code. But when you are have started a C# code block, the ASP.NET MVC View Engine is intelligent enough to understand that the code that follows is C# and not simply some string.

jQuery .append(html) command appending incorrectly

I am using a jQuery/Ajax call to append a partial view to a table. When the page loads, the partial view is created correctly. However, once the use attempts to append another item to the table, the formatting is incorrect despite the exact same partial view being used.
Here is the table. When this loads, the items are loaded onto the page correctly as the picture below illustrates:
<table id="fixedRows">
<thead>
<tr>
<th>State Code</th>
<th>Agent ID</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.BankListAgentId)
{
if (!String.IsNullOrWhiteSpace(item.AgentId) && item.FixedOrVariable.Equals("F"))
{
#Html.EditorFor(model => item, "FixedPartialView")
}
}
</tbody>
</table>
<br />
Add Another
Once you click the Add another link, this jQuery/Ajax call is activiated
<script type="text/javascript">
$(document).ready(function () {
$(".addFixed").click(function () {
//alert('test');
event.preventDefault();
$.ajax({
url: '#Url.Action("BlankFixedRow", "BankListMaster")',
cache: false,
success: function (html) { $("#fixedRows").append(html); }
});
});
$("#addVariable").click(function () {
event.preventDefault();
$.ajax({
url: '#Url.Action("BlankFixedRow", "BankListMaster")',
cache: false,
success: function (html) { $("#variableRows").append(html); }
});
});
});
</script>
That jQuery calls this method from the controller
public ViewResult BlankFixedRow()
{
SelectList tmpList = new SelectList(new[] { "AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NA", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "US", "VT", "VI", "VA", "WA", "WV", "WI", "WY" });
ViewBag.StateCodeList = tmpList;
return View("FixedPartialView", new BankListAgentId());
}
Which calls this partial view
EDIT(a couple people noticed the id tag missing from the <tr>, this was just a copy/paste error for this post, the actual code has the id tag)
#model Monet.Models.BankListAgentId
#{
Layout = null;
}
#using (Html.BeginCollectionItem("BankListAgentId"))
{
<tr id="item-#Model.AgentId">
<td>
#Html.DropDownListFor(model => model.StateCode,
(SelectList)ViewBag.StateCodeList, Model.StateCode)
</td>
<td>
#Html.EditorFor(model => model.AgentId)
#Html.ValidationMessageFor(model => model.AgentId)
</td>
<td>
delete
</td>
#*<td>Delete</td>*#
</tr>
}
This is the same partial view that is called when the page first loads, which part of why I'm confused that the end result after hitting the Add another link turns out looking like this
EDIT
If you hit the Add another link twice, this is the result
EDIT
I've tried the following jQuery sucess commands with no luck
success: function (html) { $("#fixedRows > tbody:last").append(html); }
success: function (html) { $("#fixedRows tr:last").after(html); }
success: function (html) { $("#fixedRows > tbody").append(html); }
Here is the HTML that is rendered after the Add another link is clicked. I included the opening <form> tag for the form below it to show that the new rows are nowhere to be found.
<form action="/BankListMaster/Edit/11" method="post">
<fieldset>
<legend>Stat(s) Fixed</legend>
<table id="fixedRows">
<tr>
<th>State Code</th>
<th>Agent ID</th>
<th></th>
<th></th>
</tr>
<tr id="item-1164998320">
<td>
<select id="item_StateCode" name="item.StateCode"><option value="">HI</option>
<option>AL</option>
..
<option>WY</option>
</select>
</td>
<td>
<input class="text-box single-line" id="item_AgentId" name="item.AgentId" type="text" value="1164998320" />
<span class="field-validation-valid" data-valmsg-for="item.AgentId" data-valmsg-replace="true"></span>
</td>
<td>
delete
</td>
</tr>
<tr id="item-1164998219">
<td>
<select id="item_StateCode" name="item.StateCode">
<option value="">HI</option>
<option>AL</option>
..
<option>WY</option>
</select>
</td>
<td>
<input class="text-box single-line" id="item_AgentId" name="item.AgentId" type="text" value="1164998219" />
<span class="field-validation-valid" data-valmsg-for="item.AgentId" data-valmsg-replace="true"></span>
</td>
<td>
delete
</td>
</tr>
<tr id="item-0352926603">
<td>
<select id="item_StateCode" name="item.StateCode">
<option value="">GA</option>
<option>AL</option>
..
<option>WY</option>
</select>
</td>
<td>
<input class="text-box single-line" id="item_AgentId" name="item.AgentId" type="text" value="0352926603" />
<span class="field-validation-valid" data-valmsg-for="item.AgentId" data-valmsg-replace="true"></span>
</td>
<td>
delete
</td>
</tr>
</table>
<br />
Add Another
</fieldset>
</form>
Add Another
<form action="/BankListMaster/Edit/11" method="post">
EDIT
Here is a screen shot of the table in Chrome's debugger after the Add Another link is clicked. As you can see, the data pulled from the table is loaded properly in respective <tr> tags, however the empty row (which is sent via the same partial view as the rest) doesn't have any of the same table elements. The screen shot below that shows Response, however, which does include the <tr> tags
EDIT
I put a console.log(html) line in the success Ajax function so it now reads
success: function (html) {
console.log(html);
$("#fixedRows > tbody").append(html);
}
Here is the console output (state edited for readability)
<input type="hidden" name="BankListAgentId.index" autocomplete="off" value="3f7e0a92-8f20-4350-a188-0725919f9558" />
<tr>
<td>
<select id="BankListAgentId_3f7e0a92-8f20-4350-a188-0725919f9558__StateCode" name="BankListAgentId[3f7e0a92-8f20-4350-a188-0725919f9558].StateCode">
<option>AL</option>
..
<option>WY</option>
</select>
</td>
<td>
<input class="text-box single-line" id="BankListAgentId_3f7e0a92-8f20-4350-a188-0725919f9558__AgentId" name="BankListAgentId[3f7e0a92-8f20-4350-a188-0725919f9558].AgentId" type="text" value="" />
</td>
<td>
delete
</td>
</tr>
What a complete nightmare...
First off, the HTML that was being returned as viewable in Chrome's debugger was fine, however when I clicked on "View Source" for the page, I could not see anything but what was originally loaded. After finding this post, I found that this is normal. I then used this Chrome add-on to finally see that the <tr> and <td> tags were being stripped out. By simply adding an opening and closing tag to the append statement, I got the returned items to append to the table.
$(".addFixed").click(function () {
$.ajax({
url: '#Url.Action("BlankFixedRow", "BankListMaster")',
dataType: 'html',
cache: false,
success: function (html) {
$("#fixedRows > tbody").append('<tr>' + html + '</tr>');
}
});
});
I see a few things here. You're referencing <tbody> in some of your code but I don't see it anywhere in the page. So first I would suggest using <thead> and <tbody>. In your partial view I see <tr "item-#Model.AgentId"> which should have an id.
You should also remove the onclick handler and the delete button and put that in with the rest of your JavaScript. Set a class on your delete links instead.
For links that don't need urls and are only used for attaching JavaScript handlers, I recommend using href="javascript:void(0)" as this would prevent the browser from doing anything special with href="#" so then you'll be able to remove the calls to preventDefault().
As to the source of your problem, $("#fixedRows tbody").append(html) is the code you want so no need to try after(). It looks like your html is getting stripped. Try setting the dataType attribute in the $.ajax() call to html.

Resources