I have a check list of checkbox that are generated like this:
#foreach($documents as $PDF)
<input {{$PDF->problem != 0 ? "disabled" : ""}}type="checkbox"
id="mail_{{$PDF->id}}" value="{{$PDF->id}}"
name="email[]"
>
<input type="checkbox"
id="post_{{$PDF->id}}" value="{{$PDF->id}}"
name="post[]"
>
#endforeach
When you click on any of these checkbox, a jQuery function should be called that will use the value of the clicked checkbox.
I am having troubles calling the function only when these 2 generated checkboxes are clicked.
There are, however, more inputs and checkbox in the page so something like $(document).delegate('input', 'click', function (event) is out of question.
There sure must be an easier way to do this.
Add a common CSS class to these elements
<input class="checkbox" type="checkbox" id="post_{{$PDF->id}}"
Then use a selector to target them
$(document).delegate('.checkbox:checkbox', 'click', function (event)...
Note .delegate() is depreciated in the favour of .on()
As of jQuery 1.7, the .on() method provides all functionality required for attaching event handlers.
So changes code as
$(document).on('click', '.checkbox:checkbox', function (event)...
In place of document you should use closest static container for better performance.
Related
I have 'chain' of checkboxes (parent checkbox and childs), and problem is:
When first clicking on 'parent' checkbox it is working well, but after that when clicking on 'childs', the 'parent' checkbox then isn't doing what is supposed. Parent is checking/unchecking childs except the child which was pressed before.
Here is code:
JavaScript
checks_bind();
function checks_bind(){
$("#x_main").off('click');
$("#x_main").on('click',function(){
var obj = $(this);
var val = obj.is(':checked');
$("#checks").find("input[type='checkbox']").attr('checked',val);
});
}
HTML
<input id='x_main' type='checkbox'/>Main<br>
<p>--------------------------------</p>
<div id='checks'>
<input type='checkbox'/>1<br>
<input type='checkbox'/>2<br>
</div>
<p>--------------------------------</p>
<i>1 - Click on 1 or 2 <br>2 - Try <b>Main</b> checkbox. <br>
3 - Main checkbox isn't working</i>
jsfiddle example
And one more question:
Is it good to use .on('click.namespace') on checkboxes since it's working well? I can use .change() method, but I want to call .off('click.namespace') (or something to unbind) before .on() each time when calling the function.
As checked is a property, You need to use .prop() instead of .attr()
$("#checks").find("input[type='checkbox']").prop('checked', val);
Updated Fiddle, A good read .prop() vs .attr()
If you want to use .off() then its advisable to use namespaced event.
Try this: user 'prop' instead of attribute and you can check all or uncheck all as per checked condition of main check box.
Also, you can check the count of all checkbox to check /uncheck main checkbox. see below
Note: bind click handler when DOM is ready hence user $(document).ready or $(function(){})
$(function(){
$("#x_main").on("change", function(){
$("#checks").find("input[type='checkbox']").prop("checked",$(this).is(":checked"));
});
$("#checks input[type='checkbox']").on("change", function(){
var total = $("#checks").find("input[type='checkbox']").length;
var checked = $("#checks").find("input[type='checkbox']:checked").length;
$("#x_main").prop("checked",total==checked);
});
});
JSFiddle Demo
I have a block of list element which I need to add when "Add" button is clicked.
HTML:
<li>
<div><h3 >User name sss updated this.
<input type="button" value="X" class="delete"/></br></h3>
</div>
SOME TEXT HERE
</li>
jQuery:
$(".delete").click(function(){
$(this).closest("li").slideUp();
});
$("#addPost").click(function(){
var inData = '<li><div><h3>User name sss updated this.<input type="button" value="X" class="delete"></input></br></h3></div>';
$("#midContent ul").append(inData+'Sarthak</li>');
});
This block has a delete button and a jQuery function attached to it.
If the block already exist on the page, its working fine.
But, when I add this block using jQuery append, the block is rendered rightly, but delete functionality does not work on newly added block.
Where I am going wrong?
Also, what will be the better way to add this block than hardcoding in JS code? (just by referring the element already on page by using id or class)
You need to delegate events for dynamically created DOM nodes. You can delegate to the parent div, or the document itself.
$(document).on('click', '.delete', function(e) {
//your code here
});
The second argument in the click handler is the selector for which you are attaching the click handler.
Further reading: http://learn.jquery.com/events/event-delegation/
Try to use the event .on('click',function(){}) on dynamically created elements.
$(".delete").on('click',function(){
$(this).closest("li").slideUp();
});
$("#addPost").on('click',function(){
var inData = '<li><div><h3>User name sss updated this.<input type="button" value="X" class="delete"></input></br></h3></div>';
$("#midContent ul").append(inData+'Sarthak</li>');
});
Also, why create a variable when you could append the code directly?
I have several inputs that have the class specifierInput
I want this function to run when any of those are focus'd on (it does)
$('.specifierInput').focus(function (e) {
if (isValidationErrorResponse($(this).val())) {
$(this).val('');
$(this).trigger('keyup');
}
$(this).css('color', 'black');
});
Some of my HTML
<textarea id="mfpIdentifierText" name="ASSerialNumber" class="specifierInput"style="width:99%; height:80px; resize:none;"><%= (Session["ASSerialNumber"] ?? "").ToString()%></textarea>
<input name="ASModel" class="specifierInput alphaNumericWithSpacesCommasDashes" type="text" value="<%= (Session["ASModel"] ?? "").ToString()%>"/>
My issue is that $(this) is returning the first element that has the specifierInput applied to it, rather than the element that the event fired for.
My version of jQuery is populating this with the element that fires the event, not necessarily the first element that meets fulfills the selector. Not sure why it's returning the first element for you.
In any case, you may want to see if the property e.target has the element you're looking for. From the jQuery API, e.currentTarget is not always the initiating element, but can be modified due to event bubbling. e.target will always be the initiating event.
jQuery event.target API
Look towards the jQuery Proxy here : http://api.jquery.com/jquery.proxy/
A proxy will set the right 'this'.
I have some checkboxes like the following which are dynamically created.
<input type="checkbox" name="feature[]" value="9">
As you can see there is no id or class with it. And name property is of the type array. Now I can't detect the check event on these checkboxes. I need to detect the events and at the same time their values in which events have occurred.
I've checked several examples regarding this, but usually they all used class or id or name.But name is not in array type in those examples. I've tried with the name property to use, but couldn't manage. Please help.......
You can try this
$("input[name^='feature']").click(function(){
alert($(this).val());
});
use the attribute equals selector
$(document).on('change', 'input[name="feature[]"]', function(){
//do something
})
<input type="text" name="feature" value="123" />
$("input").click(function(){
var txt = $(this).val();
alert(txt);
alert($(this).attr("name"));
});
Try this once
I have a listener for 3 DIV's containing several form elements:
<div id="div-a">
<input type="text" id="txt-a"/>
<!-- more elements here -->
...
</div>
<div id="div-b">
<input type="text" id="txt-b"/>
<input type="text" id="txt-c"/>
<!-- more elements here -->
...
</div>
<div id="div-c">
<input type="text" id="txt-d"/>
<input type="text" id="txt-e"/>
<input type="text" id="txt-f"/>
<!-- more elements here -->
...
</div>
I bound the change event for the 3 DIV's as follows:
$("#div-a, #div-b, #div-c").change(function(){
// do something, except if the change happened to txt-b and txt-c
})
The above listens to change from all of their respective child elements. It works fine, but there is one thing more missing from the equation. The txt-b and txt-c change events is out of my business. So I must not include them in the action being performed by the change event listener. Also, each of the elements under the 3 DIV's already have their own listeners for change so adding the listeners to each of the element's change events is a last option.
I need to listen to changes from the child elements of the three DIV's with some exceptions. I need to execute a function when the child elements of the three DIV's change except for 5 input-types.
So far I did the following which did not work:
I tried separating the three DIV's and added the :not() selector
$("#div-b :not(#txt-b)").change(function(){
//...
});
Using .not()
I would like to know the best possible way to approach this problem. I'd be happy to add more information if you need so. Thank you.
You can try checking the target's id for those and then ignore them:
$("#div-a, #div-b, #div-c").change(function(e) {
var target = e.target;
if (target.id === "txt-b" || target.id === "txt-c") {
return;
}
//Is not a txt-b or a txt-c
})
http://jsfiddle.net/HGXDT/4/
You can just use $(this) variable to your advantage.
Assuming that events are generated by input tag, you just need to check
if(!$(this).parent().attr('id')=='div-b')
if only txt-b and txt-c will be inside div-b.
otherwise you can just go with
if($(this).attr('id')!='div-b') && !$(this).attr('id')!='div-b'))
not selector is not recommended but still if you want to go with :not selector itself try $("div").children("input :not(#txt-b)").change(function(){ //... }); approach with children alone rather than parent clubbing parent and child elements
You can do this with one handler..
<div id="controls-wrapper">
<!--Wrap all your controls and div's here -->
</div>
Then..
$('#controls-wrapper').delegate('input', 'change', function(e){
if($(this).parent().is('#div-a')){
//this input was in #div-a, do something
}
// and so on, as your case might need
});
Note: You can also use .on() in place of .delegate()