jqgrid - how to circumvent number checking - javascript

I have a column in a jqgrid defined as number. The user is forced to enter a number like 6.5 with the comma delimeter being a point.
This grid is also used by german speaking people who are used to insert numbers like this 6,5 using the comma as the delimeter.
This people are getting upset when they are not allowed to insert 6,5 instead of 6.5 :D
To make their (and in the end) my life more convenient I'm looking for a way to convert automatically the 6,5 to 6.5 . This should be done on the client side, since I want to rely on jqgrid num checking.
Thus I should check (and maybe transform) the number before jqgrid is checking it.
Is this possible?
--edit--
None of these functions are called, except the first one.
Any idea why this could be the reason?
afterInsertRow:function (rowid, aData){
alert('fire');
},
beforeSaveCell : function(rowid,celname,value,iRow,iCol){
alert('no fire');
return "new value";
},
beforeSubmitCell : function(rowid,celname,value,iRow,iCol){
alert('no fire2');
return "new value";
},
beforeEditCell : function(rowid,celname,value,iRow,iCol){
alert('no fire3');
return "new value";
},
--edit2--
This is the code I'm using for inline editing.
onSelectRow: function(row_id){
if(row_id != null) {
var date_str = jQuery('#grid').getCell(row_id, 'date_str');
//var sum = jQuery('#grid').getCell(row_id, 'sum');
var description = jQuery('#grid').getCell(row_id, 'description');
if(date_str != "Total"){
if(row_id !== last_selected_row) {
if(row_id == -99){
//thats the first click of the user after initial load of the grid
jQuery('#grid').jqGrid('saveRow',row_id)
.editRow(row_id, true,true,reload);
last_selected_row = row_id;
}
else{
//after user jumps from one cell to another using the mouse
jQuery('#grid').jqGrid('saveRow',last_selected_row,reload);
jQuery('#grid').jqGrid('restoreRow',last_selected_row);
last_selected_row = row_id;
}
} else {
jQuery('#grid').jqGrid('saveRow',row_id)
.editRow(row_id, true,true,reload);
last_selected_row=row_id;
}
}
}
},

If you use cell editing, you can try to write your beforeSaveCell event handler which do the text replacement which you need.
UPDATED: I don't know which information can be placed in the cell, but probably the usage of Masked Input Plugin (see old answer here) or just 'keypress' filtering (see another answer) could improve user experience.

Related

Script to automatically capitalize contents of a cell in Google Sheets?

