say i have a list
<ul class="ul-1">
<li class="li-1">xx -1</li>
<li class="li-2">xx -2</li>
<li class="li-3">xx -3</li>
</ul>
i then save it as
var list = $('.ul-1').html();
i can populate another element i.e
$('.ul-2').html(list);
but what if I wanted to replace the first list element <li class="li-1">xx -1</li> with another list element, how do I do this using the list variable? thanks
Firstly note that it's generally better practice to work with references to the elements in the DOM rather than serialising them to strings which need to be deserialised again when re-added to the DOM.
In addition, if you work with the li references you can use jQuery to retrieve the first() of them and then replaceWith() to change it as necessary. Try this:
var $list = $('.ul-1 > li');
$list.appendTo('.ul-2');
$list.first().replaceWith('<li>Foobar</li>');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="ul-1">
<li class="li-1">xx -1</li>
<li class="li-2">xx -2</li>
<li class="li-3">xx -3</li>
</ul>
<ul class="ul-2"></ul>
Related
I inherited template with the menu in which categories and subcategories is in the same scope. Here is an example:
<ul class="menu">
<li class="cat" data-item-type="category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
<li class="cat" data-item-type="category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
<li class="cat" data-item-type="category"></li>
<li class="cat" data-item-type="category"></li>
<li data-item-type="sub-category"></li>
<li data-item-type="sub-category"></li>
</ul>
I cant change the structure of this, but can add extra attributes to it.
So my question is if it is possible to select all categories subcategories when clicking on one of subcategories. In general i need to select all li until first class="cat" or data-item-type="category" occurrence including it - category and all it's subs.
Update answer per OP's update:
$('li[data-item-type="sub-category"]').click(function() {
$(this)
.add( $(this).nextUntil('.cat') )
.add( $(this).prevUntil('.cat') )
.prev('.cat').addBack() //in jQuery < 1.8, replace addBack by andSelf
//do something
});
Demo
After some brainstorming in the comments, here's a shorter alternative:
$('li[data-item-type="sub-category"]').click(function() {
$(this).prevAll('.cat:first').nextUntil('.cat').addBack()//do something
});
Demo
So .prevAll('.cat:first') matches the first previous .cat, nextUntil('.cat') gets all its subcategories and addBack (or andSelf in older versions) adds the .cat element back to the set of matched elements.
In up-to-date jQuery versions, the .add() and .addBack() methods sort the matched elements in document order, hence both alternatives will have .cat as the first element in the set followed by the subcategories in document order.
Reference
add
addBack
first
nextUntil
prev
prevUntil
This will solve your problem according to your request (updated) for category and subs (not buggy)
$('li').click(function() {
var x = $(this).add($(this).nextUntil('.cat')).add($(this).not('.cat').prevUntil('.cat')).andSelf().add($(this).not('.cat').prevAll('.cat:first'));
});
for clicking on the subs or the cat and selecting the other subs around it with it's category too
Use jQuery .nextUntil
$('li.cat').on('click', function() {
$(this).nextUntil('.cat');
/* then write you logic here */
});
Is there a way to search elements based on data attributes?
I have the following code and would like to know how can this be achieved
<UL>
<LI data-relation_id=1/>
<LI data-relation_id=1/>
<LI data-relation_id=1/>
<LI data-relation_id=2/>
<LI data-relation_id=2/>
<LI data-relation_id=2/>
<LI data-relation_id=3/>
<LI data-relation_id=3/>
<LI data-relation_id=3/>
</UL>
On a click event I basically want to find out all the items that belong to a specific data-relation?
function getRelatedObjects(relationId){
//Search all the li's and get the LI
//that have the data-relation_id== relationId
}
Can this be done using jquery?
The data attribute is just an attribute, so you can use the attribute selector.
$('li[data-relation_id='+relationId+']')
You can't search by associated data specifically, but if the data is set by attribute then you can search using the attribute selector:
function getRelatedObjects(relationId){
return $('li[data-relation_id="'+relationId+'"]');
}
JSFiddle
I'm using jQuery in my current project. I have an list of elements with unique ids. I would like to pick out a particular element and append a new list item after that element. For example, if I have something like:
<ul>
<li id="one">one</li>
<li id="three">three</li>
</ul>
I would like to append <li id="two">two</li> after the list item with an id of one.
Thanks.
$('ul #one').after('<li id="two">two</li>');
Use the imaginatively named after method.
I have a nested list like this:
<ul class="list">
<li class="list_item_type_1">
<ul class="list">
<li class="list_item_type_2">Unnested item</li>
</ul>
</li>
<li class="list_item_type_2">Unnested item</li>
</ul>
With jQuery I want to add a list item before all .list_item_type_2 in the first .list.
I write it like this:
$('.list:first').find('li.list_item_type_2:first').before('<li class="list_item_type_1">Nested list (...)</li>');
This won't work as intended because the script finds the first .list_item_type_2 in the second .list and appends the new code there instead.
How can I keep the search in the first ul and prevent it from entering underlying ul elements?
Cheers!
Firstly, I'd advise constructing HTML that way. Use jQuery to assemble the HTML. It takes care of escaping and all those other useful things:
$("<li></li>").addClass("list_item_type_1")
.text("Nested list (...)")
.prependTo("ul.list:first > li.list_item_type:first");
Also, always use a tag selector ("ul.list") over a naked class selector (".list") where possible. It's much faster on most browsers.
You were so close!
Instead of find(), which searches all descendants, use children(), which only searches children.
Test: http://jquery.nodnod.net/cases/723/run
Maybe try to combine the selector in one expression ?
$('.list:first > LI.list_item_type_2:first').before('<li class="list_item_type_1">Nested list (...)</li>');
The > selector does only match the direct children, as explained in the doc.
I am trying to formulate a selector to select a set of visible elements. Our application uses the Prototype JavaScript framework, version 1.6.0.3.
The markup I'm working with is as follows:
<ul>
<li style="display:none;">1 Hidden</li>
<li style="display:none;">2 Hidden</li>
<li style="">3 Visible</li>
<li style="display:none;">4 Hidden</li>
<li style="display:none;">5 Hidden</li>
<li style="display:none;">6 Hidden</li>
<li>7 Visible</li>
<li style="">8 Visible</li>
</ul>
As you can see, some elements may have a style attribute, but only the hidden ones contain the string "display:none;". I need to select the <li> elements that are visible, where visibility is defined as "does not contain display:none".
What I've tried to far:
var visibleItems = $$('li[style*="display:none"]'); // Yields: [ ]
var visibleItems = $$('li[style*="display"]'); // Yields: [li, li, li, li, li], but isn't specific enough
Ideas? Ideally I'd like this to be as compact as possible, but I'll take what I can get.
Yes, I know that jQuery can do this but I do not want to introduce another framework in to this application since much of it already depends on Prototype.
You can filter the items using the findAll function:
var notVisible = $$('li').findAll(function(el) { return !el.visible(); });