Alternative to "onChange" event with Semantic UI dropdown? - javascript

This is a dumb question but I've been all over the Semantic UI site, along with searching here and I haven't found a solution.
The gist is: I have been using the code below with a Semantic dropdown list. It works fine – except that I have a table component through which the user can also make a selection (which triggers a function) – and when they do, I update the Semantic dropdown to reflect the current selection . . . and then the onChange event fires – so a function is running twice when it doesn't need to.
I tried using onSelect but that is apparently not a valid event for a dropdown. I could do some stupid hack to work around this but I'd rather just use a different event. Is there one?
$(function () {
$('#productStates').dropdown({
allowAdditions: true,
allowReselection: true,
placeholder: "Select State",
onChange: function (value, text) {
if (projectData == undefined) return;
loadStateByID(value)
}
})
});

Ok - solved this. Wish the Semantic docs were clearer on event handling.
I was trying to prevent a "loading" function from getting called twice when a user clicked on a table cell and the dropdown was updated to reflect the current selection. I update the dropdown using:
$('#productStates').dropdown('set selected', activeStateID);
The onChange event handler captured all changes and so the "load" event would fire twice. Using action, the event only fires on a user action, not on setting the dropdown state through code.
$('#productStates').dropdown({
allowAdditions: true,
allowReselection: true,
placeholder: "Select State",
action: function (value, text) {
if (projectData == undefined) return;
$(this).dropdown('set selected', value);
loadStateByID(text)
}
})

Related

Mithril JS input checkbox events and element refresh

Working on a SPA with Mithril.js (love it!), but having a problem with input checkboxes not behaving correctly when I assign an "onchange" listener to them.
var Widget = {
view: function(vnode) {
return m("div", [
m("input[type=checkbox]", {
id: "cb" + vnode.attrs.id,
checked: Boolean(vnode.attrs.state),
onchange: function(e) {
console.log(
(e.target.checked) ? "ON" : "OFF"
);
}
}),
m("span", vnode.attrs.name)
]);
}
}
The page will initially populate properly, with checkboxes in their correct state (on or off), but when clicking the checkbox... the checkbox element does not switch.
At first, I thought the onchange event was interrupting and blocking the DOM redraw. But, then found that if I removed the "checked: (true|false)" attribute the elements works as expected.
Of course, this is not acceptable. The checkbox state needs to be presented according to it's current on/off state in the database.
I'm unsure if this is weirdness with Mithrils DOM redraw. Or some other strange behavior with HTML checkboxes and Javascript in general.
Here is a sample illustrating the broken behavior.
https://jsfiddle.net/v1aq85kj/14/
Any ideas are appreciated!
changed the "onchange" listener to an "onclick", but still the same.
tried updating checkbox states with javascript after the page load, but seemed clunky and a bad way to address the issue
You are missing out changing the value the checkbox binds to so checked/unchecked will never change.
something like this might help on the way
onchange: function(e) {
vnode.attrs.state = e.target.checked
}

How stop refreshing the kendo grid while selecting dropdown inside grid?

Acutally i am using kendo tree view. If i click check box it will create another one grid inside of Activity Column.In that one of the column is outputcategorycode. when ever i am clicking the none value one dropdown will bind dynamically there. then i need to select any one of the value in that dropdown. Once selection is done , checkbox is changing to uncheck mode then inside grid also disappearing that means whole grid is refreshing.
Please have look my Dojo link and give me solution for that.
http://dojo.telerik.com/#bagya/iMeRi
Thanks in advance...
You can bind the databinding event and stop grid from refreshing. Adding this in databound will prevent grid from refreshing.
$("#grid").data("kendoGrid").bind("dataBinding", function(e) {
e.preventDefault();
});
Once you are done with 'doing stuff' you can unbind the function by simply calling
grid.unbind("dataBinding");
Check your updated dojo with the changes :
NOTE : I have added it in databound of the grid just to show working,
but you probably should not do that, since it wont bind other grid data. So
add a different handler and based on certain event as per your
requirement, disable grid refresh and enabled after event is done.
Update:
You can use the onOpen and onClose event of the kendoDropDownList. Refer below:
Bind the onOpen and onClose events to the dropdown
function OutputProductEditor(container, options) {
$('<input required data-text-field="Value" data-value-field="Key" data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
//autoBind: false,
dataSource: ProductData,
close: onClose,
open: onOpen,
});
}
onOpen prevent refresh by adding databinding function
function onOpen() {
var grid = $("#grid").data("kendoGrid");
grid.bind("dataBinding", function(e) { e.preventDefault(); });
};
onClose - remove databinding
function onClose() {
var grid = $("#grid").data("kendoGrid");
grid.unbind("dataBinding");
};
Here is the updated dojo