I have a spreadsheet that takes input of stock symbols. I would like them to always be in ALL CAPS regardless of how they are typed in. This appears to require some scripting as there is no way to do this with a function unless a second copy of the column exists, which is not acceptable.
I have a solution which works, with one critical problem. The code is as follows:
function OnEdit(e) {
var ss = e.source.getActiveSheet(),
sheets = ['Trades', ''],
ind = sheets.indexOf(ss.getName());
if (ind === 0 && e.range.rowStart > 1 && e.range.columnStart >= 1 ) {
e.range.setValue(e.value.toUpperCase());
}
}
It works great, and allows me to add as many tabs and columns to format as I wish. Unfortunately it also capitalizes the FORMULAS inside the cells, which is breaking formulas that use the importhtml() function, because it capitalizes the URL being requested.
So, anyone know a way to do exactly what the above code does, but not touch the actual formulas inside the cells, only the text that they output?
EDIT: Thanks to #ocordova's comment, I thought I had something that would do the job well enough. Unfortunately it's behaving strangely... it works partly o some columns, and not at all on others. Here is my current code (slightly altered from earlier for clarity):
function onEdit(e){
var activeSheet = e.source.getActiveSheet(),
sheets = ['NEW Trades', ''],
sheetIndex = sheets.indexOf(activeSheet.getName());
if (sheetIndex === 0 && e.range.rowStart > 1 && e.range.columnStart >0 && e.range.getFormula() == '') {
e.range.setValue(e.value.toUpperCase());
}
}
Anyone have any ideas why some cells in some columns will capitalize as expected, and other cells in those same columns won't, and yet other columns won't capitalize at all, anywhere?
EDIT 2: My trouble appears to be related to, or a conflict with, Data Validation. The columns I'm trying to capitalize are fed by lists of values on another sheet. If the value was present previously in lower case, and then I applied the data validation to the column, the script will not capitalize the value. However if I select the appropriate, capitalized selection from the data validation list, and then re-type the same value in lower case, the script DOES kick in and capitalize. Very strange and confusing. I could be wrong about the conflict, but that's what it seems like to me.
EDIT 3: It's not related to data validation, because it's behaving the same way on a simple column that has no validation at all. If the value I had previously entered was already in lowercase, then typing it again in lowercase will not activate the script. BUT if I type the value in CAPS, then re-type it in lowercase, the script capitalizes it. Maybe some strange condition relating to when the script is triggered...?
If you don't want to capitalize if the cell contains a formula, you can use the method getFormula() and check if the cell contains a formula.
Returns the formula (A1 notation) for the top-left cell of the range, or an empty string if the cell is empty or doesn't contain a formula.
The code should look like this:
if (ind === 0 && e.range.rowStart > 1 && e.range.columnStart >= 1 && e.range.getFormula() == '') {
e.range.setValue(e.value.toUpperCase());
}
EDIT:
If I've understood you correctly, you're typing exactly the same value, example: if the value in the cell is México, and you delete all or some characters and inmediately type México again, in that scenario the old value and the new value are the same and the OnEdit() won't be fired. Another example is if you change the format of the value, that's another type of event.
If you want know how the event is considered, you can use an installable on change trigger:
function triggerOnChange(e) {
MailApp.sendEmail('john.doe#gmail.com', 'Testing triggerOnChange', JSON.stringify(e));
}
Then in the Script Editor menu: Resources -> Current Project Triggers -> Add a new trigger -> ['triggerOnChange', 'From spreadsheet', 'On change']
On how to change the case of the formula's result, I think #Rubén has the right idea, but it will only work if the formula contains UPPER() in the first characters, and also since you're using the formula IMPORTHTML() using UPPER() will break it and maybe some other functions like array formulas, unless you use INDEX():
=INDEX(UPPER(IMPORTHTML(url, query, index)))
Another option could be Regular expressions, but I think it's a little risky considering all the combinations.
So, anyone know a way to do exactly what the above code does, but not touch the actual formulas inside the cells, only the text that they output?
Consider to make a slight change in the OP approach: rather than capitalize all the cells content for any case, capitalize according the following conditions:
If the cell value, including the values of cells that holds constants or formulas, is not a string then do nothing .
If the cell value is a string
and the cell content is a constant, then change the case directly from the script.
and the cell content is a formula, then nest the original formula inside the built-in function UPPER.
Example:
function onEdit(e) {
var range = e.range;
var value = range.getValue();
var sheet = range.getSheet();
var sheetName = sheet.getName();
if (sheetName === 'Sheet1' &&
range.getRow() > 1 &&
range.getColumn() > 1 &&
typeof value === 'string') {
if(!range.getFormula()) {
range.setValue(value.toUpperCase());
} else {
if(range.getFormula().substring(0,6).toUpperCase() == '=UPPER') {
return;
} else {
range.setFormula('=UPPER(' + range.getFormula().substring(1) + ')');
}
}
}
}
Notes:
For simplicity the ind array was not included.
typeof e.value always returns 'string', so instead range.getValue(); is used.

How To Check For Empty Fields In HTML Form With JavaScript

I'm checking a website registration form with JavaScript code and onchange listeners.
Empty fields/spaces need to be checked for first before checking for illegal characters, too long strings, etc.
I've read this.
But for a null string,
if (field.value ==="")
alert("Empty field!");
this will not generate the desired alert.
People at the end of the above thread suggested that recent browser versions might not accept such a statement.
So, how do I sort out empty/blank/ignored fields ?
EDIT 1
I've already tried
if (!field.value)
but it only provides an alert if the user has already typed some characters in the field and immediately deleted them before entering a blank field. It will not provide an alert just by clicking the mouse on it and then tabbing on to the next field. It looks like I may need to assign a null value to these form fields at the outset . . I am using implicit adding of the changeEvent listener, i.e. on seeing a value explicitly assigned to the onchange attribute of an element, it is activated without any addEventListener(..) statement.
Also,
if (field.value.length == 0)
does not seem to produce any alert.
EDIT 2
Sorted, I think.
I was using the JavaScript null field check as part of a field-by-field validation check on a web form.
I was using onchange as the event handler. This was wrong. What was needed here was onblur since in the case of a completely null field (i.e. a field on which nothing had been entered before tabbing away from it), no change has been effected -- and therefore no onchange event occurs that would trigger a JavaScript alert.
Thanks for your efforts.
I was stuck on this one across a couple of weeks and only sorted it with the help of some experimental programming by a more experienced guy at work here.
In this script you can see an alert of your variable value ( a console.log would be lees noisy :)
The use of === is for type check but in your example does not make sense as you are using an empty string
<script>
var field= {};
checkEquality(field);
field.value = "";
checkEquality(field);
function checkEquality(object){
alert(object.value);
if (object.value === "")
{
alert("===");
}
if(object.value == ""){
alert("==");
}
}
You can use bellow code for check all four(4) condition for validation like not null, not blank, not undefined and not zero only use this code (!(!(variable))) in javascript and jquery.
function myFunction() {
var data; //The Values can be like as null, blank, undefined, zero you can test
if(!(!(data)))
{
alert("data "+data);
}
else
{
alert("data is "+data);
}
}

