Select following-sibling if element unknown - ruby-on-rails

I want to select the first sibling of a tag from an HTML element. Lets say I want to get the <a> that follows this <span>:
<span id="unique"></span>
<a href="#">
This can easily be done with the following Xpath:
//div[#id="unique"]/following-sibling::a
This, however, is very specific in a way that it looks for an <a> tag. How can I make it more generic that it would find any tag as long as it is the first sibling to the element I selected?

Write as below
//span[#id="unique"]/following-sibling::*[1]
Here is a sample HTML :
<div>
<span id="unique"></span>
<p>foo</p>
<p>bar</p>
</div>
XPATH expression:
//span[#id="unique"]/following-sibling::*[1]
output
<p>foo</p>

Related

How to apply elvis operator in Thymeleaf?

how to apply a ternary condition that Elvis Operator in Thymeleaf.
I tried this but there is an error showing in IDE. the error Tag start is not closed
<div th:utext="${ed.aurl} ? '<button th:href="#{ed.aurl}" target="_blank" download>View Attachment </button>' : 'No Attachment' "></div>
You shouldn't/can't use HTML in attributes like that (it's expecting a valid HTML doc)... why not write this as regular HTML?
<div>
<button th:if="${ed.aurl}" th:href="#{ed.aurl}" target="_blank" download>View Attachment</button>
<span th:unless="${ed.aurl}">No Attachment</span>
</div>

SLIM h3 inside p

If I want to put header tag h1..h5 into p it render HTML in wrong way:
slim
p
h3 Header here
span Just text
expected
<p>
<h3>Header here</h3>
<span>Just text</span>
</p>
in real it render
<p></p>
<h3>Header here</h3>
<span>Just text</span>
<p></p>
looks like nothing special but in this case I can't bind CSS style because structure renders in broken way.
Is it a bug? Or I can solve this in some way?
You can not define tags like h3 and span inside the p tag.
See HTML5 specification for more information.
Slim itself doesn’t care about the tags, and renders your code as you expect:
$ slimrb
p
h3 Header here
span Just text
produces:
<p><h3>Header here</h3><span>Just text</span></p>
which matches what your expected code, except for whitespace.
This isn’t valid HTML though, so when the browser parses it it will correct it to something valid. For example the Chrome inspector will show:
<p></p>
<h3>Header here</h3>
<span>Just text</span>
<p></p>
Where the browser has closed the p element before the next h3 element.
If you want this to work in the browser, make sure you are generating valid HTML. Perhaps use a div instead of a p?

Capybara: how to retrive the Test Services code value(F603YPW) of an element from below html page

I want to retrieve the value of Test Services code
<p>
<span class="floatLeft w30p">Test Services code:</span>
<span> <strong>F603YPW</strong> </span>
</p>
The rest of the page will really affect what selector(s) you would need to use to get that text, however given only the HTML specified you can use the css adjacent sibling selector to get the element
value = find(:css, 'span.floatLeft.w30p + span').text
if there are a bunch of other elements with the floatLeft and w30p classes then you could get more complicated using xpath selectors and do something along the lines of
value = find(:xpath, XPath.descendant(:span)[XPath.string.n.is('Test Services code:')].next_sibling).text
or with multiple finds
value = find(:css, 'span', text: 'Test Services code:').find(:xpath, XPath.next_sibling).text
If you are able to edit the HTML to
<p>
<span class="floatLeft w30p">Test Services:</span>
<span class="your_class"> <strong>F603YPW</strong> </span>
</p>
(so by adding a class to the span),
you will be able to find its value doing
value = page.find('.your_class').text
If you are not able to edit the HTML, do
value = find(:css, 'the css selector').text

Grails: Removing Unwanted Brackets when Displaying Variable

I have a .gsp page where a student can select a course that they are in. That selection is then stored in an array list. I have another .gsp page that shows student details and within those details it shows which course they selected from the other page. However, when it displays the course it displays like this: "[courseName]", but I would like it to display without the brackets: "courseName".
This is my code for displaying the selection:
<g:if test="${studentDetails?.course}">
<li class="fieldcontain">
<span id="course-label" class="property-label">
<g:message code="student.course.label" default="Course(s)" /></span>
<span class="property-value" aria-labelledby="course-label">
<g:set var="course" value="${studentDetails?.course.courseName}" />
<g:message message="${course}" /></span>
</li>
</g:if>
So far I've tried displaying the variable with g:fieldValue, g:message, and just the variable itself without a tag. All methods display with the brackets. Any suggestions on how to remove the brackets are appreciated. If any other code is needed I can provide it. Thanks.
If your studentDetails?.course.courseName contains a List of courses and your want to display all of them, you need to convert it to a String. But default implementation of List.toString() uses brackets. Your could use .join(',') instead.
Like:
<g:if test="${studentDetails?.course}">
<li class="fieldcontain">
<span id="course-label" class="property-label">
<g:message code="student.course.label" default="Course(s)" /></span>
<span class="property-value" aria-labelledby="course-label">
${studentDetails.course.courseName.join(', ')}
</span>
</li>
</g:if>
Also I suggest to add .encodeAsHTML() if you got this data (course name) from a user, to escape any HTML content inside variables (avoid XSS, etc). Like:
${studentDetails.course.courseName.join(', ').encodeAsHTML()}

How do I have an Angular.dart filtered list update automatically

I have an html template that filters a list by the column property of the objects of that list like so:
<ul>
<li card-view
card-id="state.card"
ng-repeat="state in ctrl.game.states | filter:{column:'backlog'} "
ng-include="cardview.html">
</li>
</ul>
If I modify the column property in one of the elements of that list, the display does not update.
How can I make that happen?
Here's one option that uses an imaginary placeholder tag and avoids the |filter replacing it with an ng-if, but I hope someone has a better answer than this one.
<ul>
<xx ng-repeat="state in ctrl.game.states">
<li card-view
card-id="state.card"
ng-if="state.column == 'backlog'"
ng-include="cardview.html">
</li>
</xx>
</ul>
Doing the ng-if and ng-repeat on the same element didn't work.

Resources