Keydown event inside onSelectRow method - javascript

I have this code in my JQuery grid:
onSelectRow:function(rowid){
var r=$("#myGrid").getRowData(rowid);
var col1 = r.column1;
$("#myGrid #"+rowid).keyup(function(e) {
if(e.keyCode == 46) {
alert(col1);
}
});
}
my actual purpose is to delete the selected row record in database when [delete] key is pressed on the keyboard.
I am testing the code with alert(), as given code above.
The problem is, whenever I clicked on the same row multiple times, say 4 times, followed by single [delete] key press, the alert popup 4 times. However, it works fine when I clicked 4 different rows, followed by single [delete] key press.
This is the illustration of the situation(clicked rows, followed by [delete]):
clicked row(in sequence) alert popups
row1 ->[delete] row1
row1, row2, row3, row4 ->[delete] row4
row1, row1, row1, row2 ->[delete] row2
row1, row2, row3, row3 ->[delete] row3, row3
row1, row2, row2, row2 ->[delete] row2, row2, row2
row1, row1, row1, row1 ->[delete] row1, row1, row1, row1
Why and how to overcome this problem? Or maybe there is another better way to do this?

Yes, each time You select a row, You're registering a keydown event listener.
Perhaps should You take your keydown event handler out like this:
$("#myGrid tr").keyup(function(e) {
var rowid = parseInt($(this).attr("id"));
var r=$("#myGrid").getRowData(rowid);
var col1 = r.column1;
if(e.keyCode == 46) {
alert(col1);
}
});
EDIT: If your grid is generated dynamically:
$("#myGrid").on("keyup", "tr", function(e) {
var rowid = parseInt($(this).attr("id"));
var r=$("#myGrid").getRowData(rowid);
var col1 = r.column1;
if(e.keyCode == 46) {
alert(col1);
}
});
You may need to somehow check that the row is selected.

What seems to be happening is when you click a row, onSelectRow is called. In this function you bind a keydown event on row. So, when you click the row 4 times, onSelectRow will be called 4 times, this will in-turn bind the event 4 times and so you see an alert 4 times.
Solution is NOT to bind the keydown event inside onSelectRow function. You should rather bind keyup outside onSelectRow function this way :
$("#myGrid someRowSelector").keyup(function(e) {
if(e.keyCode == 46) {
alert(col1);
}
});
Where someRowSelector identifies the rows to bind events on.

Instead of keydown event try keyup event
onSelectRow:function(rowid){
var r=$("#myGrid").getRowData(rowid);
var col1 = r.column1;
$("#myGrid #"+rowid).keyup(function(e) {
if(e.keyCode == 46) {
alert(col1);
}
});
}

if you dont want to modify the plugin you can make extend function for your jqgrid like this.
$.extend($.fn.jqGrid, {
bindKeysCustom: function (settings) {
var o = $.extend({
onEnter: null,
onSpace: null,
onLeftKey: null,
onRightKey: null,
onSupr: null,
scrollingRows: true
}, settings || {});
return this.each(function () {
var $t = this;
if (!$('body').is('[role]')) { $('body').attr('role', 'application'); }
$t.p.scrollrows = o.scrollingRows;
$($t).keydown(function (event) {
var target = $($t).find('tr[tabindex=0]')[0], id, r, mind,
expanded = $t.p.treeReader.expanded_field;
//check for arrow keys
if (target) {
mind = $t.p._index[$.jgrid.stripPref($t.p.idPrefix, target.id)];
if (event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40) {
// up key
if (event.keyCode === 38) {
r = target.previousSibling;
id = "";
if (r) {
if ($(r).is(":hidden")) {
while (r) {
r = r.previousSibling;
if (!$(r).is(":hidden") && $(r).hasClass('jqgrow')) { id = r.id; break; }
}
} else {
id = r.id;
}
}
$($t).jqGrid('setSelection', id, true, event);
event.preventDefault();
}
//if key is down arrow
if (event.keyCode === 40) {
r = target.nextSibling;
id = "";
if (r) {
if ($(r).is(":hidden")) {
while (r) {
r = r.nextSibling;
if (!$(r).is(":hidden") && $(r).hasClass('jqgrow')) { id = r.id; break; }
}
} else {
id = r.id;
}
}
$($t).jqGrid('setSelection', id, true, event);
event.preventDefault();
}
// left
if (event.keyCode === 37) {
if ($t.p.treeGrid && $t.p.data[mind][expanded]) {
$(target).find("div.treeclick").trigger('click');
}
$($t).triggerHandler("jqGridKeyLeft", [$t.p.selrow]);
if ($.isFunction(o.onLeftKey)) {
o.onLeftKey.call($t, $t.p.selrow);
}
}
// right
if (event.keyCode === 39) {
if ($t.p.treeGrid && !$t.p.data[mind][expanded]) {
$(target).find("div.treeclick").trigger('click');
}
$($t).triggerHandler("jqGridKeyRight", [$t.p.selrow]);
if ($.isFunction(o.onRightKey)) {
o.onRightKey.call($t, $t.p.selrow);
}
}
}
//check if enter was pressed on a grid or treegrid node
else if (event.keyCode === 13) {
$($t).triggerHandler("jqGridKeyEnter", [$t.p.selrow]);
if ($.isFunction(o.onEnter)) {
o.onEnter.call($t, $t.p.selrow);
}
} else if (event.keyCode === 32) {
$($t).triggerHandler("jqGridKeySpace", [$t.p.selrow]);
if ($.isFunction(o.onSpace)) {
o.onSpace.call($t, $t.p.selrow);
}
} else if (event.keyCode === 46) {
$($t).triggerHandler("jqGridKeySupr", [$t.p.selrow]);
if ($.isFunction(o.onSupr)) {
o.onSupr.call($t, $t.p.selrow);
}
}
}
});
});
}
});
Then, instead call your jqgrid like this
grid.jqGrid('bindKeys');
You have to call it like this
grid.jqGrid('bindKeysCustom', {
'onSupr': function (rowid) { }
});

