Logic for multiple and single select/combo boxes - javascript

Below is my code:
<%#taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%>
<%#taglib uri="/WEB-INF/struts-html.tld" prefix="html"%>
<script type="text/javascript">
var flag = false;
function test(selObject)
{
alert("hi");
var form = document.forms[0];
alert("form"+form);
var txtS = form["city"];
alert("txt"+txtS);
var len = txtS.length;
alert("len"+len);
for(var i=0; i<len; i++)
{
if (selObject == txtS[i] )
{
if(txtS[i].value==txtS[i].options[3].value)
{
alert("YOU ARE SELECTING MYSORE CITY");
flag = true;
}
if(!txtS[i].options[3].selected && flag)
{
var result = confirm("Are you sure you wnat to travel to this city");
if(result)
{
flag = false;
}
else
{
txtS[i].options[txtS[i].options.selectedIndex].selected=false;
txtS[i].options[4].selected=true;
}
}
}
}//end of for loop
}
</script>
<html:form action="/login">
username:<input type="text" name="username" /></br>
password:<input type="password" name="password"/></br>
<%
for(int i = 0; i < 10; i++){
%>
<html:select property="city" onchange="javascript:test(this);">
<html:option value="B">BANGALORE</html:option>
<html:option value="C">CHENNAI</html:option>
<html:option value="M">MANGALORE</html:option>
<html:option value="MR">MYSORE</html:option>
</html:select></br>
<%
}
%>
<input type="submit" value="submit"/>
</html:form>
When select-box or combo-box is looped for ten times then I am getting form["city"] length as 10 properly and behaviour of alerts within combox-box is appropriate, but if I have a single-select-box, then instead of giving form["city"] length as 1 it gives it as 4 which is the number of option elements in my dropdown-box.
So my logic doesn't work here.
How do I make it work for both single as well as multiple combo/select boxes.
Any help would be appreciated.

Please use a javascript library like jQuery for cross-browser compatibility.
You can use the following code to determine that only a single select element is present or multiple select elements with the same name are present:
if (selObject == txtS) {
alert("Single select");
// ... your logic for a single combo-box follows after this
} else {
// your logic for multiple combo-box follows, like the "for" loop and if-else
}
When there is only one select box the line var txtS = form["city"]; will return an array of option elements within that select box and when more than one select box with the same name it returns an array of the select boxes.
Hope this helps.
Not related to your question, but this logic if(!txtS[i].options[3].selected && flag) will always return false.

Related

Validating a checkbox after already validating other sections of a form [duplicate]

