What causes jQuery objects to be different? - javascript

Why doesn't the first attempt to close the dialog work? Or maybe a better question is why is jQuery object $("#dialog") different than $(this).parent('div.dialog')?
$('#click').click(function() {
$("#dialog").dialog("open");
});
$("#dialog").dialog({autoOpen:false}).find('li').click(function(){
$(this).parent('div.dialog').dialog('close');
$("#dialog").dialog("close");
});
<div id="dialog">
<ul>
<li>111</li>
<li>222</li>
<li>333</li>
</ul>
</div>

$(this).parent('div.dialog') will only look up one level to see if the parent matches that selector. It will not traverse any further. The result is an empty set, and as a result using .dialog() has no effect.
What would work here would be closest jQuery API.
$(this).closest('div.dialog')
This would be the same as $("#dialog") in your example.

Related

Find if ancestor has a certain CSS class

I would like to know if there is an easier way to check if an element has an ancestor with a particular class.
Consider the following HTML code:
<ul id="uniqueID" class="parentClass">
<li class="subclassA">
<div class="subclassB">
<nobr>
MyText
</nobr>
</div>
</li>
<li class="subclassA"> ... </li>
<li class="subclassA"> ... </li>
<li class="subclassA"> ... </li>
</ul>
<div>other elements in this page which I want to select</div>
Right now, I can select the element MyText by using a jQuery selector checking the href for a particular format. What I can then do is do .parent() a known number of times (4) and then check the class attribute of that particular element that I've now moved to. While this is working just fine, I am curious if there is a better way to do it, perhaps one that lets me be a bit more dynamic?
PS. There are a lot of elements that I'm selecting that'll fit this $('[href *= index.php]') format, so I want to keep those but remove the ones that fall under the categorization where they are a descendant of a member of class listclass. Currently I'm just selecting all of the elements with the selector above, then using an if statement to check through and see if it fits this condition. Again, if there is a more efficient way to do this (perhaps select these certain elements in the first place?) I would love to hear about it.
Current code:
$('[href *= "index.php"]').each(function(){
if ($(this).parent().parent().parent().parent().attr('class') != 'parentClass'){
//do things
}
});
To generalise you can use
.closest(".parentClass")
You can use closest and is:
$('[href*="index.php"]').each(function(){
if ($(this).closest('ul').is('.parentClass')) {
//do things''
}
});
if($(this).parents("ul.parentClass").length == 0){
//do something
}

JQuery not acting as it should

I am trying to make a "drop down" menu where you click a div and the sibling below it will become visible or disappear. It should be extremely simple, but it is giving me trouble for some reason.
$(".dropDownClick").click(function(){
alert($(self));
$(self).next().css("display",(node.css("display")=="inline")?"none":"inline");
});
This code returns [object Object] and then doesn't change the display css of the next sibling. After a bit of testing I found that $(self).next(); will actually break the code (if I try to do something like alert($(self).next()); the code will not execute). I am assuming this is because there is no next sibling? But my HTML would suggest otherwise:
<div class="dropDownClick"><h1>Drop</h1></div>
<div class="dropDown" style="display: none;">
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
Shouldn't the div with the class "dropDown" be selected when I call .next()?
it should be this not self, also you can use .toggle() instead of manually applying the display value
$(".dropDownClick").click(function () {
$(this).next().toggle();
});
this is a special variable, which is always available - but self/node are custom variables which has to be declared before using else it will throw a reference error
Demo: Fiddle

My javascript hides all the divs.

So, Here is my little barter calculator.
The problem is that when I try to add it to my site it goes all nuts by hiding all the divs. (It literally applies display:none to all of them).
How can I make this work?
Additionaly, I would like to make the script calculate value after pressing Submit button, not dynamically like now. Any easy way to do it?
It goes like this(sample, for full code go to jsfiddle, link at the bottom):
<div id="Apple">
<ul>
<li><span data-val="2"></span> bananas</li>
<li><span data-val="3"></span> oranges</li>
</ul>
</div>
And this is my JS
$(document).ready(function () {
function showTab(name) {
$('div').hide();
var $div = $('#' + name).show();
var number = parseInt($('.number').val(), 0);
$('span', $div).each(function() {
$(this).text($(this).data('val') * number);
});
}
$('#dropdown').change(function () {
showTab($(this).val());
});
showTab($('#dropdown').val());
});
Fiddle - check it live
Analyse the code carefully. The showTab() function hides all divs on your site:
$('div').hide();
And then it shows the one which matches your tab:
var $div = $('#' + name).show();
You'll need to change the first selector to something a little more specific to your own markup, otherwise it will continue to hide other <div> elements. Unfortunately, it's not clear what structure you're using based on the Fiddle, so I can't help more.
I'd recommend adding a class to the numerous sections, and then updating your code. For the #Apple example:
<div id="Apple" class="tab">
In turn, you can then use the selector:
$('div.tab').hide();
It might be better to also use jQuery's not() function, to create some exclusivity as follows:
$('div.tab').not('#'+name).hide();
This will also eliminate the need to later call show().
$('div').hide(); will hide every div on the page. Be more specific:
$('div.fruit').hide();
<div id="Apple" class="fruit">
<ul>
<li><span data-val="2"></span> bananas</li>
<li><span data-val="3"></span> oranges</li>
</ul>
</div>
Demo
you have $('div').hide(); - no wonder all divs are hidden, maybe you should narrow it down with some $('#container div').hide(); ?
Try to change your selector
$('div').hide();
to
$('#Apple').hide();

