How to reference "this" in a function - javascript

I want to validate several input fields. The code below works fine, except for the focus method. I expect that it can not interpret the "input" variable which relates to the input location on the form. Question: How do I reference the location of the specific input, bearing in mind that there are 20+ inputs ? tks !
function validateInput(quantity,input)
{
if (quantity.value !== " ") {
if(isNaN(quantity)) {
$(".myerror_alert").append('<div class="alert alert-danger"><strong>Warning!</strong> You have entered an non valid character, go back and enter a real number </div>');
input.focus(); // THIS DOES NOT WORK
return false;
}
}
return true;
}
$(".product_table").on('change', '.edit_quantity',function (){
var quantity = $(this).parents(':eq(1)').find('input').filter(".edit_quantity").val();
var input = $(this).parents(':eq(1)').find('quantity').filter(".edit_quantity");
validateInput(quantity, input);
// MORE CODE GOES HERE //
});
HTML:
<tr class='delete_row'>
<td><input class="product_id form-control" readonly="readonly" name="product_id[0]" type="text" value="123"></td>
<td><input class="edit_product_id form-control" readonly="readonly" name="product_id[0]" type="text" value="Euroshake Blackstone"></td>
<td><input class="edit_quantity" name="product_id[0]" type="text" value="120"></td>
<td id="price"><input class="unit_price form-control" readonly="readonly" style="text-align:right;" name="price" type="text" value="120.00"></td>
<td><input class="line_cost form-control" readonly="readonly" style="text-align:right;" name="cost" type="text" value="14400.00"></td>
<td>
<span style="padding-left:12px;"><input name="delete" type="checkbox" value="123"></span>
</td>
</tr>

