jQuery (attach, detach, reattach) event handlers issues - javascript

What I'm trying to do is to make a Datatable Editable. So the feature flow is this.
When clicking a cell, an input will be CREATED. So, whatever the cell has, it will be overwritten and moved to the value of the created input. (see an example of DataTables Editor, it works like that.)
Upon blur of the input. (Pressing Enter Key also triggers blur)
a. If the value is unchanged, it will return to a normal cell (with its value unchanged of course)
b. If the value was changed, it will stay as an input.
So, if I made an edit to a cell, it should stay as an input upon blur, but if I made an edit to that cell again, this time to input the original value, UPON BLUR, it should NOW shrink back into a cell.
But something weird is happening. This is the flow.
I click one cell, edit, make it lose focus. (so it will stay as an input)
I click another cell, edit, make it lose focus. (it will also stay as an input)
Now, when I click the cell that I've edited first, and retain it back to its original value. UPON BLUR, the cell which I've edited second, also returns back into a cell!
I'm suspecting a scope/reference issue here.
Feel free to see my working code in JSFiddle to understand the problem more.
JSFiddle: http://jsfiddle.net/UvjnT/2512/
For the JSFiddle, try to do these (in first row):
Click cell with Trident value.
Edit it, like add a letter. Like: aTrident
Now lose the focus, it will stay as an input.
Try clicking the cell with Internet value.
Edit it, for me it was: aInternet
Lose focus. It will remain as an input.
Now click the cell with aTrident value.
Edit it back to Trident.
See the bug happen.
To prove you that the feature is working and there's just a bug.
Try editing a cell, lose focus, edit it again to its original value, and watch it shrink back into a cell. :D
Help would be greaaaaaaat! :)
I'm running the following code on each on click of a td element inside the table.
el.html('<input class="table-edit form-control input-sm" type="text" value="' + val + '" />');
el.off('click');
input = el.children('input').first();
input.focus();
input.on('keyup', function(e) {
if (e.which == 13) {
$(this).blur();
}
});
input.on('blur', function(e) {
newVal = $(this).val();
if (val == newVal) {
input.css('font-weight', 'normal');
input.parent('td').css('outline', 'none');
input.off('blur keyup');
input.fadeOut('fast', function() {
el.html(val);
toInput(el, val);
});
} else {
input.parent('td').css('outline', '1px solid #F79421');
}
});

It seems like the problem was here:
input.fadeOut('fast', function() {
el.html(val);
toInput(el, val); // <- this
});
Correction: You forgot add var at newVal = $(this).val();.
This caused the variable newVal to be defined globally.
Corrected JSFiddle

Related

Move to a specific tab index when leaving another input with jquery

I have a page that is generated dynamically and all the tabindex's are preset. What I am attempting to do is to have the focus set to a specific tabindex when another input loses focus. For example if I have <input tabindex=119> and another with <input tabindex=16> how can I get to tabindex=16 when 119 loses focus? I have tried
$(zip).keydown(function(event) {
if (event.which == 9) {
event.preventDefault();
//$('#DublinTheme_wt213_block_wtMainContent_WebPatterns_wt50_block_wtPanelContent_WebPatterns_wt191_block_wtColumn1_wtVendors_EmailAddress').focus();
$('input').find("[tabindex=16]").focus();
}
});
where zip is the input field id of tabindex = 119. This did nothing at all for me. I have also tried just setting the focus to the id of the input I want:
$('#DublinTheme_wt213_block_wtMainContent_WebPatterns_wt50_block_wtPanelContent_WebPatterns_wt191_block_wtColumn1_wtVendors_EmailAddress').focus();
put in the place of $('input').find("[tabindex=16]").focus();
again, this did not place the focus on the correct input.
Any help here would be greatly appreciated.
You shouldn't put Outsystems generated id's hardcoded in your script. Create a new expression like in the example below. The blur event will be executed when an element loses focus.
Obviously replace the yourOutsystemsTabIndex199Element and yourOutsystemsTabIndex16Element with the name of your inputs.
Also set the expression so it doesn't escape content.
"<script>
$(document).ready(function(){
$('#" + yourOutsystemsTabIndex199Element.id + "').on('blur', function(){
$('#" + yourOutsystemsTabIndex16Element.id + "').focus();
});
});
</script>"

Mvc Telerik grid cancel cell changes when input invalid

