I have this type of html:
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field " name="username" id="username" placeholder="" value="" required="required" data-label="Username">
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" class="input-text um-field " name="firstname" id="firstname" placeholder="" value="" required="required" data-label="FirstName">
</p>
<p class="form-row " id="radio_SXsPOwVSD_input">
<input type="radio" class="input-radio um-field" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male">Male
<input type="radio" class="input-radio um-field" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
</p>
applyConditions array contains input, condition and value indexes. Could be any inputs and also many conditions. Suppose,
input = username
condition = 0 (is)
value = abc
input = firstname
condition = 1 (is not)
value = pqr
I need to do something(show/hide checkbox) if
username is abc and firstname isnot pqr
from the frontend. But could be input radio_sXsPOwVSD, condition 1 and value Male.
then,
applyConditions.forEach( function( item ) {
if(item.condition == 0) {
jQuery("#"+ item.input+"_input").on('change', ( function( avalue ) {
return function(e) {
if( e.target.value == avalue ) {
//show checkbox
}
else {
//hide checkbox
}
};
})(item.value));
}
else if( item.condition == 1 ) {
jQuery("#"+ item.input+"_input").on('change', ( function( avalue ) {
return function(e) {
if( e.target.value != avalue ) {
//show checkbox
}
else {
//hide checkbox
}
};
})(item.value));
}
});
However, this seems to be OR, if any matches, but I need all matches. I could count the matches and compare with array length, but with onChange count on same field seems to increase/decrease multiple times. What could be the solution? I am stuck on this for a while.
applyConditions =
[
{"input":"username","condition":"0","value":"abc"},
{"input":"firstname","condition":"1","value":"pqr"}
];
could also be {"input":"radio_SXsPOwVSD","condition":"0","value":"Male"},
Compare if ($(ele).val() == item.value) equals item.condition
to determine whether it matches the condition.
The following version now works on radio buttons and checkbox.
Well, I finally found that there're name attr on every input.
var applyConditions = [
{
'input': 'username',
'condition': 0,
'value': 'abc'
},
{
'input': 'firstname',
'condition': 1,
'value': 'pqr'
},
{
"input": "radio_SXsPOwVSD",
"condition": 0,
"value":"Male"
},
{
"input": "check_box_XmNoe",
"condition": 0,
"value": "Apple"
}
]
applyConditions.forEach(function(condition) {
var targetInput = $('input[name='+condition.input+']');
targetInput.on('change',function(){
var results = $.map(applyConditions,(item, index)=>{
var targetInput = $('input[name='+item.input+']');
var type = targetInput.get(0).type;
var check = false;
if(type == "radio" || type == "checkbox"){
var input = targetInput.get().find(x=>$(x).is(":checked") && $(x).val() == item.value)
if (input)
{
check = input.value == item.value != item.condition;
}
else{
// since 0 means equal, if there's no any radio button or checkbox is checked, check = false
check = item.condition ? true : false;
}
}
else{
check = (targetInput.val() == item.value) != item.condition;
}
if(check){
// matches
}
else{
// not matches
}
return check;
})
console.log(...results);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field" name="username" id="username" placeholder="" value="" required="required" data-label="Username">
( ==abc )
</p>
<p id="email_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field" name="email" id="email" placeholder="" value="" required="required" data-label="Email">
( no condition )
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" class="input-text um-field" name="firstname" id="firstname" placeholder="" value="" required="required" data-label="FirstName">
( !=pqr )
</p>
<p class="form-row" id="radio_SXsPOwVSD_input">
<input type="radio" class="input-radio um-field" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male">Male
<input type="radio" class="input-radio um-field" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
( Male should be checked )
</p>
<p id="check_box_XmNoe_input">
<label class="checkbox data-label=">Checkbox</label>
<input type="checkbox" class="input-checkbox um-field" name="check_box_XmNoe" id="check_box_XmNoe_Apple" value="Apple"> Apple
<input type="checkbox" class="input-checkbox um-field" name="check_box_XmNoe" id="check_box_XmNoe_Orange" value="Orange"> Orange
( Apple should be checked )
</p>
This is just an alternative algorithm.
var applyConditions = [
{
"input": "username",
"condition": "0",
"value": "abc",
},
{
"input": "firstname",
"condition": "1",
"value": "pqr",
},
{
"input": "radio_SXsPOwVSD",
"condition": "0",
"value": "Male"
},
];
var totalConditions = applyConditions.length,
conditionFulfilled = 0;
function compare($element, rule) {
if ($element.length > 1) $element = $element.filter(':checked'); //radio
return ($element.val() == rule.value) == (rule.condition == "0");
}
function setOK() {
if (conditionFulfilled == totalConditions) $('#iresult').html('OK');
else $('#iresult').html('Completed('+conditionFulfilled+'/'+totalConditions+')');
}
applyConditions.forEach(function(rule) {
var $element = $('[name=' + rule.input + ']');
var isConditionTrue = compare($element, rule);
if (isConditionTrue) conditionFulfilled++;
$element.change(function() {
var updatedIsConditionTrue = compare($element, rule);
if (isConditionTrue != updatedIsConditionTrue) {
if (updatedIsConditionTrue) conditionFulfilled++;
else conditionFulfilled--;
isConditionTrue = updatedIsConditionTrue;
setOK();
}
});
});
setOK();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field " name="username" id="username" placeholder="value = abc" value="" required="required" data-label="Username">
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" class="input-text um-field " name="firstname" id="firstname" placeholder="value != pqr" value="" required="required" data-label="FirstName">
</p>
<p class="form-row " id="radio_SXsPOwVSD_input">
<input type="radio" class="input-radio um-field" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male">Male
<input type="radio" class="input-radio um-field" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
</p>
<div>Result: <b id="iresult">Not OK</b></div>
Removed the Array and used the data attribute instead.
$(document).ready(function(){
$('.validator').delegate('input', 'change', function(event){
event.stopPropagation();
var condition = $(this).closest('.validator').data('condition');
var valueToCompare = $(this).closest('.validator').data('value');
var result = "";
if(condition == "1"){
result = $(this).val().trim() == valueToCompare ? "Condition Satisfied" : "Condition Not Satisfied";
}else{
result = $(this).val().trim() != valueToCompare ? "Condition Satisfied" : "Condition Not Satisfied";
}
console.log(result)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="validator" data-condition="1" data-value="Rony">
<label for="username">First Name</label>
<input type="text" >
</div>
<div class="validator" data-condition="0" data-value="White">
<label for="username">Last name</label>
<input type="text" >
</div>
<div class="validator" data-condition="1" data-value="Male">
<input type="radio" name="gender" value="Male">Male
<input type="radio" name="gender" value="Female">Female
</div>
<div class="validator" data-condition="0" data-value="Banana">
<input type="radio" name="fruit" value="Apple">Apple
<input type="radio" name="fruit" value="Banana">Banana
</div>
To test that every one of a set of conditions is true use Array.prototype.every.
This solution has a function, setRules, which accepts a set of rules in the above format and returns an object with an onChange property to add listeners. These listeners are triggered when any of the values changes and are passed the new boolean value. It would not be hard to keep a current value so that this only fires when it switches from true to false or vice-versa.
You can use it like this:
const ruleHandler = addRules(applyConditions);
ruleHandler.onChange(function(newValue) { /* do something */ }
(or simply chain these together like below.)
This also makes it easy to add new conditions, as they are simple functions that accept the current value and the entire rule (enhanced with a jQuery reference to the element.) You can add a condition like this:
'2': function(val, rule) {return val.length >= rule.minLength;}
And use it like this:
{input: "lastname", condition: "2", minLength: "4"},
This also points out that you could use arbitrary names for these conditions, rather than "0" and "1". Perhaps they could be eq, not_eq, and if you use that last one, minLength.
Most of this is reasonably simple. The only part that I think needs explanation is this:
var newVal = rules.every(function(rule) {
var $elt = (rule.$elt.length > 1) ? rule.$elt.filter(':checked') : rule.$elt;
return (conds[rule.condition] || function() {return true;})($elt.val(), rule);
})
Note first that we start by calling every on our rules.
In the second line we let radio buttons be represented by the :checked element and others by the only element in the $elt object.
The third line is the heart of this code: it finds the correct condition function by looking it up, or if it's not found, chooses a function that simply returns true. Then it calls this function with the value of the element and the rule itself.
var setRules = function(rules) {
var listeners = [];
var conds = {
'0': function(val, rule) {return val === rule.value;},
'1': function(val, rule) {return val !== rule.value;},
}
var test = function() {
var newVal = rules.every(function(rule) {
var $elt = (rule.$elt.length > 1) ? rule.$elt.filter(':checked') : rule.$elt;
return (conds[rule.condition] || function() {return true;})($elt.val(), rule);
})
listeners.forEach(listener => listener(newVal));
}
rules.forEach(function(rule) {
rule.$elt = $('[name=' + rule.input + ']').change(test);
});
return {
onChange: function(listener) {
listeners.push(listener);
test();
}
};
}
var applyConditions = [
{input: "username", condition: "0", value: "abc"},
{input: "firstname", condition: "1", value: "pqr"},
{input: "radio_SXsPOwVSD", condition: "0", value: "Male"}
];
const $results = $('#result');
setRules(applyConditions).onChange(function(newVal) {
$results.html(newVal ? 'OK' : 'Not OK');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" name="username" id="username" value="abc">
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" name="firstname" id="firstname" value="pqr">
</p>
<p id="radio_SXsPOwVSD_input">
<input type="radio" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male" checked>Male
<input type="radio" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
</p>
<div>Result: <b id="result">Not OK</b></div>
Also note that this would be cleaner and more readable if you were using ES6:
const setRules = (rules) => {
const listeners = [];
const conds = {
'0': (val, rule) => val === rule.value,
'1': (val, rule) => val !== rule.value
}
const test = () => {
var newVal = rules.every(function(rule) {
var $elt = (rule.$elt.length > 1) ? rule.$elt.filter(':checked') : rule.$elt;
return (conds[rule.condition] || (() => true))($elt.val(), rule);
})
listeners.forEach(listener => listener(newVal));
}
rules.forEach((rule) => {
rule.$elt = $('[name=' + rule.input + ']').change(test);
});
return {
onChange: (listener) => {
listeners.push(listener);
test();
}
};
}
Related
I have 5 checkboxes, I want to tick 1 checkbox then the other 4 checkboxes will disable to tick, if I untick the 1 checkbox, the other 4 checkboxes will able to tick. Hope someone can guide me on how to solve it based on my below the coding:
<div class="form-group" id="taraf_keselamatan_fail">
<label for="cp1" class="control-label col-lg-4">Taraf Keselamatan Fail:</label>
<div class="col-lg-3">
<input type="checkbox" name="rahsia_besar" id="rahsia_besar" value="1"><b> Rahsia Besar</b></input>
<input type="checkbox" name="rahsia" id="rahsia" value="1"><b> Rahsia</b></input>
<input type="checkbox" name="sulit" id="sulit" value="1"><b> Sulit</b></input> <br>
<input type="checkbox" name="terhad" id="terhad" value="1"><b> Terhad</b></input>
<input type="checkbox" name="terbuka" id="terbuka" value="1"><b> Terbuka</b></input>
</div>
</div>
Now my output result like below the picture can tick all the checkboxes:
My expected result like below the sample picture, just can tick 1 box in the checkbox.
This is my try the coding in the javascript, but it cannot work:
<script>
var form = document.getElementById("checkForm");
form.onclick = delegateFormClick;
addChangeHandlers(form);
function addChangeHandlers(form)
{
for(var i=0;i<form.elements.length;i++)
{
var element = form.elements[i];
if(element.tagName === "INPUT" && element.type === "checkbox")
{
if(!element.onchange)
{
element.onchange = checkBoxChanged;
}
}
}
}
function delegateFormClick(evt)
{
var target;
if(!evt)
{
//Microsoft DOM
target = window.event.srcElement;
}else if(evt)
{
//w3c DOM
target = evt.target;
}
if(target.nodeType === 1 && target.tagName === "INPUT" && target.type === "checkbox")
{
if(target.checked)
{
disableCheckBoxes(target.id, document.getElementById("checkForm"));
}else if(!target.checked)
{
enableCheckBoxes(document.getElementById("checkForm"));
}
}
}
function checkBoxChanged()
{
if(this.checked)
{
disableCheckBoxes(this.id, document.getElementById("checkForm"));
}else if(!this.checked)
{
enableCheckBoxes(document.getElementById("checkForm"));
}
}
function disableCheckBoxes(id, form)
{
var blacklist = [];
if(id)
{
switch(id)
{
case "rahsia_besar":
blacklist = ["rahsia", "sulit","terhad","terbuka"];
break;
case "rahsia":
blacklist = ["rahsia_besar", "sulit","terhad","terbuka"];
break;
case "sulit":
blacklist = ["rahsia_besar", "rahsia","terhad","terbuka"];
break;
case "terhad":
blacklist = ["rahsia_besar", "rahsia","sulit","terbuka"];
break;
case "terbuka":
blacklist = ["rahsia_besar", "rahsia","sulit","terhad"];
break;
}
}else
{
throw new Error("id is needed to hard-wire input blacklist");
}
for(var i=0;i<blacklist.length;i++)
{
var element = document.getElementById(blacklist[i]);
if(element && element.nodeType === 1)
{
//check for element
if(element.tagName === "INPUT" && element.type === "checkbox" && !element.checked)
{
element.disabled = "disabled";
}
}else if(!element || element.nodeType !== 1)
{
throw new Error("input blacklist item does not exist or is not an element");
}
}
}
function enableCheckBoxes(form)
{
for(var i=0;i<form.elements.length;i++)
{
var element = form.elements[i];
if(element.tagName === "INPUT" && element.type === "checkbox" && !element.checked)
{
element.disabled = "";
}
}
}
</script>
The intended behavior does (almost ... see EDIT) not need any form of additional scripting for one gets such a behavior for free with any radio group ...
// scripting is just for proofing the behavior of a radio group/collection
function logCurrentlyCheckedFailValue(evt) {
if (evt.target.type === 'radio') {
console.log(`radio name: ${ evt.target.name }\nradio value: ${ evt.target.value }`);
}
}
function mainInit() {
document
.querySelector('#taraf_keselamatan_fail')
.addEventListener('click', logCurrentlyCheckedFailValue)
}
mainInit();
.as-console-wrapper { max-height: 60%!important; }
<form>
<fieldset class="form-group" id="taraf_keselamatan_fail">
<legend class="control-label col-lg-4">Taraf Keselamatan Fail:</legend>
<div class="col-lg-3">
<label>
<input type="radio" name="taraf_keselamatan_fail" value="rahsia_besar"/>
<b>Rahsia Besar</b>
</label>
<label>
<input type="radio" name="taraf_keselamatan_fail" value="rahsia"/>
<b>Rahsia</b>
</label>
<label>
<input type="radio" name="taraf_keselamatan_fail" value="sulit"/>
<b>Sulit</b>
</label>
<label>
<input type="radio" name="taraf_keselamatan_fail" value="terhad"/>
<b>Terhad</b>
</label>
<label>
<input type="radio" name="taraf_keselamatan_fail" value="terbuka"/>
<b>Terbuka</b>
</label>
</div>
</fieldset>
</form>
EDIT
I want to apologize to the OP because of me not reading the question carefully enough. The OP's use case indeed is distinct from what a radio group actually does offer.
Here we go ...
function setControlStateViaBoundConfig(elm) {
const config = this;
if (elm !== config.ignore) {
elm.checked = config.checked;
elm.disabled = config.disabled;
}
}
function toggleBehaviorOfFailureOptions(evt) {
const targetElement = evt.target;
if (targetElement.type === 'checkbox') {
const isDisableOthers = targetElement.checked;
evt.currentTarget // equals element with `id="taraf_keselamatan_fail"`
.querySelectorAll('[type="checkbox"]')
.forEach(setControlStateViaBoundConfig, {
ignore: targetElement,
checked: false,
disabled: isDisableOthers,
});
}
}
function mainInit() {
document
.querySelector('#taraf_keselamatan_fail')
.addEventListener('click', toggleBehaviorOfFailureOptions)
}
mainInit();
[type="checkbox"]:disabled + b { opacity: .4; }
.as-console-wrapper { max-height: 60%!important; }
<form>
<fieldset class="form-group" id="taraf_keselamatan_fail">
<legend class="control-label col-lg-4">Taraf Keselamatan Fail:</legend>
<div class="col-lg-3">
<label>
<input type="checkbox" name="rahsia_besar" value="1"/>
<b>Rahsia Besar</b>
</label>
<label>
<input type="checkbox" name="rahsia" value="1"/>
<b>Rahsia</b>
</label>
<label>
<input type="checkbox" name="sulit" value="1"/>
<b>Sulit</b>
</label>
<label>
<input type="checkbox" name="terhad" value="1"/>
<b>Terhad</b>
</label>
<label>
<input type="checkbox" name="terbuka" value="1"/>
<b>Terbuka</b>
</label>
</div>
</fieldset>
</form>
I created a Stackblitz from you code extract and it is working, could you please check if this is what you expected as solution ?
I've got the following function that gets all checked checkboxes on my html form with the given element Name. I have a loose understanding that a reduce function can replace the .map and .join sections so was looking for a poke in the right direction of how to implement that and also if there is any other steps I could take to optimise this function?
function getCheckedValuesOf(elmName){
return [...document.getElementsByName(elmName)].filter(box=>box.checked==true).map(box=>box.value).join(", ")
}
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)]
// acc is value returned by previous iteration
// curr is the current iterated element
.reduce((acc, curr) => {
// do nothing on unchecked
if (curr.checked) {
// add a , only if acc is not empty, to prevent useless starting ,
acc += (acc !== "" ? ", " : "") + curr.value
}
// always return acc, or next iteration will have acc === undefined
return acc;
// second argument of reduce is the initial value of acc
// if not set then it default to the first element of the array
// and the iteration starts on the second element
}, '')
}
document.getElementById("log").onclick = () => console.log(getCheckedValuesOf("name"))
console.log(getCheckedValuesOf("name"))
<input type="checkbox" name="name" checked="false" value="i1"/>i1
<input type="checkbox" name="name" value="i2"/>i2
<input type="checkbox" name="name" checked="false" value="i3"/>i3
<input type="checkbox" name="name" value="i4"/>i4
<input type="checkbox" name="name" checked="false" value="i5"/>i5
<input type="checkbox" name="name" value="i6"/>i6
<button id="log">log</button>
Can you try this one? Let me know if it works.
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)].reduce((a, b) => b.checked && b.value && (a.length>0 ? `${a}, ${b.value}`: `${a} ${b.value}`) || a, "");
}
You can do it with reduce only. modified from #akshaybande 's answer to fix the errors (like leading ", " etc.)
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)].reduce((acc, cur) => {
if (cur.checked && cur.value){
return acc.length >= 1 ? `${acc}, ${cur.value}` : `${cur.value}`
}
return acc;
}, "");
}
document.getElementById("log").onclick = () => console.log(getCheckedValuesOf("name"))
console.log(getCheckedValuesOf("name"))
<input type="checkbox" name="name" checked="false" value="1"/>1
<input type="checkbox" name="name" value="2"/>2
<input type="checkbox" name="name" value="3"/>3
<input type="checkbox" name="name" value="4"/>4
<input type="checkbox" name="name" checked="false" value="5"/>5
<input type="checkbox" name="name" value="6"/>6
<button id="log">log</button>
something like this?
function getCheckedValuesOf(elmName) {
return [...document.getElementsByName(elmName)]
.reduce((str, box) => {
if (box.checked == true) {
str += box.value +', '
}
return str;
}, '');
}
document.querySelector('button').onclick = () => {
console.log(getCheckedValuesOf('input'))
}
<input type="checkbox" checked name="input" value="1">
<input type="checkbox" name="input" value="2">
<input type="checkbox" name="input" value="3">
<input type="checkbox" checked name="input" value="4">
<input type="checkbox" name="input" value="5">
<button>click</button>
var labelsarray = document.getElementsByTagName("label");
var inputsarray = document.getElementsByTagName("input");
var array = [];
function agecal() {
var Bdate = inputsarray[4].value;
var Bday = +new Date(Bdate).getFullYear();
var age = (new Date().getFullYear() - Bday);
inputsarray[5].value = age;
}
function subm() {
var users = {
FirstName: inputsarray[0].value,
LastName: inputsarray[1].value,
UserName: inputsarray[2].value,
Password: inputsarray[3].value,
DateofBirth: inputsarray[4].value,
Age: inputsarray[5].value,
Purpose: ""
};
if (inputsarray[6].checked === true) {
users.Gender = "Male";
} else if (inputsarray[7].checked === true) {
users.Gender = "Female";
}
if (inputsarray[8].checked === true) users.Purpose += " Storing Apps";
if (inputsarray[9].checked === true) users.Purpose += " Storing Sites";
if (inputsarray[10].checked === true) users.Purpose += " Fun";
array.push(users);
localStorage.setItem("Users Data: ", JSON.stringify(array));
var item = localStorage.getItem("Users Data: ");
var arrayobjfromls = JSON.parse(item);
for (var i = 0; i < arrayobjfromls.length; i++) {
if (inputsarray[2].value === arrayobjfromls[i].UserName) {
alert("This username is already in use. Please try another.");
localStorage.removeItem(arrayobjfromls[i]);
}
}
}
<div>
<center>
<form action="javascript:void(0);" method="post" onsubmit="subm();">
<label for="fname">First Name:</label>
<input type="text" id="fname" />
<br/>
<label for="lname">Last Name:</label>
<input type="text" id="lname" />
<br/>
<label for="uname">User Name:</label>
<input type="text" id="uname" />
<br/>
<label for="pass">Password:</label>
<input type="password" id="pass" />
<br/>
<label for="dob">Date of Birth:</label>
<input type="date" id="dob" onchange="agecal();" />
<br/>
<label>Age:</label>
<input type="text" id="age" disabled="disabled" />
<br/>
<span>Gender:</span>
<input type="radio" name="gender" id="male" />
<label for="male">Male</label>
<input type="radio" name="gender" id="female" />
<label for="female">Female</label>
<br/>
<p>For what purpose(s) you are making account?</p>
<input type="checkbox" id="app" name="purpose" value="storingapps" />
<label for="app">Storing Apps</label>
<input type="checkbox" id="site" name="purpose" value="storingsites" />
<label for="site">Storing Sites</label>
<input type="checkbox" id="fun" name="purpose" value="fun" />
<label for="fun">Fun</label>
<br/>
<input type="submit" value="Submit" class="button" />
</form>
</center>
</div>
Please help me I want to stop user for using username which already present in my local storage by showing an alert and also I don't want to send data to local storage in which username is same of that data which is already present in my local storage...so that my local storage contain only those objects which have different usernames.
You're already checking for this; you're just doing it after you've already added the new user. Do the check first:
var item = localStorage.getItem("Users Data: ");
var arrayobjfromls = JSON.parse(item);
var found = false;
for (var i = 0; i < arrayobjfromls.length; i++) {
if(users.UserName === arrayobjfromls[i].UserName) {
found = true;
break;
}
}
if ( found ) {
alert("This username is already in use. Please try another.");
} else {
array.push( users );
localStorage.setItem("Users Data: ", JSON.stringify(array));
}
So I have this piece of HTML and JavaScript
function validate() {
const tabs = document.getElementsByClassName("tab");
const input = tabs[currentTab].querySelectorAll("input[type=tel], input[type=text], input[type=time], input[type=number], input[type=email]");
const radio = tabs[currentTab].querySelectorAll("input[type=radio]");
const select = tabs[currentTab].getElementsByTagName("select");
let valid = true;
if (radio.length == 0) {
for (let i = 0; i < input.length; i++) {
if (input[i].value == "") {
valid = false;
break;
}
}
for (let i = 0; i < select.length; i++) {
if (select[i].value == "") {
valid = false;
break;
}
}
} else if (radio[0].name == "phnum" && radio[0].checked) {
if (input[0].value == "" || input[1].value == "") {
valid = false;
}
} else if (radio[1].name == "phnum" && radio[1].checked) {
if (input[0].value == "" || input[1].value == "" || input[2].value == "") {
valid = false;
}
}
if (valid) {
document.getElementById("next").className = "prevNext";
}
}
<span id="radio">
<label for="phnum1" class="radio-container">
<input type="radio" name="phnum" id="phnum1" value="1" onchange="displayPhone(this);">1 Number
<span class="radio"></span>
</label>
<label for="phnum2" class="radio-container">
<input type="radio" name="phnum" id="phnum2" value="2" onchange="displayPhone(this);">2 Numbers
<span class="radio"></span>
</label>
<label for="phnum3" class="radio-container">
<input type="radio" name="phnum" id="phnum3" value="3" onchange="displayPhone(this);">3 Numbers
<span class="radio"></span>
</label>
</span>
</p><br>
<p id="ph1" class="disable">
<label for="phone-number1">Add a Phone Number: </label><input type="tel" name="phone-number1" id="phone-number1" class="input" placeholder="Add A Phone Number" required oninput="validate();">
</p>
<p id="ph2" class="disable">
<label for="phone-number2">Add a Phone Number: </label><input type="tel" name="phone-number2" id="phone-number2" class="input" placeholder="Add A Phone Number" required onchange="validate();">
</p>
<p id="ph3" class="disable">
<label for="phone-number3">Add a Phone Number: </label><input type="tel" name="phone-number3" id="phone-number3" class="input" placeholder="Add A Phone Number" required onchange="validate();">
</p>
that handles the input added by the user to make a button clickable if all necessary data is added. the problem is when i delete inside the input with back arrow key(the one above enter) the button remains active even if the condition for its activation no longer applies.
thank you guys for your time and help i really do appreciate it. :D
One thing I see - you're setting the class name if valid == true via document.getElementById("next").className = "prevNext";.
But nowhere are you removing that class name if valid == false.
That's probably why you aren't seeing the button disappear when you empty out the fields (if I understand your problem correctly).
if (!valid) { document.getElementById("next").className = ""; } is a quick and dirty way to get what you need.
I've been working on this assignment for the longest while. My form validations weren't working previously but then I found out what the error was & everything was working perfectly.
Later on, I had made some changes to the code then deleted those changes and now the validations aren't working again & I can't seem to find what the problem is this time.
Below is my unfinished code:
function validateEmail() {
var email = document.getElementById('email').value;
if( email==null || email=="")
{
alert("Please input an email address");
}
}
function validateFName() {
var firstname = document.getElementById('firstname').value;
if( firstname==null || firstname=="")
{
alert("Please input a last name");
return false;
}
}
function validateLName() {
var lastname = document.getElementById('lastname').value;
if( lastname==null || lastname=="")
{
alert("Please input a last name");
}
}
function validateGender() {
var gender = document.getElementById('gender').value;
if( gender==null || gender=="")
{
alert("Please select a gender");
}
}
function validateDate() {
var date = document.getElementById('date').value;
if( date==null || date=="")
{
alert("Please select a date");
}
}
function validateVName() {
var vname = document.getElementById('vname').value;
if( vname==null || vname=="")
{
alert("Please input a victim's name");
}
}
function validateVEmail() {
var vemail = document.getElementById('vemail').value;
if( vemail==null || vemail=="")
{
alert("Please input a victim's email");
}
}
<div id="navi">
<nav>
<ul class="fancyNav">
<li id="home">Home</li>
<li id="news">TRUTH</li>
<li id="about">DARE</li>
</ul>
</nav>
</div>
<div id="box">
<form id="truth">
<h1> Truth </h1>
<label> First Name: </label> <input type="text" name="firstname" id="firstname" maxlength="30" placeholder="John" /> <br><br>
<label> Last Name: </label> <input type="text" name="lastname" id="lastname" maxlength="30" placeholder="Doe" /> <br><br>
<label> Email:</label> <input type="text" name="email" id="email" /> <br><br>
<label> Male </label><input type="radio" name="gender" id="gender" value="male"/>
<label> Female </label><input type="radio" name="gender" id="gender" value="female"/> <br><br>
<label> Date to be performed: </label><input type="date" name="date" id="date" /><br><br>
<h2> Victim </h2>
<label> Name: </label> <input type="text" name="vname" id="vname" maxlength="30" /><br><br>
<label> Email:</label> <input type="text" name="vemail" id="vemail" /> <br><br>
<h2> Please select a truth questions below </h2> <br>
<input type="radio" name="truth" value="q1"> Have you ever fallen and landed on your head? <br>
<input type="radio" name="truth" value="q2"> Have you ever return too much change? <br>
<input type="radio" name="truth" value="q3"> Have you ever been admitted into the hospital? <br>
<input type="radio" name="truth" value="q4"> Have you ever baked a cake? <br>
<input type="radio" name="truth" value="q5"> Have you ever cheated on test? <br>
<input type="radio" name="truth" value="q6"> Did you ever wish you were never born? <br>
<input type="radio" name="truth" value="q7"> Did you ever hide from Sunday School? <br><br>
<input type="submit" onclick="validateFName(); validateLName(); validateGender(); validateDate(); validateVName(); validateVEmail();" /> <br>
</form>
</div>
<input type="submit" onclick="validateFName(); validateLName(); validateGender(); v
typo in function name, onclick="validateFName()...
it should be validateLName()
and you define duplicate
<!DOCTYPE html>
<html> // remove this one
The best possible solution would be to not use any alert boxes at all but instead embed the error message next to the place of the error, but that would be more involved. Instead, to stick with this solution, first add an id to your submit button:
<button type="submit" id="truth-submit">Submit</button>
Then, attach an onclick handler through JavaScript (and rewrite your code to be more re-usable):
// Only run when the window fully loads
window.addEventListener("load", function() {
function validateEmail() {
var email = document.getElementById("email").value;
if (email === null || email === "") {
return "Please input an email address";
}
return "";
}
function validateFName() {
var firstname = document.getElementById("firstname").value;
if (firstname === null || firstname === "") {
return "Please input an first name";
}
return "";
}
function validateLName() {
var lastname = document.getElementById("lastname").value;
if (lastname === null || lastname === "") {
return "Please input an last name";
}
return "";
}
function validateGender() {
var gender = document.getElementById("gender").value;
if (gender === null || gender === "") {
return "Please select a gender";
}
return "";
}
function validateDate() {
var date = document.getElementById("date").value;
if (date === null || date === "") {
return "Please select a date";
}
return "";
}
function validateVName() {
var vname = document.getElementById("vname").value;
if (vname === null || vname === "") {
return "Please input a victim's name";
}
return "";
}
function validateVEmail() {
var vemail = document.getElementById("vemail").value;
if (vemail === null || vemail === "") {
return "Please input a victim's email";
}
return "";
}
document.getElementById("truth-submit").addEventListener("click", function(event) {
// Grab all of the validation messages
var validationMessages = [validateFName(), validateLName(),
validateGender(), validateDate(), validateVName(), validateVEmail()];
var error = false;
// Print out the non-blank ones
validationMessages.forEach(function(message) {
if (message) {
alert(message);
error = true;
}
});
// Stop submission of the form if an error occurred
if (error) {
event.preventDefault();
}
}, false);
}, false);