I am trying to validate a group of two sex radio buttons, but am getting an error.
I have the following:
It is giving an error on itm.length; says it is undefined.
function validateSex(itm, elmt) {
var dom = document.getElementById(elmt);
var numChecked = 0;
for (var index = 0; index < itm.length; index++) {
if (itm[index].checked) {
numChecked++;
break;
}
}
// if sex not selected display error message.
if (numChecked === 0) {
dom.innerHTML = "Please select the sex.";
return false;
}else {
dom.innerHTML = "";
return true;
}
}
<table>
<tr>
<td>
<input type = "radio" name = "sex" value= "male"
title = "Select sex"
onchange = "validateSex(this, 'msgSex')"/>Male
<input type = "radio" name = "sex" value= "female"
title = "Select sex"
onchange = "validateSex(this, 'msgSex')"/>Female
</td>
<td id = "msgSex"></td>
</tr>
<table>
You should use document.getElementsByName('sex') instead of this in validateSex(this, 'msgSex') if you need the length attribute.
But you can't validate radio button like this.
Related
A form with 50 entries: each with P1-48, E1-48, and X1-48. I want to calculate the Entry Fee "E1" based on the expires date X1. The js date format for the expires date is YYYY.MM.DD, ex. 2018.04.21 and a player pays $3 if his expires date is greater or equal to today's date. He pays $5 if his expires date is older or less than today's date. But if the expires date is blank and the player pays a membership fee, the Entry Fee is waived to zero.
JS:
<script src = "js/moment.min.js"></script>
I also have this as a "template" starting guide. I think it could be modified and piggyback the target result onto it.
<script> // change expiration date color
function getExpireDate(ele) {
var i = null;
for (i = 0; members.length > i; i++) {
if (members[i].Name == ele.value) {
var exDate = moment(members[i].Expires, 'YYYY.MM.DD');
if (moment().isAfter(exDate)) {
$(ele).closest('.universal').find('.expDate').css('color', "#A3005B");
} else {
$(ele).closest('.universal').find('.expDate').css('color', "#275052");
}
return members[i].Expires;
}
}
return '';
}
</script>
<script>
for (let i = 0; i <= 48; i++) {
$("#P" + i).on("blur", function(){
$("#X" +i).val(getExpireDate(this));
});
}
</script>
<script>
var members [
{"Name": "Jones, David", "Expires": "2017.05.03" },
{"Name": "Roth, Bill", "Expires": "2017.03.08" },
{"Name": "Scullin, Kenn", "Expires": "2019.02.20" }
]
<script>
HTML:
<div>
<input type = "text" id = "P1"> <!--Player-->
<input type = "text" id = "E1"> <!--Entry Fee-->
<input type = "text" id = "M1"> <!--Membership Fee-->
<input type = "text" id = "X1" onblur="getExpireDate()" class="expDate"> <!--expires-->
<div>
Funny thing is:
<input type = "text" onblur="getClass()" class="text" id="Y1" maxlength = "4" size = "4" disabled /> <!--works even with input disabled -->
<input type = "text" onblur="calcEntryFee(this);" class="expDate" name = "exp" id="X1" maxlength = "10" size = "10" disabled /><!--new code doesn't work -->
<script> // Lookup class or rating
function getClass(ele) {
var i = null;
for (i = 0; members.length > i; i++) {
if (members[i].Name == ele.value) {
return members[i].Rating;
}
}
return;
}
for (let i = 0; i <= 48; i++) {
$("#P" + i).on("blur", function(){
$("#Y" +i).val(getClass(this));
});
}
</script>
How about this:
(The main function is calcEntryFee().)
var members = [
// ... fill data here.
];
function getMemberData( name ) {
var a = jQuery.trim( name ).toLowerCase(),
i, b, member;
for ( i = 0; i < members.length; i++ ) {
b = jQuery.trim( members[ i ].Name ).toLowerCase();
if ( a === b ) {
member = members[ i ];
break;
}
}
return member || {};
}
function calcEntryFee( elem ) {
var idx, member, exDate, today, fee;
elem = elem || {};
if ( /^[PEMX](\d+)$/.test( elem.id ) ) {
idx = RegExp.$1;
} else {
return false;
}
member = getMemberData( jQuery( '#P' + idx ).val() );
mmfee = parseFloat( jQuery( '#M' + idx ).val() );
exDate = moment( member.Expires, 'YYYY.MM.DD' );
today = moment();
fee = '';
if ( exDate.isBefore( today ) ) {
fee = 5;
} else if ( exDate.isSameOrAfter( today ) ) {
fee = 3;
} else if ( ! member.Expires && mmfee > 0 ) {
fee = 0;
}
// Updates the entry fee input value.
jQuery( '#E' + idx ).val( fee );
return fee;
}
You'd use calcEntryFee() like this:
<input id="X1" placeholder="X" size="10" onblur="calcEntryFee( this );" />
See the full code and try a live demo on https://codepen.io/anon/pen/WJRNVY.
UPDATE
Because the expiry date field/input is disabled, use this instead: (take note of the id value, which could also be P2, P3, etc.)
<input id="P1" placeholder="P" onblur="calcEntryFee( this );" />
I.e. Add the calcEntryFee( this ); to the onblur attribute of the "Player" field and not the expiry date field. Or add it to any sibling/related fields which is not disabled, or which we can tab to. (So that we can focus and "un-focus" or blur on the field, and the browser would then invoke the calcEntryFee( this ); that was attached to the field's blur event.)
Try a live demo on: https://codepen.io/anon/pen/xjgQyx
Alternatively, you may add it without using the onblur attribute of the input/field: (refer to the code you provided in your question)
for (let i = 0; i <= 48; i++) {
$("#P" + i).on("blur", function() {
$("#X" + i).val(getExpireDate(this));
calcEntryFee(this); // <- add it here
});
}
Had to re-read your question a few times. I'm still not sure a fully understand what you're trying to achieve, but I believe this is pretty close:
let getMember = {
index: function(name) {
let index = -1;
$.each(members, function(i, player) {
if (player.Name === name) { index = i; }
});
return index;
},
entryFee: function(memberIndex) {
if (memberIndex === -1) {
return 'waived';
} else {}
let today = new Date();
let expires = new Date(members[memberIndex].Expires.replace(/\./g, '-'));
return today <= expires ? '$3' : '$5';
}
};
let members = [
{"Name": "Jones, David", "Expires": "2017.05.03" },
{"Name": "Roth, Bill", "Expires": "2017.03.08" },
{"Name": "Scullin, Kenn", "Expires": "2019.02.20" }
];
let tableHTML = '';
for (let i=0; i < 50; i++) {
tableHTML += `
<div class="row">
<input type="text" class="player" placeholder="player">
<input type="text" class="entryFee" placeholder="entry fee">
<input type="text" class="membershipFee" placeholder="membership fee">
<input type="text" class="expDate" placeholder="expire date">
<div>`;
}
$(`<div class="table">${tableHTML}</div>`)
.appendTo('body')
.on('blur', '.player', function() {
if (!this.value) { return false; }
let memberIndex = getMember.index(this.value);
let entryFee = getMember.entryFee(memberIndex);
$(this)
.next().val(entryFee)
.next().val(entryFee === 'waived' ? 'yes' : 'no')
.next()
.val(memberIndex >= 0 ? members[memberIndex].Expires : 'non-member')
.addClass(entryFee === '$3' ? 'currentMember' : 'nonCurrentMember');
$('.player').eq($('.player').index(this) + 1).focus();
});
https://jsfiddle.net/ypzjfkxk/
Without an external library to boot! Can't say I have any experience with moment.js, but all of the questions I've come across seem to be solvable in plain javascript. Also, it would be just as fast and easy to generate an alphabetical table for this. Then you wouldn't have to worry about typos in the player input. Unless you're trying to create a log or something?
This works for me:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.js"></script>
<script type="application/javascript">
var members = [
{"Name": "Jones, David", "Expires": "2017.05.03" },
{"Name": "Scullin, Kenn", "Expires": "2019.02.20" },
{"Name": "Peter, Kenn", "Expires": "2018.04.24" },
{"Name": "Chris, Kennx", "Expires": "" }
];
$(document).ready(function(){
var nUsers = 4; // Number os users
// Fill inputs (tmp: visual purpose)
for (count=1; count<=nUsers; count++){
$("#P"+count).val(members[count-1].Name);
$("#X"+count).val(members[count-1].Expires);
}
$("#M4").val("$20");
/* Get current date. For security purpose you should
get this from the server and not the client side.*/
var date = moment().toDate();
// Go through every input row
for (count=1; count<=nUsers; count++){
var exDate = $("#X"+count).val(); // Get the exire date
// Confirm that date is has the right format
if (moment(exDate, 'YYYY.MM.DD').isValid()){
exDate = moment(exDate, 'YYYY.MM.DD').toDate();
var diff = new Date(exDate - date);
var nDays = parseInt(diff/1000/60/60/24);
console.log(nDays);
if (nDays >= 0){ // If his expires date is greater or equal to today's date
$("#E"+count).val("$3");
$("#X"+count).css('color', "#275052");
}
if (nDays < 0){
$("#E"+count).val("$5"); // If his expires date is older or less than today's date
$("#X"+count).css('color', "#A3005B");
}
}
else{ // If expire date is empty
var mFee = parseFloat($("#M"+count).val().replace(/\$/, ''));
if ((exDate.length == 0) && (mFee > 0 )){ // If the expires date is blank and the player pays a membership fee
$("#E"+count).val("$0");
}
}
}
});
</script>
</head>
<body>
<!-- visual purpose -->
<div>
<input type = "text" id = "P1"> <!--Player-->
<input type = "text" id = "E1"> <!--Entry Fee-->
<input type = "text" id = "M1"> <!--Membership Fee-->
<input type = "text" id = "X1" class="expDate"> <!--expires-->
<br>
<input type = "text" id = "P2"> <!--Player-->
<input type = "text" id = "E2"> <!--Entry Fee-->
<input type = "text" id = "M2"> <!--Membership Fee-->
<input type = "text" id = "X2" class="expDate"> <!--expires-->
<br>
<input type = "text" id = "P3"> <!--Player-->
<input type = "text" id = "E3"> <!--Entry Fee-->
<input type = "text" id = "M3"> <!--Membership Fee-->
<input type = "text" id = "X3" class="expDate"> <!--expires-->
<br>
<input type = "text" id = "P4"> <!--Player-->
<input type = "text" id = "E4"> <!--Entry Fee-->
<input type = "text" id = "M4"> <!--Membership Fee-->
<input type = "text" id = "X4" class="expDate"> <!--expires-->
<div>
</body>
</html>
And a recommendation that I gave to you in the code is you should get the current time from the server side and not from the client side.
I hope that works for you. :)
My code generates a two dimensional matrix when the OK is clicked. The code stores the data in the multidimensional array, but I am trying to add a sort function to the code which rearranges the code in ascending order using the 4th text box. Any suggestions on how I can do that ?
HTML Code
<div class="rightDiv">
<div id = "pastcalcblock">
<h3> PAST CALCULATIONS </h3>
<input type = "text" size = "1" id = "text1"/>
<input type = "text" size = "1" id = "text2"/>
<input type = "text" size = "1" id = "text3"/>
<input type = "text" size = "1" id = "text4"/><br>
<input type = "button" value = "Ok" id = "operation" onClick = "display()"/>
<div id = "resultTab">
SORT<br>
<input type = "button" value = "As Entered" id = "enteredBut">
<input type = "button" value = "By Result" id = "resultBut" onClick = "sort()"><br><br>
<div id="expressions">
</div>
</div>
</div>
Javascript Code
function display()
{
var arrayOne =[document.getElementById('text1').value,document.getElementById('text2').value,document.getElementById('text3').value,document.getElementById('text4').value ];
new_array=arrayOne.join(" ");
var para = document.createElement("p");
var t = document.createTextNode(new_array);
para.appendChild(t)
document.getElementById("expressions").appendChild(para);
}
function sort(){
var dispArr = [document.getElementById('text1').value,
document.getElementById('text2').value, document.getElementById('text3').value,document.getElementById('text4').value];
var myArray = [];
for(var i = 0 ; i < 1 ; i ++ ) {
myArray[i] = [];
for(var j = 0 ; j < 5 ; j++ )
{
myArray[i][j] = dispArr[j];
console.log(myArray[i][j]);
}
}
}
You would better keep the whole matrix in a memory variable, and add to that. Also consider that when the output is sorted, you must know how to get back to the original order also, so that the "As Entered" button still has the desired effect. So, it is better to have a display function that starts from scratch, empties the output and reproduces all the data in either entered or sorted order.
Here is how you could do that:
var matrix = []; // global value with all data
function addExpression() {
var arrayOne = [
document.getElementById('text1').value,
document.getElementById('text2').value,
document.getElementById('text3').value,
document.getElementById('text4').value
];
// add to matrix
matrix.push(arrayOne);
display(false);
}
function display(byResult) {
// Determine whether to sort or not:
var matrix2 = byResult ? sorted(matrix) : matrix;
// display each row:
var expressions = document.getElementById("expressions");
expressions.innerHTML = ''; // empty completely
matrix2.forEach( row => {
var para = document.createElement("p");
var t = document.createTextNode(row.join(" "));
para.appendChild(t)
expressions.appendChild(para);
});
}
function sorted(m){ // Create a copy, and sort that by last column
return m.slice().sort( (a, b) => a[3] - b[3] );
}
<div class="rightDiv">
<div id = "pastcalcblock">
<h3> PAST CALCULATIONS </h3>
<input type = "text" size = "1" id = "text1"/>
<input type = "text" size = "1" id = "text2"/>
<input type = "text" size = "1" id = "text3"/>
<input type = "text" size = "1" id = "text4"/><br>
<input type = "button" value = "Ok" id = "operation" onClick = "addExpression()"/>
<div id = "resultTab">
SORT<br>
<input type = "button" value = "As Entered" id = "enteredBut" onClick="display(false)">
<input type = "button" value = "By Result" id = "resultBut" onClick = "display(true)"><br><br>
<div id="expressions">
</div>
</div>
</div>
</div>
Trying to test 7 possible values of variable 'a', which is passed to my function from the values entered into seven 'input type text' boxes, and then individually executed by 7 'input type image' clicks. I do not get a result nor do I get the 'switch default' action of an alert box. I have tried using getElementsById and also getElementsByName.
Here is the first two tests and default from the function:
function check_answer(a)
{
var check = 0;
switch (a)
{
case 1 :
check = document.getElementById("blue").value;
if(check == 21)
{
document.images[a].src = "ok.gif";
score = score + 1000;
}
else
{
document.images[a].src = "wrong.gif";
score = score - 500;
}
break;
case 2 :
check = document.getElementById("red").value;
if(check == 22)
{
document.images[a].src = "ok.gif";
score = score + 1000;
}
else
{
document.images[a].src = "wrong.gif";
score = score - 500;
}
break;
default :
alert("fail";
}
The input elements are in table data on 7 table rows of a table as below:
<td id="b">How many BLUE triangles?</td>
<td><input type = "text" id = "blue"></td>
<td><input type = "image" id="bb" src="q.gif" height="25" width="25" onclick = "check_answer(1)">
<td width=10%><img src ="empty.gif" width="25" height="25"</td>
</td>
...... for 6 additional table rows.
Thanks
getElementsByName returns a list of elements, you can't use value on it like that.
You'd get the first element returned from the list in this case, e.g.
document.getElementsByName("blue")[0].value;
I've corrected your Javascript and sorted out the stray HTML markup below.
HTML:
<td id="b">How many BLUE triangles?</td>
<td><input type = "text" name = "blue"/></td>
<td><input type = "image" id="bb" src="q.gif" height="25" width="25" onclick ="check_answer(1)"/>
<td width="10%"><img src ="empty.gif" width="25" height="25"/></td>
JavaScript:
function check_answer(a){
var check = 0;
switch (a) {
case 1:
check = document.getElementsByName("blue")[0].value;
break;
case 2:
check = document.getElementsByName("red")[0].value;
if(check == 22) {
document.images[a].src = "ok.gif";
score = score + 1000;
}
else {
document.images[a].src = "wrong.gif";
score = score - 500;
}
break;
default: alert("fail");
}
}
i have a problem in html and javascript. i have tried different approach but everything didnt worked. so this is my sample code.
<select id = "testselect" name = "testselect">
<option> </option>
<option id = "o1" name = "testselect" value = "1" onselect='document.getElementById("os1").disabled = true;'> 1 </option>
<option id = "o2" name = "testselect" value = "2" > 2 </option>
<option id = "o3" name = "testselect" value = "3"> 3 </option>
</select>
<div >
<input id = "os1" type="checkbox" name="othser[]" value="7000" />cb1<br/>
<input id = "os2" type="checkbox" name="othser[]" value="7001"/>cb2<br/>
<input id = "os3" type="checkbox" name="othser[]" value="7002"/>cb3<br/>
</div>
ok, that's the code. what i want to happen is, when i selected o1(option id), os1(checkbox id) must be disabled and when i selected o2(option id), os2(checkbox id) must be disabled, and so on. so can anyone help me?
Try this:
Using plain javascript:
var select;
function changeIt() {
var allCheckboxes = document.querySelectorAll('input[type=checkbox]');
for (var i = 0; i < allCheckboxes.length; i++) {
allCheckboxes[i].removeAttribute('disabled');
}
var value = select.options[select.selectedIndex].value;
var checkBox = document.querySelector('input[id=os' + value + ']');
checkBox.disabled = true;
}
window.onload = function () {
select = document.getElementById('testselect');
select.onchange = changeIt;
changeIt();
}
Demo
Using jQuery:
$('select').change(function () {
$('input[type=checkbox]').removeAttr('disabled');
$('input[id=os' + this.value + ']').attr('disabled', true);
});
Demo
My own suggestion would be to move the event-handling outside of the HTML (for ease of future maintenance and change), and take the following approach:
function disableCheck(event) {
// get the element that was the target of the 'change' event:
var that = event.target,
/* find the option tags, and retrieve the option that was selected
from that collection (nodeList) of elements: */
opt = that.getElementsByTagName('option')[that.selectedIndex];
/* find the element whose 'id' is equal to the 'id' of the 'option'
once the 's' is inserted, and set the 'disabled' property to 'true': */
document.getElementById(opt.id.replace('o', 'os')).disabled= true;
}
// bind the onchange event-handler to the element with the id of 'testselect':
document.getElementById('testselect').onchange = disableCheck;
JS Fiddle demo.
To toggle which elements are disabled (rather than simply increase the number of disabled elements):
function disableCheck(event) {
var that = event.target,
opt = that.getElementsByTagName('option')[that.selectedIndex],
idToFind = opt.id.replace('o','os'),
allInputs = document.getElementsByTagName('input');
for (var i = 0, len = allInputs.length; i < len; i++){
if (allInputs[i].type == 'checkbox') {
allInputs[i].disabled = allInputs[i].id === idToFind;
}
}
}
document.getElementById('testselect').onchange = disableCheck;
JS Fiddle demo.
Well, this is ugly...and suggests I really need to rethink the approach above, however it does work (though it doesn't properly support IE as yet). This uses a trigger function which is fired upon the window.load event which triggers the change event from the select element-node:
function trigger(event, source) {
var newEvent;
if (document.createEvent) {
newEvent = document.createEvent("HTMLEvents");
newEvent.initEvent(event, true, true);
} else {
newEvent = document.createEventObject();
newEvent.eventType = event;
}
newEvent.eventName = event;
if (document.createEvent) {
source.dispatchEvent(newEvent);
} else {
source.fireEvent("on" + newEvent.eventType, newEvent);
}
}
function disableCheck(event) {
var that = event.target,
opt = that.getElementsByTagName('option')[that.selectedIndex],
idToFind = opt.id.replace('o', 'os'),
allInputs = document.getElementsByTagName('input');
for (var i = 0, len = allInputs.length; i < len; i++) {
if (allInputs[i].type == 'checkbox') {
allInputs[i].disabled = allInputs[i].id === idToFind;
}
}
}
window.addEventListener('load', function(){
trigger('change', document.getElementById('testselect'));
});
document.getElementById('testselect').onchange = disableCheck;
JS Fiddle demo.
onselect should go into the select
<script>
function onSelect(obj){
var x = document.getElementsByName("othser[]");
for (var i in x) x[i].disabled = false;
document.getElementById("os"+obj.value).disabled=true;
}
</script>
<select id = "testselect" name = "testselect" onchange='onSelect(this)'>
<option> </option>
<option id = "o1" name = "testselect" value = "1" > 1 </option>
<option id = "o2" name = "testselect" value = "2" > 2 </option>
<option id = "o3" name = "testselect" value = "3"> 3 </option>
</select>
<div >
<input id = "os1" type="checkbox" name="othser[]" value="7000" />cb1<br/>
<input id = "os2" type="checkbox" name="othser[]" value="7001"/>cb2<br/>
<input id = "os3" type="checkbox" name="othser[]" value="7002"/>cb3<br/>
</div>
I'm doing an assignment for a uni subject and having some trouble with javascript. I want to be able to change the value of an input field based on the value of another field. in short, the purpose is to input a quantity of a product in one field, and have the field next to it change to display the total amount of money required to purchase that quantity of products.
When I run my html, the quantity entered does not change the value of the cost field and im thinking there must be something wrong with my javascript.
Here is a copy of my javascript function, and the related html for it to execute within.
SCRIPT:
function calcRowWash(){
var theForm = document.forms["orderform"];
var x = theForm.getElementById("quantc").value;
var quantity = 0;
if(x.value!=""){
quantity = parseInt(x.value);
}
var totalC = (quantity*0.30);
document.getElementById("totc").value = totalC;
return;
}
HTML:
<td width = "90px" align ="left"><input type = "text" id ="quantc" name = "quantWash" size = "5" tabindex = "13" onblur="calcRowWash()"/></td>
<td width = "90px" align ="left"><input type = "hidden" id ="totc" name = "washtotal" size = "5" tabindex = "14" value=""/></td>
Thanks for the help!.
var theForm = document.forms["orderform"];
var x = theForm.getElementById("quantc").value;
This is redundant. IDs are unique on the entire document, so this will suffice:
var x = document.getElementById('quantc');
Also note that I removed the .value - this was the problem, because you then tried to get the value... of the value.
This works.
calcRowWash = (function(){
var x = document.getElementById("quantc");
var quantity = 0;
if (x.value!="") quantity = parseInt(x.value);
var totalC = (quantity*0.30);
document.getElementById("totc").value = totalC;
});
JSFiddle.
try with this code
function calcRowWash() {
var x = document.forms[0]['quantc'].value;
var quantity = 0;
if (x != "") {
quantity = parseInt(x);
}
var totalC = (quantity * 0.30);
document.forms[0]['totc'].value = totalC.toString();
}
Html Markup, I've changed the hidden type for an textbox and It works for me.
<td width = "90px" align ="left"><input type = "text" id ="quantc" tabindex = "13" onblur="calcRowWash()"/></td>
<td width = "90px" align ="left"><input type = "text" id ="totc" tabindex = "13"/></td> </div>
function calcRowWash(){
var theForm = document.forms["orderform"];
var x = theForm.getElementById("quantc").value;
var quantity = 0;
// Check if it is not empty
if(x.value != ""){
// Check if it is a valid number
if(x / x == 1){
quantity = parseInt(x.value);
}
}
var totalC = (quantity * 0.30);
document.getElementById("totc").value = totalC;
}
this works for me.
<form name="myForm" action="#" method="POST">
<input type = "text" id="quantc" name = "quantWash" size = "5" tabindex = "13" onblur="calcRowWash()"/>
<input type = "hidden" id ="totc" name = "washtotal" size = "5" tabindex = "14" value=""/>
</form>
function calcRowWash(){
var quantity = document.myForm.quantWash.value;
var price = 10.0;
document.myForm.washtotal.value = quantity * price;
}
The function doesn't comprise the parsing stuff. I just want to show how to read and set the value of both input fields.
You can use this JavaScript Code:
var inp = document.getElementById("inp"); // getting the Input ID
function change_value() {
inp.value = 'Your Value'; // <-- value
}
You can add Events:
inp.onfocus = change_value;
inp.onblur = another function with another action;
Good Luck Liam and Have a Nice Day.