How do I specify an optional character in an input mask?
I found this masked input plugin http://digitalbush.com/projects/masked-input-plugin/ and these mask definitions.
$.mask.definitions['g']="[ ]";
$.mask.definitions['h']="[aApP]";
$.mask.definitions['i']="[mM]";
$.mask.definitions['2']="[0-1]";
$.mask.definitions['6']="[0-5]";
new_mask = "29:69";
$("#txtTime").mask(new_mask);
This defines an input mask for a 12 hour time format, e.g. 11:00. I'd like to allow the user to specify only one digit for the "hour". Instead of having to type 01:00, the user should be able to type 1:00. How do I do that?
You need to use ? for optional characters so in your case you should use "2?9:69".
Quote and example from the page you linked to in your question:
You can have part of your mask be optional. Anything listed after '?'
within the mask is considered optional user input. The common example
for this is phone number + optional extension.
jQuery(function($){
$("#phone").mask("(999) 999-9999? x99999");
});
You can use $.mask.definitions['g']="[0-9 ]";
I have a similar problem I am trying to solve for variable currency amounts ($0.00 - $10000.00), and I don't really understand how the plugin is working.
On the one hand, the $.mask.definitions['symbol'] = '???' bit looks like it's employing a regex fragment, based on the examples in the API reference, and somewhat confirmed by this part in the source, within the mask function's code:
$.each(mask.split(""), function (i, c) {
if (c == '?') {
len--;
partialPosition = i;
} else if (defs[c]) {
tests.push(new RegExp(defs[c]));
if (firstNonMaskPos == null)
firstNonMaskPos = tests.length - 1;
} else {
tests.push(null);
}
});
...On the other, a mask definition of []|[0-9] does not work (I am attempting to do empty string or 0-9, for those not literate in regex.) For reference, I am attempting to build a mask to fulfill the 0.00-10000.00 condition like oooo9.99, where o is []|[0-9].
Since the code confirms that this is based upon regexes, the null or range pattern should be working but aren't; this is a more obscure bug in the mask framework. Unless I am the one trying to do something incorrectly, which is also possible...
Related
Hope someone can help with this. I have come across an issue with the application im testing. The developers are using vue.js library and there are a couple of fields which reformat the entered test. So for example if you enter phone number, the field will automatically enter the spaces and hyphens where its needed. This is also the same with the date of birth field where it automatically enters the slashes if the user does not.
So the issue I have is that using both 'setValue()' or 'sendKeys()' are entering the text too fast and the cursor in the field sometimes cannot keep up and the text entered sometimes appears in the incorrect order. For example, if I try to enter '123456789'. Some times it ends up as '132456798' (or any other combination). This cannot be produced manually and sometimes the test does pass. But its flakey.
What I wanted to do was to write a custom command to do something where it enters the string but in a slower manner. For this I need to have control of how fast I want the text to be entered. So I was thinking of something like this where I can pass in a selector and the text and then it will enter one character at a time with a 200 millisecond pause in between each character. Something like this:
let i = 0;
const speed = 200; // type speed in milliseconds
exports.command = function customSetValue(selector, txt) {
console.log(selector);
console.log(txt);
if (i < txt.length) {
this.execute(function () {
document.getElementsByName(selector).innerHTML += txt.charAt(i);
i++;
setTimeout(customSetValue, speed);
}, [selector, txt]);
}
return this;
};
When running document.getElementsByName(selector) in browser console I get a match on the required element. But it is not entering any text. Also note that I added a console.log in there and I was actually expecting this to log out 14 times but it only logged once. So itss as if my if condition is false
I checked my if condition and it should be true. So not sure why its not reiterating the function. Any help is much appreciated.
Also if it helps. I am using the .execute() command to inject javascript which is referenced here: https://nightwatchjs.org/api/execute.html
And the idea on this type writer is based on this: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_typewriter
We ended up taking a different approach much simpler. Wanted to post here in case anyone else ever needs something similar
exports.command = function customSetValue(selector, txt) {
txt.split('').forEach(char => {
this.setValue(selector, char);
this.pause(200); // type speed in milliseconds
});
return this;
};
I'm trying to write a function that validates number depending on the country. With each country, using intl-input, I obtain different class. Depending on that class inside the PrestaShop checkout module I am trying to implement the different amount of characters in phone input.
Result is something like this:
function validatePhoneNumber(s)
{
if ($('div').hasClass("opt216")) {
var reg = /^\+(?:[0-9] ?){10}$/;
}else {
var reg = /^\+(?:[0-9] ?){10,14}$/;
}
return reg.test(s);
}
What I have in this is every country has the same amount of characters (10) and if the statement doesn't seem to work. So, I thinking, is making this regex variable and changing it on if statement actually allowed?
Thanks everyone, I figured out what was wrong - i had few opt216 classes in document, so i went another way with attribute selection, something like that
if ($('#iti-item-216').attr('aria-selected') == 'true')
I have a WooCommerce store, which is connected with Zapier to a Google spreadsheet. In this file, I keep track of the sales etc. Some of these columns contain -obviously- prices, such as price ex VAT, etc. However, for some reason the pricing values are stored in my spreadsheet as strings, such as 18.21.
To be able to automatically calculate with these values, I need to convert values in these specific columns to numbers with a comma as divider. I'm new to Google Script, but with reading some other post etc, I managed to "write" the following script, which almost does the job:
function stringIntoNumber() {
var sheetActive = SpreadsheetApp.openById("SOME_ID");
var sheet = sheetActive.getSheetByName("SOME_SHEETNAME");
var range = sheet.getRange("R2:R");
range.setValues(range.getValues().map(function(row) {
return [row[0].replace(".", ",")];
}));
}
The script works fine as long as only values with a dot can be found in column R. When values that belong to the range are changed to values with a comma, the script gives the error:
TypeError, can't find the function Replace.
Select the column you want to change.
Goto Edit>Find and Replace
In Find area put "."
in Replace with area put ","
The error occurs because .replace is a string method and can't be applied to numbers. A simple workaround would be to ensure the argument is always a string, there is a .toString() method for that.
in your code try
return [row[0].toString().replace(".", ",")];
The locale of your spreadsheet is set to a country that uses commas to seperate decimal places. Zapier however seems to use dots and therefore google sheets interprets the data it gets from Zapier as strings since it can't interpret it as valid numbers.
If you change the locale to United States (under File/Spreadsheet settings) it should work correctly. But you may not want to do that because it can cause other issues.
You got a TypeError because the type was number and not string. You can use an if statement to check the type before calling replace. Also you should convert the type to 'number' to make sure it will work correctly independent of your locale setting.
range.setValues(range.getValues().map(function(row) {
if(typeof row[0] === "string") return [Number(row[0].replace(",", "."))];
else return row;
}));
In this case I convert , to . instead of the other way around since the conversion to number requires a ..
Click on Tools > Script Editor.
Put this on your macros.gs (create one if you don't have any):
/** #OnlyCurrentDoc */
function ReplaceCommaToDot() {
var range = SpreadsheetApp.getActiveRange();
var col = range.getColumn();
var row = range.getRow();
function format(str) {
if(str.length == 0) return str;
return str.match(/[0-9.,]+/)[0]
.replace('.','')
.replace(',','.');
}
var log = [range.getRow(), range.getColumn()];
Logger.log(log);
var values = range.getValues()
for(var row = 0; row < range.getNumRows(); row++){
for(var col = 0; col < range.getNumColumns(); col++){
values[row][col] = format(values[row][col]);
}
}
range.setValues(values);
}
Save. Go back to the spreadsheet, import this macro.
Once the macro is imported, just select the desired range, click on Tools > Macro and select ReplaceCommaToDot
Note: This script removes the original ., and replaces , by .. Ideal if you are converting from US$ 9.999,99 to 9999.99. Comma , and whatever other text, like the currency symbol US$, were removed since Google Spreadsheet handles it with text formatting. Alternatively one could swap . and ,, like from US$ 9.999,99 to 9,999.99 by using the following code snippet instead:
return str.match(/[0-9.,]+/)[0]
.replace('.','_')
.replace(',','.')
.replace('_',',');
An alternative way to replace . with , is to use regex functions and conversion functions in the Sheets cells. Suppose your number is in A1 cell, you can write this function in any new cell:
= IF(REGEXMATCH(TO_TEXT(A1), "."), VALUE(REGEXREPLACE(TO_TEXT(A1), ".", ",")), VALUE(A1))
These functions do the following step:
Convert the number in the target cell to text. This should be done because REGEXMATCH expects a text as its argument.
Check if there is a . in the target cell.
If there is a ., replace it with ,, and then convert the result to a number.
If there is no ., keep the text in the target cell as is, but convert it to a number.
(Note : the Google Sheets locale setting I used in applying these functions is United States)
I have different solution.
In my case, I`m getting values from Google Forms and there it is allowed use only numbers with dot as I know. In this case when I capture data from Form and trigger script which is triggered when the form is submited. Than data is placed in specific sheet in a specific cell, but formula in sheet is not calculating, because with my locale settings calculating is possible only with a comma not dot, that is coming from Google Form.
Then I use Number() to convert it to a number even if it is already set as a number in Google Forms. In this case, Google Sheets script is converting number one more time to number, but changes dot to comma because it is checking my locale.
var size = Number(sizeValueFromForm);
I have not tested this with different locale, so I can`t guarantee that will work for locale where situation is opposite to mine.
I hope this helps someone. I was looking for solution here, but remembered that some time ago I had similar problem, and tried this time too and it works.
=IF(REGEXMATCH(TO_TEXT(F24);"[.]");REGEXREPLACE(F24;"[.]";",");VALUE(F24))
Works for me
If find dot replace with comma if not, put value
I am using the the following function in javascript.
function chknumber(a) {
a.value = a.value.replace(/[^0-9.]/g, '', '');
}
This function replaces any non numeric character entered in a textbox on whose onkeyup i have called the above function. The problem is it allows this string as well
1..1
I want the function to replace the second dot character as well. Any suggestions will be helpful.
I don't advocate simplistically modifying fields while people are trying to type in them, it's just too easy to interfere with what they're doing with simple handlers like this. (Validate afterward, or use a well-written, thoroughly-tested masking library.) When you change the value of a field when the user is typing in it, you mess up where the insertion point is, which is really frustrating to the user. But...
A second replace can correct .. and such:
function chknumber(a) {
a.value = a.value.replace(/[^0-9.]/g, '').replace(/\.{2,}/g, '.');
}
That replaces two or more . in a row with a single one. But, it would still allow 1.1.1, which you probably don't want. Sadly, JavaScript doesn't have lookbehinds, so we get into more logic:
function chknumber(a) {
var str = a.value.replace(/[^0-9.]/g, '').replace(/\.{2,}/g, '.');
var first, last;
while ((first = str.indexOf(".")) !== (last = str.lastIndexOf("."))) {
str = str.substring(0, last) + str.substring(last+1);
}
if (str !== a.value) {
a.value = str;
}
}
Can't guarantee there aren't other edge cases and such, and again, every time you assign a replacement to a.value, you're going to mess up the user's insertion point, which is surprisingly frustrating.
So, yeah: Validate afterward, or use a well-written, thoroughly-tested masking library. (I've had good luck with this jQuery plugin, if you're using jQuery.)
Side note: The second '' in your original replace is unnecessary; replace only uses two arguments.
try with match method if your input is "sajan12paul34.22" the match function will return a array contain [12 , 34.22]
the array index [0] is used for getting first numeric value (12)
function chknumber(a) {
a.value = a.value.match(/[0-9]*\.?[0-9]+/g)[0];
}
I have a project that want to have CodeMirror implemented. Basically, one of the requirements is that you can type double % (for example: %% keyword %%) to display a list (a hint). I have seen the official example with Ctrl+Space, but I'm wondering how I can make typing the second percent character of the start double percent be a trigger to show the hint list, and how I can display the keyword with the end double percent after choosing an option from the list. I need help or any demo or sample code.
I was having similar problems with CodeMirror, I'll share what I have learned.
type double % (for example: %% keyword %%) to display a list (a hint).
To achieve this, first you need to handle the 'change' event:
var cm = CodeMirror.fromTextArea(document.getElementById('textArea'),
{
mode: 'your_custom_language',
lineNumbers: true,
extraKeys: {'Ctrl-Space': 'autocomplete'}
});
var onChange = function(instance, object)
{
// do stuff...
}
CodeMirror.on(cm, 'change', onChange);
Then, on the onChange function you must do the following:
Check if the last inserted character is %.
Check if the previous character is %.
Summon the hint list.
I did it this way:
var onChange = function(instance, object)
{
// Check if the last inserted character is `%`.
if (object.text[0] === '%' &&
// Check if the previous character is `%`.
instance.getRange({ch: object.to.ch - 1, line: object.to.line}, object.to) === '%')
{
// Summon the hint list.
CodeMirror.showHint(cm, CodeMirror.hint.your_custom_language);
}
}
Note that I use the cm object previously declared, you must change this to meet your requirements. And also, the deduced context for your keyword will not match what you're expecting; in order to fix this you need to modify your own codemirror/addon/hint/your_custom_language-hint.js; in my case, I based my custom language on JavaScript (refactoring the javascript-hint.js) modifying the function called maybeAdd from:
function maybeAdd(str) {
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
}
to:
function maybeAdd(str)
{
if (isValidHint(str))
{
found.push({text: '%%' + str + '%%', displayText: str});
}
}
Note that the array found of getCompletions is no longer storing strings, it is storing objects with this format:
{
// this will be written when the hint is selected.
"text": "%%text%%",
// this will be shown on the hint list.
"displayText": "text",
// You can custom each hint match with a CSS class.
"className": "CSSClass"
}
Please, note that all the things I've writed above are refactoring of my CodeMirror custom language, it is untested on your own custom language but I hope it helps.
BTW; I think that CodeMirror documentation doesn't look clear and lacks on examples of many demanded features.