I have a table with data, and when I click on a cell in a certain column, I want it to change into a select dropdown for the user to choose a category for that row (which will be written to the database by AJAX but that'll come later).
I've done something similar before with text boxes using this, which works great, but I'm not sure if I'm modifying it correctly.
I've created a JSFiddle which shows the problem I'm having. I click on the text and it turns into a select element as expected, but when I click on that to choose an option, the dropdown doesn't stay open and I can't select anything. Debugging has shown me that when I click the dropdown, it runs the $("td.ChooseType").click() routine again so I've tried to suppress that by removing the class then adding it back on on selection, but that hasn't solved it. On the rare occasion that the dropdown stays open, I am unable to select anything by either mouse or keyboard.
All of the users will be on IE8 unfortunately, so I need it to be compatible with that.
Thanks!
You need to use event delegation, as otherwise that click event is always bound to that td - regardless of whether its class changes.
Simply change:
$("td.ChooseType").click(function() {
To:
$("table").on('click', '.ChooseType', function () {
JSFiddle demo.
Purely as an alternative to the accepted answer, you can remove an attached handler with unbind. So instead of adding and removing the class, you could unbind and rebind your handler. Only requirement is that the function can't be in-line, but has to be declared separately.
example: http://jsbin.com/qiqunici/1/edit
var handler = function () {
$(this).unbind('click', handler); //unbind the clicked element only
//create and change the element
//inside the select-change event, instead of addClass, re-attach:
{
//$(this).parent().addClass("ChooseType").text(selected).find('select').remove();
$(this).parent().click(handler).text(selected).find('select').remove();
}
};
$("td.ChooseType").click(handler);
Related
So I have a simple dropdown in my code that I attach a click hander to, like so (code is technically typescript)
this.highElement.click(() => {
console.log(event);
});
This event is triggered both when I click the select box AND when I click one of the options (Here's a Js fiddle that demonstrates what I mean https://jsfiddle.net/Kolichikov/zmdL6q2d/). What I would like ideally is for the event to only fire when I click the select box itself, not the resulting list of items.
I tried setting a delegated event for the option this.highElement.on("click", "option", () => { console.log("option!"); });, but that didn't work.
I have noticed that the MouseEvent properties are different (the mouse coordinates aren't populated when an item is clicked), but this seems like a browser implementation that could change (maybe?).
Is there a way to properly differentiate between the two events?
I'll give you 2 options, you pick the one it's best for you:
First you can differentiate between the 2 events like this:
$("#selectItem").click(function(event){
if (event.target.id == 'selectItem')
console.log(event)
});
the event has a different target when it returns from clicking in select and from choosing an option.
But I think it would be much clearer if you used the change event
$("#selectItem").change(function(event){
console.log(event)
});
it fires only when you select an item. Depending on what you need this could be better.
EDIT
Checkingwhat #libzz said, I notice that the first part of the above response is wrong. I didn't edit it because the OP accepted the answer as is and I'd be changing the code that lead to his decision.
But as #libzz said, the event when fired has always the same id.
What I also noticed now is that the click event only fires when an option is clicked, not when the select box is clicked. That levels the onclick with the onchange event. They basically do the same thing in this case.
So in order to make code clearer, the best would be using only onchange event for selects.
I'm trying to use FancySelect.js to style the select boxes used on WooCommerce and have managed a few but I'm struggling with the Variation form on product pages.
While FancySelect triggers a change event on the original select box, it appears to affect nothing. Looking at the javascript used in the variations form, it looks like they've unbinded the change event on the select box and are handling it some other way, by triggering events on the .variations_form instead. I can't seem to get it to work though.
My code is something along the lines of:
$('.summary select').fancySelect().on('change.fs', function() {
$(this).trigger('change.$');
$('.variations_form').trigger('woocommerce_variation_select_change');
});
I've tried triggering multiple events but none seem to have any affect.
Any ideas?
Thanks.
So it turns out that the original trigger didn't work, for reasons I can't quite work out. However, manually triggering a change event on the original select box worked to some degree, but it wouldn't update fancySelect's "Trigger" element. I think this was because the original select's options didn't get a :selected attribute (for whatever reason). I've had to add a custom event to fancySelect to manually trigger it's updateText() method.
Updated code:
$('.summary .options li').on('click', function(){
$('.summary select').trigger('change').trigger('select.fs');
});
And the additional event for fancySelect (which I'll try contribute to if I get chance):
sel.on('select.fs', function(){
updateTriggerText();
});
Cheers.
Please see the jsfiddle link http://jsfiddle.net/Bjf7c/1/ and explain why the on click function does not work after we select another item and return back to the first selected item. It looks something weird to me since all the similar items fires the click function but not for the default selected item.
In the example first click on F and then click on E. You will find that all other items are clickable except E.
$(".items.cursor:not('.selected')").on('click',function(){
$('.items.selected').removeClass('selected');
$(this).addClass('selected');
});
When you write
$(".items.cursor:not('.selected')").on('click',function(){
you bind your event handler to all items that are not selected at time of binding, not at time of click. So you don't bind to your initially selected element.
You could use on and delegation to keep your selector and have it tested each time but here is a better solution :
$(".items.cursor").on('click',function(){
if ($(this).hasClass('selected')) return;
$('.items.selected').removeClass('selected');
$(this).addClass('selected');
});
(in this specific example the test isn't really useful but it might be if you add more code and don't want it to be executed if the user clicks the already selected element)
You are binding a function on the click event only to the non selected elements.
E is selected when the page loads and you bind this function.
Is there a way to 'undo' functions in jQuery? Let me explain.. I have a function which recreates exactly the select html tag. As you know with a select tag, clicking on a list item select that one, when clicking outside the select tag, the whole dropdown list closes. The selecting works fine, but the closing isn't. I though this would work with the event.stopPropagation() event object but it doesn't. Is there any other solution for this?
Demo: http://jsfiddle.net/cmAtc/
There is really nothing like what you are asking for that is built into jQuery natively. You have to do it on your own.
My suggestion would be to bind to the document:
$(document).on('click', function () {
$(".dropdownlist li").parent().children(":not(.selected)").hide();
});
You already have the stopPropagation that would prevent this from being triggered when you click the list too.
http://jsfiddle.net/cmAtc/1/
Please have a look at this fiddle: http://jsfiddle.net/mrmartineau/53fkV/embedded/result/
The intended outcome is that when a .poll_option td is clicked, the background colour changes to pink & the checkbox is checked. Each option has different bugs, these are:
Option 1:
The problem I have is that on Option 1, when I click the checkbox itself, it does not check but everything else works fine. By that I mean that when I click the label & the <td> the outcome is correct. It seems that the event is not bubbling correctly..
Option 2:
For this one, I tried another solution (removed the .toggle() method) and tried to figure out what element is actually being clicked (console.log(e.target.nodeName);) and now I can click the checkbox but not the label, rather the label does not make the event work.
Could you please have a look at my code & see where I'm going wrong because I'm sure it can't be this hard...
Cheers
Proposed simpler solution:
$('.poll_option.one td').click(function (e) {
$(this).toggleClass('highlight');
$(this).find('input').prop("checked", $(this).hasClass("highlight"));
console.log(e.target.nodeName);
// weird that clicking the label does not naturally propagate
// the click event to the parent
}).find("label").click(function () {
$(this).closest("td").click();
});
​Demo.