I have created a JQuery dynamic table here and I'm trying to implement input checking to make sure only the numbers are saved. The cell is updated either by clicking outside of it or by pressing the enter button and what I am trying to achieve is having an alert whenever an invalid input is entered.
The 'focusout' function alert is is working perfectly. The 'keypress' function alert on the other hand is behaving strangely, the alert message is popping out as normal however it doesn't go away no matter how many times I click ok.
According to console.log() the alert is triggering the 'focusout' function somehow. But even if that was the case, I don't understand how that is causing the error since the 'focusout' function works fine. I've tried to use $(this).focus() after the alert but this didn't work. Any Idea what I may be missing?
Thanks in advance
$(document).on('keypress', '.row_data', function (event) {
if (event.which === 13) {
event.preventDefault()
if (isNaN($(this).html())) {
alert("Enter valid number")
} else {
var elem = $(this)
saveValue(elem)
}
}
});
/* Saves the edited cell data when user clicks outside the cell */
$(document).on('focusout', '.row_data', function (event) {
event.preventDefault();
if (isNaN($(this).html())) {
alert("Enter valid number")
} else {
var elem = $(this)
saveValue(elem)
}
});
EDIT
So here is my HMTL for context. I am using Handlebars to create a table but basically all my cells are like this..
<span class="row_data" edit_type="click" col_name="col_1">{{col_1}}</span>
</td>
<td>£
<span class="row_data" edit_type="click" col_name="col_2">{{col_2}}</span>
</td>
<td>£
<span class="row_data" edit_type="click" col_name="col_3">{{col_3}}</span>
</td>
and I'm using JQuery to make the cells editable like this...
/* Makes each cell on the table editable */
$(document).on('click', '.row_data', function (event) {
event.preventDefault();
if ($(this).attr('edit_type') === 'button') {
return false;
}
$(this).closest('span').attr('contenteditable', 'true');
$(this).css("background-color", "beige").css('padding', '5px');
$(this).focus();
})
I've made some changes below to your code and have commented on it fully. It's best to not repeat code whenever possible, and just maintain a single function and trigger that using various methods rather than having to ensure two different functions are maintained separately.
You are currently triggering your alert multiple times, we can rationalize the code a bit to avoid the two different functions triggering the warning.
I think you can simplify things by using:
$(":focus").blur();
This removes the focus from whichever element is in focus.
I've assumed your .row_data is an input, so have also used .val() rather than .html(), you might need to change this back depending on your use case.
Let me know if you were hoping for something else.
// I would recommend using keyup rather than keypress
$(document).on('keyup', '.row_data', function(event) {
// Check if it is a return
if (event.which === 13) {
// Remove focus
// This will triger the function below, it'll be easier to manage a single function
$(':focus').blur();
// Prevent default
event.preventDefault()
}
});
/* Saves the edited cell data when user clicks outside the cell */
$(document).on('focusout', '.row_data', function(event) {
// Prevent default
event.preventDefault();
// Check if NaN
// Used .val() - not sure if you need to use .html in your use case
if (isNaN($(this).val())) {
// Notify user
alert("Enter valid number")
} else {
// Pass element to save
saveValue($(this))
}
});
// Test saving function
function saveValue(elem) {
// Send to console to prove it works
console.log("Saving " + elem.val());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="row_data">
Hi having your HTML here will help suggest a better soultion, but the simple guess is that you are creating a loop, with your events.
You said the keypress event is the problem, just for testing purposes have you tried changing keypress to keydown/keyUp.
Also i sugges changing the alert to console.log, for easier debuging.
Related
I am a little lost in working on this and need some help please. I have a checkbox for terms and conditions that needs to be pressed before users can be registered. I have written some pseudo code in how I think it should be programmed.
//If user hovers over anchor
//Check to see if check box is checked
//If not checked
//Display alert saying "You need to check the terms and conditions"
//Else if - do not allow user to use anchor
//Else if user does check the box allow anchors to be used submitted
Hope that make sense. Here is some of the code I have written but I am getting nowhere! Please help :)
$("#checkbox1").click(function() {
$("#id-reg-submit").attr("disabled", !this.checked);
});
This above code is what I am using at the moment for users to actually click the box and prevents the moving forward in the sign up process.
What I need to do is get this to interacted with the other links (social media signup)
and the submit button, thus this is what I have so far:
$(".wp-social-login-provider").hover(function(){
alert("Click The Terms & Conditions!");
});
if($("#checkbox1").click(function() {
$("#id-reg-submit").attr("disabled", !this.checked);
});){
$(".wp-social-login-provider").hover(function(){
alert("Click The Terms & Conditions!");
});
}else{
alert("hi");
}
I have been playing with code hover on and off stated trying to figure this out and have wrapped some code in an if else statement.
if({$("#checkbox1").click(function() {
$("#id-reg-submit").attr("disabled", !this.checked);
}); && $( "a.wp-social-login-provider" ).hover(
function() {
$( this ).append( $( "<span> ***</span>" ) );
}, function() {
$( this ).find( "span:last" ).remove();
}
); )} else{
alert.("huhuuhu");
}
As you can tell I need a little help! Can anyone help me please?
Cheers,
Max.
I think this is what you want to achieve?
you can use event.preventDefault(); to stop the form from submitting.
$('input[type=button]').on('mouseenter', function() {
if($('input[type=checkbox]').prop('checked')) { alert('true');} else {alert('false');}
});
http://jsfiddle.net/c1d7j70u/
There are a few possible ways of getting this done, but since you have already provided a fiddle, I will follow your logic from there :)
Your logic in the fiddle you have provided is actually sound (sans a few typos), and I have expanded on it based on your requirements. Basically what you want to do is to disable the anchor link when it is hovered on, but only when the terms and conditions are not accepted/checked. Therefore, you can use a namespaced event (in case if you have other click events bound to it), which prevents the default link action from executing using e.preventDefault(). You turn this off if the if condition evaluates otherwise:
$('input[type=button], .something').on('mouseenter', function () {
if(!$('input[type="checkbox"]').prop('checked')) {
alert('Please accept the terms and conditions');
$('.something').on('click.disable', function(e) {
e.preventDefault();
});
} else {
$('.something').off('click.disable');
}
});
See fiddle here: http://jsfiddle.net/teddyrised/znrrsxyr/1/
The only flaw of this system is that if a user tabs his way to the anchor link, he/she can actually use the link because the if conditionals are only evaluated on mouseenter.
An alternative approach is instead of listening to events on the targets (button and anchor), you can listen to the onChange events of your checkbox, and decide if you want to enable the targets accordingly:
// Function: disable interactions
var disableActions = function() {
$('.something').on('click.disable', function(e) {
e.preventDefault();
});
$('input[type="button"]').prop('disabled');
$('input[type="button"], .something').on('mouseenter.disable', function() {
alert("Please check the terms and conditions.");
});
}
// Disable interactions at runtime
disableActions();
// Conditional onchange
$('input[type="checkbox"]').change(function() {
if(!$(this).prop('checked')) {
disableActions();
} else {
$('input[type="button"]').prop('disabled', false);
$('.something').off('click.disable');
$('input[type="button"], .something').off('mouseenter.disable');
}
});
See alternative solution here: http://jsfiddle.net/teddyrised/znrrsxyr/4/
Here is an efficient solution as per Jquery standard.
JSFIDDLE
<input type="checkbox" id="chkBox"/>
<input type="button" id="btn" value="Hello World">
MY link
$("#btn, #linkTo").on("mouseenter",function(){
// $("#chkBox").is(":checked") ? alert("checked"): alert("not checked");
});
$("#btn, #linkTo").on("click",function(e){
$("#chkBox").is(":checked") ? alert("call your function and replace the alert"): e.preventDefault();
});
I'm currently working on code that builds a div box when the user clicks on the .pTile div that does not have the .join class. The click function works, however, for accessibility reasons, I need to have the enter key also build the div when the user uses the enter key. There are multiple .pTile's on the page and more or less can be added at any time through a database. I can't seem to get the enter key function to work. Assistance would be much appreciated.
The following is the working click function the code in it is omitted as it's pretty long:
$(document).on('click', '.pTile:not(.join)', function (e) {
//Do stuff
});
This is the code that I am not able to get to work:
$('.pTile:not(.join)').bind('keypress', function (e) {
if (e.keyCode || e.which) {
$('.pTile:not(.join)').click();
return false; }
});
EDIT: I'd also like to note that the key press function does not get fired at all.
Here is a JSBin with a solution: http://jsbin.com/yelomunafo/1/
Basically you add keypress to the $(document).on('click') part.
I am trying to use jquery to override the default tabbing navigation. I cannot simply use the tabindex property because I am trying to get the tab key to navigate from a text input to a virtualized textbox (codemirror). I have been trying to use the following javascript/jquery to no avail:
$('#modelName').focus(function() {
$(this).keydown( function(event) {
if(event.keyCode=='9') {
codeMirror.focus();
}
});
});
Any thoughts on how to make this work?
$('#modelName').keydown( function(event) {
if(event.keyCode == 9) {
event.preventDefault();
codeMirror.focus();
}else{
alert("Not the right key! " + event.keyCode);
}
});
It's good to have a catch, just so you can see where you're going wrong.
In this case, I think it's string vs int.
Also, the way your code is, you would be applying a new keydown event handler each time the #modelName gets focus, without removing the old one. Would likely cause problems later.
try this
$('#modelName').keyup(function (e) {
if(e.keyCode== 9){
codeMirror.focus();
}
});
use keyup() instead of keydown()
i have a function that currently working on .keypress event when the user right something in the textbox it do some code, but i want the same event to be triggered also when the user clear the textbox .change doesn't help since it fires after the user change the focus to something else
Thanks
The keyup event will detect if the user has cleared the box as well (i.e. backspace raises the event but backspace does not raise the keypress event in IE)
$("#inputname").keyup(function() {
if (!this.value) {
alert('The box is empty');
}
});
jsFiddle
As Josh says, this gets fired for every character code that is pressed in the input. This is mostly just showing that you need to use the keyup event to trigger backspace, rather than the keypress event you are currently using.
The solution by Jonathon Bolster does not cover all cases. I adapted it to also cover modifications by cutting and pasting:
$("#inputname").on('change keyup copy paste cut', function() {
//!this.value ...
});
see http://jsfiddle.net/gonfidentschal/XxLq2/
Unfortunately it's not possible to catch the cases where the field's value is set using javascript. If you set the value yourself it's not an issue because you know when you do it... but when you're using a library such as AngularJS that updates the view when the state changes then it can be a bit more work. Or you have to use a timer to check the value.
Also see the answer for Detecting input change in jQuery? which suggests the 'input' event understood by modern browsers. So just:
$("#inputname").on('input', function() {
//!this.value ...
});
Another way that does this in a concise manner is listening for "input" event on textarea/input-type:text fields
/**
* Listens on textarea input.
* Considers: undo, cut, paste, backspc, keyboard input, etc
*/
$("#myContainer").on("input", "textarea", function() {
if (!this.value) {
}
});
You can check the value of the input field inside the on input' function() and combine it with an if/else statement and it will work very well as in the code below :
$( "#myinputid" ).on('input', function() {
if($(this).val() != "") {
//Do action here like in this example am hiding the previous table row
$(this).closest("tr").prev("tr").hide(); //hides previous row
}else{
$(this).closest("tr").prev("tr").show(); //shows previous row
}
});
Inside your .keypress or .keyup function, check to see if the value of the input is empty. For example:
$("#some-input").keyup(function(){
if($(this).val() == "") {
// input is cleared
}
});
<input type="text" id="some-input" />
I have a simple in-line edit in my grid, and I want to commit the change when the user tabs off the textbox. The default behavior of jqGrid forces the user to press 'Enter' to commit the change, but this is non-intuitive for our users.
onSelectRow: function(id) {
$(gridCoreGroups).editRow(id, true, undefined, function(response)
{
alert("hello world");
}
}
I've worked my way through the events provided, but they all happen as a result of the user pressing 'Enter', which I want to avoid. Is there something I can wire up that would trigger an action when the user tabs off this cell?
For in line editing you can accomplished this several ways. To bind an onblur event to the input field using the onSelectRow trigger, eliminating the need for edit and save buttons, do something like this:
$('#gridId').setGridParam({onSelectRow: function(id){
//Edit row on select
$('#gridid').editRow(id, true);
//Modify event handler to save on blur.
var fieldName = "Name of the field which will trigger save on blur.";
//Note, this solution only makes sense when applied to the last field in a row.
$("input[id^='"+id+"_"+fieldName+"']","#gridId").bind('blur',function(){
$('#gridId').saveRow(id);
});
}});
To apply a jQuery live event handler to all inputs that may appear within a row (jqGrid labels all inputs as rowId_fieldName ), loop throw the number of rows in your grid and do something like this:
var ids = $("#gridId").jqGrid('getDataIDs');
for(var i=0; i < ids.length; i++){
fieldName = "field_which_will_trigger_on_blur";
$("input[id^='"+ids[i]+"_"+fieldName+"']","#gridId").live('blur',function(){
$('#gridId').jqGrid('saveRow',ids[i]);
});
}
Note: To use blur with .live() like above, you'll need jQuery 1.4 or the patch located at:
Simulating "focus" and "blur" in jQuery .live() method
Be careful with rowIds. When you get into sorting, adding and removing of rows, you may find yourself writing some tricky jQuery to convert row ids to iRows or row numbers.
If you're like me and you went with individual cell edit, you'll want to modify the afterEditCell trigger with something like:
$('#gridId').setGridParam({afterEditCell: function(id,name,val,iRow,iCol){
//Modify event handler to save on blur.
$("#"+iRow+"_"+name,"#gridId").bind('blur',function(){
$('#gridId').saveCell(iRow,iCol);
});
}});
Hope that helps..
This is pretty horrible, but its my take on this problem, and is prob a bit easier and more generic - it presses enter programmatically when the item loses focus :)
afterEditCell: function() {
//This code saves the state of the box when focus is lost in a pretty horrible
//way, may be they will add support for this in the future
//set up horrible hack for pressing enter when leaving cell
e = jQuery.Event("keydown");
e.keyCode = $.ui.keyCode.ENTER;
//get the edited thing
edit = $(".edit-cell > *");
edit.blur(function() {
edit.trigger(e);
});
},
Add that code to your jqgrid setup code.
It assumes that the last edited item is the only thing with .edit-cell as a parent td.
My solution was to use basic jQuery selectors and events independently of the grid to detect this event. I use the live and blur events on the textboxes in the grid to capture the event. The two events are not supported in combination with each other, so this hack ended up being the solution:
Simulating "focus" and "blur" in jQuery .live() method
I know this question is old however the answer is outdated.
A global variable called lastsel must be created and the following added to the jqGrid code
onSelectRow: function (id) {
if (!status)//deselected
{
if ($("tr#" + lastsel).attr("editable") == 1) //editable=1 means row in edit mode
jQuery('#list1').jqGrid('saveRow', lastsel);
}
if (id && id !== lastsel) {
jQuery('#list1').jqGrid('restoreRow', lastsel);
jQuery('#list1').jqGrid('editRow', id, true);
lastsel = id;
}
},
I had the same issue and tried the answers above. In the end I went with a solution that inserts an "Enter" key press when the user is leaving the tab.
// Call this function to save and unfinished edit
// - If an input exists with the "edit-call" class then the edit has
// not been finished. Complete the edit by injecting an "Enter" key press
function saveEdits() {
var $input = $("#grid").find(".edit-cell input");
if ($input.length == 1) {
var e = $.Event("keydown");
e.which = 13;
e.keyCode = 13;
$input.trigger(e);
}
}
Instead of using selectRow use CellSelect.
onCellSelect: function (row, col, content, event) {
if (row != lastsel) {
grid.jqGrid('saveRow', lastsel);
lastsel = row;
}
var cm = grid.jqGrid("getGridParam", "colModel");
//keep it false bcoz i am calling an event on the enter keypress
grid.jqGrid('editRow', row, false);
var fieldName = cm[col].name;
//If input tag becomes blur then function called.
$("input[id^='"+row+"_"+fieldName+"']","#gridId").bind('blur',function(e){
grid.jqGrid('saveRow', row);
saveDataFromTable();
});
//Enter key press event.
$("input[id^='"+row+"_"+fieldName+"']","#gridId").bind('keypress',function(e){
var code = (e.keyCode ? e.keyCode : e.which);
//If enter key pressed then save particular row and validate.
if( code == 13 ){
grid.jqGrid('saveRow', row);
saveDataFromTable();
}
});
}
//saveDataFromTable() is the function which validates my data.