adding content problem

Here I've got some trouble trying to add content in a page.
<body>
<div id="wrapper">
<div id="nav">
<ul>
<li><span>exercizeI</span></li>
<li><span>exercizeII</span></li>
<li><span>........</span></li>
<li><span>........</span></li>
</ul>
</div>
<div id="content"></div>
</div>
</body>
So I'be tried to use that piece of code and it didn't work
var table1='<table>..some content..</table>}';
$('#nav li a:eq(1)').click(function (){$('#content').innerHTML='habarlaaaa';});
then tried this one
function press(){
var but = document.getElementById('wrapper').getElementById('nav').getElementsByTagName('ul')[0].getElementsByTagName('li')[1].getElementsByTagName('a')[0];
var table1='<table>..some content..</table>}';
var content = document.getElementById('wrapper').getElementById('content');
but.onclick=function(){content.innerHTML=table1};
};
..and it became even worse by giving me:
Uncaught TypeError: Object # has no method 'getElementById'
error
Why is this happening?
BR, Stephan
Using jQuery you can use the html() function like this:
$('#nav li a:eq(1)').click(function (){$('#content').html(table1);});
To add data inside the content div:
$('#content').append("data");
The reason why your second try fails is because you are applying getElementById() to the result of the previous "getElementById()".
In your first Javascript code you were mixing concepts of DOM methods and jQuery code. Please try the following code
$('#nav li a:eq(1)').click(function (){$('#content').eq(0).html('habarlaaaa');});
the difference is that instead of
$('#content').innerHTML = '......';
You should have used
.eq(0).html('habarlaaaa')
Agreed with Vincent, the reasoning is that when you use the jQuery function, $, you don't get a DOM element, but rather you get a jQuery object representing what you've selected. There are a couple ways of doing this, one of which #vincent-ramdhanie has already mentioned. If you want to get at the actual DOM element, you can do either this:
$('#content')[0].innerHTML='habarlaaaa';
or this:
$('#content').get(0).innerHTML='habarlaaaa';
remember: innerHTML is a property of a DOM element, not a jQuery object.

How do I hide a parent element using jquery?

Suppose the following HTML:
<li class="fooli">
<a class="foo" href="javascript:foo(this);">anchor</a>
</li>
<li class="fooli">
<a class="foo" href="javascript:foo(this);">anchor</a>
</li>
and the following Javascript (using jquery 1.3.2):
function foo(anchor) {
alert($(anchor).attr('href'));
}
My goal is to be able to hide the li that is clicked on, but I can't assign them unique ids. Thus, I want to do it positionally (i.e. identify the particular anchor clicked on) by something like $(anchor).parent().hide().
However, the alert above returns "undefined", so it's not obvious to me that I even have the right jquery object.
How do I figure out what object $(anchor) is? In particular, how do I see what attributes it has, what class it has, what HTML element it is, etc?
Can't you do this:
$(function() {
$("a.foo").click(function() {
$(this).parent().hide();
return false;
});
});
with:
<li class="fooli"><a class="foo" href="#">anchor</a></li>
<li class="fooli"><a class="foo" href="#">anchor</a></li>
$(...) in jQuery is never a single HTML element; it's always a list of them.
You can use .get() to convert to a regular Javascript list or, better, use .each():
$(anchor).each(function() { alert(this) });
This will give you something like [object HTMLAElement]. You'd have to use for/in to examine it entirely, but .tagName and .innerHTML are probably good enough to figure out where you are.
I also like to use $(...).css('outline', '1px solid lime') to find elements. It makes them hard to miss and easy to pinpoint with Firebug.
Addendum: I definitely agree with the above answer about separating your Javascript from your HTML. Don't inline JS.

Categories