Loop through list using Jquery - javascript

Total js newb here.
Here is the HTML
Size 8.5
<div class="product1">
<ul class="sizeAvail" style="display:none;">
<li>8</li>
<li>8.5</li>
<li>9</li>
<li>9.5</li>
<li>10</li>
</ul>
</div>
<div class="product2">
<ul class="sizeAvail" style="display:none;">
<li>8</li>
<li>8.5</li>
<li>9</li>
<li>9.5</li>
</ul>
</div>
Here's the 'logic' of what I need...
When the user clicks the Link
Capture the id of that element
Set that as a variable
Loop through li for all ul that have class 'sizeAvail'
If li element matches variable
stop looping and move onto next ul
If ul does not have li that matches variable
set class of container div to 'hide'
This is where I'm at so far...any help would be greatly appreciated.
<script type = "text/javascript" > $(document).ready(
$(".dur").click(function () {
var clickedSize = $(this).attr("id");
$(".sizeAvail").each(function (li,+) {
alert($(this).text());
});
});
</script>

Here is a working fiddle:
http://jsfiddle.net/Hive7/uZTYf/
Here is the jquery I used:
$(".dur").click(function () {
var clickedSize = this.id;
$(".sizeAvail li").each(function () {
if($(this).text() == clickedSize) {
$(this).parent().show();
} else {
$(this).hide();
}
});
});
What you are currently doing is not right as you aren't looping through the children of .sizeAvail because you didn't directly state though what you did state wasn't in quotes like most aspects of jquery need to be.
If this still does not work make sure you have a jquery library
Or you can use the pure js option:
var $items = document.getElementsByClassName('sizeAvail');
var $dur = document.getElementsByClassName('dur');
for (i = 0; i < $dur.length; i++) {
$dur[i].addEventListener('click', durClick);
}
function durClick() {
var clickedSize = this.id;
for (i = 0; i < $items.length; i++) {
var $liElems = $items[i].getElementsByTagName('li');
for (i = 0; i < $liElems.length; i++) {
if ($liElems[i].innerHTML == clickedSize) {
$liElems[i].parentNode.style.display = 'block';
$liElems[i].style.display = 'block';
} else {
$liElems[i].style.display = 'none';
}
}
}
}
http://jsfiddle.net/Hive7/uZTYf/2/

everything you are trying to do is pretty simple syntax-wise. you can find documentation on methods to use in a number of places. you could simply use javascript for this but i am assuming you want to use jQuery
on a high level you'll want to use the jQuery selector to get all UL objects and then for each UL loop over all LI children, e.g.:
$('ul').each(function() {
$(this).find('li').each(function(){
});
});
to get the data you are looking for, you can use jQuery methods like addClass(), attr(), etc.

You may use this. Set a flag when checking all li's of a div. If none li has same value as the id, at the end hide the div.
$(document).ready(function(){
$(".dur").click(function () {
var clickedSize = this.id;
$(".sizeAvail").each(function(){
var hide = 1;
$(this).children('li').each(function(){
if(clickedSize == $(this).text()) hide=0;
});
if(hide){
$(this).closest('div').hide(); //Or $(this).parent().hide();
}
});
});
});
JSFIDDLE

You may try this too
$('a.dur').on('click', function(e){
e.preventDefault();
var id = this.id;
$('ul.sizeAvail li').each(function(){
if($(this).text() == id) $(this).closest('ul').addClass('hide');
});
});
EXAMPLE.

Demo: http://jsfiddle.net/QyKsb/
This is one way to do it, as you were doing. However, i don't, personally like cluttering html with data as that. But it maybe good choice in some situations but i dont like it.
also you cant give id a value that starts with numbers.
var products= $("div[class^='product']"),
dur =$('.dur');
dur.click(change);
function change(){
var size= $(this).data('size');
products.each(function(){
var d = $(this);
d.find('.sizeAvail>li').each(function(){
d.hide();
if($(this).text()==size) { d.show(); return false;}
});
});
}

You can use a combination of not, has and contains selectors to get the matched elements and set a class on them using addClass.
Ref:
http://api.jquery.com/not-selector/
http://api.jquery.com/has-selector/
http://api.jquery.com/contains-selector/
http://api.jquery.com/addClass/
Code:
$(".dur").click(function () {
$(".sizeAvail:not(:has(li:contains('"+$(this).prop("id")+"')))").addClass('hide')
});
Demo: http://jsfiddle.net/IrvinDominin/t8eMD/

Related

If Statements with data attribute - load two different templates based on what product has been clicked

I would like to open two templates based on the data attribute, if brand is SIM then open template1, if Samsung open the other.
Here is my code:
$('.item .show-detail').click(function(){
if($(this).find('[data-brand="SIM"]')) {
var myLink1 = $(this);
alert('hey');
$('.content .row').fadeOut({complete: function(){detailTemplate1('Voice',$(myLink1).parent().data('brand'), $(myLink1).parent().data('model'), $(myLink1).parent().data('subcat')); $('.content .row').fadeIn(400)}});
}else
($(this).find('[data-brand="Samsung"]'))
var myLink = $(this);
alert('link All');
$('.content .row').fadeOut({complete: function(){detailTemplate('Voice',$(myLink).parent().data('brand'), $(myLink).parent().data('model'), $(myLink).parent().data('subcat')); $('.content .row').fadeIn(400)}});
})
You have a lot of problems in your code.
You can't specify a condition for else, you have to say else if
Wrap else if block in figure brackets.
Use length to find if element exists.
This is assuming that data-brands exist inside item element you're clicking on:
$(document).ready(function(){
$('.item').click(function(){
if( $(this).find('[data-brand="SIM"]').length ) {
var myLink1 = $(this);
alert('SIM');
}
else if ( $(this).find('[data-brand="Samsung"]').length ) {
var myLink = $(this);
alert('Samsung');
}
});
});
http://jsfiddle.net/f32epg16/
jquery objects will always be truthy, you need to check the length.
if($(this).find('[data-brand="SIM"]').length)
Second else does not have a clause. You need to either drop it or use else if.
Try this
$(document).ready(function(){
$('.item .show-detail').click(function(){
if($(this).attr("data-brand")=="SIM")
alert("SIM");
else if($(this).attr("data-brand")=="Samsung")
alert("Samsung");
});
});
Use jquery attr method to find its value and do the relevant work

How do invoke an already existing jquery function on an html anchor?

I created expandable content using jquery on several divs with unique ids. The code is working but now I also want to trigger this function from a top navigation using an anchor. I have tried several things but nothing works. I am very new to jquery so any help would be greatly appreciated.
I am specifically trying to invoke the click() function on each anchor.
Here is my jquery:
(function($) {
$(document).ready(function () {
var panelspeed = 500;
var totalpanels = 6;
var defaultopenpanel = 0;
var accordian = true;
var panelheight = new Array();
var currentpanel = defaultopenpanel;
var iconheight = parseInt($('.icon-close-open').css('height'));
var highlightopen = true;
//Initialise collapsible panels
function panelinit() {
for (var i=1; i<=totalpanels; i++) {
panelheight[i] = parseInt($('#cp-'+i).find('.expandable-panel-content').css('height'));
$('#cp-'+i).find('.expandable-panel-content').css('margin-top', -panelheight[i]);
if (defaultopenpanel == i) {
$('#cp-'+i).find('.icon-close-open').css('background-position', '0px -'+iconheight+'px');
$('#cp-'+i).find('.expandable-panel-content').css('margin-top', 0);
}
}
}
$('.expandable-panel-heading').click(function() {
var obj = $(this).next();
var objid = parseInt($(this).parent().attr('ID').substr(3,2));
currentpanel = objid;
if (accordian == true) {
resetpanels();
}
if (parseInt(obj.css('margin-top')) <= (panelheight[objid]*-1)) {
obj.clearQueue();
obj.stop();
obj.prev().find('.icon-close-open').css('background-position', '0px -'+iconheight+'px');
obj.animate({'margin-top':0}, panelspeed);
if (highlightopen == true) {
$('#cp-'+currentpanel + ' .expandable-panel-heading').addClass('header-active');
}
} else {
obj.clearQueue();
obj.stop();
obj.prev().find('.icon-close-open').css('background-position', '0px 0px');
obj.animate({'margin-top':(panelheight[objid]*-1)}, panelspeed);
if (highlightopen == true) {
$('#cp-'+currentpanel + ' .expandable-panel-heading').removeClass('header-active');
}
}
});
function resetpanels() {
for (var i=1; i<=totalpanels; i++) {
if (currentpanel != i) {
$('#cp-'+i).find('.icon-close-open').css('background-position', '0px 0px');
$('#cp-'+i).find('.expandable-panel-content').animate({'margin-top':-panelheight[i]}, panelspeed);
if (highlightopen == true) {
$('#cp-'+i + ' .expandable-panel-heading').removeClass('header-active');
}
}
}
}
//Uncomment these lines if the expandable panels are not a fixed width and need to resize
$( window ).resize(function() {
panelinit();
});
$(window).load(function() {
panelinit();
}); //END LOAD
}); //END READY
})(jQuery);
The html for the expandable jquery content is:
<div class="expandable-panel" id="cp-3">
<div class="expandable-panel-heading">
<h2>Testimonials<span class="icon-close-open"></span></h2>
</div>
<div class="expandable-panel-content">
<p>Panel HTML...</p>
</div>
</div>
The html anchors that I want to trigger the click() function are:
<ul class="nav">
<li class="nav">What is Justice Court Judge?</li>
<li class="nav">About Reeves Jones</li>
<li class="nav">Testimonials</li>
<li class="nav">Polling Locations</li>
<li class="nav">Map</li>
<li class="nav">Contact</li>
</ul>
Thank you in advance for your help!
If I understand correctly, you don't want to trigger the click event for the anchors, but instead you want to trigger the click event of the corresponding navigation element when an anchor is clicked.
You can do that by adding the following code inside your document-ready function:
$('.nav a').click(function() {
$($(this).attr('href')).find('.expandable-panel-heading').click();
});
This code registers a click handler on all the <a> elements inside the .nav element. It uses the href value of the clicked <a> element to get a jQuery object representing the navigation element.
In this case, you should not place the "onclick" attribute on the <a> elements.
BTW: For valid HTML, you should nest the <a> elements inside the <li> elements, not the other way around.
I recommend not to use inline event handlers.
You can add the following to your jquery code:
$(".nav").find('a').trigger("click");
$(".nav").find('a').click(function(){
//your code
})

adding specific class to element on click jquery

I'm having trouble with a simple nav bar that uses jQuery to add and remove a specific class when a certain page is active. I want a class to append to my aLink class depending on which ID is click. If I click on #aboutLink I want .linkActive to be added, but if I click on #sasLink I want .link2Active to be added. The tutorials I've looked at all have a single class being added, but since both my classes are different I need a specific one to be added depending on which ID is click.
HTML:
<div id="mainNav">
<ul id="nav">
<a id="mainLogo" href="/"><li></li></a>
<a id="aboutLink" class="aLink" href="/"><li></li></a>
<a id="sasLink" class="aLink" href="/savings-and-support"><li></li></a>
<a id="external" href="/"><li></li></a>
</ul>
</div><!--/#mainNav-->
I know my jQuery doesn't make sense, but it's all I could come up with. Logically I get it, but I'm lost on the syntax.
jQuery:
$(function () {
$(".aLink").click(function () {
if ($(this) == $("#aboutLink")
$(this).addClass('activeLink');
else $(this).addClass('active2Link');
});
});
Thanks for any input or direction.
var idToClass = {
'aboutLink' : 'linkActive',
'sasLink' : 'link2Active'
}
$('#nav a').click(function(){
e.preventDefault();
$(this).addClass(idToClass[this.id]);
});
JS Fiddle demo.
You could, instead, use toggleClass() to allow for those classes to be removed by a second click:
var idToClass = {
'aboutLink' : 'linkActive',
'sasLink' : 'link2Active'
}
$('#nav a').click(function(e){
e.preventDefault();
$(this).toggleClass(idToClass[this.id]);
});
JS Fiddle demo.
Edited in response to question, from the OP, in comments, below:
How would I remove the class so that both links don't appear to be active at the same time?
There's a few ways, but because you're adding different class-names to denote the 'active' state, they're a little inefficient. The first approach is to use a brute-force method, effectively looking for all a elements that have a class attribute and setting that attribute to the empty string, and then adding the linkActive/link2Active class-name to the clicked-on a element:
$('#nav a').click(function(e){
e.preventDefault();
var self = $(this);
self.closest('ul').find('a[class]').attr('class', '');
self.toggleClass(idToClass[this.id]);
});
JS Fiddle demo.
The alternative is to remove the specific classes from the elements who have their id listed in the idToClass object. This is, however, somewhat expensive in that it needs to iterate over the object, retrieving the id, finding the element with that id and then removing a class-name:
$('#nav a').click(function(e){
e.preventDefault();
for (var id in idToClass) {
if (idToClass.hasOwnProperty(id)){
$('#' + id).removeClass(idToClass[id]);
}
}
$(this).addClass(idToClass[this.id]);
});
JS Fiddle demo.
If, of course, you use a common class-name then it all becomes much easier:
$('#nav a').click(function (e) {
e.preventDefault();
var self = $(this);
self.closest('ul')
.find('.commonActiveClassName')
.removeClass('commonActiveClassName');
self.addClass('commonActiveClassName');
});
JS Fiddle demo.
References:
addClass().
closest().
event.preventDefault().
find().
removeClass().
toggleClass().
Since you already have ID tags to easily reference... I think you want something more like this?
$(function () {
$("#aboutLink").click(function () {
$(this).addClass('activeLink');
});
$("#sasLink").click(function () {
$(this).addClass('active2Link');
});
});
Try using this instead:
$(function () {
$(".aLink").click(function () {
var currentId = this.id;
if ( currentId == "aboutLink"){
$(this).addClass('activeLink');
else if( currentId == "sasLink") {
$(this).addClass('active2Link');
}
});
});

How to call and run same function simultaneously from different `<LI>`

How to call and run same function simultaneously from different <LI> using javascript or jQuery.
I want to use same function with different parameters. I want to create like Browser tabs.The multiple tabs are loading simultaneously.
(Sorry, I missed the jquery tag somehow originally.)
Using jQuery:
HTML:
<ul id="mylist">
<li>One</li>
<li>Two</li>
</ul>
JavaScript using jQuery:
$("#mylist > li").click(function() {
// Here, `this` refers to the raw DOM element.
// If you want to know which one it is by index,
// you can use $(this).index() (they start at 0).
// Or you can store information on the element
// using data-* attributes, and use
// $(this).data(...)
});
Live example
Original answer from when I'd missed the jquery tag (doh!):
There's the DOM0 way:
<li onclick="doSomething(1);">One</li>
<li onclick="doSomething(2);">Two</li>
Or there's the unobtrusive DOM0 way:
HTML:
<ul id="mylist">
<li>One</li>
<li>Two</li>
</ul>
JavaScript:
var ul = document.getElementById("mylist");
var li;
var index;
for (li = ul.firstChild; li; li = li.nextSibling) {
if (li.nodeName.toUpperCase() === "LI") {
li.onclick = makeCallback(++index);
}
}
function makeCallback(val) {
return function() {
doSomething(val);
}
}
Or the DOM2 way:
(Same HTML.)
JavaScript:
var ul = document.getElementById("mylist");
var li;
var index;
for (li = ul.firstChild; li; li = li.nextSibling) {
if (li.nodeName.toUpperCase() === "LI") {
hookEvent(li, "click", makeCallback(++index));
}
}
function makeCallback(val) {
return function() {
doSomething(val);
}
}
function hookEvent(element, eventName, handler) {
if (element.addEventListener) {
element.addEventListener(eventName, handler, false);
}
else if (element.attachEvent) {
element.attachEvent("on" + eventName, handler);
}
Try to use $.each:
$(...).each(function(index, Element) {
...
});
See: http://api.jquery.com/each/
For example:
$(...).each(function(index, Element) {
var target = $(this);
target.click(function() {
// when user click...
});
// something other logic...
});
$('li').click(function(){ var target = $(this);// get your target element
});
And here is the jquery way:
$("li").click(function(){
doSomething($(this).data('someValue'));
});
With the HTML holding the parameters.
<li data-someValue="one">One</li>
<li data-someValue="two">Two</li>
Add a rel attribute to the <li> element, then call the function on the <li>
$('li.your-class').bind('event_type', function(){
var ref = $(this).attr('rel');
// call your function
myFunction(ref);
}
There are quite a few outof the box solutions for this, such as jquery ui. If you wanted to do it manually you could do it fairly easily.
jQuery tabs:
http://jqueryui.com/demos/tabs/
Have your content areas named:
#main_0
#main_1
...
Then add a selector to LI
Something like:
var CurrentTabIndex = null;
$("li").live('click', function(e) {
var TabIndex = $(this).index;
var divName = "#main_" + TabIndex;
$.ajax({
url: "OpenTab.php",
data: { TabId: TabIndex },
success: function (data) {
$(divName).html(data);
$(divName).show();
if(CurrentTabIndex != null)
{
$("#main_" + CurrentTabIndex).hide();
}
CurrentTabIndex = TabIndex;
}
});
});

How to I undo .detach()?

I'm using JQuery 1.5 and the following code to detach li elements w/ a certain class when a button is clicked. What I want to know is, when that button is clicked again, how do I add the element back onto the page?
<script>
$("#remove").click(function () {
$('li.type').fadeOut(300, function() { $(this).detach(); });
});</script>
The question is: where on the page do you want to put the element back? If, for example, all the li elements go back inside <ul id="foo"></ul> you might use something like this:
var items = [];
$('li.type').fadeOut(300, function() {
items.push( $(this).detach() );
});
$('#replace').click(function() {
for(var i = 0; i < items.length; i++) {
$("ul#foo").append(items[i]);
}
items = [];
});
here u can't for loop.
var demo;
$('li.type').fadeOut(300, function() {
demo = $(this).detach();
});
$('#replace').click(function() {
$("ul#foo").append(demo);
});

Categories

Resources