Empty validation not working in a particulor empty textbox - javascript

I've few similar textboxes. When i run the validation script given below, One of them isn't affected the first time, even though it's empty. I'd like to know why.
Following is the HTML:
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='text' class='txt' value="" />
<input type='button' onclick='validate()' value='validate' />
JS:
function validate() {
var txts = document.getElementsByClassName('txt');
for (var i = 0; i < txts.length; i++) {
if(txts[i].value === "")
txts[i].className = 'txtError';
}
}
and CSS:
.txt {
border:1 px solid green;
}
.txtError {
border:1 px solid blue;
background:red;
}
This might be a dumb mistakes but i stared at it many times and my eyes isn't catching anything at the moment. I also tried it in different browsers.
Here's a JSfiddle demonstrating the problem.
Side note: i'm not looking for another validation script, i just want to know why the second textbox escapes the validation.

Because getElementsByClassName returns a live collection. Meaning it is updated underneath you as you change the DOM. So when you remove the txt class from the first box (replacing it with txtError you suddenly have an enumerable of size 2 instead of 3.
To fix it you can convert the live collection to a regular array using the array slicing trick
var txts = Array.prototype.slice.call(document.getElementsByClassName('txt'), 0);
However there are better ways to achieve pretty much everything that you're doing here. SO isn't really the place to discuss this but once you get it working go ahead and post it on the codereview stackexchange for feedback.

This seems like a strange issue and I cannot fully explain the issue. But when debugging and stepping though the code, every time you update the classname of one of the elements, your collection of txts decrements. Therefore, this is the only way I can think of to fix it. Basically the same thing you have, but instead I start with the last element of the txts array, instead of the first.
function validate() {
var txts = document.getElementsByClassName('txt');
for (var i = txts.length - 1; i >= 0; i--) {
if (txts[i].value === "") txts[i].className = 'txtError';
}
}

I think the problem arose because you were changing the class entirely instead of just adding a class; at least, it fixed the problem for me.
Here's a jsfiddle I created from yours that works fine by changing the behaviour to something more like jQuery's .addClass() method - I set .className = 'txt txtError' instead of just changing it to txtError.

Related

Javascript can't apply an existing function to onkeyup

I have a bunch of HTML number inputs, and I have grabbed them by
x=document.querySelectorAll('input[type="number"]');
I then try and iterate through this with a for-loop, and apply an onkeyup function. The function is this:
t=function(elem){
elem.onkeyup=function(e) {
if(!/[\d\.]/.test(String.fromCharCode(e.which))) {
elem.value='';
}
};
};
Basically, what it does is clear the value of the input if there is a letter typed in. I know I can apply it via HTML:
<input type='number' onkeyup='t(this)'/>
But how can I do it with Javascript? I tried iterating through it with:
x=document.querySelectorAll('input[type="number"]');
for(i=0; i<x.length; i++){
x[i].onkeyup=t(this);
}
but it doesn't work. What am I doing wrong? How can I do this? Please regular JavaScript answers only, no jQuery or other frameworks/libraries.
change
x[i].onkeyup=t(this);
to
x[i].onkeyup=t(x[i]);
because this isn't what you want it to be
Apologies, all. I found my answer. Agreeing with Jaromanda X, I needed to change
x[i].onkeyup=t(this);
to
x[i].onkeyup=t(x[i]);
This (pun intended ;)was part of the problem, but the main problem was that the valid property name is
keyup=function();
and not
onkeyup=function(){}'

How to add user input to a JavaScript array

I am in the process of learning JavaScript and jQuery, so apologies if any of this sounds naive or obvious. I started what I thought was a fairly simple project to practice and hopefully learn something in the process.
What I want to do is this: the user inputs a sentence and hits a submit button. The sentence gets added to a list of other sentences submitted by people (preferably on a separate file, preferably encrypted, but not necessary). Then, the website grabs a random sentence from the list and displays it.
I am not asking on how to build all of this. I have already put most of it together, but I am including it here for reference.
I have a separate javascript file with the array of quotes.
var quotes=new Array();
quotes[0]="<p>Quote 1</p>";
quotes[1]="<p>Quote 2</p>";
quotes[2]="<p>Quote 3</p>";
quotes[3]="<p>Quote 4</p>";
quotes[4]="<p>Quote 5</p>";
quotes[5]="<p>Quote 6</p>";
quotes[6]="<p>Quote 7</p>";
Then I randomly display one using this:
function getQuote(){
var thisquote=Math.floor(Math.random()*(quotes.length));
document.write(quotes[thisquote]);
}
And adding <script> getQuote(); </script> to the html.
This all works fine.
The part I cannot seem to figure out is taking user input and adding it to the jQuery array. I am using a contenteditable div instead of an <input> because I want it to have multiple lines of text and have a character limit, which as far as I know can only be done with a contenteditable div (according to the research I did at the time, I may be wrong).
I have looked around and tried many if not all the examples I found of how to do this, and none of them worked. This is the last method I tried, if it helps:
$(".submit").click(function() {
quotes[quotes.length] = document.getElementsByClassName("input").value;
});
So, to reiterate, I want to take user input and add it to a JavaScript array. I have scoured stackoverflow and the interet but nothing has worked. Please help!
UPDATE: Arvind got it right. I still have a lot to learn, and it seems I need to read up on localstorage and cookies. I will also need to use PHP to save the sentences on the server. Thank you to all who answered!
Problem is document.getElementsByClassName("input") gives you a NodeList and not just a single html element. So if you do this document.getElementsByClassName("input").value, you will end up quotes as [undefined, undefined ... undefined]. Assuming you have single element with the class name input, go with index 0. Also as you stated that you are using div with attribute contenteditable, you may try this instead. document.getElementsByClassName("input")[0].innerHTML
Try this example.
var quotes = localStorage.getItem('quotes'); //get old, if any, gives you string
quotes = quotes ? [quotes] : []; // if got quotes then make it as array else make new array
$(function() {
var quote = $('#quote'); //get the quote div
quote.html(quotes.join('') || quote.html()); //set the default text
$('#btn').on('click', function(e) {
quotes.push(quote.html());
localStorage.setItem('quotes', quotes.join('')); //save the quotes
alert(quotes.join(''));
});
});
#quote {
border: 1px solid grey;
height: 100px;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div contenteditable='' id='quote'>
<ol>
<li>Quote 1</li>
<li>Quote 2</li>
</ol>
</div>
<input type='button' id='btn' value='Submit' />
P.S.
In order to preserve the old quotes you may possibly use cookie, localStorage, etc.
Are these "quotes" being saved locally?
Yes, to share it among several users visiting by different browsers, you have to save it with the server script like PHP, Java, ASP, etc. Here you can either use ajax, if you wana avoid page reload on submit, else you can go for form submit.
$(".submit").click(function() {
quotes[quotes.length] = document.getElementsByClassName("input").value;
});
should be
$(".submit").click(function() {
quotes.push(document.getElementsByClassName("input").text());
});
EDIT: With a content editable div you need to use text() instead. Here is an example fiddle. https://jsfiddle.net/
var quotes=[];// better
// function to add to array
function addQuote(myquote){
quotes.push('<p>'+myquote+'</p>');
}
addQuote("Quote 1");
addQuote("Quote 2");
addQuote("Quote 3");
addQuote("Quote 4");
addQuote("Quote 5");
addQuote("Quote 6");
addQuote("Quote 7");
addQuote("Quote 8");
$(".submit").on('click',function() {
addQuote(document.getElementsByClassName("input")[0].value);
});
NOTE: suggest NOT using the "input" class name and use some other one as that might be confusing to others at some point later (confused by element named input)
I also added the paragraph tags as that would provide a consistent pattern for your input text. Assumption on my part however.
NOTE I also assume that the element IS an input type with the .value since that is NOT provided (the markup)

onkeyup, get value from textbox, update another textbox, not working

Here is the javascript:
function changeText(containerId) {
var datatext = document.getElementById('masterText').value;
var collection = document.getElementById(containerId).getElementsByTagName('INPUT');
for (var x = 0; x < collection.length; x++) {
if (collection[x].type.toUpperCase() == 'TEXTBOX')
collection[x].value = datatext;
}
}
and this is the html
<input id="masterText" type="textbox" onkeyup="changeText('divGrid')"><br />
<div id="divGrid">
<input type="textbox"><br />
<input type="textbox"><br />
<input type="textbox"><br />
<input type="textbox"><br />
</div>
Suppose that all the textbox's value will change, but it is not. Do you know what is the error?
As I said in the comments, textbox is not a valid type for <input> elements. Although unknown types default to text, it might have somehow messed up the js (maybe the type property doesn't work right with unknown types), and changing it to just text seems to work fine, as you can see in this jsbin: http://jsbin.com/xakoxeyi/1/
My best guess at why this is happening is that using element.type doesn't work right with unknown types, so it doesn't have the value textbox, even though that's what html says. The best way to fix this is to change everything to text instead (as I said above), but another great way is to, instead of using collection[x].type, to use collection[x].getAttribute('type'), as using getAttribute always gives you what's in the HTML attribute
Just to expand on what Markasoftware said:
Had you chosen to get the attribute type, using getAttribute, your code would have worked.
function changeText(containerId) {
var datatext = document.getElementById('masterText').value;
var collection = document.getElementById(containerId).getElementsByTagName('INPUT');
for (var x = 0; x < collection.length; x++) {
if (collection[x].getAttribute('type').toUpperCase() == 'TEXTBOX') {
collection[x].value = datatext;
}
}
}
JSFiddle: http://jsfiddle.net/MSTUe/
So, my guess is that behind the scenes, an unknown type gets set as a text input, however you can still query an input with textbox, if needed. Probably for those awesomely new (but poorly supported) HTML5 inputs (like color, datetime-local, week, etc.) that a browser may not support.

Getting my javascript output to display in my HTML

I am sure this is a simple question.
To begin really playing with javascript and understand it I need to have the environment to see what my output is. I have done lessons in javascript but need to actually get the HTML and javascript talking.
What I am looking to do:
Have a user input information into an text box and have it show the result in the html.
is the sky blue? Yes (makes true be displayed on my HTML)
is the sky blue? No (makes false be displayed in my HTML)
currently i have no idea if my javascript is doing anything!
Here is my code:
HTML:
<form action="" onsubmit="return checkscript()">
<input type="text" name="value">
<input type="submit" value="Submit">
Javascript:
function checkscript() {
for (i=0;i<4;i++) {
box = document.example.elements[i];
if (!box.value) {
alert('You haven\'t filled in ' + box.name + '!');
box.focus()
return false;
}
}
return true;
}
document.write(box);
I am so confused but need to see the results of what i am doing to see where to fix things, i tried using console in chromes inspect elements function but this has confused me more.
Can someone help and clean the code up to make sense by labelling everything as what they do?
box? check script?
Thanks :)
I updated the jsfiddle I had made for you. It's a working version that might get you started.
HTML
<!-- I avoided all the mess of forms, since that submits to a server, and that's more than you want right now. Note that I added ids to each input. Ids make it very easy to access the elements later. -->
<input type="text" name="value" id="fillIn">
<input type="button" value="Submit" id="button">
JS
// My methodology here is totally different, since I directly get the element I care about
function checkscript() {
// find the element in the DOM
var box = document.getElementById("fillIn");
// check for a value
if (box.value) {
// if there is one, add a new div. That's probably not what you'll want in the long run, but it gives you something to work with (and seems to match your old idea of using document.write. I have never yet used document.write, though others with more experience than I may like the concept better.
// This creates a new element. If you press F12 and look at this in your debugger, you'll see it actually appear in the HTML once it's appended
var newElement = document.createElement("div");
// Set the value to what you want
newElement.innerHTML = box.value;
document.body.appendChild(newElement);
} else {
alert('You haven\'t filled in ' + box.name + '!');
box.focus()
// No returns necessary, since we're not dealing with formsubmittal.
}
}
// This hooks up the function we just wrote to the click event of the button.
document.getElementById("button").onclick = checkscript;
This may or may not be what you want, but it's at least a place to get started.
A few things to start out:
1.) Make sure all elements have end tags
<input type="text" name="value" />
Note backslash at end of tag.
2.) You are using a form tag, which submits a form to a server side component.
Suggest you need to use the onclick event. Which is available on all input controls. Suggest you start with buttons so:
<input type="text" name="value" onclick="myFunction()" />
<script type="text/javascript">
function myFunction() {
document.write("Hello");
console.log("Hello");
}
</script>
Writes stuff directly to the html and console. Hope that gets you started.
Regards,
Andy

