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

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.

Related

$("#myTextArea").val() returns an empty string

I'm having an issue where my textarea value is returning an empty string. I have a modal which opens on a dblclick event where there's a textarea and a button. I want that when the button is clicked the text written in the textarea is fetched and stored in a variable to be used in other functions. By the way when I click on the button the returned text is "".
the textarea html is:
<textarea id="text-comment" placeholder="Insert a new comment" style="min-width:100%"></textarea>
the button html is:
<button class="btn btn-default" data-dismiss="modal" id="edit">Edit</button>`
the function code is:
$(document).on('click', '#edit', function(){ //edits the selected note
var classes = $(selectedNote).attr("class").toString().split(' ');
var id = classes[2];
var newText = $("#text-comment").val();
console.log("new text is: "+newText);
$(selectedNote).attr("title", newText);
for(var i = 0; i < temporaryNotes.length; i++) {
if(temporaryNotes[i]["ref"] == id) {
temporaryNotes[i]["text"] = newText;
}
}
for(var i = 0; i < notes.length; i++) {
if(notes[i]["ref"] == id) {
deleteNotes.push(notes[i]);
notes[i]["text"] = newText;
}
}
})
I'm going to go on a limb here. The limb might break but who knows?
I believe your modal's contents are defined within the HTML itself. Perhaps you have <div class="modal-content"> or something - I don't know what modal plugin you're using (but if I ever write one, it will use <script type="text/html"> specifically to prevent this issue...)
The problem with defining modals in this way is that the "template" contents are themselves part of the document, even if the "base" one is never shown. The modal plug-in can then call cloneNode on the template and render that as the modal. Simple, right?
Not quite. IDs must be unique on the page, so any modal plug-in that uses cloneNode to render will end up with duplicate IDs all over the place.
To find out if this is the case, try running this code when your modal is visible on-screen:
alert($("[id='text-comment']").length);
This will show how many elements have that ID (whereas #text-comment may just stop after the first one). This value should be exactly 1. If it is 2 (or worse, more!) then you do indeed have a badly implemented modal plugin.
Without knowing exactly which plugin you're using nor how it works, I would suggest finding some way to uniquely identify the displayed modal as opposed to the template, and don't use IDs inside the template.
You'll need to use your browser's Developer Tools to do this, but as an example if your modal appears with class="modal-display" then you could do something like this:
var button = $(this),
container = button.closest(".modal-display"),
textarea = container.find("textarea"),
value = textarea.val();
This kind of "relative search" for elements is much more flexible, and it will help you in future to learn this kind of thing. But for now, it should work around the issue of the duplicate IDs.

How to dynamically access user-entered Input-field-data, in Javascript or J-Query

HELP!!.... I can't dynamically access data entered by users into Input fields!
I'm a curriculum-designer trying to make a 'Matching'-activity (18-questions-with-18-scrambled-up-possible-answers), in which answer-choices get dynamically crossed out, 1 by 1, as they get 'used up' by the student, whenever (s)he types the letter of that choice (in this case "r") into the input-field. Here's the HTML for 1 of those 18 matches: (Hint: Pay attention to the "id"-attributes)
HTML
<input title="Question 18 - type 'R' into this input field"
class="questions" maxlength="1" id="18" onblur="My_Blur_Fx(this);">
</input>
<span class="r_as_selected, choices" id="r"> <!--I use the first class ('r_as_selected') in the J-Query example below, and the 2nd class ('choices') in the Javascript example below.-->
[Choice] R. (**All this span should soon be crossed-out.**)
</span>
I thought I could pull this off with a "change" event. However, neither my Javascript, nor my J-Query seems to be able to do it, because neither one can dynamically access the user's typed-in input (the very stuff that PHP would normally access via GET or POST).
J-Query
My J-Query-attempt to dynamically access this user-entered input...
$("input").change(function(){
$("input"[value="r"])
.add('.r_as_selected')
.eq(1).css({'color': 'red', 'text-decoration': 'line-through'})
});
...failed because, although it could cross out the '#r' answer-choice, yet it would ALSO cross it out whenever they typed in ANYTHING....So the [value='r'] part of the code wasn't able to target JUST the field where someone had typed 'r'.
Javascript
My Javascript-attempt to dynamically access this user-entered input...
<script>
function My_Blur_Fx(x) {
var userInput = document.getElementById(x).value;
var userChoices = document.getElementsByClassName("choices").id;
var i;
for(i = 0; i < 18; i++)
{ if (userChoices[i].attributes[1].value == userInput) {
/*Note: "attributes[1] is my way of accessing the 2nd attribute in the HTML span above, which is 'id="r"'*/
userChoices[i].style.textDecoration = "line-through";};
};
}
</script>
...failed too because an 'Input' is an "Element" whose "Value," is defined by the DOM to be "NULL,"...so line 3 above gives an error. Neither could any of the other potentially-relevant DOM-modifiers, instead of .value (i.e. .innerHTML / .nodeValue / .attributes) access that user-entered value. So it seems that 'Input' elements just can't be accessed dynamically. . . . ( Any suggestions...J-Query, Javascript, or other? )
You can't use an attribute selector to match user input, it only matches the static attributes, not the dynamic values. You can use .filter() to search for an element that matches a selector and has a specific value.
$("input").change(function() {
$("input").filter(function() {
return this.value == 'r';
}).add(".r_as_selected")
.eq(1).css({'color': 'red', 'text-decoration': 'line-through'});
});
You have several problems in MyBlurFx().
document.getElementById(x).value won't work beceause x is the element, not its ID. You should just use x.value.
document.getElementsByClassName("choices").id won't work because getElementsByClassName() returns a NodeList, not a single element, so it doesn't have an id property. But you don't need the ID, just use document.getElementsByClassName("choices"), since the for loop operates on the elements, not IDs.
Maybe there is more than one mistake, but I see that your code $("input"[value="r"]) is same as $(undefined). You must use $('input[value=\'r\']') instead.

Empty validation not working in a particulor empty textbox

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.

Javascript get form array values

I have a form that is set up so that there is an add button so my user can submit multiple people at once to the site.
At first the form has an input to fill out the persons name one example below
<input type="text" name="name[]" value="Name" />
If they hit the add button another one is appended so that I'm left with the following
<input type="text" name="name[]" value="Name" />
<input type="text" name="name[]" value="Name" />
Then when they hit submit I'm trying to get the values of each name in Javascript and loop through them I've tried this but it's not working
var inputs = document.getElementById('formIDhere').getElementsByTagName('name');
alert(inputs.length);
I never get the alert and if I just set up a loop like this
for(int i=0; i<inputs.length; i++)
Nothing happens, any help on looping through the values of name[] in javascript would be greatly appreciated
I guess you could try:
var inputs = document.querySelectorAll("#formIDHere input[name='name[]']");
alert(inputs.length);
for (i = 0; i < inputs.length; i++) {
// your code here
}
Simple approach:
var names=document.getElementsByName('name[]');
for(key=0; key < names.length; key++) {
alert(names[key].value);
//your code goes here
}
[...document.querySelector("#FORMID").elements['name[]']].map(el=>el.value);
// Returns ["name","name",...]
I think you can use document.getElementById('formIDhere').elements.name.
It will give you an array with all the values.
your mistake is using getElementsByTagName, which is asking for a tag called <name>, and of course you don't have it, try setting a class to the input for example and fetch it using jquery $('className') which will surely get the result correct, or using dom you can still use
document.getElementById('form').elements.name but still this way might not be cross browser safe unless tested carefully
getElementsByTagName returns the array of elements whoose tag name is specified in argument.
In html there is no element whoose tag name is name.
name is an attribute given to html elements.
To get elements based on name you can use
var ele=document.getElementsByName('whatevername');
ele will contain the array of elements whose name is specified. Then you can use your loop to iterate through each element.
this is what form elements is for
var inputs = document.getElementById('formIDhere').elements["name[]"];
alert(inputs.length);
for (i = 0; i < inputs.length; i++) {
// your code here
}
Using JQuery you could try:
var arr = $('#frmId').serializeArray();
serialize method offers several options that you could check in: https://api.jquery.com/serializearray/

Can't set disabled=false (javascript)

I have this function:
function disableDiv(divId, action){
var divId = byId(divId);
if(action==true){
divId.style.display='none';
}
else if(action==false){
divId.style.display='block';
}
var inputs = divId.getElementsByTagName("input");
var selects = divId.getElementsByTagName("select");
var i;
for (i=0; i<inputs.length; i++){
inputs[i].disabled=action;
}
for (i=0; i<selects.length; i++){
selects[i].disabled=action;
}
}
This takes a divId (id of DIV) and an action (false or true) and gets all inputs and selects inside the div, and sets their disabled attribute to either false or true.
According to Firebug, the elements inside the Div are disabled all the time. But they should be active once hitting a drop-list option... The triggering is fine so you know.
I can see this function beeing called by using alert boxes, and it does in fact set the disabled=false. But the elements are still disabled.
Something to point out is that according to firebug, the disabled attribute looks like this:
<input name="test" id="test" disabled="">
Note there is just two doublequotes... Shouldn't it say "disabled='disabled'" or "disabled=true"?
Any tips on how to troubleshoot further?
Here is how I call the function:
(category=="Cars")?disableDiv("nav_sub_cars", false):disableDiv("nav_sub_cars", true);
If you need more input, just let me know...
Thanks
Edited to reflect the comments.
According to the W3C the code you posted should be correct. The disabled attribute is a boolean attribute. Use of the removeAttribute() method may be helpful as well.
In my experience, you can also achieve this effect using the string values 'disabled' or ''. This may work because these values are coerced into a boolean representation when the browser encounters them.
try .disabled = null or .removeAttribute('disabled'). My understanding is that it's the presence or absence of the disabled attribute that governs disabledness, not its value.
To disable elements you need to use attribute disabled = "disabled" rather than true or false. To make it enabled again, you need to remove the disabled attribute. Modify your code like this:
for (i=0; i<inputs.length; i++){
if (action === false) {
inputs[i].removeAttribute('disabled');
}
else {
inputs[i].setAttribute('disabled', 'disabled');
}
}
for (i=0; i<selects.length; i++){
if (action === false) {
selects[i].removeAttribute('disabled');
}
else {
selects[i].setAttribute('disabled', 'disabled');
}
}
The setAttribute and removeAttribute functions are used to set and remove disabled attribute respectively.
More code needed. Everything looks correct, and setting the disabled property of an <input> element to a Boolean value (the correct approach) certainly works in Firefox, regardless of the presence or absence of the disabled attribute in the source HTML.

Categories