PrototypeJS: Selecting visible elements - javascript

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(); });

Related

replace ul list child element

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>

How to select a list's li based on text and then edit child span?

Say I have this HTML:
<ul class="list-group" id="words">
<li class="list-group-item"><span class="badge">10</span>Apple</li>
<li class="list-group-item"><span class="badge">50</span>Banana</li>
<li class="list-group-item"><span class="badge">30</span>Carrot</li>
</ul>
I'm looking for a jQuery selector that will select a list item like Banana and then be able to edit its child badge to whatever value.
I was looking around and saw some very complex selectors involving contains (which isn't exact enough for me already) and lambda functions/loops spanning multiple lines and was wondering if there was a better way.
Fiddle Example.
You can use .data() like #dsh mentioned in comment, see the example below :
HTML :
<ul class="list-group" id="words">
<li class="list-group-item" data-text="Apple"><span class="badge">10</span>Apple</li>
<li class="list-group-item" data-text="Banana"><span class="badge">50</span>Banana</li>
<li class="list-group-item" data-text="Carrot"><span class="badge">30</span>Carrot</li>
</ul>
JS :
$( ".list-group-item[data-text='Banana'] .badge" ).text(); //50
Hope this helps.
$("li:contains(Banana)>.badge").text("whatever")
should be the proper selector for jQuery. However, you should try to avoid :contains() if you are not specific. The selector above has to search in every list element. If you only search in the given list use
$("#words>li:contains(Banana)>.badge").text("whatever")
instead or use data Attributes, as dsh has commented,

Is it allowed to have value for list item?

<ul id="my-list">
<li value="1001">item1 </li>
<li value="1002">item2 </li>
<li value="1003">item3 </li>
<li value="1004">item4 <li/>
</ul>
Is it allowed to have value for list item? If I can, how to access the value using javascript or jquery?
According to the W3C specification for LI element it is allowed to use value attribute for LI in some cases, but not this one. If you're using HTML5 use data-* attributes:
<ul id="my-list>
<li data-my-value="...">...</li>
<li data-my-value="123">...</li>
<li data-my-value="...">...</li>
</ul>
To get a reference to a particular element using jQuery use following selector:
$("ul#my-list li[data-my-value='123']")...
Or, if you already got reference to all LI elements use jQuery.filter():
var $items = $listItems.filter(function() {
retrun $(this).data("my-value") === "123";
});
You can add any sort of custom data attributes to your node (of course that HTML won't validate and it won't be a valid XHTML document). You can then access them using jQuery attr() function (for example).
That said it's a terrible practice and you should use a standard data- attribute, accessible for example with data() function (more details and examples in the provided link):
var theValue = $("#yourItemId").data("value");
For an attribute like:
<li id="yourItemId" data-value="1001">item1</li>
For this purposes I would recommended use jquery Data
<ul id="my-list">
<li data-value="1001">item1 </li>
<li data-value="1002">item2 </li>
<li data-value="1003">item3 </li>
<li data-value="1004">item4 <li/>
</ul>
Get second li value
$("#my-list").children().eq(2).data("value");
If you want to produce valid HTML5, you should stick to the data attributes for custom properties:
<li data-value="1001">
However, any element can have a custom attribute. In fact this has been standard in IE since version 5 (sometimes called expando properties).

mcDropDown plugin: how to show parent node attributes?

I'm using the mcDropDown plugin which is very effective.
Without reporting all the code, I just put the jsfiddle example. http://jsfiddle.net/SwxP3/
What I want to do, and I wasted hours of trials, is to get the parent of the selected node.
Example
<li rel="1">
Arts & Humanities
<ul>
<li rel="2">
Photography
<ul>
<li rel="3">
3D
</li>
<li rel="4">
Digital
</li>
</ul>
</li>
<li rel="5">
History
</li>
<li rel="6">
Literature
</li>
</ul>
</li>
In such example, if I select "3D" I want to be able to retrieve the rel property of its parent.
I played a bit with the getValue function of mcDropDown plugin, without any success.
I saw that this plugin, in the dom tree, creates hidden elements reporting the list tree structure, and also the getValue functions uses them, but I couldn't find a way of retrieving the parent (I tried with the parent() function of jquery of course)...
Does anybody have an idea of how to get the parent?
I really need this feature, so if somebody has some sulution which includes NOT using mcDropDown but any other plugin (or creating a dropdown natively with css and jquery) it is wellcomed.
$(document).ready(function (){
$("#current_rev").html("v"+$.mcDropdown.version);
$("#category").mcDropdown("#categorymenu",{
select: function(value,name){
alert($("[rel="+value+"]").parents('li').attr("rel"))
}
});
});
This get's the rel of the parent. Undefined if the selected element doesn't have a parent.

Searching html elements based on data attributes

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

Categories