javascript function return to a form input element not working

I have a form input like so:
<input type="text" name="footer_contact_name" class="footer_contact_input" onfocus="this.value='';" onblur="return inp_cl(this);" value="Name" />
I have made a js function:
function inp_cl(input){
if(input.value==''){
return 'Name';
}
}
The problem is that the form input value wont change to "Name" onBlur!
Any ideas whats wrong here?
Or maybe you all have better suggestions to how to make the code as short as possible, or maybe even a whole different approach to this? All I want is the text "Name" to be the default value, then dissappear onFocus, and if nothing entered, reappear again.
Thanks
You need to change return 'Name'; to input.value = 'Name';
There's a few solutions to this:
Solution 1
A return in your onblur isn't what you want with the function the way you've written it. Without changing your function, you can change your onblur to make use of the return value of your function using this:
onblur="this.value=inp_cl(this);"
or you can fix your function to update the input contents directly:
function inp_cl(input) {
if (input.value == '') {
input.value = 'Name';
}
}
and change your onblur attribute to:
onblur="inp_cl(this);"
The issue with your onfocus is that it's going to wipe out the content of your input box regardless of what's in there, so if you've got it populated and you leave and come back to this field, it's going to be wiped out, so you need the reverse of your function and point your onfocus to that:
onfocus="inp_bl(input)"
<script type="text/javascript">
function inp_bl (input) {
if (input.value == 'Name') {
input.value = '';
}
}
</script>
Solution 2
Alternatively you can hook it up in javascript removing the need for your onfocus/onblur attributes in your markup - this script will hook the watermark onto the required inputs events directly:
<script type="text/javascript">
watermark = function(input, watermarkText) {
input.onfocus = function () {
if (this.value == watermarkText)
this.value == '';
}
input.onblur = function () {
if (this.value == '')
this.value == watermarkText;
}
}
new watermark(document.getElementById("txtName"), "Name");
new watermark(document.getElementById("txtAddress"), "Street Address");
new watermark(document.getElementById("txtPostalCode"), "Postal Code");
</script>
<input type="text" id="txtName" />
<input type="text" id="txtAddress" />
<input type="text" id="txtPostalCode" />
Now you can scrap your onfocus/onblur attributes in your markup... and you've got repeatable code meaning you don't have to contaminate your markup with onfocus/onblur functionality.
Solution 3
By far the simplest way I can think of though, is to use jQuery and the watermark plugin - if you're already using jQuery, then it's no big deal, but if you're not, it adds a bunch of overhead you may not want. jQuery is pretty lightweight, but it comes with a bit of a learning curve as the set based paradigm it uses isn't quite what imperative programmers are used to:
$(document).ready(function() {
//This is the important bit...
$("#id_of_your_input_control").watermark("String to use as watermark");
});
Then scrap your onfocus/onblur attributes as the watermark function will hook it all up for you.
For this kind of functionality, jQuery makes things much more expressive - if you're not familiar with it, it's definitely worthwhile looking up and getting familiar with.
Addendum
The nice thing about Solution 3 is that it handles things like styling of your text when the watermark is displayed so that it looks like a watermark, meaning you don't have to handle all that yourself. It also attaches to the onblur/onfocus properly. If you go with Solution 2, it's a naive solution - if you want multiple handlers for the onblur and/or onfocus then that method doesn't attach properly and all other handlers for those events will be replaced with these - so it's not technically a safe approach, though in 99.9% of cases, it will work just fine.
try dis dude its help u!!
<input type="Text" value="Name" onblur="if(this.value=='') this.value=this.defaultValue; "
onfocus="if(this.value==this.defaultValue) this.value=''; ">

Categories