What I did was supose that in this part .find('quantity') you was probably meaning .find('input') as its previous statement, then I figure out that you were working with the same element there. So being the same element, you don't need to hold it's reference(in input var) and it's value(quantity var) to pass into validateInput. As this is a function, why not work with less code and make the function handles it, right? So I've changed it to pass only the element reference and inside the function with this condition if ($input.val().length > 0 && isNaN($input.val())) I could check if element ins't empty and also if it isn't a number:
function validateInput(input)
{
var $input = $(input);
if ($input.val().length > 0 && isNaN($input.val())) {
$(".myerror_alert").append('<div class="alert alert-danger"><strong>Warning!</strong> You have entered an non valid character, go back and enter a real number </div>');
input.focus();
return false;
}
return true;
}
$(".product_table").on('change', '.edit_quantity',function (){
validateInput(this);
});
Demo
One important mistake you've done that you've workaround it - probably - without noticing it, is that you navigate through the element tree to find the input, but when you do $(".product_table").on('change', '.edit_quantity' you're in fact binding an event in all elements with class edit_quantity inside the element with class product_table, so inside the event, your this already is the input, you don't need to go after it, as I did:
validateInput(this);
I hope this helps.

Related

forcing focus to remain on a form text element until the value is numeric

I have a form which has input fields that expect numbers only.
I'm using javascript to validate the form when the value of the field changes.
If the value is numeric, do nothing.
If the value is not numeric, set it to zero and put focus in that text field. Essentially, I'm trying to trap the cursor in that field until a numeric value is entered. For some unknown reason, focus is not being placed on that form element. cell.focus() does not work. I've even tried document.getElementById(cel.getAttribute("ID")).focus(); What might I be doing wrong?
<html>
<head>
<script>
function NAN(cell){
if (cell.value != "") {
var re = /^(0|[1-9][0-9]*)$/;
if (re.test(cell.value) == false) {
alert('You must supply a numeric value greater than 0.');
cell.value = "0";
cell.focus();
}
}
}
</script>
</head>
<body>
<input type="text" name="num" value="" onchange="NAN(cell)"/>
</body>
</html>
Your problem is in the onchange attribute:
<input type="text" name="num" value="" onchange="NAN(cell)"/>
The value is executed as JavaScript code directly. You're passing code, not just a generic signature or prototype.
Inside those event handler snippets, there's a special object this defined, referring to the current DOM element (the input tag in this example).
(Just to mention it, there is also a second predefined object event, which most likely caused your confusion.)
As a simple fix for your issue, replace cell with this in the call and it should work:
<input type="text" name="num" value="" onchange="NAN(this)"/>
It's also important to note that you should keep in mind that this verification requires JavaScript to be executed. If it's disabled, the user might still pass any values, so you should check the value server side as well (assuming this isn't just client-only code).
As an alternative to using JavaScript, you could just use HTML5 to force a specific pattern on inputs. In this case this would be trivial to do:
<input type="text" name="num" value="" pattern="(?!0)\d+" title="Quantity">
The user won't be able to submit the form unless the pattern is validated, so there's no need to force the input focus. The pattern always has to match the full value, from beginning to the end. The title attribute is typically used to provide more information in the error popup.
There are two things done:
You have to change cell to this with onchange.
According to this question at least with Firefox setTimeout has to wrap this focus-method so that it works as expected.
And a more user-friendly approach is inserted as well at the second input-field.
Hope this example helps you:
function NAN(cell) {
if (cell.value != '') {
var re = /^(0|[1-9][0-9]*)$/;
cell.value = cell.value[0]=='0'?+cell.value:cell.value;
if (re.test(cell.value) == false) {
alert('You must supply a numeric value greater than 0.');
cell.value = '0';
setTimeout(function () {
cell.select();
cell.focus();
}, 0);
}
}
}
/*
* a more user friendly approach
*/
function NAN2(cell) {
if (cell.value != '') {
var re = /^(0|[1-9][0-9]*)$/;
cell.value = cell.value[0]=='0'?+cell.value:cell.value;
if (re.test(cell.value) == false) {
alert('You must supply a numeric value greater than 0.');
cell.value = '0';
setTimeout(function () {
cell.select();
cell.focus();
markElement(cell);
}, 0);
}
else{
tickElement(cell);
}
}
}
function tickElement(cell){
cell.setAttribute('style','border: 1px solid green');
}
function markElement(cell){
cell.setAttribute('style','border: 1px solid red');
}
<p>
Your approach(onchange):
<input type="text" name="num" value="" onchange="NAN(this)"/>
</p>
<p>
Or you can use a more user friendly approach to notify an user right now when they are tipping something wrong (onkeyup):
<input type="text" name="num" value="" onkeyup="NAN2(this)"/>
</p>

Why 1. returns an empty string when I try to get value of an input type number using javascript and html5?

I have a normal input as follows:
<input type="number" name="quantity" id="myInput">
If I type "1." (without the quotes of course) when I try to get the value of the input with
document.getElementById("myInput").value
Only an empty string is obtained.
Is there any other way to get the "1." input with javascript?
Edit
I am working using Polymer 1.0 and databinding, so in my example I showed using normal JavaScript syntax with the intention of finding a solution to my problem using only javascript.
I just want to know how to access a property that returns the value of the input, and which I believe should be stored in some property of the object.
If you use <input type="number"> the element is enriched with an extra attribute, valueAsNumber. So instead of
document.getElementById("myInput").value
use
document.getElementById("myInput").valueAsNumber
valueAsNumber will return NaN instead of blank if the value entered in the input not is convertable to a number. There is also a validity attribute holding information of the status of the current value, both according to the value as supposed number but also according to the number input's settings, i.e "why is the number invalid".
Fun with number inputs, try this out in various browsers :
<input type="number" name="quantity" id="myInput" ><br>
<input type="text" id="value" ><br>
<input type="text" id="valueAsNumber" ><br>
<input type="text" id="validity" ><br>
document.getElementById("myInput").onkeyup = function() {
document.getElementById("value").value = this.value;
document.getElementById("valueAsNumber").value = this.valueAsNumber;
document.getElementById("validity").value = '';
for (validity in this.validity) {
if (this.validity[validity]) {
document.getElementById("validity").value+=validity+' ';
}
}
}
actually quite informative, if you want to investigate exactly why you get an empty value back from the input -> http://jsfiddle.net/oaewv2Lr/ Have tried with Chrome, Opera and FF - Chrome seems to be the most "forgiving" browser of those three.
I found a way to get invalid values:
Focus the input.
Select its contents using execCommand().
Grab the selection using window.getSelection().
Example:
document.querySelector('input[type="submit"]').addEventListener('click', function() {
var inp= document.getElementById('myInput');
inp.focus();
document.execCommand('SelectAll');
var value = window.getSelection().toString();
document.getElementById('output').textContent = value;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" name="quantity" id="myInput">
<input type="submit">
<div id="output"></div>
It won't work if you will enter 1., as 1. is not a valid number.
Update: It seems that your use of type="number" means that certain values won't come back. You can switch it to a type="text" and do the checking yourself:
document.getElementById('mySubmit').addEventListener('click', function() {
var value = document.getElementById('myInput').value;
if ( value != parseFloat(value) )
alert('Invalid Number');
document.getElementById('myOutput').innerHTML = value;
});
<input type="text" name="quantity" id="myInput">
<input type="submit" id="mySubmit">
<div id="myOutput"></div>

Knockout validation throttle

Hi i have a css binding on a input type which adds the class CircleErrors if it matches my function. My problem is it has a delay on taking the class off it only happens when i tab off the input box. I want the class to be removed on key down of the keyboard.. i know there is a throttle you can use for knockout but i am not sure how to go about doing it.
<input id="firstName" type="text" placeholder="First name" data-bind="value: Registration.FirstName, css: { CircleErrors: Registration.FirstName().length == 0 && Registration.FirstNameValidation(), valueUpdate: 'afterkeydown' }">
You've misplaced your valueUpdate parameter. It's inside the css parameter - you need to move it outside the }:
<input id="firstName" type="text" placeholder="First name" data-bind="value: Registration.FirstName, css: { CircleErrors: Registration.FirstName().length == 0 && Registration.FirstNameValidation() }, valueUpdate: 'afterkeydown'">
Here's a demo with it working
Use the textInput binding instead of the value binding for the first name property (and for any text input fields for that matter). To quote the docs
Unlike the value binding, textInput provides instant updates from the
DOM for all types of user input, including autocomplete,
drag-and-drop, and clipboard events.
You don't need the valueUpdate binding any more, however it was inside your CSS binding so would not have had any effect.
<input id="firstName" type="text" placeholder="First name" data-bind="textInput: Registration.FirstName, css: { CircleErrors: Registration.FirstName().length == 0 && Registration.FirstNameValidation() }">
Demo
this is what you looking for
` var reg = new (function() {
var self = this;
this.FirstName = ko.observable('');
this.checkifEmpty = ko.observable(false);
this.check=function(){
if(this.FirstName()!=null&&this.FirstName()!=undefined && this.FirstName() !=''){
this.checkifEmpty(true);
}else{
this.checkifEmpty(false);
}
}
this.FirstNameValidation = function() {
return true;
}
})();
ko.applyBindings(reg);
`

impossible to give focus to an input

I need your help here, because I'm out of idea
I have the following HTML5 code
<form>
<table class="main">
<tr>
<td>Volume</td>
<td><input type="text" id="Q1" onblur="updateQ(Q1)" autofocus /></td>
<td>ml </td>
<td><input type="text" id="Q2" onblur="updateQ(Q2)" /></td>
<td>ml </td>
<td><input type="text" id="Qt" onblur="updateQ(Qt)" /></td>
<td>ml </td>
</tr>
</table>
</form>
and the following javascript function
function updateQ(ident) {
var valeur = ident.value;
var inputId = ident.id.toString();
if (isNaN(valeur)) {
ident.value = "";
document.getElementById(inputId).focus();
}
}
When the page is loaded, the first < input > get the focus.
I want to check if the user is entering only number, so "onblur" I call the function, which check the content.
If it's not a number, I remove the value and I try to give back the focus to the < input >
It doesn't work !
Impossible to give back the focus, the second input have it and it never goes back to the first one
I don't see any error in the Javascript console, and the rest of the script works nicely.
Even giving the real id ("Q1") doesn't work ...
However, out of the function, giving the focus to another < input > works nicely
Any idea ?
Thanks in advance for your help
ericc
please see here http://jsbin.com/bapuyanuvula/1/
function updateQ(ident) {
var valeur = ident.value;
var inputId = ident.id.toString();
if (isNaN(valeur)) {
ident.value = "";
setTimeout(function() {
document.getElementById(inputId).focus();
}, 0)
}
}
The onblur event is happening while the user is leaving it. In some browsers this event can be canceled (i.e.: event.preventDefault()). So you can't focus it, because at this time it's still focused. So you either prevent the blur event or use a setTimeout as provided above...
This is browser related issue, Try this
function updateQ(ident) {
var valeur = ident.value;
var inputId = ident.id.toString();
if (isNaN(valeur)) {
ident.value = "";
setTimeout(function(){
document.getElementById(inputId).focus();
},
0);
}
}
Its because you are passsing the wrong reference.
change this:
onblur="updateQ(Q1)"
to this:
onblur="updateQ(this)"

Text as place holder for textbox input?

I notice that at some websites like http://academia.edu/, the signup form has some "place-holder" in their text input field. Such that in a textbox, there's no label but a rather slight font "First name" word inside the text box.
When using Firebug to investigate, I see the following code:
<input class="standard_text magic-default magic-default-on" id="user_first_name" name="user[first_name]" size="30" type="text" value="First Name">
It looks like there's some "magic" javascript happen behind the scene. But since I'm not familiar with javascript debugging yet, I can't trace out how they do that yet.
Does anyone know how to produce that effect?
For modern browsers you can use the HTML5 placeholder attribute.
This will achieve the result you're after without any Javascript and will scale (won't do anything) in older browsers.
<input placeholder="First Name">
To get this working in older browsers you can include a little bit of jQuery:
$('input:text').focus(function(){
if ( $( this ).val () === $( this ).attr ( 'placeholder' ) ) {
$(this).val('');
}
}).blur(function(){
if($(this).val() == "")
{
$(this).val($(this).attr('placeholder'))
}
}
);
Working Example
You have to create a "onFocus" event handler for the input box, and clear the value of said input box. Off course you only clear the value if it's the default value ("First Name" in your example), so that you don't clear away whatever user entered if he returns to the input later.
You could also attach a "onBlur" event handler, and restore the value of the input box back to the default value (if user didn't enter anything).
<input id="user_first_name" name="user[first_name]" size="30" type="text" value="First Name" onFocus="inputFocus('First Name', this)" onBlur="inputBlur('First Name', this)">
<script type="text/javascriptt">
function inputFocus(ph, el){
if(el.value == ph)
el.value = "";
}
function inputBlur(ph, el){
if(el.value == "")
el.value = ph;
}
</script>
HTML5 placeholder is what you're looking for:
http://diveintohtml5.info/forms.html
In your case it would be:
<input name="firstname" placeholder="First name">
But also you can do it 100% with javascript:
http://lab.dotjay.co.uk/experiments/forms/input-placeholder-text/

Categories

Resources