jQuery single event for several DOM objects - javascript

I'm trying to make a change event trigger for several objects in the DOM. Let me show you; I have this code
$(document).ready(function() {
$(".select_something").change(function() {
if (!($(".select_something option[value='0']").attr("selected"))) {
$(".write_something").css('display','');
}
else
{
$(".write_something").css('display','none');
}
});
});
And with this I have several selectors/dropdowns all of which is called .select_something. When the option is not the default value (which is 0), it should show a <textarea></textarea> appear, again all of which is called .write_something.
All in all it's a quite simplistic function.
The problem I'm experiencing is that this only affects the very first .select_something, .write_something pair, and the rest is unaffected.
I've tried mixing around with .find(), .parent() and .children() to see if it could stick, but it don't.
How can I make it so all of my .select_something, .write_somethingpairs get changed when triggered?
Edit: The IDs was supposed to be classes, of course.

#select_something
Is an id. IDs must be unique over your entire page. If you have multiple elements with this same id, that's fundamentally wrong (and will cause you massive problems).
Having said that, the fix is easy: change those ids to css classes.
<select id="select_something">
becomes
<select class="select_something">
Then you could select against the css class, but of course you'll have to select the : write_something element relative to the current select. Something like this might work depending on your structure:
$(".select_something").change(function() {
if (!($("option[value='0']", this).attr("selected"))) {
$(this).siblings(".write_something").css('display','');
}
else
{
$(this).siblings(".write_something").css('display','none');
}
});

You should be using a common class for the multiple objects, not a common ID.
The ID attribute is used to IDentify a single item. The CLASS attribute is used to define that an item is part of a group of items, all which have the same class name.
Use the class name selectObject on all of them, and then..
$(document).ready(function() {
$(".selectObject").change(function() {
//inside of an event, $(this) refers to the object that triggers the event,
//in this case, the item that was clicked.
if (!($(this).val()==0)) {
...
}
else
{
...
}
});
});
Here is something for illustration.
http://jsfiddle.net/FxLSR/1/