Register one keydown-listener and then loop through a list of elements.
This is how I would do this:
var colsToDelete = {};
$(document).keydown(function(e) {
if(e.keyCode == 46) {
for(var id in colsToDelete) {
var data = colsToDelete[id];
alert(data);
}
colsToDelete = {};
e.preventDefault();
}
});
And your code looks like this:
onSelectRow:function(rowid){
var r = $("#myGrid").getRowData(rowid);
colsToDelete[rowid] = r.column1;
}

Related

Datatable search result add to cart enter key

I have joined a script called jquery.mycart with datatable.
document.onkeydown = function(evt) {
evt = evt || window.event;
var isEscape = false;
if ("key" in evt) {
isEscape = (evt.key == "Enter" || evt.key == "Enter");
} else {
isEscape = (evt.keyCode == 13);
}
if (isEscape) {
table.rows( { search:'applied' } ).data().each(function(value, index) {
console.log(value, index);
});
}
};
I have a problem that when we suppose we search for "Antalgina" when we press enter this search is added to the shopping cart. (look at the console).
Full code
https://codepen.io/anon/pen/oaQJNg
Please how could I do it or give me some hint
I hope you can help me.
Working codePen.
You could a simple jQuery event like :
$("document").on('onkeydown', function (e) {
if (e.keyCode !== 13) {
table.rows( { search:'applied' } ).data().each(function(value, index) {
console.log(value, index);
});
});
});

Chaining jquery keydown event