I am facing a small problem regarding input validation in mvc telerik grid.
I have it set to batch editting and I'm modifing the cells in an InCell mode.
Now whenever a user enters an invalid value in one of the inputs(Telerik's comboboxes/autocompletes), I'd like to display a message that
the entered value is iligal(this far I've managed on my own).
In addition to the message I'd like to revert the cell's value to it's previus value before
the user input.
So far I've tried:
grid.CancelCell(this);
$('#grid .t-grid-edit-cell input[type="text"]').value or innerText = prevVal;
The closest so far was e.newVal = e.oldVal, although it sometimes throws me a wierd exception in the jquery scripts or displays the combobox's drop down.
All the validatios and things I've tried are from the grid's client event OnSave()
It's same like what i searched before and I have solution for you.
On your OnSave() method has event like OnSave(e) and that 'e' carry all the elemnts and functions inside in my example after validation if not ok i can change that value to old value. Also you can use inspecter element log to look up what is inside 'e'
function onSave(e){
if(!validation)
{
///
}
else
{
e.cell.firstChild.value = "0"; // that is my edited cell
}
}

jQuery UI checkboxes misbehaving when cloned

I'm trying to create a table of inputs that automatically adds a new row when you enter text in one of the inputs on the bottom line. For the most part, it works fine. However, I'm having some trouble with jQuery UI checkbox buttons.
The checkbox buttons are supposed to change their icon when clicked. This works fine for the original buttons, but the cloned button that appears when you add a new row doesn't work properly.
You can see it in jsfiddle here. To replicate the issue, put some text in the third input down. You'll see that a fourth row appears. If you press the fourth checkbox, you'll see the third checkbox is the one whose icon changes. The wrong button also gets ui-state-focus but doesn't actually get focus, which really baffles me, though the correct button does get ui-state-active and seems, as far as I can tell, to evaluate as having been checked properly.
To be clear, the two checkboxes do not have the same ID, and their labels are for the right checkbox - the createNewRow() function takes care of that. If you comment out the line that turns the checkboxes into jQuery UI checkboxes, you'll see everything works fine. If you console.log the value of $(this).attr('id') in the buttonSwitchCheck function, you'll see that it has the right ID there too - if you click the fourth button, it'll tell you that the id of $(this) is "test4", but it's "test3" (the third button) that gets the icon change.
I'm going mad staring at this and I'd appreciate any help people can give. Here's the code:
// Turns on and off an icon as the checkbox changes from checked to unchecked.
function buttonSwitchCheck() {
if ($(this).prop('checked') === true) {
$(this).button("option", "icons", {
primary: "ui-icon-circle-check"
});
} else {
$(this).button("option", "icons", {
primary: "ui-icon-circle-close"
});
}
}
// Add a new row at the bottom once the user starts filling out the bottom blank row.
function createNewRow() {
// Identify the row and clone it, including the bound events.
var row = $(this).closest("tr");
var table = row.closest("table");
var newRow = row.clone(true);
// Set all values (except for buttons) to blank for the new row.
newRow.find('.ssheet').not('.button').val('');
// Find elements that require an ID (mostly elements with labels like checkboxes) and increment the ID.
newRow.find('.ssheetRowId').each(function () {
var idArr = $(this).attr('id').match(/^(.*?)([0-9]*)$/);
var idNum = idArr[2] - 0 + 1;
var newId = idArr[1] + idNum;
$(this).attr('id', newId);
$(this).siblings('label.ssheetGetRowId').attr('for', newId);
});
// Add the row to the table.
newRow.appendTo(table);
// Remove the old row's ability to create a new row.
row.removeClass('ssheetNewRow');
row.find(".ssheet").unbind('change', createNewRow);
}
$(document).ready(function () {
// Activate jQuery UI checkboxes.
$(".checkButton").button().bind('change', buttonSwitchCheck).each(buttonSwitchCheck);
// When text is entered on the bottom row, add a new row.
$(".ssheetNewRow").find(".ssheet").not('.checkButton').bind('change', createNewRow);
});
EDIT: I was able to find a solution, which I'll share with the ages. Thanks to "Funky Dude" below, who inspired me to start thinking along the right track.
The trick is to destroy the jQuery UI button in the original row before the clone, then reinitializing it immediately afterwards for both the original row and the copy. You don't need to unbind and rebind the change event - it's just the jQuery UI buttons which have trouble. In the createNewRow function:
row.find('.checkButton').button('destroy');
var newRow = row.clone(true);
row.find('.checkButton').add(newRow.find('.checkButton')).button().each(buttonSwitchCheck);
Try using the newer method .on, that allows for delegation, which should help with the dynamic changes to your DOM:
$(".checkButton").button().each(buttonSwitchCheck);
$("table").on("change", ".checkButton", buttonSwitchCheck);
I'm not sure, but it might help with not having to worry about binding events to specific elements.
Also, you could use it for the textbox change event:
$("table").on("change", ".ssheetNewRow .ssheet:not(.checkButton)", createNewRow);
Here's your fiddle with my changes: http://jsfiddle.net/Cugb6/3/
It doesn't function any different, but to me, it's a little cleaner. I thought it would've fixed your problem, but obviously hasn't, due to problems with the button widget.
And funny enough, it doesn't seem they "support" cloning: http://bugs.jqueryui.com/ticket/7959
i think you are using deep clone, which also clones the event handler. in your create new row function, try unbinding the change event then rebind on the clone.

overriding data-confirm values

I want to change the value of data-confirm attribute on a button (submit) based on user's choices on a form. I put the following on the change function of a dropdown list:
...
if($("#"+select_name).val() == "abc")
{
$(".variable_button").attr("data-confirm","abc is good choice!");
} else
{
$(".variable_button").attr("data-confirm","abc would have been great but this is fine too...");
}
...
The problem I am facing is that apparently data-confirm cannot be changed once it is assigned a non-empty string. I have it set to "" in the server code. And, it changes to one of the two messages shown above when the user first makes a selection on the dropdownlist. But if the user changes the selection one more time, the data-confirm message does not change. Is this per design or am I missing something?
Don't use .attr(), use .data():
var newData = ($("#"+select_name).val() == "abc")
? "abc is good choice!"
: "abc would have been great but this is fine too...";
$(".variable_button").data("confirm", newData);
jQuery does allow you to update a data- attribute with the .attr() method, so something else is breaking.
Here's a working example (JSFiddle):
var counter = 1;
$('#click').click(function() {
button = $('#click');
console.log(button.attr('data-confirm'));
button.attr('data-confirm', 'this is test ' + counter);
console.log(button.attr('data-confirm'));
counter++;
});
Can you try to repo the issue in a JSFiddle?
On rereading your question, it sounds like an event handler isn't firing the second time the user changes the selection. See if you can set a breakpoint in your event handler to see if it even gets hit.

set value to jquery autocomplete combobox

I am using jquery autocomplete combobox
and everything is ok. But I also want to set specific value through JavaScript like $("#value").val("somevalue") and it set to select element, but no changes in input element with autocomplete.
Of course, I can select this input and set value directly, but is it some other ways to do that? I try set bind to this.element like this.element.bind("change", function(){alert(1)}) but it was no effects. And I don't know why.
Edit
I found a workaround for this case. But I don't like it. I have added the following code to _create function for ui.combobox
this.element.bind("change", function() {
input.val( $(select).find("option:selected").text());
});
And when I need to change the value I can use $("#selector").val("specificvalue").trigger("change");
Is this demo what you are looking for?
The link sets the value of the jQuery UI autocomplete to Java. The focus is left on the input so that the normal keyboard events can be used to navigate the options.
Edit: How about adding another function to the combobox like this:
autocomplete : function(value) {
this.element.val(value);
this.input.val(value);
}
and calling it with the value you want to set:
$('#combobox').combobox('autocomplete', 'Java');
Updated demo
I cannot find any available existing function to do what you want, but this seems to work nicely for me. Hope it is closer to the behaviour you require.
I managed a quick and dirty way of setting the value. But, you do need to know both the value and the text of the item that you want to display on the dropdown.
var myValue = foo; // value that you want selected
var myText = bar; // text that you want to display
// You first need to set the value of the (hidden) select list
$('#myCombo').val(myValue);
// ...then you need to set the display text of the actual autocomplete box.
$('#myCombo').siblings('.ui-combobox').find('.ui-autocomplete-input').val(myText);
#andyb,
i think rewrite:
autocomplete: function (value) {
this.element.val(value);
var selected = this.element.children(":selected"),
value = selected.val() ? selected.text() : "";
this.input.val(value);
}
I really like what andyb did, but I needed it to do a little more around event handling to be able to handle triggering the a change event because "selected" doesn't handle when hitting enter or losing focus on the input (hitting tab or mouse click).
As such, using what andyb did as a base as well as the latest version of the jQuery Autocomplete script, I created the following solution: DEMO
Enter: Chooses the first item if menu is visible
Focus Lost: Partial match triggers not found message and clears entry (jQuery UI), but fully typed answer "selects" that value (not case sensative)
How Change method can be utlized:
$("#combobox").combobox({
selected: function (event, ui) {
$("#output").text("Selected Event >>> " + $("#combobox").val());
}
})
.change(function (e) {
$("#output").text("Change Event >>> " + $("#combobox").val());
});
Hopefully this helps others who need additional change event functionality to compensate for gaps that "selected" leaves open.
http://jsfiddle.net/nhJDd/
$(".document").ready(function(){
$("select option:eq(1)").val("someNewVal");
$("select option:eq(1)").text("Another Val");
$("select option:eq(1)").attr('selected', 'selected');
});
here is a working example and jquery, I am assuming you want to change the value of a select, change its text face and also have it selected at page load?
#
Attempt 2:
here is another fiddle: http://jsfiddle.net/HafLW/1/ , do you mean that you select an option, then you want to append that value to the autocomplete of a input area?
$(".document").ready(function(){
someString = "this,that";
$("input").autocomplete({source: someString.split(",")});
$("select").change(function(){
alert($(this).val()+" appended");
someString = someString+","+$(this).val();
$("input").autocomplete({source: someString.split(",")});
});
});

Categories

Resources