I have weird structure and want to disabled first element inside li.expanded using a[href="/abc"]. I have parent and child have same href and title is different. How can I select parent only element?
Here the code:
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">xyz-parent</li>
<li class="leaf">pqr</li>
<li class="last expanded">abc //want to find this element and apply treatment
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">abc</li> //not this one
<li class="last leaf">mno</li>
</ul>
</li>
</ul>
What I have tried, the function is working. it's selecting both a[href="/abc"] parent and child. I want to find and select only parent one.
openabcInNav: function() {
var navEl = $('#main-menu, #main-right-menu li.expanded').find('a[href="/abc"]:nth-child(1)');
navEl.addClass('doNotClose');
navEl.on('click mouseover', function(event) {
event.preventDefault();
$('nav.global-nav').find('li.expanded').toggleClass('show');
});
},
You could use the :first selector that will return the first occurrence what it the parent :
$('ul>li.expanded>a[href="/abc"]:first')
$('ul>li.expanded>a[href="/abc"]:first').css('background-color', 'green');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">xyz-parent</li>
<li class="leaf">pqr</li>
<li class="last expanded">abc //want to find this element and apply treatment
<ul class="n-right m-menu__link-list" id="main-right-menu">
<li class="first leaf">abc</li> //not this one
<li class="last leaf">mno</li>
</ul>
</li>
</ul>
a[href="/abc"]:nth-child(1) looks at first child object inside a[href="/abc"]
Try using:
a[href="/abc"]:nth-of-type(1)
This will return the first that matches a[href="/abc"]
Related
I have few li elements and I want each of them to be clickable. This is what I have:
<li id="stream-object" data-stream="val1">
<li id="stream-object" data-stream="val2">
<li id="stream-object" data-stream="val3">
and my jquery
$("#stream-object").click(function(){
var stream_link=$(this).data("stream");
$("#main_stream").attr("data",stream_link);
});
But this only works on the first li.
This is expected behavior as ID's in HTML must be unique, You can use a common class then use Class Selector (“.class”)
Selects all elements with the given class.
HTML
<li class="stream-object" data-stream="val1">
<li class="stream-object" data-stream="val2">
<li class="stream-object" data-stream="val3">
Script
$(".stream-object").click(function(){
var stream_link=$(this).data("stream");
$("#main_stream").attr("data",stream_link);
});
ID (#) must be unique for page use clasess (.) instead
<li class="stream-object" data-stream="val1">
<li class="stream-object" data-stream="val2">
<li class="stream-object" data-stream="val3">
$(".stream-object").click(function(){});
An id should be unique. Instead use classes
$(".stream-object").click(function(){
var stream_link=$(this).data("stream");
$("#main_stream").attr("data",stream_link);
alert( $(this).html()+' is clicked' );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="stream-object" data-stream="val1">Item 1</li>
<li class="stream-object" data-stream="val2">Item 2</li>
<li class="stream-object" data-stream="val3">Item 3</li>
</ul>
I have a portfolio site set up and I have my portfolio set up to shuffle through by selecting certain filters. What I want to do is set some header text, based upon which filter they choose.
The issues is when I select a link, let's say advertising, Advertising will show up as my header text. However if I select something else, say branding, it doesn't change, it stays at advertising.
here is my html
<div id="portfolio-filter-container">
<h2 class="workFilterSelect">FILTER OPTIONS: <span class="currentFilter">ALL</span></h2>
</div>
<ul id="portfolio-filter">
<!--<li class="workFilterSelect">FILTER OPTIONS:</li>-->
<li class="workFilterButtons">All</li>
<li class="workFilterButtons">Advertising</li>
<li class="workFilterButtons">Branding</li>
<li class="workFilterButtons">Catalog</li>
<li class="workFilterButtons">Corporate ID</li>
<li class="workFilterButtons">Consumer Relations</li>
<li class="workFilterButtons">Incentive/Loyalty</li>
<li class="workFilterButtons">Packaging</li>
<li class="workFilterButtons">Product Launch</li>
<li class="workFilterButtons">Promotion</li>
<li class="workFilterButtons">Public Relations</li>
<li class="workFilterButtons">Sales Support</li>
<li class="workFilterButtons">Social Media</li>
<li class="workFilterButtons">Tradeshows</li>
<li class="workFilterButtons">Web/Mobile</li>
</ul>
<div id="bottomWrapper">
and here is my script
$(document).ready(function(){
$(".workFilterButtons a").click(function(){
$(".currentFilter").replaceWith($(this).append());
});
});
by default the page is set to "ALL" when loaded, but as you can see I am trying to gett he dynamic text to work within the .currentFilter span
Any help would be greatly appreciated.
If you only want text you use text() method to both get and set. Also you don't want to replace the element or it won't be found again because it will no longer exist
Try
$(".workFilterButtons a").click(function(){
$(".currentFilter").text($(this).text());
});
You don't need to replace the element with the clicked <a> element (unless you really want to), all you need to do is update the text:
$(document).ready(function () {
$(".workFilterButtons a").click(function () {
// selecting the element with the class
// of 'currentFilter', and setting its
// text (using the text() method) to
// the textContent of the clicked <a>
// element:
$(".currentFilter").text(this.textContent);
});
});
$(document).ready(function() {
$(".workFilterButtons a").click(function() {
$(".currentFilter").text(this.textContent);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="portfolio-filter-container">
<h2 class="workFilterSelect">FILTER OPTIONS: <span class="currentFilter">ALL</span></h2>
</div>
<ul id="portfolio-filter">
<!--<li class="workFilterSelect">FILTER OPTIONS:</li>-->
<li class="workFilterButtons">All
</li>
<li class="workFilterButtons">Advertising
</li>
<li class="workFilterButtons">Branding
</li>
<li class="workFilterButtons">Catalog
</li>
<li class="workFilterButtons">Corporate ID
</li>
<li class="workFilterButtons">Consumer Relations
</li>
<li class="workFilterButtons">Incentive/Loyalty
</li>
<li class="workFilterButtons">Packaging
</li>
<li class="workFilterButtons">Product Launch
</li>
<li class="workFilterButtons">Promotion
</li>
<li class="workFilterButtons">Public Relations
</li>
<li class="workFilterButtons">Sales Support
</li>
<li class="workFilterButtons">Social Media
</li>
<li class="workFilterButtons">Tradeshows
</li>
<li class="workFilterButtons">Web/Mobile
</li>
</ul>
<div id="bottomWrapper"></div>
JS Fiddle demo.
Incidentally, the reason your original code didn't work, and couldn't work, is because of this line:
$(".currentFilter").replaceWith($(this).append());
This replaced the selected element(s) with the clicked <a> element, which meant that, in future, the there was no .currentFilter element to replace or update.
On the other hand, if you want to put the clicked <a> element into the .currentFilter span-element, then you could try the following approach:
$(document).ready(function () {
$(".workFilterButtons a").click(function () {
// finding those <li> elements whose text, when trimmed
// (removing leading and trailing white-space) is equal
// to an empty string (''):
var emptyLi = $('.workFilterButtons').filter(function () {
return $(this).text().trim() === '';
}),
// caching the '.currentFilter' element(s):
currentFilter = $('.currentFilter'),
// checking for those elements in the
// currentFilter jQuery object that have
// a descendant <a> element, and finding
// length of that collection, and then
// checking that it's greater than 0:
hasA = currentFilter.has('a').length > 0;
// appending the contents of the currentFilter
// element into the found emptyLi element:
emptyLi.append(currentFilter.contents());
// if there are no <a> elements in the
// currentFilter element(s):
if (!hasA) {
// we replace the contents (textNode 'all')
// with the clicked <a> element:
currentFilter.contents().replaceWith(this);
} else {
// otherwise we append the clicked link to
// the currentFilter; this works because
// once we get to this stage the <a> element
// if it exists has already been moved back
// to the empty <li>, therefore we can't
// use '.contents().replace()' because
// there are no contents remaining by this point
// (and yes, this was incredibly counter-intuitive
// to me for quite a long time, which is why this
// update took a while):
currentFilter.append(this);
}
});
});
$(document).ready(function() {
$(".workFilterButtons a").click(function() {
var emptyLi = $('.workFilterButtons').filter(function() {
return $(this).text().trim() === '';
}),
currentFilter = $('.currentFilter'),
hasA = currentFilter.has('a').length > 0;
emptyLi.append(currentFilter.contents());
if (!hasA) {
currentFilter.contents().replaceWith(this);
} else {
currentFilter.append(this);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="portfolio-filter-container">
<h2 class="workFilterSelect">FILTER OPTIONS: <span class="currentFilter">ALL</span></h2>
</div>
<ul id="portfolio-filter">
<!--<li class="workFilterSelect">FILTER OPTIONS:</li>-->
<li class="workFilterButtons">All
</li>
<li class="workFilterButtons">Advertising
</li>
<li class="workFilterButtons">Branding
</li>
<li class="workFilterButtons">Catalog
</li>
<li class="workFilterButtons">Corporate ID
</li>
<li class="workFilterButtons">Consumer Relations
</li>
<li class="workFilterButtons">Incentive/Loyalty
</li>
<li class="workFilterButtons">Packaging
</li>
<li class="workFilterButtons">Product Launch
</li>
<li class="workFilterButtons">Promotion
</li>
<li class="workFilterButtons">Public Relations
</li>
<li class="workFilterButtons">Sales Support
</li>
<li class="workFilterButtons">Social Media
</li>
<li class="workFilterButtons">Tradeshows
</li>
<li class="workFilterButtons">Web/Mobile
</li>
</ul>
<div id="bottomWrapper"></div>
JS Fiddle demo.
References:
JavaScript:
Node.textContent.
String.prototype.trim().
jQuery:
append().
click().
contents().
filter().
has().
replaceWith().
text().
I changed your class="currentFilter" to id="currentFilter" so now you won't need a .each() to do what you want to do, the selector selects only 1 element and not an array of 1 element.
Also changed replaceWith() with text(), and likewise append() replaced with text().
Here's a fiddle if you want to see it in action
https://jsfiddle.net/s6bpwycn/
I have the following HTML:
<ul id="sortable1 venuetags" class="connectedSortable">
<li id="venuetagli">fried</li>
<li id="venuetagli">garlic</li>
<li id="venuetagli">rosemary</li>
<li id="venuetagli">new potatoes</li>
</ul>
And am trying to get the values of each using JQuery:
$('#venuetagli').each(function(j,li) {
console.log(j,li)
})
However, from the console I am only getting the first value returned.
The ids are supposed to must be unique that is why you are getting single element use class selector instead. Also the id of UL would not have space.
Html
<ul id="sortable1 venuetags" class="connectedSortable">
<li class="venuetagli">fried</li>
<li class="venuetagli">garlic</li>
<li class="venuetagli">rosemary</li>
<li class="venuetagli">new potatoes</li>
</ul>
Javascript
$('.venuetagli').each(function(j,li) {
console.log(j,li)
});
You can simple get the li with ul using parent-child selector
$('#sortable1 li').each(function(j,li) {
console.log(j,li)
});
Just for the test and never recommended way, you can get elements having same id using attribute selector.
$('[id=venuetagli]').each(function(j,li) {
console.log(j,li);
});
Id must be assign to a single element in complete page else it will return only one of those element or unexpected result:
Here is demo with class
<ul id="sortable1 venuetags" class="connectedSortable">
<li class="venuetagli">fried</li>
<li class="venuetagli">garlic</li>
<li class="venuetagli">rosemary</li>
<li class="venuetagli">new potatoes</li>
</ul>
and jQuery:
$('.venuetagli').each(function(j,li) {
console.log(j,li)
})
I have one Activity xml file and I am try to get from activity when click on activity there child display. Its look like end of the all click.
<ul id="firstLevelChild">
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</ul>
Now I want that if li have no leaf node then its display in other another div. Something like:
Click on Acitivities there have child node Physical1 and there also child Cricket and there chil One Day now one day have no child when click on one day its display in my <div id="result"></div>
I would add this as a comment, but I don't have enough rep. ChildNodes() isn't a function - since it looks like you're using jQuery, try children() instead.
I think javascript could helpr you there. A part from the fact that you first build your DOM correct ;)
The hasChildNodes() method returns TRUE if the current element node has child nodes, and FALSE otherwise.
http://www.w3schools.com/dom/met_element_haschildnodes.asp
Assuming the markup you provided is how it's going to be always i.e. ul as child for all li. You just check if ul exists inside the current li. See fiddle
HTML
<div id="content">
<ul id="firstLevelChild">
<li>
<ul id="ul">
<li id="4">Activities
<ul class="ul">
<li id="10066">Physical1
<ul class="ul">
<li id="10067">Cricket
<ul class="ul">
<li id="10068">One Day</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<h2>Result</h2>
<ul id="result"></ul>
JS
$('#content li').each(function (i) {
//for display purpose only
$('#content').append('<span class="list">li(' + i + '):' + $('ul', $(this)).length + '</span>');
//the code you needed
if ($('ul', $(this)).length < 1) {
$(this).on('click', function () {
$('#result').append($(this).parent().html());
});
}
});
I am trying to add only select items of a list to a new list. So for example, I only wish to add banana to my second list, the following code in my function adds all the items in coll-selected-list to coll-grouped-list. How may I only make a clone of a specific item. Any tips would be great.
jQuery:
$("#coll-selected-list li").clone().appendTo("#coll-grouped-list");
Markup:
<ul id="coll-selected-list" class="droptrue sort-drop ui-sortable">
<li class="sorted">apple</li>
<li class="sorted">pear</li>
<li class="sorted">banana</li>
<li class="sorted">grape</li>
<li class="sorted">guava</li>
</ul>
<ul id="coll-grouped-list">
</ul>
You can use the :contains selector:
$("#coll-selected-list li:contains('banana')").clone().appendTo("#coll-grouped-list");
Note that the string you pass to :contains is case sensitive.
Here's a working example.
Add a custom data attribute and value to the items you want to clone and then only target items with that data attribute and value.
e.g.
<ul id="coll-selected-list" class="droptrue sort-drop ui-sortable">
<li class="sorted">apple</li>
<li class="sorted">pear</li>
<li class="sorted" data-action="clone">banana</li>
<li class="sorted">grape</li>
<li class="sorted">guava</li>
</ul>
<ul id="coll-grouped-list">
</ul>
$('#coll-selected-list li[data-action="clone"]').clone().appendTo("#coll-grouped-list");
Working Demo:
http://jsfiddle.net/QXEdn/
You can add class to elements which you want to clone e.g.:
<ul id="coll-selected-list" class="droptrue sort-drop ui-sortable">
<li class="sorted">apple</li>
<li class="sorted">pear</li>
<li class="sorted clone">banana</li>
<li class="sorted">grape</li>
<li class="sorted">guava</li>
</ul>
<ul id="coll-grouped-list">
</ul>
// get elements with clone class
$('#coll-selected-list li.clone]').clone().appendTo("#coll-grouped-list");
If you want to clone elements based on index you can use :eq selector:
// clone li containing bannana
$('#coll-selected-list li:eq(2)]').clone().appendTo("#coll-grouped-list");