I have a form with multiple checkboxes and I want to use JavaScript to make sure at least one is checked. This is what I have right now but no matter what is chosen an alert pops up.
JS (wrong)
function valthis(){
if (document.FC.c1.checked) {
alert ("thank you for checking a checkbox")
} else {
alert ("please check a checkbox")
}
}
HTML
<p>Please select at least one Checkbox</p>
<br>
<br>
<form name = "FC">
<input type = "checkbox" name = "c1" value = "c1"/> C1
<br>
<input type = "checkbox" name = "c1" value = "c2"/> C2
<br>
<input type = "checkbox" name = "c1" value = "c3"/> C3
<br>
<input type = "checkbox" name = "c1" value = "c4"/> C4
<br>
</form>
<br>
<br>
<input type = "button" value = "Edit and Report" onClick = "valthisform();">
So what I ended up doing in JS was this:
function valthisform(){
var chkd = document.FC.c1.checked || document.FC.c2.checked||document.FC.c3.checked|| document.FC.c4.checked
if (chkd == true){
} else {
alert ("please check a checkbox")
}
}
I decided to drop the "Thank you" part to fit in with the rest of the assignment. Thank you so much, every ones advice really helped out.
You should avoid having two checkboxes with the same name if you plan to reference them like document.FC.c1. If you have multiple checkboxes named c1 how will the browser know which you are referring to?
Here's a non-jQuery solution to check if any checkboxes on the page are checked.
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
var checkedOne = Array.prototype.slice.call(checkboxes).some(x => x.checked);
You need the Array.prototype.slice.call part to convert the NodeList returned by document.querySelectorAll into an array that you can call some on.
This should work:
function valthisform()
{
var checkboxs=document.getElementsByName("c1");
var okay=false;
for(var i=0,l=checkboxs.length;i<l;i++)
{
if(checkboxs[i].checked)
{
okay=true;
break;
}
}
if(okay)alert("Thank you for checking a checkbox");
else alert("Please check a checkbox");
}
If you have a question about the code, just comment.
I use l=checkboxs.length to improve the performance. See http://www.erichynds.com/javascript/javascript-loop-performance-caching-the-length-property-of-an-array/
I would opt for a more functional approach. Since ES6 we have been given such nice tools to solve our problems, so why not use them.
Let's begin with giving the checkboxes a class so we can round them up very nicely.
I prefer to use a class instead of input[type="checkbox"] because now the solution is more generic and can be used also when you have more groups of checkboxes in your document.
HTML
<input type="checkbox" class="checkbox" value=ck1 /> ck1<br />
<input type="checkbox" class="checkbox" value=ck2 /> ck2<br />
JavaScript
function atLeastOneCheckboxIsChecked(){
const checkboxes = Array.from(document.querySelectorAll(".checkbox"));
return checkboxes.reduce((acc, curr) => acc || curr.checked, false);
}
When called, the function will return false if no checkbox has been checked and true if one or both is.
It works as follows, the reducer function has two arguments, the accumulator (acc) and the current value (curr). For every iteration over the array, the reducer will return true if either the accumulator or the current value is true.
the return value of the previous iteration is the accumulator of the current iteration, therefore, if it ever is true, it will stay true until the end.
Check this.
You can't access form inputs via their name. Use document.getElements methods instead.
Vanilla JS:
var checkboxes = document.getElementsByClassName('activityCheckbox'); // puts all your checkboxes in a variable
function activitiesReset() {
var checkboxesChecked = function () { // if a checkbox is checked, function ends and returns true. If all checkboxes have been iterated through (which means they are all unchecked), returns false.
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
return true;
}
}
return false;
}
error[2].style.display = 'none'; // an array item specific to my project - it's a red label which says 'Please check a checkbox!'. Here its display is set to none, so the initial non-error label is visible instead.
if (submitCounter > 0 && checkboxesChecked() === false) { // if a form submit has been attempted, and if all checkboxes are unchecked
error[2].style.display = 'block'; // red error label is now visible.
}
}
for (var i=0; i<checkboxes.length; i++) { // whenever a checkbox is checked or unchecked, activitiesReset runs.
checkboxes[i].addEventListener('change', activitiesReset);
}
Explanation:
Once a form submit has been attempted, this will update your checkbox section's label to notify the user to check a checkbox if he/she hasn't yet. If no checkboxes are checked, a hidden 'error' label is revealed prompting the user to 'Please check a checkbox!'. If the user checks at least one checkbox, the red label is instantaneously hidden again, revealing the original label. If the user again un-checks all checkboxes, the red label returns in real-time. This is made possible by JavaScript's onchange event (written as .addEventListener('change', function(){});
You can check that atleast one checkbox is checked or not using this simple code. You can also drop your message.
Reference Link
<label class="control-label col-sm-4">Check Box 2</label>
<input type="checkbox" name="checkbox2" id="checkbox2" value=ck1 /> ck1<br />
<input type="checkbox" name="checkbox2" id="checkbox2" value=ck2 /> ck2<br />
<script>
function checkFormData() {
if (!$('input[name=checkbox2]:checked').length > 0) {
document.getElementById("errMessage").innerHTML = "Check Box 2 can not be null";
return false;
}
alert("Success");
return true;
}
</script>
< script type = "text/javascript" src = "js/jquery-1.6.4.min.js" > < / script >
< script type = "text/javascript" >
function checkSelectedAtleastOne(clsName) {
if (selectedValue == "select")
return false;
var i = 0;
$("." + clsName).each(function () {
if ($(this).is(':checked')) {
i = 1;
}
});
if (i == 0) {
alert("Please select atleast one users");
return false;
} else if (i == 1) {
return true;
}
return true;
}
$(document).ready(function () {
$('#chkSearchAll').click(function () {
var checked = $(this).is(':checked');
$('.clsChkSearch').each(function () {
var checkBox = $(this);
if (checked) {
checkBox.prop('checked', true);
} else {
checkBox.prop('checked', false);
}
});
});
//for select and deselect 'select all' check box when clicking individual check boxes
$(".clsChkSearch").click(function () {
var i = 0;
$(".clsChkSearch").each(function () {
if ($(this).is(':checked')) {}
else {
i = 1; //unchecked
}
});
if (i == 0) {
$("#chkSearchAll").attr("checked", true)
} else if (i == 1) {
$("#chkSearchAll").attr("checked", false)
}
});
});
< / script >
Prevent user from deselecting last checked checkbox.
jQuery (original answer).
$('input[type="checkbox"][name="chkBx"]').on('change',function(){
var getArrVal = $('input[type="checkbox"][name="chkBx"]:checked').map(function(){
return this.value;
}).toArray();
if(getArrVal.length){
//execute the code
$('#msg').html(getArrVal.toString());
} else {
$(this).prop("checked",true);
$('#msg').html("At least one value must be checked!");
return false;
}
});
UPDATED ANSWER 2019-05-31
Plain JS
let i,
el = document.querySelectorAll('input[type="checkbox"][name="chkBx"]'),
msg = document.getElementById('msg'),
onChange = function(ev){
ev.preventDefault();
let _this = this,
arrVal = Array.prototype.slice.call(
document.querySelectorAll('input[type="checkbox"][name="chkBx"]:checked'))
.map(function(cur){return cur.value});
if(arrVal.length){
msg.innerHTML = JSON.stringify(arrVal);
} else {
_this.checked=true;
msg.innerHTML = "At least one value must be checked!";
}
};
for(i=el.length;i--;){el[i].addEventListener('change',onChange,false);}
<label><input type="checkbox" name="chkBx" value="value1" checked> Value1</label>
<label><input type="checkbox" name="chkBx" value="value2"> Value2</label>
<label><input type="checkbox" name="chkBx" value="value3"> Value3</label>
<div id="msg"></div>
$('input:checkbox[type=checkbox]').on('change',function(){
if($('input:checkbox[type=checkbox]').is(":checked") == true){
$('.removedisable').removeClass('disabled');
}else{
$('.removedisable').addClass('disabled');
});
if(($("#checkboxid1").is(":checked")) || ($("#checkboxid2").is(":checked"))
|| ($("#checkboxid3").is(":checked"))) {
//Your Code here
}
You can use this code to verify that checkbox is checked at least one.
Thanks!!

Getting the input tag(s) and setting them as unchecked

I want to write a java script function which will get the input tag(s) with type as "checkbox" from the td and mark them unchecked. Following is the jsp code:
<td id="uncheckedByDefault" align=center class=listTypeOne>
<% if (priv.getViewPrivilege() == 1) { %>
<input name="view" type="checkbox" value='<%= priv.getAttributeId() %>' checked>
<% } else { %>
<input name="view" type="checkbox" value='<%= priv.getAttributeId()%>'>
<% } %>
</td>
Now here the td has the id="uncheckedByDefault". I want to get all the input tag(s) and set them as unchecked. Can anybody tell how can I do that. Thanks in advance.
Try:
inputs = document.getElementById('uncheckedByDefault').getElementsByTagName('input');
for (index = 0; index < inputs.length; ++index) {
// deal with inputs[index] element.
inputs[index].checked=false;
}
Here is the function you need, call it whenever you want:
function uncheckAll(){
var inputsContainer = document.getElementById('uncheckedByDefault');
var allInputs = inputsContainer.getElementsByTagName('input');
var len = allInputs.length;
for(var i=0; i<len; i++){
if(allInputs[i].type == 'checkbox'){
allInputs[i].checked = false;
}
}
}
I don't know if I understood your problem, but I will give it a try.
First of all, you can print elements into your web page with a <% ... %> (I will show how in my answer), so you don't have to set a condition into <% ... %>, print an element... etc. All in the same Java function.
Secondly, you can access to your Object properties without calling your getters. Aren't needed at all if you want to set his value into an specific field. (i.e.) <input type="text" name="clientName" value="${client.clientName}" />
Here is my proposal for your question:
<td id="uncheckedByDefault" align=center class=listTypeOne>
<%
if (priv.getViewPrivilege() == 1) {
out.println("<input name='view' type='checkbox' +
value=" + priv.getAttributeId() + " checked = 'checked'>");
} else {
out.println("<input name='view' type='checkbox' +
value=" + priv.getAttributeId() + ">");
}
%>
</td>
Report if it worked or it's not what you wanted.
UPDATE
If you want them all unchecked, because of your element id attribute suggests it. Why do you want to check your Object properties to set it checked or not? Just add your element and don't set it a checked property.
<input name='view' type='checkbox' value="${priv.attributeId}">
This should work
var allInputs = document.getElementById("uncheckedByDefault").getElementsByTagName("input");
for (i = 0; i < allInputs.length; i++) {
if (allInputs[i].getAttribute("type") == 'checkbox') {
allInputs[i].removeAttribute("checked");
}
}
You just need to get a list of all of the elements you're interested in, then you need to perform some action on them. I've added the forEachNode function, since the querySelectorAll function doesn't actually return an array - it returns a nodeList which has similar syntax and functionality as an array, but omits the forEach function.
Note: a checkbox is checked if it has the attribute checked. The actual value of the attribute is not used - it's just it's presence or lack thereof that dictates the check-state. As such, you could write anything rather than 0 to the checked attribute.
EDIT: The above note is incorrect. Both the 'checked' attribute as visible in the html and the 'checked' member variable control the state. I've updated the uncheck and check functions.
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
window.addEventListener('load', mInit, false);
function mInit()
{
}
/*
func to be called takes 3 variables. currentElement, currentIndex, nodeList the element belongs to.
*/
function forEachNode(nodeList, func)
{
var i, n = nodeList.length;
for (i=0; i<n; i++)
{
func(nodeList[i], i, nodeList);
}
}
/*
function uncheck(elem)
{
elem.removeAttribute('checked');
}
function check(elem)
{
elem.setAttribute('checked',0);
}
*/
function uncheck(elem)
{
elem.checked = false;
elem.removeAttribute('checked');
}
function check(elem)
{
elem.checked = true;
elem.setAttribute('checked',0);
}
function checkAll()
{
var checkBoxElements = document.querySelectorAll('input[type=checkbox]');
forEachNode(checkBoxElements, check);
}
function uncheckAll()
{
var checkBoxElements = document.querySelectorAll('input[type=checkbox]');
forEachNode(checkBoxElements, uncheck);
}
</script>
<style>
</style>
</head>
<body>
<button onclick='uncheckAll()'>Uncheck all</button>
<button onclick='checkAll()'>Check all</button>
<br>
<input type='checkbox'/>CB 1
<br>
<input type='checkbox'/>CB 2
<br>
<input type='checkbox'/>CB 3
<br>
<input type='checkbox'/>CB 4
<br>
<input type='checkbox'/>CB 5
<br>
</body>
</html>

validate a dynamicnumber of checkboxes using javascript

I have some ASP code which presents any where from 1-any number of checkboxes (which are named the same) on the page. This validation does work however I think its a bit weak:
if (document.getElementById('selectedDocs').checked)
{
//this is here to handle the situation where there is only one checkbox being displayed
}
else
{
var checked = false;
var field = myForm.selectedDocs;
for(var j = 0; j < field.length; j++)
{
if(field[j].checked == true)
{
checked = true;
break;
}
}
if(!checked)
{
alert("You have not ticked any options. At least one must be selected to proceed!")
return false;
}
}
I was working with the code in the else block but this only works when there is more than one checkbox. It ignores the fact I have ticked the one single option when there is only one. So I placed the code inside the if section......Although it woks its a bit of a hack, can someone kindly improve it for me?
Thanking you...
Use:
var field = myForm.getElementsByName('selectedDocs');
This always returns a NodeList that you can iterate over.
If they are in a form and all have the same name, they can be accessed as a collection that is a property of the form. So given:
<form id="f0" ...>
<input type="checkbox" name="cb0" ...>
<input type="checkbox" name="cb0" ...>
<input type="checkbox" name="cb0" ...>
...
</form>
All the following return a reference to the form:
var form = document.getElementById('f0');
var form = document.forms['f0'];
var form = document.forms[0]; // if first form in document
and and all the following return a collection of the checkboxes named "cb0":
var checkboxes = form.cb0
var checkboxes = form['cb0'];
var checkboxes = form.elements.['cb0'];

Simple JavaScript check not working?

I have this validate form function:
function ValidateForm() {
var chks = document.register.elements['sendto[]'];
var hasChecked = false;
for (var i=0;i<chks.length;i++){
if (chks[i].checked){
hasChecked = true;
break;
}
}
if (!hasChecked){
alert("Please select at least one friend.");
chks[0].focus();
return false;
}
}
html for this is:
<input type="checkbox" name="sendto[]" value="2" >
I know this is not full code. Full code is huge. But basically if i have only one checkbox in the code the above code gives a message undefined on ValidateForm(). Which is called when form is submitted and and above checkbox is checked.
But if i have two checkboxes in the code like this:
<input type="checkbox" name="sendto[]" value="2" >
<input type="checkbox" name="sendto[]" value="4" >
On submit when ValidateForm() function is called this works correctly. Am i doing something wrong that it is not working for 1 checkbox even if it is checked?
The statement
var chks = document.register.elements['sendto[]'];
gets the element (element*s*, if there are more then one) with namesendto[]
If there is only one element with name sendto[] then you have the reference of that element in chks.
If there are more than one element with name sendto[], then chks holds the reference to the array of those elements.
When you do this:
for (var i=0;i<chks.length;i++){
You try to loop based on chks.length. If chks is an array (see above: when there are multiple elements by name sendto[]), then chks.length will hold the number of elements in the array.
If there is only one sendto[] element, then chks will hold that element and since the element (<input type="checkbox" name="sendto[]" value="2" >) does not have a property called length, the browser says length is indefined
So you have o differentiate between two scenarios, when there is only one sendto[] checkbox and when there are more than one.:
var chks = document.register.elements['sendto[]'];
var hasChecked = false;
//Check whether there is one checkbox or whether there are more
if(chks.length)
{
for (var i=0;i<chks.length;i++)
{
if (chks[i].checked)
{
hasChecked = true;
break;
}
}
}
else
{
if(chks.checked)
{
haschecked = true;
}
}
PS:
code gives a message undefined on ValidateForm() does not convey much. Even for you it is not clear what this means right (That's why you have asked this question). Try to give more details. Any modern browser will give more details on the undefined, the what is undefined which line etc. Even pre-historic browsers will tell you the line number where the undefined error was thrown. With those details you can try to find the line and try to see what is happening. You most likely will find out. If you don't, post it to the community here with all these details.
<script language="javascript">
function validate() {
var chks = document.getElementsByName('sendto[]');
var hasChecked = false;
for (var i = 0; i < chks.length; i++) {
if (chks[i].checked) {
hasChecked = true;
break;
}
}
if (hasChecked == false) {
alert("Please select at least one friend.");
return false;
}
return true;
}
</script>
Here is how I would do it.
if(!validate()){
alert("Please select at least one.");
return false;
}
function validate(){
var els=document.getElementsByName('sendto[]');
for(var i=0;i<els.length;i++){
if(els[i].checked){
return true;
}
}
return false;
}
You could use validate as an anonymous function.

Multiple select validation

I have a form in HTML, that has several select elements, what is the best way to make validation for them in such way that no two select elements can have same value, validation function should fire on select, so it can check are there any selects with the same option value if yes then alert something, can I get a explanation how to write this in javascript?
Thank you
here is a bit of HTML code I want to validate :
<form name="forma" action="" method="POST">
<select name="sel1">
<option>Please select</option>
<option>brand1</option>
<option>brand2</option>
<option>brand3</option>
</select>
<select name="sel2">
<option>Please select</option>
<option>brand1</option>
<option>brand2</option>
<option>brand3</option>
</select>
<select name="sel3">
<option>Please select</option>
<option>brand1</option>
<option>brand2</option>
<option>brand3</option>
</select>
</form>
Here is the solution slightly adjusted but this is it:
var selectTest = function () {
var i, j;
sels = [document.getElementById("sel1"), document.getElementById("sel2"), document.getElementById("sel3")];
for (i = 0; i < sels.length; i += 1) {
for (j = i + 1; j < sels.length; j += 1) {
if(sels[i].value != "Please select")
{
if (sels[i].value === sels[j].value) {
alert("Selected values must be different");
return;
}
}
}
}
};
Special tnx to austin cheney, thanks to everyone who posted and participated.
First, don't use the name attribute as a reference point for script. Name refers to an array of named elements in the DOM, which is typically useless in the global DOM outside of form controls. When using the name array it is difficult to tell child nodes apart from child nodes of a same named element. Use the id attribute for use with script, which is a unique identifier instead.
var selTest = function () {
var i, j, error = document.getElementById("error"),
sels = [document.getElementById("sel1"), document.getElementById("sel2"), sel3 = document.getElementById("sel3")];
for (i = 0; i < sels.length; i += 1) {
for (j = i + 1; j < sels.length; j += 1) {
if (sels[i].value === sels[j].value) {
error.display = "block";
sels[i].backgroundColor = "#f00";
sels[j].backgroundColor = "#f00";
return false;
}
}
}
};
EDIT: changed return; to return false; for use with an onsubmit event.
Simply add the id attribute value of the select lists to the "sels" array in the code above. The above code will make a hidden element with an id of "error" appear if the test results in a true condition. It will also change the background color of the offended select lists to red.
I would generally recommend using jQuery for this as it simplifies it quite a bit. You'd want to do something along these lines.
function hasDuplicates() {
var dupe = false;
$("select option:selected").each(function(i) {
var id = $(this).parent().attr("id");
var value = $(this).attr("value");
$("select option:selected").each(function(c) {
if ($(this).parent().attr("id") != id && $(this).attr("value") == value) {
alert("Duplicate");
dupe = true;
return false;
}
});
if (dupe) {
return false;
}
});
return dupe;
}
This will cycle through all the select boxes on the page and compare each one to every other one. If there's a duplicate value it will popup an alert and return true.
For it to fire when a change to a select box is made you'd want to add onchange events to each as shown below. Each select will need a unique id to be set, although you could change the calls to attr("id") to attr("name") if you don't want to add ID's.
<select onchange="hasDuplicates()">...
Performance wise it may make sense to store the values in an array, as this solution hits the DOM quite a lot by having a nested loop.
Give onchange="validate('1')" onchange="validate('2')" onchange="validate('3')" for each selecte statement.
function validate(x){
if(x==1)
{
var selectedvalue=document.forma.sel1.options[document.forma.sel1.selectedIndex].value
if(selectedvalue==document.forma.sel2.options[document.forma.sel2.selectedIndex].value ||
selectedvalue==document.forma.sel3.options[document.forma.sel3.selectedIndex].value)
alert("No two values cannot be same");
}
esle if(x==2)
{
var selectedvalue=document.forma.sel2.options[document.forma.sel2.selectedIndex].value
if(selectedvalue==document.forma.sel1.options[document.forma.sel1.selectedIndex].value ||
selectedvalue==document.forma.sel3.options[document.forma.sel3.selectedIndex].value)
alert("No two values cannot be same");
}
else if(x==3)
{
var selectedvalue=document.forma.sel3.options[document.forma.sel3.selectedIndex].value
if(selectedvalue==document.forma.sel1.options[document.forma.sel1.selectedIndex].value ||
selectedvalue==document.forma.sel1.options[document.forma.sel1.selectedIndex].value)
alert("No two values cannot be same");
}
}

Categories

Resources