I am trying to create a drop down like functionality where a div is shown once somebody starts typing in the input box. I am able to attach mouse click event on the individual elements to select them. But I am not able to select them via pressing enter.
HTML
<input type="text" class="input" name="example" id="example" placeholder="example..." autocomplete="off" list="examplelist" />
<div class="autofill">
<ul class="autocomplete">
<li class="autocomplete-list">John Doe (San Jose, CA)</li>
<li class="autocomplete-list">Jane Doe (San Francisco, CA)</li>
<li class="autocomplete-list">John Jane (San Carlos, CA)</li>
</ul>
</div>
JQuery
$(document).ready(function () {
var $listItems = $('li.autocomplete-list'),
$div = $('div.autofill'),
$input = $('#example');
$div.hide();
$('input#example').on('keydown', function (e) {
var key = e.keyCode,
$selected = $listItems.filter('.selected'),
$current;
$div.show();
if (key != 40 && key != 38) return;
$listItems.removeClass('selected');
if (key == 40) { // Down key
if (!$selected.length || $selected.is(':last-child')) {
$current = $listItems.eq(0);
} else {
$current = $selected.next();
}
} else if (key == 38) { // Up key
if (!$selected.length || $selected.is(':first-child')) {
$current = $listItems.last();
} else {
$current = $selected.prev();
}
}
$current.addClass('selected');
// When I press enter after selecting the li element
// Does not work :(
$current.on('keypress keydown keyup', 'li', function (event) {
if (event.keyCode == 13) {
var value = $(this).text().split('(')[0].trim();
$input.val(value) ;
$div.hide();
}
});
});
// If somebody clicks on the li item
$('li.autocomplete-list').on('click', function (e) {
var value = $(this).text().split('(')[0].trim();
$input.val(value);
$div.hide();
});
// change color on hover
$('li.autocomplete-list').hover(
function(){ $(this).addClass('hover') },
function(){ $(this).removeClass('hover') }
);
// When I press enter after selecting the li element
// Does not work :(
$('li.autocomplete-list').on('keypress keydown keyup', 'li', function (event) {
if (event.keyCode == 13) {
var value = $(this).text().split('(')[0].trim();
$input.val(value) ;
$div.hide();
}
});
});
How can I select a particular li element and then take its value when press enter? Here is the JSFiddle
The <li> element doesn't have focus, even though it's selected visually. The text input still has focus.
You need to check for the enter key on the text <input>. Not on the <li>
$('input#example').on('keydown', function (e) {
//...
var key = e.keyCode
if (key == 40) { // Down key
//...
} else if (key == 38) { // Up key
//...
} else if (key == 13) { // Enter key
//... make sure $current is not null
}
//...
}
Also be careful of this statement
if (key != 40 && key != 38) return;
Which will return from the event handler when the enter key is pressed.
Here's a fiddle: http://jsfiddle.net/q1vtwtdp/4/
Jordan P is correct, the handling of the list should all happen within the keydown handler function of the input.
$('input#example').on('keydown', function (e) {
var key = e.keyCode,
$selected = $listItems.filter('.selected'),
$current;
$div.show();
$listItems.removeClass('selected');
if (key == 40) { // Down key
if (!$selected.length || $selected.is(':last-child')) {
$current = $listItems.eq(0);
} else {
$current = $selected.next();
}
}
if (key == 38) { // Up key
if (!$selected.length || $selected.is(':first-child')) {
$current = $listItems.last();
} else {
$current = $selected.prev();
}
}
if (key == 13) {
var value = $('.autocomplete-list').html().split('(')[0].trim();
$input.val(value);
$div.hide();
$current = $selected
}
$current.addClass('selected');
});
So you don't need:
$('li.autocomplete-list').on('keypress keydown keyup', 'li', function (event) {
if (event.keyCode == 13) {
var value = $(this).text().split('(')[0].trim();
$input.val(value) ;
$div.hide();
}
});
Working JSFiddle

after keyup event I want the change to be permanent

I want to add a class to a list using keyup event but when the keyup event is called it add the class to the list. After some seconds, the class from the list will be removed then i try to use setinterval on the callback function. It work but if i try to navigate through the list it behave funny.
Here is the code
(function(){
var AutocompleteActivities = {
init: function(config)
{
this.config = config;
$("#keywords").on("keyup", this.confirm);
},
confirm: function(e)
{
var self = AutocompleteActivities;
var con = self.config.div;
key = e.keyCode;
press = e.timeStamp
//check whether there is a key up invent in the search textfield and up or down arrow is press
if(press != "" && e.keyCode == 40 || e.keyCode == 38)
{
if(con.css("display") == "block")
{
setInterval(function(){
self.navigation(key)},500)
}
}
},
navigation: function(key)
{
var con = this.config.div, // #options - the container of the autocomplete
li = con.find("ul").find(">li"),
totalLi = li.length,
firstLi = li.first(),
current = 1; // it should be zero for debug reasons it is one
if(key == 40)
{
if(current != 0) // check whether the autoComplete selection is the first in the
{
firstLi.addClass("selection")
++current
con.find("ul li").filter(function() {
return $(this).hasClass("selection");
}).next().addClass("selection").end().removeClass("selection")
return false;
}
}
}
}
AutocompleteActivities.init({
div: $("#options"),
})
})()

Javascript ActiveElement and Keydown Event Listener

I'm new to Javascript and I'm trying to make the following code scan to see if a textbox with an id="lessonNum" is active, if it is not i would like to send a .click to a submit button with an id="A" when I press 'a' on the keyboard. Right now when I select the textbox I get an alert, but when I don't have it selected it doesn't pick up my keydown. Please Help!
function GetActive () {
if (document.activeElement.id == 'lessonNum') {
alert('lessonNum is active');
var b1=new Boolean(1);
} else {
var b1=new Boolean(0);
}
}
document.addEventListener("keydown", keyDownTextField, false);
function keyDownTextField(e) {
var keyCode = e.keyCode;
if(keyCode==65) {
if(b1==0) {
alert('a has been pressed');
document.getElementById('A').click();
}
}
}
In your code:
> function GetActive () {
> if (document.activeElement.id == 'lessonNum') {
> alert('lessonNum is active');
> var b1 = new Boolean(1);
the above line creates a local variable called b1 and assigns a new boolean object. I think you just want a primitive, so:
var b1 = true;
or the whole if..else statement can be replaced with:
var b1 = document.activeElement.id == 'lessonNum';
if (b1) alert('lessonNum is active');
Note that getActive is never called so b1 is never set anyway.
In keyDownTextField you have:
> if(b1==0) {
> alert('a has been pressed');
however b is local to GetActive so a reference error will be thrown. The simple solution is to make b global, a little more work but better though to hold it in a closure.
e.g.
(function(global) {
var b1;
var getActive = function () {
b1 = document.activeElement && document.activeElement.id == 'lessonNum';
if (b1) alert('lessonNum is active');
}
global.getActive = getActive;
var keyDownTextField = function (e) {
e = e || window.event;
var keyCode = e.keyCode || e.which;
if (keyCode == 65) {
getActive(); // should it be called here?
if (b1) {
alert('a has been pressed');
document.getElementById('A').click();
}
}
}
global.keyDownTextField = keyDownTextField;
}(this));
window.onload = function() {
addEvent(document, 'keydown', keyDownTextField);
};
// Just a helper
function addEvent(el, evt, fn){
if (el.addEventListener) {
el.addEventListener(evt, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + evt, fn);
}
}

JQuery .focus() event changing DropDown option

I have a selectlist with that is built using jquery inside a grid. When a user enters a key the select list is built, I then call click() and focus() so that I can use the key commands again.
The problem that I have is that .focus() is changing the selection of the select list when fired when it is fired. Has anyone experienced this behaviour before or found a workaround? Thanks in advance
function INTEREST_createPaymentTypeDropDown() {
//Interest specific:
//build a dropdown for the enum
//if the PaymentType input exists
if ($("#PaymentType").length > 0) {
var cellPaymentTypeValue = $("#PaymentType").val();
var selectedOption;
$("#PaymentType").replaceWith("<select id='PaymentType' style='width:95px; height: 20px;' name='PaymentType'></select>");
$.each(INTEREST_PAYMENT_TYPES, function(key, val) {
var newoption = $("<option value=\"" + val + "\">" + key + "</option>");
if (val == cellPaymentTypeValue || key == cellPaymentTypeValue) {
//append select to the current value
selectedOption = val;
}
$("#PaymentType").append(newoption);
$("#PaymentType").addClass("t-input");
});
if (selectedOption != null) {
$("#PaymentType").val(selectedOption.toString());
}
}
function INTEREST_setEditField(field) {
if ($("#PaymentType").length > 0) {
// this is where the problem is
$("#PaymentType").click();
}
else {
$(".t-grid-content").find('.t-input').click();
$(".t-grid-content").find('.t-input').select();
}
INTEREST_persistPaymentTypeOnCellChange(field);
}
function INTEREST_persistPaymentTypeOnCellChange(field) {
//keep the value of the enum not the enum index
//in the payment type field
var paymentTypeCell = $(field).parent().children().eq(1);
if ($(paymentTypeCell).html().length == 1) {
$.each(INTEREST_PAYMENT_TYPES, function(key, val) {
if ($(paymentTypeCell).html() == val) {
$(paymentTypeCell).html(key);
}
});
}
}
$('td.t-grid-edit-cell', 'div#AccountPayments').live('keydown', function(event) {
if (event.which == 39 || event.which == 9) //Tab or right arrow
{
if ($(this).hasClass('t-last')) {
INTEREST_goToNextRow(this, event);
}
else {
INTEREST_goToRight(this, event);
}
}
else if (event.which == 37 || event.which == 9 && event.shiftKey) //left arrow. Todo: add shift tab
{
if ($(this).hasClass('t-first')) {
INTEREST_goToPreviousRow(this, event);
}
else {
INTEREST_goToLeft(this, event);
}
}
else if (event.which == 40) //down arrow
{
INTEREST_goDown(this, event);
}
else if (event.which == 38) //up arrow
{
INTEREST_goUp(this, event);
}
});
$("#PaymentType").live('click', function(event) {
$(this).focus();
});
Could it be that there's no empty option at the top of the list so that when the click() is called it's causing PaymentType to auto-select the 0th option?

Categories

Resources