i have a problem with jquery condition.
Let me show you the code.
Here i have the "filter" bar:
<div id="filter_menu">
<label>Filter By:</label>
<ul>
<li>
ALL
</li>
<li>
audio
</li>
<li>
video
</li>
<li>
other
</li>
</ul>
</div>
and here my content list that i want to filter by the option in the bar:
<ul>
<li tags="audio video" class="li_item">
content
</li>
<li tags="video" class="li_item">
content
</li>
<li tags="audio" class="li_item">
content
</li>
<li tags="video other" class="li_item">
content
</li>
<li tags="audio other" class="li_item">
content
</li>
<li tags="other" class="li_item">
content
</li>
</ul>
now there is the jQuery snippet:
$(".filterFunction").click(function () {
categoryFilter = $(this).attr("tags");
$('.item_li').each(function () {
if ($(this).attr("tags") == categoryFilter) {
alert('true');
}
else {
alert('false');
}
});
});
HERE THE PROBLEM:
with contents that have more than one "tag" in the attribute tags are never true!
i need a condition that become true when one of the "tag" it's find in the attribute tags!!!
Please someone can help me!!
Thanks a lot!
and sorry for my english :)
Try
$(".filterFunction").click(function () {
categoryFilter = $(this).attr("tags");
$('.li_item').each(function () {
var tags = $(this).attr("tags").split(' ');
if ($.inArray(categoryFilter, tags) > -1) {
alert($(this).attr("tags") + ': true');
} else {
alert($(this).attr("tags") + ': false');
}
});
});
Demo: Fiddle
Instead of an $.each(); to loop over everything, why not use the tags attribute to select the ones with the key your seeking specifically ie:
var my_var = 'other';
$('.li_item[tags*="'+my_var+'"]');
Then work with those specifically. There are also multiple selector types to refine the notion of this, view http://www.w3schools.com/jquery/jquery_ref_selectors.asp for examples. The above one is one for a wild card match with at least "other" in it. But you can tell it all but, only, etc..
Related
I want to copy the text in the <li> tag using JavaScript. It should be copied when the <li> tag is clicked. All <li> tags have the same class as they will get the same formatting through CSS.
As per my research, we need to specify the button a target class which it will copy to clipboard(Using clipboard.js). The <li> tag will be generated through js so, to give different id to each one of them will be difficult and will increase the code and reduce the speed too.
So how can copy the text of the li tag that is being clicked through js/jquery/clipboard.js etc.
<ul>
<li class="data">Lorem ipdolor.</li>
<li class="data">Lo ripsum dolor.</li>
<li class="data">Lorepsum dor.</li>
</ul>
There are different methods but two that stand up on top.
$(function() {
$("li[class='data']").click(function(e) {
// 1) Use this reference
console.log("1: " + $(this).text());
// 2) Use Event Target
console.log("2: " + $(e.target).text());
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="data">Lorem ipdolor.</li>
<li class="data">Lo ripsum dolor.</li>
<li class="data">Lorepsum dor.</li>
</ul>
You can put an id on ul:
<ul id="dataContainer">
<li class="data">sometext</li>
<li class="data">sometext1</li>
<li class="data">sometext2</li>
<li class="data">sometext3</li>
</ul>
Then:
document.getElementById('dataContainer').addEventListener('click', function(e){
console.log(e.target.innerText);
});
I have Menu list which contains Sub-Menu as shown in the code below.
<li class="current">
<span class="icon4"></span>Subscriptions
<ul class="sub-menu">
<li>View Subscriptions
</li>
<li class="#((ViewBag.PageName == " Subscription ") ? "active " : " ")">Manage Subscription Plans
</li>
</ul>
</li>
<li class="current">
<span class="icon5"></span>Administration
<ul class="sub-menu">
<li class="#((ViewBag.PageName == " AssetPage ") ? "active " : " ")">Assets
</li>
<li>Configure Text
</li>
<li>Error Log
</li>
<li>Product Settings
</li>
</ul>
</li>
<li class="current">
<span class="icon6"></span>Promo Codes
<ul class="sub-menu">
<li>Manage Promo Code
</li>
<li>Used Promo Code
</li>
</ul>
</li>
Here Subscription,Administration,Promo Codes are Menu Lists which contains Sub-Menu Lists under them.
The thing is I want to apply class=current dynamically when a user clicks on Subscription,Administration,Promo Codes`.
And I am doing this in LayoutPage of MVC.
Any help will be appreciated.
Here you have a working solution: https://jsfiddle.net/c4h3sup9/
You have to use a little bit of Javascript for that.
You have to give the listitems a other class name like in my example "operator"
document.body.addEventListener("click", function(e){
if(e.target && e.target.className == "operator"){
var actives = document.getElementsByClassName("active");
actives[0].setAttribute("class", "operator");
e.target.setAttribute("class", "active");
}
});
for this example you need to assing one element as active from the beginning.
Note:
LI elements are never parents of UL.
The order is:
Unordered List (Plural) -> List item (Singular, Child).
You might want to correct that as it is not standard conform.
To add the class name to the parent <li> element, give the main links a class name. Assuming you also want to remove it from any <li> elements that already have it, also give them a class name
<li class="container">
<span class="icon4"></span>Subscriptions
and the script will be
$('.mainmenu').click(function() {
$('.container').removeClass('current'); // remove any previous
$(this).closest('.container').addClass('current');
});
In addition, if when you navigate to one of the views with this layout, and what to add the class name to the appropriate element, then you can give the <li> elements an id attribute
<li id="subscriptions" class="container">
....
</li>
<li id="administration" class="container">
....
and in the GET method, pass the value of the id to the view (e.g. using ViewBag
public ActionResult ConfigureText()
{
ViewBag.Menu = "administration";
....
return View(...);
}
and add a script that runs when the page first loads
var menu = '#ViewBag.Menu";
$('#' + menu).addClass('current');
i have this following html structure usilg ul and li.
<ul class="treeview" id="productTree">
<li class="collapsable lastCollapsable">
<div class="hitarea collapsable-hitarea lastCollapsable-hitarea"></div>
<span id="top1" class="">top1</span>
<ul>
<li class="collapsable lastCollapsable">
<span class="">mod1</span>
<ul>
<li class="last">
<span>bottom1</span>
</li>
</ul>
</li>
</ul>
</li>
<li class="collapsable lastCollapsable">
<span id="top2" class="">top2</span>
<ul>
<li class="collapsable lastCollapsable">
<span class="">mid2</span>
<ul>
<li class="last">
<span>bottom2</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
the website allows user to add more data under this structure and am using jquery treeview to show the tree structure dynamically.
Now i need to save this whole ul-li structure into a js object for future use in the website. how do i achieve this? the last node("bottom1 and bottom2 here") has a class "last" if that helps.
as we can add data dynamically we can be sure how much levels of ul li is there at the end when user clicks "save"
You can use recursive function to save a tree object;
function save(obj_ul, tree){
var obj_lis = obj_ul.find("li")
if (obj_lis.length == 0) return;
obj_lis.each(function(){
var $this = $(this);
if($this.parent("ul").get(0) == obj_ul.get(0))
{
tree.push({
name : $this.find('> span').text(),
child : save($this.find("ul").first(), [])
});
}
});
return tree;
}
console.log(save($('#productTree'), []));
If you want to reprouce the same thing verbatim, as a string of HTML elsewhere on the site, you could just do this? Then .append() or .prepend() treeview where you like.
var treeview = $('#productTree').parent().html()
Assuming you want JSON:
function save(){
var tmp = [];
$('#productTree li.collapsable').each(function(){
var $this = $(this),
$spans = $this.find('span'),
o = [];
$spans.each(function(){
o.push($(this).text())
})
tmp.push(o);
});
return tmp;
}
You could also use map() to accomplish the same thing, too.
EDIT: Updated, assuming your text will live inside a span. This will create an array of arrays, each containing the text from the spans inside each of your list-items.
My URLs look like this:
http://www.site.co.uk/en-us/aboutus/abgroup.aspx
http://www.site.co.uk/en-us/casestudies.aspx
Here is the menu HTML markup
<ul class="sf-menu">
<li class="first">Home</li>
<li class="">About Us</li>
<li class="">Case Studies</li>
</ul>
How can I read the URL and look for /aboutus/ and highlight that particular list item?
I would also like to do this with casestudies << this is different as it doesnt have a sub directory.
I would like to use jquery? I think i need to parse the URL? and then check for the words and then add a class or bold to the li ??
edit: i want to know what the URL in the browser is, it should match the check in the jquery and then make the li bold or add a class.
Simply:
$('a[href*="/aboutus/"]').css('color', 'red');
See the jsFiddle Example.
Update:
If you want to know if the current URL in the browser matches one of the links then use this:
$('a[href*="'+window.location.href+'"]').css('color', 'red');
Give each of your menu elements an ID:
<ul class="sf-menu">
<li class="first" id="home">Home</li>
<li class="" id="aboutus">About Us</li>
<li class="" id="casestudies">Case Studies</li>
</ul>
And use this jQuery:
$(function() {
var currentPage = window.location.href.split("/")[4]);
$(".sf-menu li")each(function() {
if($(this).attr("href").indexOf(currentPage) > -1) $(this).addClass("highlight");
});
}
Nothing too sophisticated about this approach:
$(document).ready(function() {
$("ul.sf-menu li a").each(function() {
if ($(this).attr('href').match(/aboutus/) && window.location.match(/aboutus/)) {
$(this).parent().addClass('aboutus-highlight');
}
if ($(this).attr('href').match(/casestudies/) && window.location.match(/casestudies/)) {
$(this).parent().addClass('casestudies-highlight');
}
});
});
<?php if ($_SERVER["SCRIPT_NAME"] == "/en-us/aboutus/abgroup.aspx") { //whatever } ?>
oh you want js, here:
<script style='text/javascript'>
function checkURL() {
if(window.location == "http://www.site.co.uk/en-us/aboutus/home.aspx") {
document.getElementById('home').style.background = "yellow";
} else if (window.location == "http://www.site.co.uk/en-us/aboutus/abgroup.aspx") {
document.getElementById('abgroup').style.background = "yellow";
} else {
document.getElementById('casestudies').style.background = "yellow";
}
}
</script>
<body onload='checkURL()'>
<ul class="sf-menu">
<li class="first" id='home'>Home</li>
<li class="" id='abgroup'>About Us</li>
<li class="" id='casestudies'>Case Studies</li>
</ul>
yep that works
If you want to highlight any page under /aboutus/ - that is, you don't have just this one page, but several, but you do want the about us menu item to highlight:
if(window.location.indexOf('aboutus') != -1){
$('.sf-menu a[href$="aboutus/abgroup.aspx"]).addClass('here');
}
Then do your styling:
.sf-menu .here { background: red; }
Or whatever else you want.
You don't need to parse the URL as the href should match it (based on your example), so just this should work.
$('a[href=' + window.location.toString() +']').parents('ul').eq(0).addClass('highlight');
I've been trying to get this problem solved, but I can't seem to figure it out without some serious workarounds.
if I have the following HTML:
<ul>
<li class="parent"> headertext </li>
<li> text </li>
<li> text </li>
<li> text </li>
<li class="parent"> headertext </li>
<li> text </li>
<li> text </li>
</ul>
Now, how do I now just select the <li> tags following the first parent (or second, for that matter)? Basically selecting an <li> with class="parent" and the following siblings until it reaches another <li> with the parent class.
I could restructure the list with nested lists, but I don't want to do that. Any suggestions?
actually, you can easily do this using nextUntil().
no need to write your own "nextUntil" since it already exists.
ex. -
$(".a").nextUntil(".b");
or as suggested by Vincent -
$(".parent:first").nextUntil(".parent");
The root of your problem is that the <li>s you have classed as parent really are NOT parents of the <li>s "below" them. They are siblings. jQuery has many, many functions that work with actual parents. I'd suggest fixing your markup, really. It'd be quicker, cleaner, easier to maintain, and more semantically correct than using jQuery to cobble something together.
I don't think there is a way to do this without using each since any of the other selectors will also select the second parent and it's next siblings.
function getSibs( elem ) {
var sibs = [];
$(elem).nextAll().each( function() {
if (!$(this).hasClass('parent')) {
sibs.push(this);
}
else {
return false;
}
});
return $(sibs);
}
You will have to run the loop yourself since jQuery does not know how to stop on a specific condition.
jQuery.fn.nextUntil = function(selector)
{
var query = jQuery([]);
while( true )
{
var next = this.next();
if( next.length == 0 || next.is(selector) )
{
return query;
}
query.add(next);
}
return query;
}
// To retrieve all LIs avec a parent
$(".parent:first").nextUntil(".parent");
But you may be better using a really structured list for your parent/children relationship
<ul>
<li class="parent"> <span>headertext</span>
<ul>
<li> text </li>
<li> text </li>
<li> text </li>
</ul>
</li>
<li class="parent"> <span>headertext</span>
<ul>
<li> text </li>
<li> text </li>
</ul>
</li>
</ul>
$("li.parent ~ li");
I know this is a very old thread, but Jquery 1.4 has a method called nextUntil, which could be useful for this purpose:
http://api.jquery.com/nextUntil/
<html>
<head>
<script type="text/javascript">
$(document).ready(function() {
$("a").click(function() {
var fred = $("li").not('.parent').text();
$('#result').text(fred);
});
});
</script>
</head>
<body>
Click me
<ul>
<li class="parent"> headertextA </li>
<li> text1 </li>
<li> text2 </li>
<li> text3 </li>
<li class="parent"> headertextB </li>
<li> text4 </li>
<li> text5 </li>
</ul>
<div id="result"></div>
</body>
</html>