get the new added characters to an input by js

I know this seems a quite easy target. I have an input[type=text], and I want to detect the new added character(s) in it. The normal way is:
$selector.keypress(function(e) {
//do sth here
var newchar = String.fromCharCode(e.which);
});
But the above method not working properly for some browsers on android devices. Typing the android virtual keyboard will not fire the keypress.
Then I found the following method is better:
$selector.on('input', function(e){
//do sth here
});
It works fine for android devices, and also, it can detect cut/paste.
Now the question is, is there a way to know the new added character(s) to the input? Do I need to do the complicated string comparison during inputing each time, i.e. compare the previous string and the new string in the input box? I said it's complicated because you may not always type in char(s) at the end, you may insert some char(s) in the middle of the previous string. Think about this, the previous string in the input box is "abc", the new string after pasting is "abcxabc", how can we know the new pasted string is "abcx", or "xabc"?
The method from keypress is quite simple:
String.fromCharCode(e.which);
So, is there similar way to do this by the on('input') method?
After reading Yeldar Kurmangaliyev's answer, I dived into this issue for a while, and find this is really more complicated than my previous expectation. The key point here is that there's a way to get the cursor position by calling: selectionEnd.
As Yeldar Kurmangaliyev mentioned, his answer can't cover the situation:
it is not working is when you select text and paste another text with
replacing the original one.
Based on his answer, I modified the getInputedString function as following:
function getInputedString(prev, curr, selEnd) {
if (selEnd === 0) {
return "";
}
//note: substr(start,length) and substring(start,end) are different
var preLen = prev.length;
var curLen = curr.length;
var index = (preLen > selEnd) ? selEnd : preLen;
var subStrPrev;
var subStrCurr;
for(i=index; i > 0; i--){
subStrPrev = prev.substr(0, i);
subStrCurr = curr.substr(0, i);
if (subStrCurr === subStrPrev) {
var subInterval = selEnd - i;
var interval = curLen - preLen;
if (interval>subInterval) {
return curr.substring(i, selEnd+(interval-subInterval));
}
else{
return curr.substring(i, selEnd);
}
}
}
return curr.substring(0, selEnd);
}
The code is quite self explanation. The core idea is, no matter what character(s) were added(type or paste), the new content MUST be ended at the cursor position.
There's also one issue for my code, e.g. when the prev is abcabc|, you select them all, and paste abc, the return value from my code will be "". Actually, I think it's reasonable, because for my scenario, I think this is just the same with delete the abc from previous abcabc|.
Also, I changed the on('input') event to on('keyup'), the reason is, for some android browsers, the this.selectionEnd will not work in a same way, e.g., the previous text is abc|, now I paste de and the current string will be abcde|, but depending on different browsers, the this.selectionEnd inside on('input') may be 3, or 5. i.e. some browsers will report the cursor position before adding the input, some will report the cursor position after adding the input.
Eventually, I found on('keyup') worked in the same way for all the browsers I tested.
The whole demo is as following:
DEMO ON JSFIDDLE
Working on the cross-browser compatibility is always difficult, especially when you need to consider the touch screen ones. Hope this can help someone, and have fun.
Important notes:
when a user types in a character, the cursor stands after it
when a user pastes the text, the cursor is also located after the pasted text
Assuming this, we can try to suggest the inputed \ pasted string.
For example, when we have a string abc and it becomes abcx|abc (| is a cursor) - we know that actually he pasted "abcx", but not "xabc".
How do this algorithmically? Lets assume that we have the previous input abc and the current input: abcx|abc (cursor is after x).
The new one is of length 7, while the previous one is of length 4. It means that a user inputed 4 characters. Just return these four characters :)
The only case when it is not working is when you select text and paste another text with replacing the original one. I am sure you will come up with a solution for it yoruself :)
Here is the working snippet:
function getInputedString(prev, curr, selEnd) {
if (prev.length > curr.length) {
console.log("User has removed \ cut character(s)");
return "";
}
var lengthOfPasted = curr.length - prev.length;
if (curr.substr(0, selEnd - lengthOfPasted) + curr.substr(selEnd) === prev)
{
return curr.substr(selEnd - lengthOfPasted, lengthOfPasted);
} else {
console.log("The user has replaced a selection :(");
return "n\\a";
}
}
var prevText = "";
$("input").on('input', function() {
var lastInput = getInputedString(prevText, this.value, this.selectionEnd);
prevText = this.value;
$("#result").text("Last input: " + lastInput);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<div id="result">Start inputing...</div>

Jquery limit text in text field copy safe

Here is a mind Boggling question i am having trouble with. I have a text field. This text field needs to accommodate U.S mobile numbers with 4 formats
XXX-XXX-XXXX
XXXXXXXXXX
X-XXX-XXX-XXXX
XXXXXXXXXXX
When the last character is entered it needs to do a check via ajax which i have no problem with.
I need to check if the textbox has the full mobile number in when typing, copying and pasting, deleting and every possible way to put numbers in that field.
i tried checking it with $("#id").keyup but that doesn't work when you paste something.
is there a way to check either via interval or something else if there is 10 or eleven characters in that field regardless of how it got there? [edit]
Here is a solution i found
var checkMsisdnInterval = window.setInterval( function () {
var msisdn = getdigits($("#newSessionMsisdn").val());
if(msisdn.length == 10 && !checked) {
doPreCheck(msisdn);
checked = true;
} else if(checked == true) {
//do something here
} else {
//do something else
}
}, (1000 * 60 * 0.1));
$("#newSessionMsisdn").keyup(function(){
checked = false;
});
function getdigits (s) {
return s.replace (/[^\d]/g, "");
}
it works like a bomb. Thanks for all the replies
Why not checking it in the ajax call, use the beforeSend method and check the length of the input field.
For your reference, http://api.jquery.com/jQuery.ajax/
Using jQuery, have you looked at the change event?
http://api.jquery.com/change/

Check all values in an array are same

I have a webpage that has a textbox.
When the user enters information into it, it makes a AJAX call to see if the entry is valid, if not it disables a button.
They can also add up to 10 textboxes which is done via jQuery Templates. At the moment each textbox has a class of serial and when a serial textbox is blurred it does this check.
If they enter a invalid serial it will disable the button but if they add a new textbox and that is valid the button is now enabled which is wrong as there is one still invalid.
The only way I can think to do this is to add a 1 or 0 to an array for each textbox and once all elements in the array are 1 then enable the button. Is that a good approach, if not please explain a better one. If it is a good approach how do I check all values in a javascript array are the same?
Thanks
This sounds like a good approach. You can check for equal elements in a javascript array using this simple javascript function. You may paste this to a firebug console to check its functionality.
// check if all elements of my_array are equal, my_array needs to be an array
function check_for_equal_array_elements(my_array){
if (my_array.length == 1 || my_array.length == 0) {
return true;
}
for (i=0;i<my_array.length;i++){
if (i > 0 && my_array[i] != my_array[i-1]) {
return false;
}
}
return true;
}
//Example:
var my_array = [];
my_array.push(5);
my_array.push(5);
// will alert "true"
alert("all elements equal? "+check_for_equal_array_elements(my_array));
my_array.push(6);
// will alert "false"
alert("all elements equal? "+check_for_equal_array_elements(my_array));
I will assume you have a isValid(str) function that returns a boolean.
Since you're using jQuery, you can take advantage of jQuery's filter() function to easily check if any inputs are invalid whenever an input blurs:
$('.serial').live('blur', function () {
// Get an array of all invalid inputs
var invalids = $('.serial').filter(function () {
return !isValid($(this).val());
});
// Does the array contain anything?
$('#button').prop('disabled', invalids.length);
});
Demo: http://jsfiddle.net/3RNV6/
Similar concept, but for use with AJAX:
$('.serial').live('blur', function () {
var me = this;
$.ajax({
// ajax config
success: function (data) {
if (data === 'Y') $(me).addClass('valid');
// Get an array of all invalid inputs
var invalids = $('.serial').filter(function () {
return !$(this).hasClass('valid');
});
// Enable if none invalid
if (invalids.length === 0) $('#button').prop('disabled', false);
}
});
});
$('.serial').live('keypress', function () {
$('#button').prop('disabled', true);
$(this).removeClass('valid');
});
First of if you dynamically create n textboxes you should use live() or delegate() methods of jQuery to inform of new DOM elements added.
Secondly your approach is just fine but instead of an array you can set param of inputs with wrong text and then disable button if there are any elements with wrong text. I think it will be faster than looping though all textboxes all over.
I would use validation to achieve this.
http://docs.jquery.com/Plugins/Validation#Demos
If you can validate client-side great - either use one of the existing jQuery validation functions shown in the link above, or write your own.
If you must validate server side via ajax, then you could build this into a custom validation routine.
Then in the call that shows/hides the button - make a call to $('#formid).validate() - returns false if any validation fails.

Categories

Resources