I am developing an application using MVC4 and handling the clienside validation using jquery.validate.unobtrusive.
I am simply using model validation and the following
<label for="fname">Name</label>
#Html.TextBoxFor(m => m.Name, new { id = "Name", #maxlength = "16", aria_describedby = "validationName" })
#Html.ValidationMessageFor(m => m.Name, string.Empty, new { id = "validationName" })
When I run the code, it renders the validation message with tags like
<span id="validationName" class="field-validation-error" data-valmsg-replace="true" data-valmsg-for="Name">
<span class="" for="fname" generated="true">Your name is required.</span>
For the CSS purpose, I need to change the span id="validationName" to
p id="validationName"
I think the span tag is coming from framework or something since I can't find span tag anywhere in my code beside the validation js file.
I see "options:errorClass:"input-validation-error",errorElement:"span"" in unobtrusive.js file but changing that span to p changes the second span class="" to p class="" without effecting the first span.
The reason I am looking for p tags is that span tags are best for inline styles; p tags style error message blocks as “block-level elements” which drops them down a line rather than making them wrap. Also, p tags would read describe error messages as “paragraphs” rather than hanging text with no meaning
Any suggestion would be really appreciated.
Related
I am creating a parser using Jsoup in Kotlin
I need to get a inner text of a tag with class "ptrack-content" inside the tag with class "titleCard-synopsis"
When I am trying to getElementsByClass in a element objects that created by a former getElementsByClass, I getting 0 elements
Code:
class NetlifxHtmlParser {
val html = """
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title"><span class="titleCard-title_text">Map Her</span><span><span class="duration ellipsized">50m</span></span></div>
<p class="titleCard-synopsis previewModal--small-text">
<div class="ptrack-content">A hidden map rocks Hartley High as the students' sexcapades are publicly exposed. Caught as the culprit, Amerie becomes an instant social pariah.</div>
</p>
</div>
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title"><span class="titleCard-title_text">Renaissance Titties</span><span><span class="duration ellipsized">50m</span></span></div>
<p class="titleCard-synopsis previewModal--small-text">
<div class="ptrack-content">Amerie, the new outcast, receives a party invitation that gives her butterflies. But when she manages to show up, a bitter surprise awaits.</div>
</p>
</div>
""".trimIndent()
fun parseEpisode() {
val doc = Jsoup.parseBodyFragment(html)
val titleCards = doc.getElementsByClass("titleCard-synopsis")
println("Episode: count titleCard = > ${titleCards.count()}") // 2
titleCards.forEachIndexed { index, element ->
val ptrack = element.getElementsByClass("ptrack-content")
println("Episode: count ptrack = > ${ptrack.count()}") // 0 !!
println("inner html = > ${ptrack.html()}") // null string !!
}
}
}
In the above code,
First, I am extracting tags with class name titleCard-synopsis.
For that , I using doc.getElementsByClass("titleCard-synopsis") which returns 2 element items.
Then, In the List of titleCard elements, I am extracting the elements that have ptrack-content as Class, by using the same getElementsByClass in each element,
which returns empty list.
Why this is happening ?
My goal is, I need to extract the description text for each title, the stored in the interior tags of p tag with class titleCard-synopsis.
If I try to get directly from "ptrack-content", it's working fine, but this a general class used in many places in the main HTML source. (this is snippet)
I need to get a inner text of a tag with class "ptrack-content" inside the tag with class "titleCard-synopsis"
But in the above method in the code, I am only getting emtpy list.
Why ?
Also note that, if I invoke the HTML() method in a element object of titleCards(ptrack.html()),
I am not getting the inner DIV tag, an empty string!!!
Please guide my to resolve the issue !
TL;DR
I need to get a inner text of a tag with class "ptrack-content" inside the tag with class "titleCard-synopsis"
I'm not really familiar with Kotlin, but this should produce the desired output:
val doc = Jsoup.parseBodyFragment(html)
val result = doc.select(".titleCard-synopsis + .ptrack-content")
result.forEachIndexed {index, element ->
println("${element.html()}")
}
Live example
This is an interesting problem!
You basically have an invalid HTML and jsoup is smart enough to auto-correct it for your. Your HTML structure gets altered and suddenly your query does not work.
This is the error:
<p class="titleCard-synopsis previewModal--small-text">
<div class="ptrack-content">A hidden map rocks Hartley High as the students' sexcapades are publicly exposed. Caught as the culprit, Amerie becomes an instant social pariah.</div>
</p>
You can't nest a <div> element inside a <p> element like that.
Paragraphs are block-level elements, and notably will automatically close if another block-level element is parsed before the closing </p> tag. [Source: <p>: The Paragraph element]
Also, look at Nesting block level elements inside the <p> tag... right or wrong?
This is how jsoup parses your tree:
<html>
<head></head>
<body>
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title">
<span class="titleCard-title_text">Map Her</span><span><span class="duration ellipsized">50m</span></span>
</div>
<p class="titleCard-synopsis previewModal--small-text"></p>
<div class="ptrack-content">
A hidden map rocks Hartley High as the students' sexcapades are publicly exposed. Caught as the culprit, Amerie becomes an instant social pariah.
</div>
<p></p>
</div>
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title">
<span class="titleCard-title_text">Renaissance Titties</span><span><span class="duration ellipsized">50m</span></span>
</div>
<p class="titleCard-synopsis previewModal--small-text"></p>
<div class="ptrack-content">
Amerie, the new outcast, receives a party invitation that gives her butterflies. But when she manages to show up, a bitter surprise awaits.
</div>
<p></p>
</div>
</body>
</html>
As you can see, elements with class titleCard-synopsis have no children with class ptrack-content.
I'm using RiotJS v3.9
I've written a custom tag that accepts a few opts. The problem is that the markup it generates includes all of those opts on the outermost element, in addition to the interior tags where I explicitly deposit them. I do not want any opts to appear on the top element unless I make that happen.
In this case, my custom tag display a list of items. One of the opts it accepts is the value for a specific data- attribute on each list item. So, I want data-something={opts.itemSomething} to appear on each list item, but I do not want that to appear on the wrapper.
// my-list.tag
<my-list>
<ul data-something={ opts.something }>
<li
each={ item in opts.items }
data-something={ parent.opts.itemSomething }
>
{ item }
</li>
</ul>
</my-list>
Using it:
<my-app>
<my-list
something="parent-value"
item-something="child-value"
items={['one', 'two', 'three']}
/>
</my-app>
What it emits into the page:
<my-list something="parent-value" item-something="child-value">
<ul data-something="parent-value">
<li data-something="child-value"> one </li>
<li data-something="child-value"> two </li>
<li data-something="child-value"> three </li>
</ul>
</my-list>
I don't want the emitted <my-list> tag to have either the parent-value or the child-value on it. I only want those attributes to appear on the <ul> and <li>, like I coded it.
// bad output
<my-list something="parent-value" item-something="child-value">
// good output
<my-list>
Is this possible?
Also, I know from working with React that I'm likely to encounter future cases where I want some of the opts to appear on the wrapper while hiding others. So, ideally I'd like to know how to control this behavior on a per-opt basis.
you can remove the unwanted attributes in both the "updated" and "mount" event.
check this demo
However I strongly suggest you to switch to riot#5!!
There are many planbox, which are having same class and ids, inside them there are a number of <p> tags and decorated text.
<div class="planbox">
<p class="baseprice">
<span>
<strike> $70 </strike>
</span>
</p>
<p> New discount price is etc. </p>
</div>
<div class="planbox">
<p class="baseprice">
<span> $70 </span>
</p>
</div>
Now, My test case is - if the base price is strikethrough, only then <p> 'New discount price .. </p> will show, otherwise not.
How to check whether a text is strikethrough or not? And even if we get this how will I check that <p> New discount.. </p> should not show if the text is not striked.
As there is no class in <p> tag on which I can check whether it displayed or not.
One solution in my mind was - add one dummy class in <span> tag and using findChildren('span.dummyCLass') it will result all the webelements having dummyClass.
Now I will check whether web-elements have strike tag or not, and this is the place where I got stuck.
Initially, i was thinking of a Jquery solution, but is it possible to do without adding new class and jquery?
You don't need to add a class to any element to accomplish this task. In general, you don't want to edit the HTML. Another issue is... if you can find the element to add a class, then you don't need to add the class to find the element. :)
The way I approach tasks like these is to find the outermost element that contains all the elements that you are interested in. I refer to this as a "container". What you want to do in this case is to find the containers and loop through them looking for the strikethrough price and for the "New discount price..." text.
The containers are DIVs with the planbox class. The strikethrough price is indicated by the STRIKE tag. The "New discount price..." text is in a P tag. With this info we can write some code. This is Java because I don't know what language you want and I'm not familiar with the Galen framework.
// gets the collection of containers using a CSS selector
List<WebElement> containers = driver.findElements(By.cssSelector("div.planbox"));
// loops through the containers
for (WebElement container : containers)
{
// determine if the STRIKE tag exists
boolean strikeExists = !container.findElements(By.tagName("strike")).isEmpty();
// determine if the "New discount price is..." text exists in the 2nd P tag
boolean discountPriceExists = container.findElements(By.tagName("p")).get(1).getText().trim().contains("New discount price is");
// if both are true log a pass, otherwise log a fail
if (strikeExists && discountPriceExists)
{
// log a pass
}
else
{
// log a fail
}
}
I haven't used much of selenium. But you can port this jquery code to selenium,
//if there is a strike element
if($(".baseprice span strike").length > 0){
//next() will select the sibling of the p tag with baseprice class
$("p.baseprice).next() != undefined){
return true
}else{
return false
}
}
you can use Galen for this. There you can verify certain CSS properties.
Below is a snippet from a sample tab control from here: http://layout.jquery-dev.net/demos/tabs.html
Those tabs inside those splitter panes are exactly what I need. But I need the tabs to be dynamically added and removed based on user interaction. Thought I could do it with composite or collection views in backbone marionette - add/remove things from the underlying collection and tabs appear and disappear in the UI.
Conceptually this shouldn't hard. But the difficulty comes in with the the dreaded extra wrapping div problem that is so discussed in various threads over the years.
Extra divs in itemviews and layouts in Backbone.Marionette
In my case, each li in my ul comes up wrapped in a it's own div. That messes up the CSS in the code snippet below. It breaks some of it, so things look weird. If I could just produce the output below, things wouldn't look weird.
<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all ui-sortable" role="tablist">
<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-west-1" aria-labelledby="ui-id-1" aria-selected="true">
Nunc tincidunt
</li>
<li class="ui-state-default ui-corner-top" role="tab" tabindex="-1" aria-controls="tabs-west-2" aria-labelledby="ui-id-2" aria-selected="false">
Proin dolor
</li>
</ul>
The output above has complex li's rendered directly in the ul container which is also complex. Why can't I make that output happen?
This extra wrapping div seems to be the default behavior of backbone marionette when itemView's are rendered. Many answers in these threads center on setting the tagName property to li. Problem is that produces a blank, generic li. Look at the li's in the snippet above. They have lots of properties.
My li's will need to have unique id's and styling and other attributes like those above. Making your item view's tagName an li just produces a simple li in your output. How do I get my dynamic id's and styling classes and such in there?
My first attempt to fix this was to pull the li code into my handlebars template so I could encode it with the dynamic data I needed:
var TabItemView = Marionette.ItemView.extend({
template: Handlebars.compile(
'<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-{{id}}" aria-labelledby="ui-id-{{id}}" aria-selected="true">' +
'{{tabName}}' +
'</li>'
),
});
But that now wraps each li in my list in it's own container div. Every combination of using el, tagName, appendHtml override produces either a wrapping element or incorrect results - like appendHtml override causes each new tab to simply replace existing tabs - so I only ever have one tab, the latest one added.
What am I missing here? Why can't I define a template for an li containing dynamic data in it and render it DIRECTLY to my ul WITHOUT an extra wrapping div around each list element? I guess another way to phrase the question is I am working with an existing template that REQUIRES complex li's. How do I produce them in a composite or collection view WITHOUT the extra wrapping container around them?
Backbone and Marionette seem to offer the promise of being able to do things like this in a way more manageable than doing it in straight jQuery. I'm not having that experience. What am I not seeing?
I don't use Marionette, but I don't see why it would override Backbone's default behavior. This should give you an idea:
var TabView = Marionette.ItemView.extend({
tagName: 'ul',
className: 'ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all ui-sortable" role="tablist',
render: function() {
//something like this
var _this = this;
this.collection.each(function(item){
var view = new TabItemView({
model: item
});
_this.$el.append(view.render().el)
})
}
});
var TabItemView = Marionette.ItemView.extend({
tagName: 'li',
className: 'ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tablist',
template: Handlebars.compile(
'{{tabName}}'
),
});
Regarding managing views and data to produce specific HTML output, I suggest you take a look at my blog post here: http://davidsulc.com/blog/2013/02/03/tutorial-nested-views-using-backbone-marionettes-compositeview/
That should get you to structure the views so they render properly. Then, you can add http://backbonejs.org/#View-attributes to the mix to get your complex attributes (for which there aren't existing Backbone attributes such as className).
and thanks in advance for your help!
Here's my situation: I have a set of divs whose IDs have an incrementing number applied to the end of the name using PHP. Each of these divs are added dynamically with PHP (They are a series of FAQ questions with a hidden div container with the answers, that slide down when the question is clicked.) [Live Example][1]
There is no limit to the number of questions that appear on the page, because this is being used for a Wordpress theme and my client wants to add new questions as they go along.
Here's an example of the structure for each FAQ question using the PHP:
<?php var $faqnum = 0; $faqnum++; ?>
<div id="faqwrap<?php $faqnum; ?>">
<h4>What data is shared?</h4>
<div id="faqbox<?php $faqnum; ?>" class="slidebox">
<p>Data sharing is defined by the type of service:</p>
<ul class="list">
<li>Third-party access to data (Enhanced Services only is strictly controlled and determined by the SDA)</li>
<li>All members must participate in points of contact and conjunction assessment but can choose whether to participate in other services</li>
<li>Participation in a service requires the member to provide associated data<br />
</ul>
</div>
</div>
Now this is what I have currently in jQuery, and it works, but only if I add a new one every time my client wants to add a new question.
$(document).ready(function() {
$('.slidebox*').hide();
// toggles the slidebox on clicking the noted link
$("#faqwrap1 a:not(div.slidebox a)").click(function() {
$("#faqbox1.slidebox").slideToggle('normal');
$('div.slidebox:not(#faqbox1)').slideUp('normal');
return false;
});
});
I thought of maybe doing something with a declared variable, like this:
for (var x = 0; x < 100; x++;) {
$('#[id^=faqwrap]'+ x 'a:not(div.slidebox a)')...
}
I hope this is clear enough for you! Again, I thank you in advance. :)
The best way to handle this is to not use the IDs, but use classes for the outer element. So your PHP would be altered like this:
<?php var $faqnum = 0; $faqnum++; ?>
<div id="faqwrap<?php $faqnum; ?>" class="question">
<h4>What data is shared?</h4>
<div id="faqbox<?php $faqnum; ?>" class="slidebox">
<p>Data sharing is defined by the type of service:</p>
<ul class="list">
<li>Third-party access to data (Enhanced Services only is strictly controlled and determined by the SDA)</li>
<li>All members must participate in points of contact and conjunction assessment but can choose whether to participate in other services</li>
<li>Participation in a service requires the member to provide associated data<br />
</ul>
</div>
</div>
Your JQuery would be rewritten with the selector for the class "question".
$(document).ready(function() {
$('.slidebox*').hide();
// toggles the slidebox on clicking the noted link
$(".question a:not(div.slidebox a)").click(function() {
/* close everything first */
$('div.slidebox').slideUp('normal');
/* selects and opens the the slidebox inside the div */
$(".slidebox", this).slideToggle('normal');
return false;
});
});
This will get you the effect you are looking for. The key differences in the JQuery is the way you get the slidebox inside the question that got clicked. I'm using the scoped selection $(".slidebox", this) to get just the slidebox inside the clicked ".question" element.
The subtle visual difference is that the slideUp() happens before the slideToggle(). This will essentially close any open queries before it opens the desired one. If you keep your animations fast, this will be more than fine. The advantage of this approach is that you don't have to worry about the count of questions on a page, and the selectors are most likely more optimized than the for loop.
Edit
I adjusted the PHP code to use a class for "slidetoggle" instead of an id. It's technically an HTML error to have multiple IDs that are the same. It can throw off some assistive technologies for people with dissabilities. I'm assuming that section of code was repeated several times on the page.
Without changing your current markup, this would work:
// toggles the slidebox on clicking the noted link
$("div[id=^faqwrap]").each(function () {
var $faqwrap= $(this);
$faqwrap.find("h4 > a").click(function () {
var $currentSlidebox = $faqwrap.children(".slidebox");
$currentSlidebox.slideToggle('normal');
$('div.slidebox').not($currentSlidebox).slideUp('normal');
return false;
});
});
Maybe you can find a few suggestions in the above code that help you.
Like #Berin, I'd also recommend giving a separate CSS class to the outer DIV and using that as a selector, instead of $("div[id=^faqwrap]").