Link to home
Start Free TrialLog in
Avatar of jldalot
jldalot

asked on

validate radio buttons

(This is my first post, so let me know if I'm doing something wrong!)
Using pieces of others code and some of my own I have a javascript validation script that will check only those elements on a form that end in "_ck".  If they don't have an answer then the element is turned red.  

It currently checks text input and select elements.  I want to add the ability to check radio buttons (that is, one of the group is checked).

I have tried several things but just can't seem to get it totally working.  Here is the main script with a call to "check_radio". This function returns true if none of the radio buttons have been selected.

I'm looking for the code for this function. Or if a call to a function is not required then the code I should use.

Here is the current script without the "check_radio" function:

<script language="JavaScript">
function check_form(form)
{
return_boolean = true
 obj = eval(form)
 for(i=0;i<obj.length;i++)
 {
  field_name = obj.elements[i].name;
  if (field_name.indexOf("_ck") != -1)
  {
    if (  (  (obj.elements[i].type == "select-one" ||
               obj.elements[i].type == "select-multiple") && 
            obj.elements[i].selectedIndex == 0) ||
         (obj.elements[i].type == "text" &&
          obj.elements[i].value == "")  ||
          ((obj.elements[i].type== "radio") && (check_radio(field_name)) ) )
    {
      obj.elements[i].style.backgroundColor = "red";
      return_boolean = false
       }
    else
    {
      obj.elements[i].style.backgroundColor = "white";
    }
  }
 }
return return_boolean;
}
</script>


Avatar of fritz_the_blank
fritz_the_blank
Flag of United States of America image

Take a look at this to see if it will suit your purposes:

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE></TITLE>
<SCRIPT LANGUAGE=javascript>
<!--

function checkRadioControl(strFormField)
{
     iControlLength = strFormField.length
     bolSelected = false;
     for (count=0;count<iControlLength;count++){
          if(strFormField[count].checked){
                    bolSelected = true;
                    break;
          }
     }    
     if(! bolSelected){
          alert("Please select one option!");
          return false;
     }else{
          return true;
     }
}
// -->
</script>

</HEAD>
<BODY>
<FORM action="http://www.fairfieldconsulting.com" method=post id=form name=form onSubmit="return checkRadioControl(document.form.RadialButton)">
Yes<input type="radio" name="RadialButton" value="Yes">
No<input type="radio" name="RadialButton" value="No">
Maybe<input type="radio" name="RadialButton" value="Maybe"><p>

<INPUT type="submit" value="Submit" id=submit1 name=submit1></FORM></P>
</BODY>
</HTML>

Fritz the Blank
Avatar of TallerMike
TallerMike

if (obj.elements[i].length)
     {
     for (var x=0; x < obj.elements[i].length; x++)
          if (obj.elements[i][x].checked)
               { return true; }
            return false;
else { return obj.elements[i].checked; }

************************************************************

I would advise, that rather than changing the name of your imputs to have _ck at the end, that you instead just add a parameter to that field called "required" like this:

<input type="text" name="fname" required="true">
<input type="text" name="mname" required="false">
<select name="sex" required="true"></select>

Then modify your validation function to check for this rather then the name like so:

if (field_name.indexOf("_ck") != -1)

becomes

if ( (obj.elements[i].required) && (obj.elements[i].required != "false") )

---------------------------------------------------------

You could also break this into a function like so:

isRequired(formInputObj)
  { return ( (formInputObj.required) && (formInputObj.required != "false") ); }

And then call it from your validation script like this:

if ( isRequired(obj.elements[i]) )
Avatar of jldalot

ASKER

fritz_the_blank, thanks for the quick reply, but I don't want to have to enter the name of the radio button group.  I won't often know how many are on the page.

TallerMike, I think this will get me there.  There is a problem with balanced "{".  After playing with it a bit I think I got it to what you were thinking.  However it still seems to not be working right.

I put it up on a server at: http://answerspot.com/validate.html

Check it out and see if you can tell what the problem is.  I think it is that it dumps out of the for loop when it finds one checked.  However, I wonder if it needs to go through it all to clear the other radio buttons in the group?

I love your idea about adding a "required" parameter to the field, I will definitely implement this and get you some points for that when I get the final answer.

Thanks!

This is the problem: since the radio button groups have the same name for each control, you need to pass the name of the control in order to determine if at least one element is checked. Otherwise, if any radio button is checked anywhere on the form, then it will pass the validation regardless of the number of groups.

If you have a way around this--other than ESP--I would be interested in seeing it.


Fritz the Blank
Avatar of jldalot

ASKER

I see your point.  I can't seem to get ESP working so that's not an option! ;-)

I was wondering if the name could be extracted using obj.elements[i].name somehow?  Then only those elements that have the same name and are type "radio" would be compared?

Thanks for your time and efforts and patience with my lack of knowledge.  

jldalot
I don't have time to finish it now, but here's the idea:

***********************************************************

<html>
<script language="JavaScript">

function isRadioParent(inputObj)
      { return ( (inputObj.length) && ((inputObj[0].type == "radio") || (inputObj[0].type == "checkbox")) ); }

function highlight(inputObj,highlightColor)
      {
      if ( isRadioParent(inputObj) )
            for (var optionIndex=0; optionIndex < inputObj.length; optionIndex++)
                  { inputObj[optionIndex].style.backgroundColor = "red"; }
      else
            { inputObj.style.backgroundColor = highlightColor; }
      }

function isRequired(inputObj)
      {
      if ( isRadioParent(inputObj) )
            { return ( (typeof(inputObj[0].required) != 'undefined') && (inputObj[0].required != "false") ); }
      else
            { return ( (typeof(inputObj.required) != 'undefined') && (inputObj.required != "false") ); }
      }

function hasValue(inputObj)
      {
      obj_type = inputObj.type.toUpperCase();
      
      if (obj_type == "TEXT" || obj_type == "PASSWORD")
            { return (inputObj.value.length != 0); }
            
         else if (obj_type == "SELECT-ONE")
               { return (inputObj.selectedIndex > 0); }
            
         else if (obj_type == "SELECT-MULTIPLE")
               {
        for (var optionIndex=0; optionIndex < inputObj.length; optionIndex++)
                  if (inputObj.options[optionIndex].selected)
                        { return true; }
             return false;
            }
            
      else if (obj_type == "RADIO" || obj_type == "CHECKBOX")
            {
            if (inputObj.length)
                  {
              for (var optionIndex=0; optionIndex < inputObj.length; optionIndex++)
                    if (inputObj[optionIndex].checked)
                              { return true; }
                   return false;
                  }
            else { return inputObj.checked; }
            }
      }
            
function check_form(formName)
      {
      var return_boolean = true;
      var processedFields = new Array();
      
      for(var elementIndex=0; elementIndex<formName.length; elementIndex++)
            {
            inputObj = formName.elements[elementIndex];
            if ( processedFields[inputObj.name] == null )
                  {
                  if ( (inputObj.type == "radio") || (inputObj.type == "checkbox") )
                        {
                        var thisType = inputObj.type
                        inputObj = eval(inputObj.form.name + "." + inputObj.name);
                        inputObj.type = thisType;
                        }
                  
                  if (isRequired(inputObj) && !(hasValue(inputObj)))
                        {
                        return_boolean = false;
                        highlight(inputObj,"red");
                        }
                  else
                        { highlight(inputObj,"white"); }
                  }
            else
                  { processedFields[inputObj.name] = 1; }
            }
      return return_boolean;
      }
</script>
<body>
<form name="myForm" onsubmit="return check_form(this)" action="worked.html">
      <table>
            <tr>
                  <td>First-name:</td>
                  <td><input type="text" name="fn" required="true"></td>
            </tr>
            <tr><td>Last-name:</td><td><input type="text" name="ln" required="true"></td></tr>

            <tr><td>Your age:</td><td><input type="text" name="age"><i>(Optional)</i></td></tr>
            <tr><td>Business Type:</td>
            <td>
            <select name="Business Type" required="true">
                  <option value=""> -Select-
                  
                  <option Retailer>Retailer
                  <option Wholesaler>Wholesaler
                  <option Manufacturer>Manufacturer
                  <option Distributor>Distributor
                  <option Service Firm>Service Firm
                  <option Manufacturer's Agent>Manufacturer's Agent
                  <option Other...>Other...
            </select>

                        </td></tr>
            <tr>
                  <td>
                  <input type="radio" name="radio1" required="true" value="always">always
                  <input type="radio" name="radio1" required="true" value="sometimes">sometimes
                  <input type="radio" name="radio1" required="true" value="never">never
                  </td>
            </tr>
            <tr>
                  <td>

                  <input type="radio" name="radio2" required="true" value="always">always
                  <input type="radio" name="radio2" required="true" value="sometimes">sometimes
                  <input type="radio" name="radio2" required="true" value="never">never
                  </td>
            </tr>
            <tr>
                  <td>
                  <input type="radio" name="radio3" required="true" value="always">always
                  </td>
            </tr>
                  </table>

      <input type=submit value="Submit">
</form>
</body>
</html>


<!-- end Source -->
You could iterate through your form elements and create a list of those that are of the radio button type, and then add each name to an array. You could then use code similar to what I posted above to iterate through the array for validation.

Fritz the Blank
Avatar of jldalot

ASKER

I'll spend some time with this latest option.  At this point it appears there are at least some errors.  

For example, "inputObj.type = thisType;" results in the error "Object doesn''t support this property or method".  It appears you can change the object type.

Thanks for your responses.  I will work on it a bit.

Something like:

var arrNames=new Array()

function getRadioNames(){
     var intArrayIndex=0
     for(i=0;i<document.forms[0].elements.length;i++){
          if(document.forms[0].elements[i].type=="radio"){
               arrNames[intArrayIndex] = document.forms[0].elements[i].name;
               intArrayIndex++;
          }
     }
}
If you want to be efficient, though, you should check to make sure the name doesn't exist before you add it to the array.

Fritz the Blank
Testing?
ASKER CERTIFIED SOLUTION
Avatar of TallerMike
TallerMike

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jldalot

ASKER

Amazing what a good nights sleep and thinking in a warm shower can produce.  I realized a problem I had with my code and fixed it!  

At the same time I got the notice that TallerMike had posted another comment.  They both work!  TallerMike's is much better than mine.

Mine incorporates some of the suggestions of fritz the blank.  So I have to figure out how to split the points. I'm thinking of adding some points and then splitting.

Thanks so much for your time, what an amazing resource!

I'll figure out how to do the split then close the question.

jldalot
Avatar of jldalot

ASKER

Thanks again for your help.  I have figgered' out how to do the points thing.

I will award TallerMike 100 points and an A on this question.

FritzTheBlank I have set up another question for you at:
https://www.experts-exchange.com/questions/20402349/points-for-Fritz-The-Blank.html

I will give you 50 points and an A also.

Thanks all!
Avatar of jldalot

ASKER

Thanks for all your time, you were outstanding.
Glad we could help.
I made some updates to the code that you are using to make it more Netscape compatible (per the request of someone else who found this post and wanted it). Please change the following functions as follows:

function isRequired(inputObj)
    { return ( inputObj.getAttribute("required") != "false" ); }

function getRadioParent(inputObj)
    { return eval("document." + inputObj.form.name + "." + inputObj.name); }

Let me know if you have any troubles!
I've (successfully) used this code in many of my apps.
Sometimes, I populate a hidden field with information from another form control (WYSIWYG Editor etc)
For completeness... I have modifed the hasValue function as such...

function hasValue(inputObj)
    {
    obj_type = inputObj.type.toUpperCase();
   
     if (obj_type == "TEXT" || obj_type == "PASSWORD"  || obj_type == "HIDDEN")

(Incidently I pop up an alert box with the field id value to alert the user of an incomplete field entry).