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(){}'
Related
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)
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.
I don't know why I am struggling with this. Should I be taking a different approach?
I have a form being generated in vb based off a database and then I am trying simply to make a text-box be disabled unless you check a checkbox.
Here is what I have so far. It needs to be dynamic (what I have commented out).
I can't seem to get it to work. The difficult part is referencing
document.form1.el.id.toString() + "_other".disabled
disabled is a binary property, not an attrbute.
You must use disabled='disabled' or remove the attribute to enable the element. It is not a true/false value.
Here is one way:
http://jsfiddle.net/C2WaU/1/
If I understand you correct, this should work for you:
function enable_text(el) {
var textbox_name = el.id.toString() + "_other";
document.getElementById(textbox_name).disabled =
(el.checked) ? "" : "disabled";
}
A working example: http://jsfiddle.net/ve9Gz/3/
I have a loop for my input checkboxes (see below).
<cfloop query="qGetCBList">
<input name="#qGetCBList.CheckBox#" type="checkbox" id="#qGetCBList.CheckBox#"onclick="CheckBoxSelect('#qGetCBList.CBNum#','#qGetCBList.CheckBox#','#qGetCBList.RecordCount#');"> #qGetCBList.CBDesc#
<br /><br />
</cfloop>
and my javascript function is,
<script language="JavaScript">
CheckBoxSelect = function(CB,cbID,rCnt){
var myVar_CB=CB;
var myVar_CB_ID=cbID;
var myVar_RCNT=rCnt;
if(myVar_CB == 2) //"Chemical(s)........."
{
for(i=1;i<=myVar_RCNT;i++){
var myVar_CB_ID_FMT="cb"+i; //check box ID format
if(i!=2){
//alert(myVar_CB_ID_FMT);
document.getElementById("myVar_CB_ID_FMT").disabled=true;
}
}
}
else{
alert('good to go');
}
}
</script>
what's happening here is, if the selected checkbox is 2 (which is the CBNum), then I want all other checkboxes to be disabled.
P.S. This is the bind page of the main page. When I un-comment my alert tag, it gives me the correct CBNums, but the disabling is not working. If it any useful I'm using CF8.
Feedbacks and/or alternate methods are appreciated. Thank you.
I know nothing about ColdFusion but the basic JavaScript tips you can use are:
Check the return value of document.getElementById(); don't assume it'll always return a node you can disable.
Most browsers have a built-in or downloadable debugger that allows you to inspect variables. Use that instead of plain alerts. E.g.:
console.log(myVar_CB_ID_FMTT, document.getElementById(myVar_CB_ID_FMT));
getElementById("myVar_CB_ID_FMT") is looking for an element called myVar_CB_ID_FMT. Does that element exist? No. Your variable myVar_CB_ID_FMT is not going to be evaluated as getElementById just sees it as the string "myVar_CB_ID_FMT".
Try document.getElementById("cb"+i)
The id in getElementById(id) is case sensitive so ensure that "cb"+i exists.
#Barry Jordan answer kinda woke me up and I was error checking along the line #Álvaro G. Vicario mentioned, I then finally figured out what's going on.
In my loop when I trim my id value ...id="#trim(qGetCBList.CheckBox)#"... it works.
of course it had be something simple stupid and my fault.
Thanks guys for support, you all rock.
hope that title makes sense. I'm a noob at javascript. What I want to do is have a form which will have a couple of inputs like, name and url for example.
When the user enters their name, I'd like the url input to automatically have as a default their name with an underscore between words. So if they type in as their name pedro kinkybottom then automatically set as the default in the url input would be pedro_kinkybottom.
I'm using cakephp if anyone happens to know a particularly cakey way to do this that'd be cool but otherwise any help at all would be most welcome.
Thanks,
Pedro
You'd probably want to do this in JavaScript and not in PHP. Even though you may be more familiar with the latter, the user experience would be better with the former and the overall design simpler (since the page wouldn't need to refresh).
You essentially need to do two things:
Set the value of an input in response to an event on another input.
Replace space characters with underscore characters.
For the second part, take a look at JavaScript's replace function. It's pretty robust and lets you do a lot of string manipulation. Definitely worth trying it out yourself.
For the first part, here's an example with jQuery:
$('#inputName').change(function() {
$('#inputURL').val($('#inputName').val());
});
This would set the value of inputURL to the value of inputName any time the value of inputName changes. For the string replacement, you'd modify it similar to this:
$('#inputName').change(function() {
$('#inputURL').val($('#inputName').val().replace(' ', '_'));
});
Note that the change event will be fired when the control loses focus. If you want to to happen as-you-type then try the keyup event. There are other events as well.
Add a keyup event to the name field that will update the url field:
<form>
<input type="text" id="name" />
<input type="text" id="url" />
</form>
...and the js:
addEvent(document.getElementById('name'), 'keyup', function () {
document.getElementById('url').value = this.value.replace(' ', '_');
});
function addEvent(ele, evnt, funct) {
if (ele.addEventListener) // W3C
return ele.addEventListener(evnt,funct,false);
else if (ele.attachEvent) // IE
return ele.attachEvent("on"+evnt,funct);
}
http://jsfiddle.net/XKEh5/
If you're only going to do some trivial stuff like this, then you'll be fine with plain old javascript. If you're going to be doing a lot of this sort of thing, plus any effects like fading out elements or whatnot, I suggest you look in to mootools or jQuery.
Here is an edited version of the above answer. There was an issue with the "value.replace(' ', '_');" where it would only take the space out between the first two words typed in. This code snippet below does it for all.
<script language="javascript" type="text/javascript">
addEvent(document.getElementById('name'), 'keyup', function () {
document.getElementById('url').value = this.value.split(' ').join('');
});
function addEvent(ele, evnt, funct) {
if (ele.addEventListener) // W3C
return ele.addEventListener(evnt,funct,false);
else if (ele.attachEvent) // IE
return ele.attachEvent("on"+evnt,funct);
}
</script>