XPath with text() to get specific text node - atata

<td style="width: 40.42%;" id="ember193" class="lt-cell align-left ember-view">
<div class="inline-block ember-tooltip-target">
<i class="fa fa-fw fa-lg valid"></i>
<div id="ember195" class="ember-tooltip-base ember-view">
<div><!----></div>
</div>
</div>
UNIVERSITY OF VERMONT AND STATE AGRICULTURAL COLLEGE
(03-0179440)<!----><br>
<div class="fa fa-fw fa-lg"></div>
(UNIVERSITY OF VERMONT)
</td>
In the browser console, I execute this:
$x("//tbody/tr[2]/td[2]/text()[7]")
and I get the actual text node I am looking for (amongst other text nodes in td2) - is there a way to specify this in a Text<_> property attribute to get just this text node?

Currently, there is no attribute to get a value of child text node by index, only first or last. Anyway, I would try not to rely on child node index as it can vary. I would try to extract the number part from the given text.
You can do it with a help of 2 properties:
[FindByXPath("td")] // TODO: Change it to your <td> locator.
[GetsContentFromSource(ContentSource.ChildTextNodesTrimmed)]
private Text<_> OrganizationNameInfo { get; set; }
public DataProvider<string, _> OrganizationNumber => GetOrCreateDataProvider(
"Organization Number",
() =>
{
string organizationNameInfo = OrganizationNameInfo.Value;
return organizationNameInfo.Substring(1, organizationNameInfo.IndexOf(')') - 1);
});
OrganizationNameInfo property because of ContentSource.ChildTextNodesTrimmed returns "(03-0179440)(UNIVERSITY OF VERMONT)" value. So in OrganizationNumber property you can easily extract as a sub-string the part you need.
Another option can be to use Regex to extract the number part.

Related

how to click on edit a button in front of Particular text in Cypress

I want to click on the edit button in front of if found Yes in the third column(Yes is also have botton)
element
I was using below code in test case but didn't work
`cy.get(':nth-child(6)').contains('Yes').within(() => {
cy.get('.btn.btn-xs.btn-edit').click()
})
or
`cy.get(':nth-child(6)').contains('Yes').find(button).eq(1).click()
HTML Table Structure
<tr role="row" class="even">
<td class="sorting_1">
abc
</td>
<td>xyz</td>
<td>aws</td>
<td>No</td>
<td>No</td>
<td>"Yes"
<button data-role="remove" id="support_22_abc" class="btn btn-rejecttxt" onclick="deletevm(this,'3','3:5659','22','abc','22_abc','284')"><i class="fa fa-times-circle" data-original-title="Remove Mapping" data-toggle="tooltip"></i></button></td>
<td>No</td>
<td>
<div class="btn-group">
<a href="http://192.168.0.1:8080/edit">
<button class="btn btn-xs btn-edit">
<i class="fa fa-pencil" data-original-title="Edit/Update row data" data-toggle="tooltip" data-placement="top"></i></button></a>
</div></td></tr>
If I'm reading it correctly, you want the 3rd <td> after the one with "Yes ".
Not sure what :nth-child(6) is selecting, but try this
cy.contains('td', 'Yes')
.siblings()
.eq(6) // 6th sibling
.find('button.btn.btn-xs.btn-edit')
.click()
Assuming .btn.btn-xs.btn-edit is the correct selector for edit button. You can directly use the eq command to click the edit button on the third row.
cy.get('.btn.btn-xs.btn-edit').eq(2).click()
Based on the available info, I came up with this. Here we are looping through the all the tr first and then using within we are scoping the next commands inside the same tr. Now using eq(5) we are searching for the Yes button, and if we found the it, then we click the Edit button.
cy.get('tr').each(($ele) => {
//Loop through all tr
cy.wrap($ele).within(() => {
//scope the next commands within the same tr
cy.get('td')
.eq(5)
.invoke('text')
.then((text) => {
//here eq(5) gets the sixth td element in the row
if (text.includes('Yes')) {
cy.get('.btn.btn-xs.btn-edit').click()
}
})
})
})

How to get className of an element in jsdom?

first time posting so sorry if I mess something up. Below is the code I have tried:
const domPreParse = new JSDOM(incident); //incident is the html fragment I want to parse
const dom = domPreParse.window.document;
const cNameHome = dom.querySelector('[data-type="home-icon"], svg').className;
So cNameHome returns an object with only the first class name. There are multiple class name on the element (e.g. class="class1 class2"). How can I return all the classes in a space separated string preferably.
And this is the code I'm trying to parse:
<div class="sco" data-type="middle">
<div class="clear">
<span class="inc" data-type="home-icon"></span>
<span class="score" data-type="score"> </span>
<span class="inc" data-type="away-icon">
<svg class="inc yellowcard"><use xlink:href="#icon-yellowcard"></use></svg>
</span>
</div>
</div>
Thanks for the help.
The problem was my CSS selectors. I should have used [data-type="home-icon"] > svg.

Jsviews filter search

