The below function does what I want it to in IE 8 but not Firefox 30. The intent is that checking the skill box should enable the user to modify the quantity textbox, and that unchecking it should restore the original value and make it readonly again.
function updateQuantity(refNum) {
var quantity = 'quantity' + refNum;
var startQuantity = 'startQuantity' + refNum;
var skill = 'skill' + refNum;
if (!document.getElementById(skill).checked){
document.getElementById(quantity).disabled = true;
document.getElementById(quantity).readOnly = true;
document.getElementById(quantity).style.color = "rgb(192,192,192)";
document.getElementById(quantity).value = document.getElementById(startQuantity).value;
} else {
document.getElementById(quantity).disabled = false;
document.getElementById(quantity).readOnly = false;
document.getElementById(quantity).style.color = "rgb(0,0,0)";
}
}
Here is an HTML snippet that exercises the functions.
<tr><td>Toughness</td>
<td></td>
<td>10 ^ (100 total)</td>
<td><input type="checkbox" name="skill8" value="Toughness" onclick="updateQuantity(8);updateTotal(8);">
<input style="color:rgb(192,192,192);" disabled readonly type="text" name="quantity8" maxlength="2" size="2" value="4" onclick="updateTotal(8);">
<input type="hidden" name="startQuantity8" value="4"></td></tr>
<tr style="background:rgb(80,30,30);"><td>Light Armor</td>
<td></td>
<td>20</td>
<td><input type="checkbox" name="skill9" value="Light Armor" onclick="updateQuantity(9);updateTotal(9);">
<input style="color:rgb(192,192,192);" disabled readonly type="text" name="quantity9" maxlength="2" size="2" value="1" onclick="updateTotal(9);">
<input type="hidden" name="startQuantity9" value="1"></td></tr>
I've tried moving the script definition to the end of the section, but that doesn't resolve the problem. I'm getting the error in the Firefox debugger that document.getElementById(skill) is null when I'm trying to evaluate it in the if statement. Any thoughts?
Well, Firefox is correct, there is no element with such an ID. From the MSDN documentation:
In IE7 Standards mode and previous modes, this method performs a case-insensitive match on both the ID and NAME attributes, which might produce unexpected results. For more information, see Defining Document Compatibility.
And look at your HTML, that seems what is happening:
<input type="checkbox" name="skill8" ... />
Possible solutions:
Add an id attribute to all the elements you wish to refer to via getElementById.
Use getElementsByName instead.
Related
What i want to do is get the name of the hidden form which in this case is named:6ca3787zz7n149b2d286qs777dd8357b, the problem is, that form name always changes, the only thing that is the same is its value, which is 1, well 99% of the time, the only thing that is 100% the same that i guess could be somehow used to retrieve the form name is:L2ZvcnVtcy8 which is just above it. I am also attempting to do this via running javascript manually on the browser (chrome), so having that in mind where the javascript code is run through the url bar like this javascript:codegoeshere, how can i get the form name, -->(6ca3787zz7n149b2d286qs777dd8357b)?
<form action="index.php?feature=xxxxxx" method="post" name="login">
<input type="submit" name="submit" class="button" value="Logout" />
<input type="hidden" name="option" value="username" />
<input type="hidden" name="task" value="logout" />
<input type="hidden" name="return" value="L2ZvcnVtcy8=" />
<input type="hidden" name="6ca3787zz7n149b2d286qs777dd8357b" value="1" /> </form>
</li>
Check all the solutions below in this fiddle.
Some possibilities:
Assuming there is only one element with the name login and that element is the <form>, you can use:
document.getElementsByName('login')[0].getElementsByTagName('input')[4].name
If the return <input> has a fixed name attribute, then this should work (the additional .nextSibling is because there is a text node between them):
document.getElementsByName('return')[0].nextSibling.nextSibling.name
If any other of of those <input>s has a fixed name, you can use (in the example I take the <input> with name=task):
document.getElementsByName('task')[0].parentNode.getElementsByTagName('input')[4].name);
If all you really have is that fixed value, you'll have to use a for loop through all the <input>s:
var lastResortName = (function () { for(var i=0, ipts = document.getElementsByTagName('input'), n = ipts.length; i < n; i++) { if (ipts[i].value === "L2ZvcnVtcy8=") return ipts[i+1].name; } })();
Note: If there are duplicated values for the mentioned name attributes, test with the index ([0], [1], [2] and so on) until you find the expected elements.
That's really easy if you use JQuery:
$('input[type="hidden"]:eq(3)').attr('name')
Here your code running:
http://jsfiddle.net/7CHYa/
I have a table which is generated from data from a datbase. It might have 3 rows and 2 cells.
Each cell has a checkbox in it and 2 hidden form fields.
So, a typical row might look like this:
<tr>
<td>
<input type="checkbox" id="Assign" onclick="setchanged(this);">
<input type="hidden" id="hfChanged" value="0">
<input type="hidden" id="hfAgentID value="272">
</td>
<td>
<input type="checkbox" id="Assign" onclick="setchanged(this);">
<input type="hidden" id="hfChanged" value="0">
<input type="hidden" id="hfAgentID value="324">
</td>
</tr>
The requirement is - when a checkbox is clicked, it should set the value of the hfChanged hidden field in the same cell to 1.
This works in Internet Explorer:
function setchanged(me)
{
me.parentElement.all("hfChanged").value = 1;
}
How can I set the value of hfChanged in Standards Compliant browsers like Firefox or Chrome?
Use repeating classes instead of IDs
<tr>
<td>
<input type="checkbox" class="Assign" onclick="setchanged(this);">
<input type="hidden" class="hfChanged" value="0">
<input type="hidden" class="hfAgentID value="272">
</td>
<td>
<input type="checkbox" class="Assign" onclick="setchanged(this);">
<input type="hidden" class="hfChanged" value="0">
<input type="hidden" class="hfAgentID value="324">
</td>
</tr>
Then change your function to select by class name, and iterate the result.
function setchanged(me) {
var changed = me.parentNode.querySelectorAll(".hfChanged");
for (var i = 0; i < changed.length; i++) {
changed[i].value = 1;
}
}
The .querySelectorAll method will not work in IE6/7 if that matters to you. If it does, it's not hard to adjust a little for greater compatibility.
I see now that there's only one in the same cell. In that case, you can do this instead.
function setchanged(me) {
me.parentNode.querySelector(".hfChanged").value = 1;
}
You can use the following function to find out the next element as given in this answer
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
Working demo here.
Code:
function setchanged(me){
next(me).value = me.checked == true ? 1 : 0;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
This code is not tested, but could give you a starting point.
$("input[type=checkbox]").change(function(){
$(this).siblings(".hfChanged").prop("value", this.checked ? 1 : 0);
});
Note: Change id to class.
Purpose is to have checkboxes disabled when the page loads, and remain greyed out until textbox is filled.
<input type="text" name="<%=commentID%>" />
<input type="checkbox" name="<%=SkipID%>" value="N" disabled/>
I tried to do something like
<input type="text" name="<%=commentID%>" onkeyup="userTyped('<%=SkipID%>') />
function userTyped(commen){
if(this.value.length > 0){
document.getElementById(commen).disabled=false;
}else{
document.getElementById(commen).disabled=true;
}
}
But it did not work. I am assuming because of the inconsistency of the name, but I have to have that.
You haven't given id to your html elements and is trying to use getElementById, which will return null. Javascript engine will not be able to set disabled attribute of null. Try setting id attribute, for elements as given below.
Also in your userTyped function you are referencing this. this here is the window object and not the input element. You need to pass the reference to input element to make this work, like this onkeyup="userTyped('<%=SkipID%>', this)"
Please find a possible correction below:
<input type="text" name="<%=commentID%>" id="<%=commentID%>" onkeyup="userTyped('<%=SkipID%>', this)" />
<input type="checkbox" name="<%=SkipID%>" id="<%=SkipID%>" value="N" disabled/>
/** commen is the id
* e is the input element
**/
function userTyped(commen, e){
if(e.value.length > 0){
document.getElementById(commen).disabled=false;
}else{
document.getElementById(commen).disabled=true;
}
}
jsFiddle here: http://jsfiddle.net/deepumohanp/dGS9H/
I have a fairly long form on a page with various checkboxes and text boxes. There is one point where I want a text box to become available if a corresponding checkbox is ticked. I almost have it working with this code:
<tr class= "formspace">
<td class="formleft" valign="top" style="line-height:22px">Extra bed(s)?</td>
<td colspan="2"><input name="extrabed" type="checkbox" value="1" onChange="jsextrabed()"><?php echo $lang["extraadultx"]." ".$lang["notsingleoccx"];?>
<div id="extrabednumber"></div>
<script type="text/javascript">
function jsextrabed() {
if(document.roomnew.extrabed.checked == 1) {
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="1">';
}else{
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="0">';
}
}
</script>
</td>
</tr>
When the page first opens, only the checkbox shows.
When I tick the checkbox, the text box opens with a value of 1. So far, so good.
When I click again the checkbox is unticked and the value in the text box changes to 0. Still good.
When I click yet again the checkbox is ticked (good) but the value in the text box stays at 0 (bad!).
Further clicking toggles the checkbox but has no effect on the value in the text box.
What have I done wrong?
use this code for check:
if(document.roomnew.extrabed.checked) {
Just check with
if(document.roomnew.extrabed.checked){
}
else
{
}
There is no problem in the displayed code.
Here's a working demonstration : http://jsfiddle.net/dystroy/u6mtW/
HTML :
<tr class= "formspace">
<td class="formleft" valign="top" style="line-height:22px">Extra bed(s)?</td>
<td colspan="2"><input name="extrabed" id=checkextra type="checkbox" value="1" >some php
<div id="extrabednumber"></div>
</td>
</tr>
Javascript :
<script>
window.onload=function(){
document.getElementById('checkextra').onchange = function() {
if(this.checked) {
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="1">';
}else{
document.getElementById("extrabednumber").innerHTML=' Max number of extra beds <input name="extrabed" type="text" id="extrabed" size="1" maxlength="1" value="0">';
}
};
};
</script>
I made a few changes to
adapt to the fact that we don't have the whole DOM. Your problem may be there, in the parts we don't see.
ensure the function is correcly hooked on the checkbox (you may have a problem of not fully loaded DOM, depending on your page)
Problem solved!
I was using the same name for two elements: both the checkbox input and the text box input (in the innerHtml were called "extrabed". Changing one of those has fixed it.
Thanks to all of you who offered help.
I'll use a simplified version below but am trying to build a form with simple yes/no questions. If the answer is no, no explanation is required. If the answer is yes, a new table row is inserted and textarea appears requiring an explanation for that particular question.
Of note, I use the jQuery validate plugin to make sure values are checked and plan to implement a required-dependency function for each field in the end.
My Form:
<form name="formtest" action="">
<table class="background_table">
<tbody>
<tr>
<td>Are you a man?</td>
<td>
<input type="radio" name="q1" id="yes1">Yes
<input type="radio" name="q1" id="no1">No
</td>
</tr>
<tr>
<td>Do you have hair?</td>
<td>
<input type="radio" name="q2" id="yes2">Yes
<input type="radio" name="q2" id="no2">No
</td>
</tr>
<tr>
<td>Do you have children?</td>
<td>
<input type="radio" name="q3" id="yes3">Yes
<input type="radio" name="q3" id="no3">No
</td>
</tr>
</tbody>
</table>
<input type="submit" />
</form>
I believe my jQuery function would iterate through all fields (given my actual form has 20+ questions) using the .each() function and then run a test on the individual fields to see if the value was yes:checked. If it was a new row is insert after the field with a blank text area.
I am not quite sure what the best method for naming and identifying the text areas might be at this time. Ultimately, all text area answers could be combined into an array I suppose and broken out by an ID and value but not sure how I'd like to handle that quite yet.
jQuery function:
$(function() {
$('input').each( function() {
if( $('#yes1').is(':checked')) { //need to figure out how to find the yes value for each input
$('#yes1').closest('tr').after('<tr><td colspan="2">Please explain below:<br><textarea name="a1" id="a1"></textarea></td></tr>');
}
});
$("#formtest").validate({
errorLabelContainer: "#form_error_message",
wrapper: "li",
rules: {
q1: 'required',
q2: 'required',
q3: 'required',
q4: 'required',
a1: { required: "yes1:checked" },
a2: { required: "yes2:checked" },
a3: { required: "yes3:checked" },
a4: { required: "yes4:checked" }
},
messages: {
//custom messages for all rules above
},
submitHandler: function() {
//Do processing
}
});
});
My function currently does not work but am looking for guidance as to how this can best be achieved. In the end it may just be easier to present a single text area for explanation of ANY checkbox is answered 'yes' at the end of the form but feel the initial method looks nicer and allows me to separate responses if I wanted.
final update
Of note, as part of a form, users have the ability to get back to this page. To prevent them having to retype answers and selections, I use PHP SESSION variables to contain previously entered data. I needed to make sure the explanation boxes showed or hid themselves as necessary. To prevent any issues with non-js browsers, I have all my explain boxes display initially then are set to hidden if the value of the corresponding checkbox is not equal to value of 1:
$(":radio:checked").each(function() {
if( $(this).val() != 1) {
$(this).closest('tr').next().hide();
}
});
It looks like you are only checking on the initial DOM load. You need to fire off a check on click events so that your box will appear/disappear on click. I would add a hidden tr row containing each comment box, and then either show or hide as appropriate. Something like this:
$('input:radio').click(function() {
$commentTr = $(this).closest('tr').next();
if ($(this).val() == 'Yes') {
$commentTr.hide();
}
else {
$commentTr.show();
}
});
On closer inspection, I suppose the check for a value of "Yes" wouldn't quite work. I'd recommend using HTML label tags with the "for" attribute populated with unique IDs of each input.
<input type="radio" name="q1" id="yes1"><label for="yes1">Yes</label>
Then you could have a check like:
$('label[for="' + id + '"'].html() == 'Yes'
I've set up a jsfiddle here which I think does what you're looking for.
There are a couple of things to consider with your current solution. First of all, as Danimal37 mentions, you are only running this on load of the page. You want the explanation boxes to show/hide whenever the value of each radio button change. Second of all, there is a built-in way to distinguish between the 'yes' and the 'no'. Just give the input elements value attributes. To fix these problems, I propose the following (I've ignored the validation portion and you can see it in action in this jsfiddle: http://jsfiddle.net/xonev/RU986/2/):
// The Javascript
$('input[value="1"]').change(function () {
var explainId = $(this).attr('name') + 'explain';
$(this).closest('tr').after('<tr id="' + explainId + '"><td colspan="2">Please explain below:<br><textarea name="a1" id="a1"></textarea></td></tr>');
});
$('input[value="0"]').change(function () {
var explainId = $(this).attr('name') + 'explain';
$(this).closest('tr').next('tr#' + explainId).remove();
});
<!-- The HTML -->
<form name="formtest" action="">
<table class="background_table">
<tbody>
<tr>
<td>Are you a man?</td>
<td>
<input type="radio" name="q1" id="yes1" value="1" />Yes
<input type="radio" name="q1" id="no1" value="0" />No
</td>
</tr>
<tr>
<td>Do you have hair?</td>
<td>
<input type="radio" name="q2" id="yes2" value="1" />Yes
<input type="radio" name="q2" id="no2" value="0" />No
</td>
</tr>
<tr>
<td>Do you have children?</td>
<td>
<input type="radio" name="q3" id="yes3" value="1" />Yes
<input type="radio" name="q3" id="no3" value="0" />No
</td>
</tr>
</tbody>
</table>
<input type="submit" />
</form>