As mentioned in other answers and comments, only use an ID for unique elements, use a class for multiple elements.
This is how I would setup my code:
HTML:
<div>
<select class="select_something"> ... </select>
<textarea class="write_something"> ...</textarea>
</div>
<div>
<select class="select_something"> ... </select>
<textarea class="write_something"> ...</textarea>
</div>
etc...
Javascript:
$(document).ready(function() {
$(".select_something").change(function() {
if (!($(this).val() == "0") {
$(this).next().show();
}
else
{
$(this).next().hide();
}
});
});
If the elements can't be placed next to each other as in the example HTML code I have given, then just make sure to select the textarea using some sort of relative selector such that you're not selecting all of the text areas. For example, if the two are siblings but they're not next to each other use: $(this).siblings(".write_something")

Related

how to know the element that performed the click in a checkbox list dynamically added (javascript)

I have to add a list of checkboxes dynamically. I then need to know which one performed the click, then ask if it's checked or not.
I have this code:
$('#MyContainerOfChecksDiv').click( '.MySelectorClass', function(){
if ("MyCheckClicked".is(':checked'))
{
//...here i need to use the label and id
}
else{...}
})
using "$(this)" i get the "MyDiv", obviously using $(this).find('input:checkbox') I get the whole list of checks.
I have to get this checkbox because I need to use its properties.
Add a formal parameter to click handler and use it like this
$('#myDiv').click('.MySelectorClass', function (e) {
if ($(e.target).is(':checked')) {
alert(e.target.id);
}
})
fiddle
Also it's not quite clear to me how you distinguish dynamically added elements and static. Do you have different class for them? If so then you dynamic and static elements can have different handlers and this will be the way to tell whether it was created dynamically
To delegate to dynamic elements you have to use .on(). The element that you clicked on will be in this.
$("#myDiv").on("click", ".MySelectorClass", function() {
if (this.clicked) {
// here you can use this.id
} else {
// ...
}
});
You can't use .click() to delegate like you tried. You're just binding the click handler to the DIV, and the string ".MySelectorClass" is being passed as additional data to the handler.

Function for adding and removing style on click and unfocus

I am trying to implement a function which changes style of element on click and remove it when unfocus. For ex: When element2 is clicked, it should remove class of other elements, and add class to the clicked element only.
<div class="dope" id="element777"></div>
<div class="dope" id="element2"></div>
<div class="dope" id="element11"></div>
<div class="dope" id="element245"></div>
<div class="dope" id="element60"></div>
.....(More are created automatically, numbers are not estimatable)
I couldnt know the element ids that are created. The only remains same is class.
I have tried this, but its an unprofessional approach.
$('#element1').click(function(){
$("#element1").addClass(dope2);
$("#element2").removeClass(dope);
$("#element3").removeClass(dope);
$("#element4").removeClass(dope);
});
$("#element1").blur(function(){
$("#element1").removeClass(dope);
});
$('#element2').click(function(){
$("#element2").addClass(dope2);
$("#element1").removeClass(dope);
$("#element3").removeClass(dope);
$("#element4").removeClass(dope);
});
$("#element2").blur(function(){
$("#element2").removeClass(dope);
});
What is the best approach for automating this function, instead of adding click and blur (unfocus) function to ALL of elements ?
You can listen for click events on any div with an id containing the word "element', then target its siblings elements (those that are not clicked, without referring to them by id). This might do it:
$("div[id*='element']").click(function(){
$(this).addClass('dope').siblings('.dope').removeClass('dope');
});
Your jQuery could be vastly simpler if you leverage this and siblings:
Instead of:
$("#element1").addClass(dope2);
$("#element2").removeClass(dope);
$("#element3").removeClass(dope);
$("#element4").removeClass(dope);
It could be:
$('.dope').click(
function() {
$(this).addClass(dope2).siblings().removeClass(dope);
}
);
NOTE:
Do you have a variable called dope with the class name, or is dope the class name? If it's the classname, you need to put it in quotes: $(this).addClass('dope2'), etc.
If you are removing the class dope, then will want to add a class you can always use to select these elements (so that when you remove dope, it continues to work).
Button part:
$("div").click(function(){
if($(this).hasClass("dope") || $(this).hasClass("dope2")){
$(this).addClass("dope2");
$(".dope").not($(this)).removeClass("dope");
}
})
Blur part:
$("div").blur(function(){
if($(this).hasClass("dope") || $(this).hasClass("dope2")){
$(this).removeClass("dope");
}
}
I would recommend using the :focus css selector rather than using javascript to do what you are doing... Read more here. Instead of having a click listener, the focus selector will take care of that for you and automatically remove the styling when the element is out of focus.

jQuery only being applied to a single button, not all instances of it

I have a page with a dynamic number of buttons all with the id "delete-button". My jQuery works great, but only on the first instance of "#delete-button".
$(document).ready(function(){
$('#delete_button').mouseenter(function() {
$(this).closest('tr').css('border-left', 'solid');
$(this).closest('tr').css('border-left-width', '2px');
$(this).closest('tr').css('border-left-color', '#dd3333');
});
$('#delete_button').mouseleave(function() {
$(this).closest('tr').css('border-style', 'none');
});
});
What cold be causing this? Can I not have more than one button with the same id?
If there are multiple elements with the same id, the id selector will only get the first one. You should be using class names instead. e.g.
$('.delete_button').mouseleave(...
Id should be unique (only one). Use .delete_button class instead.
<button id="delete_button1" class="delete_button"></button>
<button id="delete_button2" class="delete_button"></button>
....
<button id="delete_buttonN" class="delete_button"></button>
$(function(){
$('body').on('mouseenter', '.delete_button', function() {
$(this).closest('tr').css({
'border-left' : 'solid',
'border-left-width' : '2px',
'border-left-color' : '#dd3333'
});
});
$('body').on('mouseleave', '.delete_button', function() {
$(this).closest('tr').css('border-style', 'none');
});
});
both answers are correct, but to elaborate on that just a touch. Valid html dictates that you cannot have the same id on multiple elements in a given page. Id's are meant to be a unique identifier for an element. Jquery treats this as though there can truly be only one id on the page so it will stop looking through the dom for more elements that match the id selector once it has found one. If you want to apply your logic to multiple elements with the same call, you must assign a class to those elements as they are meant to be used multiple times. jquery knows this and will find all elements that match your class selector.

Javascript Prototype adding a observe click on a html tag instead of id or name

I want to add a observe statement in prototype js on a <h4> tag without using any id or name. so for example I have in html:
<h4>Some Item</h4>
In Javascript I would like to do:
$(<h4>).observe('click', function() {
//do some stuff here
});
I know I can add a id or name on the <h4> tag and use that but how do I do it without any id or name tag?
My prototype is rusty but I think this will work. Basically it just gets all of the <h4>s, loops through them, and adds the event observer.
$$('h4').each(function(h) {
$(h).observe('click', function(e) {
//do some stuff here
}
});
If you only want the first <h4> then using array dereferencing:
$$('h4')[0].observe('click', function(e) {
//do some stuff here
});
Naturally if you want the second just change the zero to a one, etc.
As far as I know you can't. How can the browser distinguish two h4's from eachother with any id?
You can also do
<h4 onclick="">
but then you can also just give it an id.
PrototypeJS has an invoke() method that will iterate over the list of items and run the same method on all items in the list.
for example
$$('h4').invoke('observe','click',function(e){
//handle event here
//'this' is the element
//'e' is the Event object
});

Using .hide() and .show() in jQuery

In my program I have several very similar drop-down menus all with the same name (foo in the following example). On change they hide or show a nearby div tag depending on whether or not "ON" was selected.
$('.togClass').hide();
$('[name*="foo"]').change(function(){
if ($('[value="ON"]').is(':selected')) {
$('.togClass').show('blind', 1000);
} else {
$('.togClass').hide(1000);
}
});
As it is, all of the div tags with class "togClass" toggle when any of the drop down menus choose "ON", is there a way that I can choose to show/hide only the nearby div to the drop-down that chooses "ON"(they are nested in the same div)? I don't want to write a copy of this function for every div I want to hide.
Here is how it works in the HTML:
<select name="foo">
<option value="OFF">OFF</option>
<option value="ON">ON</option>
</select><br/>
<div class="togClass">
//Stuff
</div>
Ofcourse you can. Check out the jquery doc about traversing: http://api.jquery.com/category/traversing/ It has a lot of great examples.
For your problem the solution could be: .closest()
$('div.togClass').hide();
$('select[name*="foo"]').change(function(){
if ($(this).val() == "ON") {
$(this).siblings('div.togClass').show('blind', 1000);
} else {
$(this).siblings('div.togClass').hide(1000);
}
});
You have to tell us a bit more about what "nearby" means. But it appears that the fundamental piece you're missing is the use of $(this) within the change function. Instead of identifying any .togClass item, you want to identify a specific one relative to $(this) -- the element being changed.
Here's one way to do it with the assumption that the associated .togClass div is the next one to be found in the DOM.
$('[name*="foo"]').change(function(){
if( $(this).is(':selected') ) { // relative to the selected item
$(this).next('.togClass').show('blind',1000);
} else {
$(this).next('.togClass').hide(1000);
}
});
Where you see .next() you'll actually need the appropriate jQuery traversal methods -- unlikely to be the one I've randomly assumed in the example.
How about using .closest()?
Should do the trick.

Categories

Resources