How do I create a filter search in JSViews? Usually I'd grab the html element by its class with the .getElementsByClassName() and .value() methods and add a === comparison to satisfy the right criteria. How can I do something similar in JsViews
I've already tried to add listItem in the IF to match the value of the html input (search bar), but I don't know how to grab the value of the search element (JQuery would be easy using $(".search")), or compare it to the listItems using regExp.
{^{if list && list.length}}
<ul autoselectitem="true" tabindex="-1" operationalindex="1" allindex="1">
{^{for list}}
{{include tmpl="listItem" /}}
{{/for}}
</ul>
{{else}}
<p>Nothing Found</p>
{{/if}}
This currently displays all items in the list, however I only want the elements in the list to be displayed that match with RegEx the .value of an search HTML element:
<input type="text" class="search" data-link="search" placeholder="Search...">
So for example, if I type in "e" into the search bar, all the items in the list that don't have the letter "e" should disappear.
The code linked all work, but what i've tried has given me null pointer errors because I'm not grabing the input element correctly by its class or data-link. How could I do this in the simplest way possible? Thanks
Here is one way of doing it:
<script id="myTmpl" type="text/x-jsrender">
<input type="text" class="search" data-link="search" placeholder="Search...">
{^{if list && list.length}}
<ul autoselectitem="true" tabindex="-1" operationalindex="1" allindex="1">
{^{for list filter=~flt depends="search"}}
<li data-link="#data"></li>
{{/for}}
</ul>
{{/if}}
</script>
<div id="page"></div>
<script>
var myTmpl = $.templates("#myTmpl"),
data = {
list: ["a", "b"],
search: ""
},
helpers = {
flt: function(item, index, items) {
return item.indexOf(data.search) > -1;
}};
myTmpl.link("#page", data, helpers);
</script>

If element hasClass, add another class to its title value

I'm using slick carousel, and once a div is active I want to open the corresponding description.
Problem I'm having is with this code:
if ($('div').hasClass('active')) {
var title = $(this).attr('title');
$('ul li').removeClass('open');
$(title).addClass('open');
}
What I'm trying to achieve:
Once a div gets class 'active', I want to take its title value, and use it as a id link to list element I want to display(add class to).
Here is a FIDDLE.
Use event handling, not class monitoring.
The slick carousel API has events for this, I believe you want to use the afterChange event to act on the active element after it has been made visible.
Check out the docs and examples, especially the section titled "Events" on Slick page: http://kenwheeler.github.io/slick/
And I think you don't want to use title attribute for this because that is for tooltips. I recommend data-* attributes instead. And element IDs should generally start with a letter and not a number (was required in HTML4 and makes life easier when mapping IDs to JavaScript variables; though if you are using HTML5 I think this requirement is no longer in effect).
HTML
<div id="carousel">
<div data-content-id="content1">
Selector 1 </div>
<div data-content-id="content2">
Selector 2 </div>
<div data-content-id="content3">
Selector 3 </div>
</div>
<ul class="content">
<li id="content1">Content 1</li>
<li id="content2">Content 2</li>
<li id="content3">Content 3</li>
</ul>
JavaScript
$('#carousel').on('afterChange', function(event, slick, currentSlide) {
// get the associated content id
var contentId = $(slick.$slides.get(currentSlide)).data("content-id");
if(contentId && contentId.length)
{
var $content = $("#" + contentId);
$(".content>li").removeClass("open"); // hide other content
$content.addClass("open"); // show target content, or whatever...
}
});
I have found a solution:
$('.slider').on('afterChange', function(event, slick, currentSlide, nextSlide){
var contentId= $(slick.$slides.get(currentSlide)).data('content');
if(contentId)
{
$(".content li").removeClass('open');
$('#' + contentId).addClass('open');
}
});
Working fiddle

How to edit a custom DisplayWithIdFor?

I have created a DisplayWithIdFor using the following code and it works showing the information I wish it to.
public static class DisplayWithIDHelper
{
public static MvcHtmlString DisplayWithIdForApplication<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string wrapperTag = "div")
{
var id = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
return MvcHtmlString.Create(string.Format("<{0} style=\"color: #003F51; margin-left: 87px;\" class=\"{1}\">{2}</{0}>", wrapperTag, id, helper.DisplayFor(expression)));
}
}
My problem is simple, when I use the custom helper I end up with the label saying Application and the displayfor holding the name of the application showing with no space between them. see below.
Lastly here is the code for the image above:
<form>
<fieldset>
<p>
#Html.LabelFor(model => model.changeStatus.usersName)
#Html.DisplayFor(model => model.changeStatus.usersName)
#Html.HiddenFor(model => model.changeStatus.usersName)
#Html.ValidationMessageFor(model => model.changeStatus.usersName)
</p>
<p style="display: inline; float: left">
#Html.LabelFor(model => model.changeStatus.application)
#Html.DisplayWithIdForApplication(model => model.changeStatus.application)
#Html.HiddenFor(model => model.changeStatus.application)
#Html.ValidationMessageFor(model => model.changeStatus.application)
</p>
<p>
#Html.LabelFor(model => model.changeStatus.reasons)
#Html.TextAreaFor(model => model.changeStatus.reasons, new { #cols = "80", #rows = "4", #class = "k-textbox" })
<span style="color: red;"> #Html.ValidationMessageFor(model => model.changeStatus.reasons)</span>
</p>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</fieldset>
</form>
Can anyone explain how to add the spacing between the two Html Helpers?
any additional code can be supplied like the Jquery popup code.
Thank you.
Edit:
Just to make things a little clearer I have to get the application name from the row of a kendo grid that is selected and set the name in the jquery using the following code:
$("div[class='changeStatus_application']").html(applicationName);
To simplify and ensure everything is acting the same, remove the:
style="display: inline; float: left"
from the second paragraph tag and use an element like a span instead of a div (block level element) in your helper.
You may then want to alter the margin left on your DisplayWithIDHelper.
Also try using classes instead of style attributes. You can then change the look of your site through your style sheet without having to recompile plus styles are centralised; easier to maintain.

Resources