I have a very strange issue with jQuery where I am triggering a click on a radio button but it is not firing completely and is not being captured by an on click function, however a similar call to jQuery trigger is being captured.
In the following jQuery I am selecting a <div> and using find to search for the suitable content.
var prev_chosen_d_option = $('#d_options_table .d_option_row[data-option-id="' + d_option_for_jq + '"]');
// this works, and the on click is captured
prev_chosen_d_option.find('.hover_target').trigger("click", true);
// this selects the radio button, but DOES NOT fire the on click function seen below
prev_chosen_d_option.find('#d_standard_use_b_as_s_no').trigger("click", true);
These are my radio buttons:
<input type="radio" value="yes" id="d_standard_use_b_as_s_yes" name="d_standard_use_b_as_s">
<input type="radio" value="no" id="d_standard_use_b_as_s_no" name="d_standard_use_b_as_s">
$("#d_options_table .d_option_row .hover_target").on("click", function(e, isFirstLoad) {
// it comes in here fine!
});
$('input[name=d_standard_use_b_as_s], input[name=d_next_day_use_b_as_s], #del_standard_use_b_as_s_no').on("click", function(e, isFirstLoad) {
// it DOESN'T come in here
});
I can't see how jQuery is able to select the radio button and successfully check it, but the on method doesn't pick it up as a click...especially when I have a very similar setup running in close proximity in the code.
I know for sure that the radio buttons are within the selector as I can dump it out to the console with a console.log. Interestingly, when I dump out the events attached to it to the console I get undefined from this after the trigger:
console.log(prev_chosen_d_option.find("#_standard_use_b_as_s_no").data('events'));
(I am using jQuery 1.7.2 and testing in FF).
Instead of
$('input[name=del_standard_use_b_as_s], input[name=del_next_day_use_b_as_s], #del_standard_use_b_as_s_no').on('click', function(e) {
//
});
Try :
$(document).on('click', 'input[name=del_standard_use_b_as_s], input[name=del_next_day_use_b_as_s], #del_standard_use_b_as_s_no', function(e) {
//
});
The reason for this not working was simply I had the click handler below where I was actually triggering the click in the code.
Related
Im having a problem attaching an event to a dynamically generated button. However after some research most of the solutions claim this error is usually generated from a form control. However in my case the error "invalid form control with name='answer'" is being generated and triggered when a button i have dynamically generated is pressed :
$("#BoxInner").append($("<button id='dynamicButton' class='btn btn-success' onclick='clickEvent()'>"+ "Button"+"</button>"));
I have appended a button to an existing div and call an onclick function that removed this element when it is clicked like this :
function clickEvent()
{
$(this).remove();
}
After running this in chrome this method works only on the first button added. After the first button is removed as expected it begins to generate the error "clickEvent" and adding a number count on each click and after reading many posts here about the error being attributed to a form i remain unsure how to solve the issue as the button is completely unrelated to the form on my HTML document and subsequently setting the form to not require validation does not solve the issue with the "novalidate" property. But note, if i remove the attached onclick event the error is not triggered.
Any help would be appreciated :)
$("#BoxInner").append($("<button id='dynamicButton' class='btn btn-success' onclick='clickEvent(this)'>"+ "Button"+"</button>")); // pass this to clickEvent function
function clickEvent(obj)
{
$(obj).remove(); // remove button like this
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="BoxInner"></div>
This is because the event listener is created on page load.
You should do something like this
$(wrapper_that_always_exists).on('click', the_freshly_added_element, function() {
...
});
So in your example it would be something like
$('#BoxInner').on('click', '#dynamicButton', function() {
...
});
When you do this, the BoxInner element will always listen for all clicks on any element inside, initially created or not, that has the id dynamicButton
The problem I am having is that the radio buttons in my scenario are not being selected when they are clicked. I have created a JSFiddle to show the code and the issue.
For whatever reason, I have an entire area that is surrounded in an element.
<a href="/link">
//some stuff
<div class="protected">
<input type="radio" name="b1" value="1" /> Button 1
<input type="radio" name="b1" value="2" /> Button 2
</div>
//some stuff
</a>
There is a small section within this tag that needs to be protected from the default behaviour of the link. This section contains some radio inputs which need to be selectable.
The way I currently have it, I am protecting the "protected" section with an event listener and:
$('.protected').off('click').on('click', function (e) {
e.preventDefault();
});
I also have an event listener on the radio buttons so that I can perform the change of property when they are clicked.
$('.protected > :radio').off('click').on('click', function (e) {
$(this).siblings(':radio').removeAttr('checked');
$(this).attr('checked', 'checked');
});
Unfortunately, this is setting the checked attribute in the dom however the radio button is not being filled in on the screen for the user.
Any help would be greatly appreciated.
You need to add stopPropagation()
$('.protected > :radio').off('click').on('click', function (e) {
e.stopPropagation();
//$(this).siblings(':radio').removeAttr('checked');
//$(this).attr('checked', 'checked');
});
Also, make sure to comment out
$(this).siblings(':radio').removeAttr('checked');
$(this).attr('checked', 'checked');
You don't need them as the browser handles this for you.
DEMO
What was happening is, since you had preventDefault in the container click handler, the nested click event was propagating to that click handler and was preventing the radio button from being set.
I've got a 'catch 22' in Chrome. I cannot programmatically select a radio button within a click event if any other function bound to the same event makes a call to preventDefault().
For example, I have a radio button with a parent element bound to a click event in which preventDefault() is called. If the radio button is clicked directly it is not checked. This is to be expected. However, I actually need the radio button to be selected so within code I attempt to check it in another function bound to the click event: $(this).prop('checked', true);.
Oddly, this doesn't work and I cannot remove the call to preventDefault() or disable propagation because it is in third party code that I need to run.
Is this a bug? Any suggested workarounds?
Here is an example:
http://jsfiddle.net/LnLuk4st/
UPDATE:
I have tried #RGraham's suggestion. His example clearly works, but oddly it does not work in the context of my code. #RGraham's code had a syntax error which made it appear to be working.
Here's some context:
// Remember kendo tab
$(".k-tabstrip").each(function () {
var $tabStrip = $(this);
var $tabs = $tabStrip.find(".k-tabstrip-items .k-item");
var tabCookie = "Current_Tab_" + $tabStrip.attr("id");
// On tab change, set cookie
$tabs.click(function () {
createCookie(tabCookie, $(this).attr("aria-controls"), 1);
$tabStrip.parent().css({ 'min-height': $tabStrip.parent().height() });
if ($(this).is('input')) { // Doesn't eval to true, 'this' is always a '.k-item'.
$(this).prop("checked", true);
} else {
// Never works if the input is clicked directly
$(this).find('input').prop("checked", true);
}
});
// #RGraham's suggestion...
$tabs.on('click', 'input', function() {
$(this).prop("checked", true); // Line reached but doesn't work either :(
});
// If cookie set, select tab
var tab = readCookie(tabCookie);
if (tab) {
$tabs.each(function () {
if ($(this).attr("aria-controls") == tab) {
$(this).click();
}
});
}
});
I still believe this behaviour to be a bug but I have found a workaround.
Capture the click of the radio button directly, prevent propagation, then programmatically click the parent of the radio button. This allows the third party code to run without applying preventDefault to the radio button.
// preventDefault bug fix.
$tabs.find("input").click(function (e) {
e.stopPropagation();
$(this).parent().click();
});
I'm using checkboxes to toggle the enabled and disabled state of some multi-lists on a registration form. The checkbox is labeled with the category, and the multi-list contains the items that belong to that category.
I'm using jQuery 1.7.2.
$('#sch_cat_hockeyschools').toggle(function(ev) {
ev.stopPropagation();
$("#type_select_hockeyschools").prop("disabled", false);
$("#type_select_hockeyschools").removeProp("disabled", "disabled");
$("#sch_cat_hockeyschools").prop("checked", true);
$("#sch_cat_hockeyschools").prop("checked", "checked");
}, function(ev) {
ev.stopPropagation();
$("#type_select_hockeyschools option:selected").removeAttr("selected");
$("#type_select_hockeyschools").prop("disabled", true);
$("#type_select_hockeyschools").prop("disabled", "disabled");
$("#sch_cat_hockeyschools").prop("checked", false);
$("#sch_cat_hockeyschools").removeProp("checked");
});
Sample of corresponding checkbox HTML:
<input class="catmark" type="checkbox" name="sch_categories[]" id="sch_cat_hockeyschools" value="1" />General Hockey Schools
<input class="catmark" type="checkbox" name="sch_categories[]" id="sch_cat_springhockey" value="2" />Spring Hockey
The problem is that the upon clicking the checkbox, the checkbox does not become ticked or checked; it immediately returns to an unchecked state, which I thought the stopPropagation() function would help with. Apparently not. The multi-lists get enabled and disabled as expected, but the checkbox doesn't get ticked.
The result of this problem is that when the form is submitted, the array containing the selected categories is empty; thus, because at least one checked category is a required field in the form, the PHP script that processes the form throws one of my errors which tells me a required field was left blank.
Any ideas on how to make sure that the checkbox actually gets checked, and by extension, POSTS actual data to the processing script?
Thanks guys.
The problem is the use of toggle -- per the documentation:
The implementation also calls .preventDefault() on the event, so links
will not be followed and buttons will not be clicked if .toggle() has
been called on the element.
toggle itself is calling preventDefault, which is stopping the default behavior of the event, checking/unchecking the box.
Rather than toggle, use bind or on (see edit note below) to add a listener for the change event, in which you can examine the state:
$('#sch_cat_hockeyschools').on('change', function () {
if (this.checked) {
// do stuff for a checked box
console.log('check is on');
} else {
// do stuff for an unchecked box
console.log('check is off');
}
});
Try it out at jsFiddle.
EDIT
Please note, this code shows use of the on method, whereas the jsFiddle example uses bind. As pointed out by Sam Sehnert, on is the preferred method for attaching events with > jQuery 1.7. If you are using an older version of jQuery, use bind as in the jsFiddle example.
Documentation
jQuery.toggle
jQuery.bind
jQuery.on
(sorry for my english)
Hi!, i'm using jquery in an app where i have a dinamycally created table with text inputs inside like this:
<td><input type="text" id="code"></td>
<td><select id="type"><option value="0">Normal</option><option value="1">Other</option></select></td>
<td><input type="text" id="price" class="price"></td>
<td><input type="text" id="total"></td>
and in other part i have a button, when this button is clicked, create another line in the table.
The container of this table and button exists inside a template.. this templates is rendered using underscore.js
Now the problem: I need to iterate over the inputs in order: code, type, price. When i fill the input price i calculate the total and shows up in the input, and then i need to change focus to the button (#more_button) to let the user click or press enter to create another line in table.
I use this:
$('.price').blur(function(e){
_this.setTotal($(e.currentTarget).val());
$('#more_button').removeClass('inactive').focus();
e.preventDefault();
e.stopPropagation();
});
When the #more_button is focused the css background change.
When i execute this piece of code, the button change the background but the focus inmediatly change to url bar. This happend in firefox and Chrome.
I try to use this to set the focus:
$('.price').blur(function(e){
_this.setTotal($(e.currentTarget).val());
$('#more_button').removeClass('inactive').;
setTiemout(function(){
$('#more_button').focus();
},100);
e.preventDefault();
e.stopPropagation();
});
But don't work either.....
Can you give some guideline to acomplish this?
The user can change the focus of input.price when press Tab or click in other part of the page.. in this moment i need to trigget seTotal and focus on the button.
I don't know what the simple method
$('your_selector').focusout(function(){
$('#more_button').focus();
});
doesn't work with tab key (only with the mouse to change the focus).. so i solve using a mix between keydown event and focusout. like this:
$('.price').bind('keydown',function(e){
if(e.keyCode === 9){//Tab key
tab = true;
check(e);
return false;
}
}).bind('focusout',function(e){
if(!tab){
check(e);
}else{
tab = false;
}
e.preventDefault();
return false;
});
where check() is a function to validate the value and tab is a flag to check if the tab key was pressed.
$('your_selector').focusout(function(){
$('#more_button').focus();
});
works in FF and chrome here at least.
here a fiddle: http://jsfiddle.net/Zabn4/
The most modern solution (jQuery 1.7+) is to use the following code:
$('#your-input').on('focusout', function(e){
$('#submit-btn').focus();
});