Javascript if else problems mobile Jquery toggle menu - javascript

I'm trying to make a jquery toggle menu for a mobile website.
I've managed to create a toggle menu with + and - when toggled and when not
Current version: http://jsfiddle.net/9Dvrr/7/
Now i'm trying to create a if else statement fot displaying a ">" when there are no children.
Experiment: http://jsfiddle.net/9Dvrr/6/
Problem is that i just can seem to figure it out..
Thanks in advance,
Rick

You need to check the length property when checking if it has children. Otherwise, all you're checking is if the result is non-null or not...and it will always be non-null even if the selector doesn't match because it will return jQuery. It will be empty of any elements, but an object nonetheless and thus non-null.
if (element.has('ul').children('a').length > 0) {
element.prepend("<span>+ </span>");

This code below will do what you want, but it could definitely use a little refactor. It's mostly to show you how you can achieve it simply :
$('#menu-mobiel ul').hide();
$.each($('#menu-mobiel li'), function(i, value) {
var $this = $(this);
if($this.find('ul a').length > 0) {
$this.find('a').append("<span>+ </span>")
.addClass('plus')
.click(function() {
togglePlus($(this));
$(this).next('.sub-menu').slideToggle('normal');
});
}
else
{
$this.find('a').append("<span>> </span>");
}
})
function togglePlus(element) {
element = $(element);
if (element.hasClass('plus')) {
element.removeClass('plus').addClass('minus');
element.children('span').text('- ');
} else {
element.removeClass('minus').addClass('plus');
element.children('span').text('+ ');
}
}

Related

How can I combine .toggleClass() with .appendTo()?

I append a new class to a HTML container. How can I toggle this on/off by clicking on the menu button?
And is it even "best practice" to write more complex HTML code in JavaScript or would you prefer another method for this? Because I plan to do this for some more containers. Thank you!
$(document).ready(function() {
$( "a.header-login" ).click(function() {
$("<div class='sub-menu'>" +
"<h2>Hi x!</h2>"+
"<a class='item' href='#'>Logout</a>"+
"</div>")
.appendTo("header .header-r");
})
});
I want to accomplish that another click on "a.header-login" deletes the container ".sub-menu". Now, it is always generated when you click "a.header-login"
In this case you need to add a condition to check whether or not the element already exists. If it doesn't create it, if it does remove it.
jQuery(function() {
$('a.header-login').click(function() {
var $target = $('header .header-r .sub-menu');
if ($target.length === 0) {
$('<div class="sub-menu"><h2>Hi x!</h2><a class="item" href="#">Logout</a></div>').appendTo('header .header-r');
} else {
$target.remove();
}
})
});
That being said, you can make this much simpler logic if you always include the .sub-menu in the HTML of your page but hide it with CSS by default. In that case your jQuery would become a simple call to toggle():
jQuery(function() {
$('a.header-login').click(function() {
$('header .header-r .sub-menu').toggle();
})
});

How to check if a HTML element contains an other one?

I want to check if my title <h3> has the class highlight so I founded How to check if element contains specific class attribute but I'm not sure about how to fit it to my use case because it's not the <h3> which contains the class but the span inside it:
I tried to do this code:
$('.liContainer div h3').each(function(i, obj) {
var contains = false;
String classes = obj.getAttribute("class");
for (String c : classes.split(" ")) {
if (c.equals("highlight")) {
contains = true;
}
}
if(contains){
obj.classList.remove("highlight");
}
});
but I got an error with the actual code:
imports/ui/layout.js:42:13: Unexpected token (42:13)
and it's the line String classes = obj.getAttribute("class");
Could someone help me to make it works ?
[EDIT] with the help of your answer I'm now here:
'click .liContainer div h3': function(e){
if ( $(e.target).find("span").is(".highlight") ) {
console.log("it was highlighted");
$(e.target).find("span").removeClass('highlight');
}
},
and it works so thank you everybody
I hope it will help you
$('.liContainer div h3').each(function(i, obj) {
if ( $(this).find("span").is(".highlight") ) {
// do something
}
});
**can you just help me to do the action only on the clicked h3?**
If `click` action:
$('.liContainer div h3').click(function() {
if ( $(this).find("span").is(".highlight") ) {
// do something
}
});
I use your code, and change the content of the `each` loop.
You loop each `<h3>` and check if child `<span>` has class `.highlight`, then you do something...
The above Code can also be written as follows:
$('.liContainer div h3').click(function() {
if ( $(this).find("span.highlight") ) {
// do something
}
});
Hope this works fine.
$('h3').filter(function(){
return $(this).find('span.highlight').length != 0;
}) // do something with it
A rough way to know if you don't know have child selector
$('#nameMachine *').hasClass('yourClass'); // either true or false
Since you are using jquery, how about this simple solution:
$('.liContainer div h3 .highlight').removeClass('highlight');
Try using `has` selector as given below code :
$('.liContainer div h3:has(span.highlight)').each(function(){
// code here
});
You may try something like:
if( $("h3", "#nameMachine").has(".highlight") ) {
// do something
}
Or a more specific version:
if( $("> h3", "#nameMachine").has("span.highlight") ) {
// do something
}
$('span.highlight','.liContainer div h3').removeClass('highlight')
Please note that the second css selector is to determine the scope of searching the first css selector.
find() will be searching in all of child element . So if there have wanted class its length will be 1 else length is 0.
$('.liContainer div h3').each(function(i, obj) {
var hasClass = $(obj).find(".highlight");
if (hasClass.length) {
hasClass[0].classList.remove("highlight");
}
});
This will do. hasClass documentation is here
$("#nameMachine h3").hasClass("highlight")
if ($('#parent').find('#child').length) {
}

JQuery not removing active class

I'm trying to make my links slide down over the page when the mobile nav is clicked and the content to disappear so only the links are shown. I have got this basically working but the .displayNone class will not remove when I click the mobilenav again and I'm a bit dumfounded as to why.
$(document).ready(function() {
$('#hamburger').on('click', function(){
$('.links').slideToggle(200);
var status = $('.wrapper').hasClass('.displayNone');
if(status){ $('.wrapper').removeClass('.displayNone'); }
else { $('.wrapper').addClass('displayNone'); }
});
});
Bit of newbie to all this. Anything obvious that anyone can see wrong with this?
Use toggleClass(),
$('.wrapper').toggleClass('displayNone');
And, jQuery's xxxClass() functions expect the name of the class, not the selector, so leave off the . class selector.
When adding/removing classes, just use displayNone, not .displayNone (note the dot!).
Also there's a toggleClass() function which saves you from doing the status thing, which means you just need to do
$('.wrapper').toggleClass('displayNone');
your are doing bit wrong
var status = $('.wrapper').hasClass('.displayNone');
when you use hasClass, addClass or removeClass then you don't need to have '.' dot before class name.
so correct way is
var status = $('.wrapper').hasClass('displayNone');
your code after correction
$(document).ready(function() {
$('#hamburger').on('click', function() {
$('.links').slideToggle(200);
var status = $('.wrapper').hasClass('displayNone');
if (status) {
$('.wrapper').removeClass('displayNone');
} else {
$('.wrapper').addClass('displayNone');
}
});
});
You can use :
$('.wrapper').toggleClass("displayNone");
Final code :
$(document).ready(function(){
$('#hamburger').on('click', function(){
$('.links').slideToggle(200);
$('.wrapper').toggleClass("displayNone");
})
})

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

loop through if, return if false, if true => stop if

So I got the following scenario:
$('.menu').find('a').each( function(el, val) {
if( window.location.hash !== val.hash ) {
$('.menu li').first().addClass('active') // we found no valid hash for us, so set first <li> active
$('#hash1').show() // and show the first content
} else {
$(this).parent().addClass('active') // we found an hash, so give its parent <li> an active class
$(window.location.hash).show() // can be #hash2, #hash3, whatever
return false; // since we found something, stop the if.
}
});
Well now obviously, each time we found no valid hash, we set the first element active and show the first content... but I dont want that.
I want the if to loop through all elements first before we go into the else statement.. and THEN if we found nothing, set the first element active and show the first content.
since I am looping through each "a", how do I do that?
Just keep a variable outside of the loop:
var found = false;
$('.menu').find('a').each( function(el, val) {
if( window.location.hash === val.hash ) {
$(this).parent().addClass('active'); // we found an hash, so give its parent <li> an active class
$(window.location.hash).show(); // can be #hash2, #hash3, whatever
found = true;
}
});
if(!found) {
$('.menu li').first().addClass('active'); // we found no valid hash for us, so set first <li> active
$('#hash1').show(); // and show the first content
}
Also, semicolons at the end of statements are not optional.
You can use .filter() to get the elements you want. If none are selected, you perform the default action:
var $links = $('.menu').find('a').filter(function() {
return window.location.hash === this.hash;
});
if($links.length > 0) {
$links.parent().addClass('active');
$(window.location.hash).show();
}
else {
$('.menu li').first().addClass('active');
$('#hash1').show();
}
Reference: .filter
If you could explain your requirement more clearly in English I think you'll find the JavaScript structure would follow naturally.
The following is my best guess at what you are trying to do: All anchors in ".menu" that have the same .hash as window.location.hash should have their parent li made "active" and the corresponding element shown. If none matched then the first menu item should be made "active" and "#hash1" shown.
var matched = false;
$('.menu').find('a').each( function(el, val) {
if( window.location.hash === val.hash ) {
matched = true;
$(this).parent().addClass('active');
$(window.location.hash).show();
}
});
if (!matched) {
$('.menu li').first().addClass('active');
$('#hash1').show();
}
var elm = $(window.location.hash).length ? window.location.hash : '#hash1';
$(elm).show();
$('a[href$="'+elm+'"]').parent().addClass('active');
Assuming the markup is the same for #hash1 as the rest, and that there is only one hash in the browser adress bar (or none) ?

Categories

Resources