Select selected option again

I have a table and I use select menu in each row for different actions for that specific row.
For example:
$(document).on('change', '.lead-action', function() {
// Do stuff
}
this method gets the value of the selected option. Based on the selected value, I display different popups. When the user leaves the page, the select menu retains the previously selected option.
Sometimes users click on the same option in the select menu. When they do, the above code doesn't work.
Is there a way to invoke the code block above if the same option in the select menu is selected?
I'm gathering that you just want the dropdown to fire anytime a selection is made. If so, check out the answer to Fire event each time a DropDownList item is selected with jQuery.
See my updated answer below:
You can use this small extension:
$.fn.selected = function(fn) {
return this.each(function() {
var clicknum = 0;
$(this).click(function() {
clicknum++;
if (clicknum == 2) {
clicknum = 0;
fn(this);
}
});
});
}
Then call like this:
$(".lead-action").selected(function(e) {
alert('You selected ' + $(e).val());
});
Update:
I'm actually rather unhappy with the original script. It will break in a lot of situations, and any solution that relies on checking the click count twice will be very fickle.
Some scenarios to consider:
If you click on, then off, then back on, it will count both clicks and fire.
In firefox, you can open the menu with a single mouse click and drag to the chosen option without ever lifting up your mouse.
If you use any combination of keyboard strokes you are likely to get the click counter out of sync or miss the change event altogether.
You can open the dropdown with Alt+↕ (or the Spacebar in Chrome and Opera).
When the dropdown has focus, any of the arrow keys will change the selection
When the dropdown menu is open, clicking Tab or Enter will make a selection
Here's a more comprehensive extension I just came up with:
The most robust way to see if an option was selected is to use the change event, which you can handle with jQuery's .change() handler.
The only remaining thing to do is determine if the original element was selected again.
This has been asked a lot (one, two, three) without a great answer in any situation.
The simplest thing to do would be to check to see if there was a click or keyup event on the option:selected element BUT Chrome, IE, and Safari don't seem to support events on option elements, even though they are referenced in the w3c recommendation
Inside the Select element is a black box. If you listen to events on it, you can't even tell on which element the event occurred or whether the list was open or not.
The next best thing is to handle the blur event. This will indicate that the user has focused on the dropdown (perhaps seen the list, perhaps not) and made a decision that they would like to stick with the original value. To continue handling changes right away we'll still subscribe to the change event. And to ensure we don't double count, we'll set a flag if the change event was raised so we don't fire back twice:
Updated example in jsFiddle
(function ($) {
$.fn.selected = function (fn) {
return this.each(function () {
var changed = false;
$(this).focus(function () {
changed = false;
}).change(function () {
changed = true;
fn(this);
}).blur(function (e) {
if (!changed) {
fn(this);
}
});
});
};
})(jQuery);
Instead of relying on change() for this use mouseup() -
$(document).on('mouseup', '.lead-action', function() {
// Do stuff
}
That way, if they re-select, you'll get an event you can handle.
http://jsfiddle.net/jayblanchard/Hgd5z/

MagicSuggest plugin related to calling ajax on item select and close to update database

I am trying to implement the magicsuggest plugin into a one page app
I need the plugin to ajax server every time an item is added or removed from the selected list.
$(ms).on('selectionchange', function(event, combo, selection) {
// save selected item to database
addToDatabase(ms.getValue()[ms.getValue().length-1]);
})
$("span.ms-close-btn").bind("click",function(event) {
var theValue=$(this).parent().text()
deleteFromDatabase(tValue);
})
I have a one page app with these two functions. When an item is added to selection list I want to call addItemToDatabase which will submit value with ajax and add it to database
When the close button (x) is clicked, I want to let magicsuggest do its default behavior where it removes item from selection and ALSO calls my deleteFromDatabase function which will send item id/value to server via ajax and delete item from database.
I am stuck. It seems like closing always fires a selectionchange event first. But, if I isSilent or someway bypass the selectionchange then the default behavior is cancelled and the item is not removed from selected in dom.
the sample code above will do everything correctly accept, when the close button is clicked, it will not only deleteFromDatabase, but also trigger the selectionchange and execute addToDatabase. So, the item will look like it was removed, but on refresh it is there because both add and remove functions were executed.
I hope this makes sense enough to receive some help. Am having a hard time figuring out the event behavior with the plugin.
Any help would be great.
Okay, after about 15 hours I got this working. Here are the 3 functions involved.
Again, this allows me to add to selection and delete from selection in real time with database updates.
// removing item from selection
function resetClose() {
$("span.ms-close-btn").not($(".span.ms-close-btn.guest")).bind("click",function() {
var tValue=$(this).parent().text()
registration.deleteAttendingEmployee(tValue)
resetClose()
})
}
// *** Adding item to selection
$(ms).bind('selectionchange', function(event, combo, selection){
$(ms).trigger('addToSelection',[eval(ms.getSelectedItems()),true]);
})
$(ms).on('addToSelection', function(selection) {
registration.addSafetyMeetingAttendee(ms.getValue()[ms.getValue().length-1])
ms.collapse()
resetClose()
});
This is another alternative based on above
go to magicsuggest library dev version;
find _renderSelection: function() {..};
find selectedItemEl variable;
modify the library;
original line:
selectedItemEl = $('<div/>', {
'class': 'ms-sel-item ms-sel-text ' + cfg.selectionCls + validCls,
html: selectedItemHtml + (index === (_selection.length - 1) ? '' : cfg.resultAsStringDelimiter)
}).data('json', value);
Updated:
selectedItemEl = $('<div/>', {
'data-id':value[cfg.valueField],
'class': 'ms-sel-item ms-sel-text ' + cfg.selectionCls + validCls,
html: selectedItemHtml + (index === (_selection.length - 1) ? '' : cfg.resultAsStringDelimiter)
}).data('json', value);
Capture the selection event change and bind close button
$(ms).on('selectionchange', function (e, m) {
$(".ms-close-btn").bind("click", function (event) {
var theValue = $(this).parent().attr("data-id");
alert(theValue);
});
});

jQuery autocomplete prevent focus after selection

Requirement:
I'd like a jQuery autocomplete element that allows the user to pick an item and set the display field and a hidden field with the selected value. But I would also like the field and the hidden field to be cleared when the input field receives focus by the user.
Problem:
The problem I'm facing is that when the user selects an item it's almost like jQuery is executing the onSelect function and then sending the focus to the input field again which fires my focus() event (and therefore clearing my selection).
Problem Browser:
IE8 , works in Chrome. Did not try others.
Attempted fixes:
I have tried setting the focus to another element in the select()
function. It did put the focus on that element but only after
focussing on the input field
Tried both event.preventDefault() and event.stopPropagation() in the
select() method. Did not work.
Blur didnt work either.
Workarounds:
I guess I can change the clearing to be on click instead of on focus, but this is not what I want.
Similar stackoverflow thread:
jquery autocomplete remove focus after suggest
Code:
Here is my code:
$(function () {
$("#autosuggest").autocomplete({
source: "my server path",
minLength: 3,
select: function (event, ui) {
if (ui.item) {
$("#autosuggest").val(ui.item.value);
$("#hidden").val(ui.item.id);
}
}
});
$("#autosuggest").focus(function () {
$("#hidden").val("");
this.value = "";
});
});
The problem is: when you click on an autocomplete suggestion, the focus shifts to that dropdown menu, ever so shortly, to return to your input afterwards. Do you still get this problem if you choose the autocomplete suggestion by using the arrow-down button? If you do not, then this is the problem.
The only way I can see to fix this is not to make it a focus event after all, but I think I know why you don't want to make it a click event: you also want to capture tabbing into the field.
Solution: make it a click handler, and add a 'keyup' handler that executes the click handler handler if the key was a tab (arrow-down etc are still allowed).
I got this from the jQuery forum and it works fabulous!
select: function(event, ui) {
$(event.target).autocomplete("close")
setTimeout(function() {
$(event.target).blur();
})
}
Link: https://forum.jquery.com/topic/autocomplete-input-field-stays-focused-after-selection
Try onSelect function..
$(function () {
$("#autosuggest").autocomplete({
source: "my server path",
minLength: 3,
select: function (event, ui) {
if (ui.item) {
$("#autosuggest").val(ui.item.value);
$("#hidden").val(ui.item.id);
}
},
onSelect: function (suggestion) {
$(this).click();}
});
$("#autosuggest").focus(function () {
$("#hidden").val("");
this.value = "";
});
});

Categories