I have some elements like TextBox, Select. I have a script to hide some elements. For this I use the code below, but it doesn't work:
$(document).on('change', '#TypeId', function (e) {
var selected = $(this).val();
if (selected == 1) {
$($('#Issue').parent(), $('#ServiceRequestId').parent()).hide();
console.log('test');
}
});
It just hides the first selector. When I change the selector like below it works fine:
$( $('#ServiceRequestId').parent()).hide();
The second argument is the context in jQuery which would help to filter element within that context.
I think you want to combine both objects, for that use add() method to combine two independent jQuery objects.
$('#Issue').parent().add($('#ServiceRequestId').parent()).hide();
Or provide both jQuery objects within an array.
$([$('#Issue').parent(), $('#ServiceRequestId').parent()]).hide()
Related
I have an element div which is created by js, i want to get it class.
I try to getElementsByClassName('lt-label')(it works), than i want to check if lt-label has class lt-online and if it true the another block on the page is block.
My code:
$(document).ready(function() {
if (document.getElementsByClassName) {
var redTags = document.getElementsByClassName('lt-label');
if (redTags.is(".lt-online")) {
$("#l-b-wrapper").css({
'display': 'block'
});
};
};
});
But it doesn't work. Where i have mistake?
I give a link only because the html code is big and i can't show my problem full .Site http://www.zemelushka.ru/test/
lt-label - is a right page widget button
l-b-wrapper - left page widget button
You are mixing native and jQuery, Use jQuery object since document.getElementsByClassName will return you an array-like object and they don't have jQuery methods
$(document).ready(function() {
if ($('.lt-label').is(".lt-online")) {
$("#l-b-wrapper").css({
'display': 'block'
});
};
});
You have a really odd mix of native JS and jQuery which is causing the problem.
getElementsByClassName returns an array of DOMElements which do not have the is() method. If you use jQuery to select your elements you can both avoid the problem and shorten your code:
$(function() {
if ($('.lt-label').hasClass('.lt-online')) {
$("#l-b-wrapper").show();
}
});
Note that if there are multiple .lt-label elements found you may need to loop over them, depending on the behaviour you require.
To work with jquery methods you need jQuery Object otherwise you'll get error: method is undefined. So, you may also wrap javascript object with jquery like this:
if ($(redTags[0]).is(".lt-online")) {
Where, redTags is wrapped by jQuery ie. $() and we use [0] for first element as getElementsByClassName result array-like object.
But I would choose simply jQuery object while I work with jquery for simplicity:
$('.lt-label') instead of document.getElementsByClassName('lt-label');
As you should know jQuery has it's own dictionary of methods and it works only with jQuery objects. And you are trying to bind a jQuery method .is() to a dom object which causes in error because .is() is available only for jq objects.
So this would do it (creating a jq wrapper):
$(redTags).is(".lt-online")
and you can shorten it like:
$(document).ready(function() {
var redTags = $('.lt-label');
$("#l-b-wrapper").css({
'display': function(){
return redTags.is(".lt-online") ? "block" : "none";
}
});
});
If you just want to show/hide the element then you can use .toggle(boolean) method:
$(document).ready(function() {
var redTags = $('.lt-label');
$("#l-b-wrapper").toggle(redTags.is(".lt-online"));
});
I have several elements on my page with the 'checkbox' class. When clicked, a corresponding checkbox input is checked. However, I need to have JQuery check if the checkbox element is active when the page first loads, and check the checkbox input accordingly at that time.
Since there are multiple 'checkbox' classes on my page, I used the 'this' selector previously and it worked fine, however I do not know how to make it do this with my conditional on page load without the .click action that I used before. Here's what I'm trying to make work:
if($('.checkbox').hasClass('active')) {
$('[name="'+$(this).attr('rel')+'"]').prop('checked', true);
}
Obviously the 'this' selector doesn't know what I'm referring to. Is there a better way of doing this? Since it's checking through a bunch of elements and not just one I'm stumped. Thanks!
You can only use this within the context of a jQuery function, so in this scope it's not going to refer to any .checkbox.
You can use .each instead:
$('.checkbox.active').each(function() {
// In this context, this refers to the DOM element represented by .checkbox.active
$('[name="'+this.rel+'"]').prop('checked', true);
});
The each function may suit your needs:
$('.checkbox').each(function() {
var $this = $(this);
if ($this.hasClass('active')) {
$('[name="'+$this.attr('rel')+'"]').prop('checked', true);
}
});
If the checkboxes must be unchecked when the active class is absent, then:
$('.checkbox').each(function() {
var $this = $(this);
$('[name="'+$this.attr('rel')+'"]').prop('checked', $this.hasClass('active'));
});
I have an element which listens to the onclick event. It calls a function once it was clicked. After that element is a < dd > which I want to select in a CSS selector. The element which is clicked, is a < select >. How would I do that?
This is the HTML:
<select onclick="myFunction();">...</select>
<dd>...</dd>
function myFunction() {
// What do I have to write for the ??????
$$('?????? dd').toggle();
}
Note: There are many of those select/dd combination, so I really have to get the next dd after the firing element.
The minimal change is: Pass this into your function:
<select onclick="myFunction(this);">...</select>
...and then:
function myFunction(select) {
$(select).next().toggle();
}
$ enhances the element, then you can use next to move to the next element. If you like, you can use .next('dd'), but in your case the dd is the next element.
That still uses onxyz attributes, which is a bit old-hat. You might consider hooking things up via observe instead.
I am guessing you mean this:
this.next("dd");
(specifying dd so when there's an error in the mark up, no other element is selected)
If you are trying CSS selectors only, try the following:
$("select + dd").toggle();
Note: this will toggle all dds that follow a select.
Note 2: apparently this does not work in Prototype but it does work in jQuery.
See T.J.Crowder's comment:
[This doesn't work in Prototype] because $ in Prototype looks up elements by ID. $$ is more like
jQuery's $, but what it returns doesn't do set-based operations like
jQuery does (or rather, not the same set-based operations as the ops
you can do on individual elements; you have to use invoke).
next() works on both jQuery as Prototype.
Use:
$(this).next("dd").toggle(); --> this is Jquery
$(element).next("dd").toggle();
see the link Element.next
<select>...</select>
<dd>...</dd>
$('select').change(function(){
$(this).next("dd").toggle();
});
Better use unobtrusive javascript, so your js is better coupled from html markup.
HTML:
<select><option value="test">Test</option></select>
<dd>Test</dd>
JS:
//Event.observe(window, "load", function() {
document.observe('dom:loaded', function() {
$$('select')[0].observe('click', function(event) {
var next = event.element().next();
next.toggle();
});
});
JSFiddle
I have a couple of drop down boxes with ids country1, country2, ... When the country is changed in a drop down the value of the country shoudl be displayed in an alert box.
if I add the onchange handler for one box like this it works fine:
$('#country1') .live('change', function(e){
var selectedCountry = e.target.options[e.target.selectedIndex].value;
alert(selectedCountry);
});
But I need to do this dynamically for all drop down boxes so I tried:
$(document).ready(function() {
$('[id^=country]') .each(function(key,element){
$(this).live('change', function(e){
var selectedCountry = e.target.options[e.target.selectedIndex].value;
alert(selectedCountry);
});
});
});
This doesn't work. No syntax error but just nothing happens when the seleted country is changed. I am sure that the each loop is performed a couple of times and the array contains the select boxes.
Any idea on that?
Thanks,
Paul
The reason .live() existed was to account for elements not present when you call the selector.
$('[id^=country]') .each(function(key,element){ iterates over elements that have an id that starts with country, but only those that exist when you run the selector. It won't work for elements that you create after you call .each(), so using .live() wouldn't do you much good.
Use the new style event delegation syntax with that selector and it should work:
$(document).on('change', '[id^=country]', function(e) {
// ...
});
Replace document with the closest parent that doesn't get dynamically generated.
Also, consider adding a class to those elements along with the id attribute.
Instead of incremental ids I'd use a class. Then the live method is deprecated but you may use on with delegation on the closest static parent or on document otherwise.
$('#closestStaticParent').on('change', '.country', function() {
// this applies to all current and future .country elements
});
You don't need an each loop this way; plus events are attached to all the elements in the jQuery collection, in this case all .country elements.
How do I limit an event to a single element in a jQuery collection?
In the case below, I've tried using .one() to limit the behaviour (inserting the <li class='close'>Close</li> line of HTML) to a single instance. The behaviour does indeed happen only once, but on EVERY matched element of $( "ul>li>a" ). How do I make it happen only once, to only ONE of the matched elements in the collection?
Any ideas?
$( "ul>li>a" ).one(
"click",
function(){
$( "ul ul")
.prepend("<li class='close'>Close</li>")
}
);
Thanks in advance.
-AS
A jQuery selection returns an array. Therefore $("selection")[0] can work. However there are better abstracted methods for this, like .get(0) or .first() (in case you're looking for the first element of the selection/array).
$("selection").get(index) returns the pure DOM element (at that specific index) of the selection, and is not wrapped in the jQuery object.
$("selection").first() returns the first element of the selection, and wraps it in a jQuery object.
So if you don't necessarely want to return the first element, but still want jQuery functionality, you can do $($("selection").get(index)).
Given your situation, this should work fine:
// bind the 'onclick' event only on the first element of the selection
$( "ul>li>a" ).first().click(function() {
$( "ul ul").prepend("<li class='close'>Close</li>");
});
Which is equivalent to this:
$($( "ul>li>a" ).get(0)).click(function() {
$( "ul ul").prepend("<li class='close'>Close</li>");
});
And this:
$($( "ul>li>a" )[0]).click(function() {
$( "ul ul").prepend("<li class='close'>Close</li>");
});
I must disagree with Ryan, working on the CSS selection string to filter the result is rather expensive compared to the native JavaScript array functionality.
Try first(), it selects the first element:
$( "ul>li>a" ).first().one('click',
function(){
$( "ul ul").prepend("<li class='close'>Close</li>")
}
);
one() is used, as you already noticed, to handle an event only once.
You have to specify the index of the element you want to work with.
If your selector returns more than one element you can do one of a couple things...
You can isolate your elements by giving them a class or id attribute in your html and alter the selector to select only the class/id of the element/s you wish to select or you can specify the index of the element you're trying to work with. The later method is a bit sloppy but works as long as your page structure doesn't ever change.
So for the first method I spoke of you'd change your selector to this after applying a class/id to your elements:
$("ul>li>a.class")
or
$("ul>li>a#id")
For the second method I mentioned you'd change your selector to this:
$("ul>li>a:eq(index)")
Where index is the zero based index of the element you're trying to select.
You can call the first method, which will return a new jQuery object containing only the first element in the original one.
However, in your case, you might as well use the (equivalent) :first selector, like this:
$("ul > li > a:first").click(function() { ... });
If you only want to handle the first click event and ignore any subsequent clicks, you'll need to use .one(), like you already are.
You need to combine first() with one():
$( "ul>li>a" ).first().one('click', function () {});
More general:
$( "ul>li>a:eq(n)" ).one('click', function () {});