SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Enthusiast
    Join Date
    Nov 2007
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    validate a list of radio buttons w/different names

    Making a php page.
    It creates a list of questions, and each of them has a yes/no to them.

    Now...
    When my php script recieves the submited page, i need to be able to get the id of the question. Thats why its in the "name" field. So I know which question holdes what value. (then its simple to create a prepared sql update statement with "update question set answear=? where userid = ? and question = ?" ... something like that).

    Now i want to create a js to validate. All radios must be checked.

    I've searched the web, and every examples are in the same way. The name of the radio buttons MUST have same name, so they can be grouped like an array and then you can loop through em.

    ...but my names are unequal... and i need the names since they are passed to the php page.

    I can't get my head around this (and ye, im inexperienced js coder).

    PS: looking for a js solution, not a php solution since I might want to know about how to solve this in other languages.

    Code HTML4Strict:
    <form name="input" action="#" method="get" >
    Blablabla about question 1 -<input type="radio" name="question.1233443" value="Yes" /><input type="radio" name="question.1233443" value="No" /><br>
    Blablabla about question 2 -<input type="radio" name="question.5224562" value="Yes" /><input type="radio" name="question.5224562" value="No" /><br>
    Blablabla about question 3 -<input type="radio" name="question.9975743" value="Yes" /><input type="radio" name="question.9975743" value="No" /><br>
    <input type ="button" value ="Submit" onClick="validate()"/>
    </form>

    Code JavaScript:
    function validate()
    {	
    	alert('validated');	
    	return true;
    }

  2. #2
    SitePoint Wizard
    Join Date
    Dec 2003
    Location
    USA
    Posts
    2,582
    Mentioned
    29 Post(s)
    Tagged
    0 Thread(s)
    Well, first off, it sounds like check boxes may serve you better than radios. Radios are for groups are values where only one can be selected (which is why they should have a matching name).

    So, we'll assume you're using check boxes (theoretically this will be the same even if you keep radios).

    We have several choices. Probably the easiest would be to give the form a name. Then, we can get all of the inputs that are contained within this form. (You can also use form[0], but that's kind of ugly and can be inflexible in many cases). So, we'll just give our form the id of "form".

    Code:
    // Holds the form
    var form = document.getElementById("form");
    Then, we want to get all of it's children which have the tag name of input "input".

    Code:
    var children = form.getElementsByTagName("input");
    Then, we'll go through all of them. We'll make sure they are a checkbox (or radio if you really want to use them), so we don't try to validate our submit.

    Code:
    for(var i=0; i < children.length; i++)
        if(children[i].type == "checkbox")
            if(children[i].checked != true) {
                 // error stuff goes here
                 return false;
            }
    return true;
    And that's it. If you wanted to use radios, you would change the if(children[i].checked != true) to if(!children[i].match(/^.+$/)). That is a regex expression which checks to see if it has any value at all. If it does, then it would be selected (in your case).

    You can combine all of that code into one function to get your function validate(). You don't actually have to put the form in a variable, you can just use this for children:
    document.getElementById("form").getElementsByTagName("input")

    Also, instead of statically setting the form name, you could pass that as a variable to the function.

    Also, it's onclick, not onClick if you are using XHTML 1.0

    Hope that helps.

  3. #3
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    You can't have single radio buttons like that. There need to be at least two buttons with the same name when you use radio buttons. A single radio button is effectively always selected since there is no second button to select in order to deselect the first.

    Checkboxes are what you are looking for to do what is wanted. If you give each field both a name and an id then you can use the name to reference it server side and the id to reference it from JavaScript.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  4. #4
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Now i want to create a js to validate. All radios must be checked.
    It seems to have gone unnoticed that your radio buttons are indeed in pairs.
    I don't think the . character is valid in names so I changed it to _ for this example.
    Code:
    <form name="input" action="#" method="get" >
    Blablabla about question 1 -<input type="radio" name="question_1233443" value="Yes" /><input type="radio" name="question_1233443" value="No" /><br>
    Blablabla about question 2 -<input type="radio" name="question_5224562" value="Yes" /><input type="radio" name="question_5224562" value="No" /><br>
    Blablabla about question 3 -<input type="radio" name="question_9975743" value="Yes" /><input type="radio" name="question_9975743" value="No" /><br>
    <input type ="button" value ="Submit" onclick="if(!validate([question_1233443, question_5224562, question_9975743]))alert('All buttons must be checked')">
    </form>
    <script type='text/javascript'>
    
    function validate(range)
    {
     for( var i=0, count=0, len=range.length; i<len; i++ )
      for( var j=0, found=false, bLen = range[i].length; j<bLen && !found; j++)
       if(range[i][j].checked) 
        {
         count++;
         found=true;
        }
        
     return count==range.length;   
    }
    </script>
    The function expects an array of radio button groups each of at least two buttons, and checks that one from each group is checked.
    Tab-indentation is a crime against humanity.

  5. #5
    SitePoint Enthusiast
    Join Date
    Nov 2007
    Posts
    74
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, first off, it sounds like check boxes may serve you better than radios. Radios are for groups are values where only one can be selected (which is why they should have a matching name).
    Ehm... the html clearly lists up several questions with yes/no options ... how and when does checkbox gets usefull in that?? check both yes and no??
    So if I want only 1 answear to be checked, then I use radio button. I appreciate the help, but making assumptions like that actually isn't helpfull always...

    Except from that a nice post samanime, and it indeed works.
    Get the form by id, then getElementsByTagName returns a collection of html objects it seems. Then we just loop through everything. Was hoping is was possible to do something like that.

    You can't have single radio buttons like that. There need to be at least two buttons with the same name when you use radio buttons. A single radio button is effectively always selected since there is no second button to select in order to deselect the first.
    True... which my code does i belive?

    Checkboxes are what you are looking for to do what is wanted. If you give each field both a name and an id then you can use the name to reference it server side and the id to reference it from JavaScript.
    Why checkboxes?? Do I want them to press both yes and no on each question?? Nooo....

    Except form that, nice idea on using both id(for js ref), and name(for server).

    ---
    But then problems hit my face:

    As I started to puzzle with the code, it just bogged me down. Let me explain a bit more, since it might clarify for you what im attempting here.

    Each user is presented with a list of questions which they have to answear either yes or no, on each question.
    The database actually holds 3 values (yes, no, not answeard). In this way my app know if the user have answeared the question at all.
    But the user is never ever given the opportunity to answear "not answeared". Either yes or no.
    They can either cancel the process, which then means we store nothing in DB, and DB holds "no answears" - or the choice is "proceede", which require the user to give an answear on each questions.

    The logic needed to be updated, and i have to say - javascript sucks big time, and array especially.

    Why can't you do this:
    Code JavaScript:
    var myarray = [];
    for(var i=0; i<children.lenght; i++)
    {
    myarray.push( children[i].name);
    }
    When iterating over myarray, it just contain rubbish.
    Even .getAttribute("name") is rubbish. Yes you get the name, but you cant use it like this:
    document.getElementById(myarray[0]);
    gawd...

    After 8 hours i found this to help me figure out what objects and methods that was usefull. Cause the web is full of rubbish on js i have to say.
    http://krook.org/jsdom/overview-summary.html

    Solution:
    Logic Ali has a solution that is painfully to code in php. I have to be sure that the form is passing the variables, and that just becomes more tedious, but he put me on the track.
    Skip the strings, just handle the objects itself.

    First we loop through elements that is of type radio and put them in a new array called radio.

    We create a new array that holds elements where name attribute is unequal to everyone.
    Then we loop through radio array, and take one element out each time. If the name does not exist in radiogrp array, we add it. If it exist, then we check if the new one is checked and replace it.
    The goal is to have the checked radio buttons in the radiogrp array.

    Then we loop through radiogrp array, and if everyone is checked then its validated.

    weeee
    Complete page and all. Yes i could put more html code on and stuff (especially mark up the yes/no columns which the radio buttons is ment to be).
    The code is fresh from editor, so im not sure if its bug free. It might be done better, but i need a small break first.
    There is a addTxt() function for "debug" so you don't need to litter it with alerts hehe.

    Thx for help.
    Code JavaScript:
    <!DOCTYPE html 
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset="" />
    	<title>Questions</title>
    </head>
    <body>
     
    <form id="myform" name="myform" action="#" method="get" >
    Blablabla about question 1 -<input type="radio" name="question.1233443" value="Yes" /><input type="radio" name="question.1233443" value="No" /><br>
    Blablabla about question 2 -<input type="radio" name="question.5224562" value="Yes" /><input type="radio" name="question.5224562" value="No" /><br>
    Blablabla about question 3 -<input type="radio" name="question.9975743" value="Yes" /><input type="radio" name="question.9975743" value="No" /><br>
    <input type ="button" value ="Submit" onClick="validate()"/>
    </form> 
     
    <div id='my_div'>
    Test
    </div>
     
    </body>
    <script type="text/javascript">
     
    function validate()
    {	
    	var form = document.getElementById("myform");
    	var children = form.getElementsByTagName("input");
     
    	var radio = [];		
    	for(var i=0; i < children.length; i++)
    	{		
    		if(children[i].type == "radio")
    		{						
    			radio.push(children[i]);		
    		}
    	}
     
    	if( radio.length == 0 )
    	{		
    		return true;
    	}
     
    	var radioGrps = [];	
    	radioGrps.push( radio.shift() );
    	var len = radio.length;
    	for(var i=0; i < len; i++)
    	{		
    		var item = radio.shift();
     
    		var loc = find( radioGrps, item.name );
    		if( loc == -1 )
    		{			
    			radioGrps.push(item);
    		}
    		else
    		{			
    			if( item.checked == true )
    			{				
    				radioGrps[loc] = item;
    			}			
    		}	
    	}
     
    	var test = true;
    	for( var y=0; y < radioGrps.length; y++ )
    	{				
    		if(radioGrps[y].checked == false && test == true)
    		{			
    			test = false;	             
    		}			
    	}
     
     
    	if( test )
    	{		
    		addTxt('validated');
    		return true;
    	}
    	else
    	{		
    		addTxt('not validated');
    		return false;
    	}
     
    	return true;
     
    }
     
    function find( arr, name )
    {
    	for(var i=0; i<arr.length; i++)
    	{
    		if(arr[i].name == name )
    			return i;
    	}
    	return -1;
    }
     
    function addTxt( str )
    {
    	document.getElementById('my_div').innerHTML += '<br />' + str;
    }
    </script>
    </html>

    PS: The code is ment to be general as possible, easily editabel/changeable, and small as possible.
    Tested on IE7, Latest FF, Latest Opera. (not tested on ie6...).

  6. #6
    SitePoint Wizard
    Join Date
    Dec 2003
    Location
    USA
    Posts
    2,582
    Mentioned
    29 Post(s)
    Tagged
    0 Thread(s)
    Sorry, I completely missed that you had pairs in there. I didn't notice the two inputs in the same line and though you were trying to have just one radio button per choice, which sounded really odd.

    Glad you could get it working.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •