I have a few inputs on my page that need to have a max length of sorts and this is working to an extent except that an extra number keeps being added because of a plugin we're using...and no I can't get rid of the plugin causing it.
To fix this I need to remove one character from the input field. I have gotten to the point where it will remove it from the value of the input, but it is still showing on the screen...which is the issue.
Is there a way to disallow typing after they hit a certain point using JavaScript? I cannot use max length in the case because the virtual keyboard we are using ignores that completely.
I have something like this
var target = event.currentTarget;
var name = $(target).attr("name");
var validationLength = $(target).attr("validation").length;
$('input[name="'+name+'"]').on('keyup keydown change', function () {
if($(this).val().length > validationLength){
$(this).val().substr(0,$(this).val().length-1);
};
});
And like I said this will remove it from the value of the input, but not what the user actually sees on the screen (the most important part). Any help would much appreciated!
validationLength = 10;
$('#test').on('keyup keydown change', function () {
if($(this).val().length > validationLength){
val=$(this).val().substr(0,$(this).val().length-1);
$(this).val(val);
};
});
http://jsfiddle.net/mctkpLph/
Related
I need to detect a change in a Gravity Form field (form 5, field 215; is a number field), round the number so I can get a trailing zero if it doesn't already have one, and then return the new, rounded value back to the field. I tried to piecemeal something together using bits of other code I found, but I must be doing something wrong. I'm an absolute rookie with JavaScript.
I'm using Gravity Wiz's "Gravity Forms Custom JavaScript" plugin to insert this script only on the page with the appropriate form.
jQuery(“#gform_fields_215”).on(“change”,”#input_215″, ( function(e) {
var number = document.getElementById("input_215");
var rounded = number.toFixed(2);
document.getElementById("input_215").value = rounded;
}
What am I doing wrong? Probably everything! LOL
I know you have already forgotten you ever asked this. but here's the solution.
jQuery('#gform_fields_215').on('change','#input_215', ( function(e) {
var number = document.getElementById("input_3_1_5").value;
var rounded = parseInt(number).toFixed(2);
document.getElementById("input_215").value = rounded;
}
You have used jQuery and vanilla js syntax. if you would use only jQuery it would be done as below.
jQuery("#gform_3").on("change", "#input_3_1_5", function (e) {
$(this).val(parseInt(this.value).toFixed(2));
});
element value is a string it need to be parsed into a number before adding decimal places
this.value can be used to get value of current element
I have an input box in a component. I want to prevent the user from being able to add any input if the value of the input box contains more than 2 decimal places.
E.g. if a user inputs 10.95 I dont want to allow them write anything else after this value. They could still update it to 101.95 but it should prevent any input being added after the final decimal place.
The code I have so far is below.
class inputBox extends Component {
countDecimals(value) {
if(Math.floor(value) === value) return 0;
return value.toString().split(".")[1].length || 0;
}
updateValue(e) {
if(this.countDecimals(e.target.value) > 2) {
//prevent user from inputting into box after the decimal place...
}
}
render() {
return(
<input type='text' onChange={this.updateValue} />
)
}
}
You could use React controlled component and bind a state to the input's value atrribute. Then your onChange event handler will look like.
updateValue(e) {
this.setState({ value: e.target.value.toString().split(".").map((el,i)=>i?el.split("").slice(0,2).join(""):el).join(".")})
}
Worked for me.
document.getElementById("yourinput").oninput=function(){
this.value=this.value.toString().split(".").map((el,i)=>i?el.split("").slice(0,2).join(""):el).join(".");
};
Replace the value with a new value, that is shortened to two chars after each dot.
http://jsbin.com/soretokuse/1/edit
I think you need to save the oldvalue, that should work.
var input=document.getElementById('input'),
countDecimals=function(value) {
if(Math.floor(value) === value) return 0;
if(value.toString().split(".")[1])
return value.toString().split(".")[1].length || 0;
},
updateValue=function(val) {
if(countDecimals(val) > 2) {
input.value=input.getAttribute('oldValue');
}
};
input.oninput=function(){
updateValue(this.value);
input.setAttribute('oldValue',this.value);
}
<input id="input" type="text"/>
As far as my knowledge in Javascript and HTML goes there is no 'easy solution' for this. Working with both 'raw' JS and ExtJs forms has learned me that there are multiple ways to focus and manipulate a field. Which makes it hard to manipulate the inner value at the right time.
So allow me to split your issue in to multiple problems. Which I will attempt to tackle:
Triggering
You want your logic to run at all the times something happens to the field.
The following link provides you with the options:
http://www.w3schools.com/TAGS/ref_eventattributes.asp
When you use onchange it will trigger when someone changes the values after you blur the field (you click or tab away from the field). So that's no good.
You could try the key (up, down, press) events. But that excludes when you paste a value.
Long story short, you could in theory try to implement a function on every event you could think of to make sure you catch the users input and do what you want with it.
My solution is, start a timer when you focus a field and validate the value and do further logic. And finalize everything you wanted to do on blur.
Determining the correctness of the value
You could write some nifty regex or a single line statement that tells you if the value is correct. It's all the same in the end, it should fit your needs.
So something like:
var inputVar = element.value;
var inputFloat = parseFloat(inputVar);
var normalizeInput = Math.round(inputFloat * 100) / 100;
if(inputFloat > 0 && normalizeInput == inputFloat){
#correct value
}else{
#incorrect value
}
Handling correct/incorrect input
Now you want to handle the user input and do something.
Things like setting the field to disabled or read only would prevent further input and changes, but would not let your users do anything to your field.
As what I read is you want the field to not change in function, you want to be able to edit it.
So that leaves you with 2 options:
Editing the field content directly by overriding the element.value with the desired value.
Manipulating key inputs / selection to try and keep the cursor at same position the user left it while correcting the false input.
I would opt for the former as it is a lot less of a hassle, although it might mess with the cursor position (browser dependant).
Final implementation
So what I propose combining all the above:
On focus you start running a setTimeout or setInterval
http://www.w3schools.com/jsref/met_win_settimeout.asp
http://www.w3schools.com/jsref/met_win_setinterval.asp
In the function run then, you check if there is a previous value set.
The first time it is NOT so:
You have to hold this previous value somewhere, you could hold it in a variable within javascript or put it in to the field in the DOM.
http://www.w3schools.com/jsref/met_element_setattribute.asp
var inputElement.setAttribute('old_value', oldValue);
Now you check if this value is correct before saving it, else just default it back to blank (or attempt to normalise the value to something that validates, you could keep cutting away characters at the right for example).
Now on each run you check if the value is correct. If the value is correct, you hold the new value as the 'new' previous value (and calling setTimeout again if you use that method).
If it is not correct you write back the old value or attempt to normalise the input value and if that fails use the last correct value.
On the blur event you clear the setTimeout or setInterval running in the background:
http://www.w3schools.com/jsref/met_win_cleartimeout.asp
http://www.w3schools.com/jsref/met_win_clearinterval.asp
(Alternatively you could check if the document.activeElement is the same as the one that is run on this 'loop' so it knows when to stop).
On blur you check the value one last time and do the same logic to prevent false input.
PLAN B
Use the HTML5 number input field:
HTML 5 input type="number" element for floating point numbers on Chrome
Try <input type="number" step="0.01" /> if you are targeting 2 decimal
places :-).
edited Apr 27 '15 at 18:10
Andre Figueiredo
Which only works on browsers that support it.
I'm working on a script for our client's project that autotabs you onto the next input field when you've hit the maximum character count for a particular input. For some reason the input value is returning one less than it should be, and therefore tabs to the 'next' input when an extra character is entered above the 'threshold'.
Here's my script to watch the inputs value - ofc, if there is a better way please advise :) -
var watchLength = function (watch) {
watch.onkeypress = function () {
var nextInput = getNextSibling(this);
console.log(this.getAttribute('data-autotab-length'));
console.log(this.value.length);
if (this.value.length == this.getAttribute('data-autotab-length')) {
nextInput.focus();
console.log('Limit reached here');
}
};
};
And a jsFiddle to the working input. The first input is limited to '2' characters, but when you type in 3 it jumps to the next input. I think this is something to do with the keypress/keydown event not reading the initial value, but I'm at a loss of how to fix it. Any help really appreciated.
I'm logging the results in the Console:
http://jsfiddle.net/qdnCZ/
The Problem is, that onkeypress will fire before you want it to. You can simply replace onkeypress by onkeyup, that way you make sure that the <input> elements value is set correctly the time you check it.
See: http://jsfiddle.net/qdnCZ/1/
Yes it will return one less, simply use +1 on the length check. This is beacuse onkeypress event is executed before the field is updated, which means using e.preventDefault() the letter will not appear in the field. You could use onkeyup otherwise.
Use onkeyup instead onkeypress
onkeyup gets fired after field gets updated
if (this.value.length == this.getAttribute('data-autotab-length')) {
nextInput.focus();
console.log('Limit reached here');
return false; // this is prevent the third value being entered
}
Updated fiddle
I need to fire an event anytime the content of a textbox has changed.
I cant use keyup nor can I use keypress.
Keyup and keydown doesn't work if you hold down on the key.
Keypress triggers before the text has actually changed. It doesn't recognize backspace or delete either.
So now I'm assuming I'm going to have to build some custom logic or download a plugin. Are there any plugins out there? Or if I should build one, what constraints should I look out for?
For eg. Facebook does it with their search at the top. you can press and hold.
another example is writing a stackoverflow question. Right below the editor, the contents are copied in real time, backspace and everythng works. How do they do it?
I just took a look at SO's source. It looks like they do something a lot like this:
function updatePreview(){
$('div').text($('textarea').val());
}
$('textarea').bind('keypress', function(){
setTimeout(updatePreview, 1);
}
);
They do some extra stuff to make HTML tags for bold and italics and links and such and they time it. They increase the delay from 1 to longer if it takes too long to generate the HTML.
I had success using jQuery (in Chrome). If you hold a key down, it counts every change, not just the first one, and it counts non-print keys like backspace.
HTML
<input id="txt" type="text" />
<span id="changeCount">0</span>
JavaScript
$('#txt').keydown(function(event) {
// Don't count the keys which don't actually change
// the text. The four below are the arrow keys, but
// there are more that I omitted for brevity.
if (event.which != 37 && event.which != 38 &&
event.which != 39 && event.which != 40) {
// Replace the two lines below with whatever you want to
// do when the text changes.
var count = parseInt($('#changeCount').text(), 10) + 1;
$('#changeCount').text(count);
}
});
Like I said above, you'll want to filter out all of the key codes that don't change the text, like ctrl, shift, alt, enter, etc. There's also the boundary condition if you press the backspace or delete key when the textbox is empty or if the textbox has a maximum length and a printable key is pressed, but it's not terribly difficult to handle those either.
Here's a working jsfiddle example.
How about a poll? Do a setInterval and call a function that checks the text say every 500ms? You don't want to detect content change on every key anyway because it gets kinda slow in some older browser/older computer and you would notice a lag between typing and the text displaying.
You need a watcher type functionality.
It resorts to setInterval polling if the other features are not available: http://james.padolsey.com/javascript/monitoring-dom-properties/
I have a simple solution that we use happily in one of our project.
you can try it # http://jsfiddle.net/zSFdp/17/
var i = 0;
$('#text').bind('check_changed', function(){
var t = $(this);
// do something after certain interval, for better performance
delayRun('my_text', function(){
var pv = t.data('prev_val');
// if previous value is undefined or not equals to the current value then blablabla
if(pv == undefined || pv != t.val()){
$('#count').html(++i);
t.data('prev_val', t.val());
}
}, 1000);
})
// if the textbox is changed via typing
.keydown(function(){$(this).trigger('check_changed')})
// if the textbox is changed via 'paste' action from mouse context menu
.bind('paste', function(){$(this).trigger('check_changed')});
// clicking the flush button can force all pending functions to be run immediately
// e.g., if you want to submit the form, all delayed functions or validations should be called before submitting.
// delayRun.flush() is the method for this purpose
$('#flush').click(function(){ delayRun.flush(); });
The delayRun() function
;(function(g){
var delayRuns = {};
var allFuncs = {};
g.delayRun = function(id, func, delay){
if(delay == undefined) delay = 200;
if(delayRuns[id] != null){
clearTimeout(delayRuns[id]);
delete delayRuns[id];
delete allFuncs[id];
}
allFuncs[id] = func;
delayRuns[id] = setTimeout(function(){
func();
delete allFuncs[id];
delete delayRuns[id];
}, delay);
};
g.delayRun.flush = function(){
for(var i in delayRuns){
if(delayRuns.hasOwnProperty(i)){
clearTimeout(delayRuns[i]);
allFuncs[i]();
delete delayRuns[i];
delete allFuncs[i];
}
}
};
})(window);
Zurb has a great plugin which might be useful for you
http://www.zurb.com/playground/jquery-text-change-custom-event
Im using the most recent moo release and trying to write a function that evaluates the user given expression on event "keyup". As soon as my test's are passing I put the focus on the next input element automatically to improve the user experience and speed, since he uses the form many times.
So I came up with something like that:
var getNextInputElement = function(element){
returns the next input element
}
var checkDay = function(event){
var input = $('booking_day').get('value');
if (input.length > 1 && input < 32) {
$('booking_day').erase('class');
if (!(event.key == "tab")) {
getNextInputElement($('booking_day')).focus();
}
else {
$('booking_day').focus();
}
}
else if(input.length > 1) {
$('booking_day').set('class','error');
}
else {
$('booking_day').erase('class');
}
};
window.addEvent('domready', function() {
$('new_booking').reset();
$('booking_day').addEvent('keyup', checkDay);
$('booking_day').focus();
});
Works fine so far. But if I try to "shift-tab" back to my input field
getNextInputElement($('booking_day')).focus();
is evaluated and focus reset to the next input field. So the user cannot roll back to previosly entered data. I do not find any possibility to catch that shift-tab event. Since two keys are pressed, there are two events fired. One for "tab" and a second one, but not for "shift". The event.key.code of this event seems to be outside the scope that mootools realizes.
Anyone out there who can help on this problem?
Thanks.
Jason
You can add event for both "Shift+Tab" keys
Link : http://mootools.net/docs/more/Interface/Keyboard