Forums

[SOLVED] Dynamically validate radio buttons

SAGO 24 Apr, 2012
Hi,

CFv3.2

I've been for a couple of days now and can't seem to find how one can add validation for radio buttons dynamically.

In short I have a radio button which lets you choose between "Video" or "Poster"
When you choose "Video" the field "Upload Video" is required.
When you choose "Poster" you will need to choose one option from a group of radio buttons and it's also required.

So the "Upload Video" is only required when you have chosen "Video".
And you must select one of the "Poster" radio buttons when "Poster" was choosen in the first radio button.

I'm able to do it for the "Upload Video" with .add(Prescence) but I can't find out how to do it for the radio buttons.

Here you see how it looks.


I've also uploaded the form.

Here is the HTML part:
<div class="form_item">
  <div class="form_element cf_radiobutton">
    <label class="cf_label" style="width: 150px;">Video or Poster</label>
    <div class="float_left">
      <input value="Upload video" title="" class="radio validate-one-required" id="video_or_poster1" name="video_or_poster" type="radio" />
      <label for="video_or_poster1" class="radio_label">Upload video</label>
      <br />
      
<input value="Choose a poster" title="" class="radio validate-one-required" id="video_or_poster2" name="video_or_poster" type="radio" />
      <label for="video_or_poster2" class="radio_label">Choose a poster</label>
      <br />
      

    </div>
    
  </div>
  <div class="cfclear"> </div>
</div>

<div class="form_item">
  <div class="form_element cf_fileupload">
    <label class="cf_label" style="width: 150px;">Upload video</label>
    <input class="cf_fileinput cf_inputbox" title="" size="20" id="uploadvideo" name="uploadvideo" type="file" />
    
  </div>
  <div class="cfclear"> </div>
</div>

<div class="form_item">
  <div class="form_element cf_radiobutton">
    <label class="cf_label" style="width: 150px;">Choose Poster</label>
    <div class="float_left">
      <input value="Poster 1" title="" class="radio" id="poster1" name="poster" type="radio" />
      <label for="poster1" class="radio_label">Poster 1</label>
      <br />
      
<input value="Poster 2" title="" class="radio" id="poster2" name="poster" type="radio" />
      <label for="poster2" class="radio_label">Poster 2</label>
      <br />
      
<input value="Poster 3" title="" class="radio" id="poster3" name="poster" type="radio" />
      <label for="poster3" class="radio_label">Poster 3</label>
      <br />
      

    </div>
    
  </div>
  <div class="cfclear"> </div>
</div>

<div class="form_item">
  <div class="form_element cf_button">
    <input value="Submit" name="button_3" type="submit" />
  </div>
  <div class="cfclear"> </div>
</div>


Here is the JavaScript part.


window.addEvent('domready', function() {

  var fileupload = new LiveValidation('uploadvideo');
  fileupload.add( Validate.Presence );

  var poster = new LiveValidation('poster');
  poster.add( Validate.Presence );

  var uploadcheck  = function() {
    if ( $('video_or_poster1').checked == true ) {
      fileupload.enable();
      poster.disable(); 
     }
     if ( $('video_or_poster2').checked == true ) {
       fileupload.disable();
       poster.enable();
     }
   };
   $('video_or_poster2').addEvent('change', uploadcheck);
   $('video_or_poster1').addEvent('change', uploadcheck);
});


This part is not working. I suspect because it needs validate-one-required instead of required.

  var poster = new LiveValidation('poster');
  poster.add( Validate.Presence );

and of course this won't work either:
poster.enable();


I really can't find how to make this work.
Please advice.

Regards,

SaGo
GreyHead 24 Apr, 2012
Hi SAGO,

I never really got this working - that's why I wrote the tutorial using the Usable Forms scripts from Quirksmode. That avoids using LiveValidation at all. Here's he code that adds the 'one required' validation - does that help?
name.add( Validate.One_Required, {
  elm : field,
  failureMessage: message_validate_one_required
});

Bob
SAGO 25 Apr, 2012
Hi,

Well thanks to you I got it working but I had a problem with where the error message was placed.
I did sort it out but I'm not sure if this is the easiest/best way.
Bob (or Max), could you give your opninion (on the part below that has to do with ther error message). Thanks

Dynamic Validation for radio buttons

The code should look like this:
var message_validate_one_required = "Make a choice please.";
  var field = $('poster3');
  var poster = new LiveValidation('poster3');
  poster.add( Validate.One_Required, {
   elm : field,
   failureMessage: message_validate_one_required
  });


field from "elm: field" has to be declared or you can replace it directly and not use a field var so it becomes elm: $('poster3').
You need to use the ID of the element. Do not use the NAME!!!!!!
See here:
<input value="Poster 3" title="" class="radio" id="poster3" name="poster" type="radio" />


Uncomplete JavaScript Part

So here is the javascript code to put in the "Form Code" -> "Form JavaScript:"
But there is still one thing we'll need to add. Keep on reading. I will show you what. :-)
window.addEvent('domready', function() {

  var fileupload = new LiveValidation('uploadvideo');
  fileupload.add( Validate.Presence );

  var message_validate_one_required = "Make a choice please.";
  var field = $('poster3');
  var poster = new LiveValidation('poster3');
  poster.add( Validate.One_Required, {
   elm : field,
   failureMessage: message_validate_one_required
  });
  
  var uploadcheck  = function() {
    if ( $('video_or_poster1').checked == true ) {
      fileupload.enable();
      poster.disable();
      
     }
     if ( $('video_or_poster2').checked == true ) {
       fileupload.disable();
       poster.enable();
     }
   };
   $('video_or_poster2').addEvent('change', uploadcheck);
   $('video_or_poster1').addEvent('change', uploadcheck);
});


The Error Message
The problem I had after doing this was that I would see the error message before the radio button.
Like this:


The only way that I was able to solve this was by using the following div:
<div id="CF_LV_ERROR_poster3" style="display:none; font-weight: bold; color:#CC0000;"></div> 

As you can see I have to put the ID of the element in the ID of the DIV.
So in my case I the ID was poster3 so CF_LV_ERROR_ + poster3 becomes CF_LV_ERROR_poster3.

This is how my HTML Code looks like:
<div class="form_item">
  <div class="form_element cf_radiobutton">
    <label class="cf_label" style="width: 150px;">Video or Poster</label>
    <div class="float_left">
      <input value="Upload video" title="" class="radio validate-one-required" id="video_or_poster1" name="video_or_poster" type="radio" />
      <label for="video_or_poster1" class="radio_label">Upload video</label>
      <br />
      
<input value="Choose a poster" title="" class="radio validate-one-required" id="video_or_poster2" name="video_or_poster" type="radio" />
      <label for="video_or_poster2" class="radio_label">Choose a poster</label>
      <br />
    </div>
  </div>
  <div class="cfclear"> </div>
</div>

<div class="form_item">
  <div class="form_element cf_fileupload">
    <label class="cf_label" style="width: 150px;">Upload video</label>
    <input class="cf_fileinput cf_inputbox" title="" size="20" id="uploadvideo" name="uploadvideo" type="file" /> 
  </div>
  <div class="cfclear"> </div>
</div>

<div class="form_item">
  <div class="form_element cf_radiobutton">
    <label class="cf_label" style="width: 150px;">Choose Poster</label>
    <div class="float_left">
      <input value="Poster 1" title="" class="radio" id="poster1" name="poster" type="radio" />
      <label for="poster1" class="radio_label">Poster 1</label>
      <br />
      
<input value="Poster 2" title="" class="radio" id="poster2" name="poster" type="radio" />
      <label for="poster2" class="radio_label">Poster 2</label>
      <br />
      
<input value="Poster 3" title="" class="radio" id="poster3" name="poster" type="radio" />
      <label for="poster3" class="radio_label">Poster 3</label>
      <br />

      <div id="CF_LV_ERROR_poster3" style="display:none; font-weight: bold; color:#CC0000;"></div> 
    </div>
  </div>
  <div class="cfclear"> </div>
</div>

<div class="form_item">
  <div class="form_element cf_button">
    <input value="Submit" name="button_3" type="submit" />
  </div>
  <div class="cfclear"> </div>
</div>


Suppose we click on the Poster and try to submit we will see the error but when we click back on Upload Video the message will still be there.
So in JavaScript we still need to use the two following code when testing which radio button is clicked:
$('CF_LV_ERROR_poster3').style.display= "none";
$('CF_LV_ERROR_poster3').style.display= "block";


The Correct and Complete JavaScript Part
So the correct JavaScript looks like this:
window.addEvent('domready', function() {

  var fileupload = new LiveValidation('uploadvideo');
  fileupload.add( Validate.Presence );
  
  var message_validate_one_required = "Make a choice please.";
  var field = $('poster3');
  var poster = new LiveValidation('poster3');
  poster.add( Validate.One_Required, {
   elm : field,
   failureMessage: message_validate_one_required
  });

  var uploadcheck  = function() {
    if ( $('video_or_poster1').checked == true ) {
      fileupload.enable();
      poster.disable();
       $('CF_LV_ERROR_poster3').style.display= "none";
     }
     if ( $('video_or_poster2').checked == true ) {
       fileupload.disable();
       poster.enable();
       $('CF_LV_ERROR_poster3').style.display= "none";
     }
   };
   $('video_or_poster2').addEvent('change', uploadcheck);
   $('video_or_poster1').addEvent('change', uploadcheck);
});


Conlusion:
So this is how I was able to make it work.
About the error message I'm not sure if it can be done without using <div id="CF_LV_ERROR_...">.
Hopefully Bob or Max can give confirmation.

Hope this helps at least one person :-)
By the way this perhaps a good addition to the following two threads:
http://www.chronoengine.com/forums.html?cont=posts&f=5&t=65334
http://greyhead.net/chronoforms/cfv3-dynamic-validation
GreyHead 25 Apr, 2012
Hi SAGO,

Here's an extract from the LiveValidation (class) documents:

Parameters for paramsObj:

validMessage (optional) - {String} - message to be used upon successful validation (DEFAULT: “Thankyou!”)
onValid (optional) - {Function} - function to execute when field passes validation (DEFAULT: function(){ this.insertMessage( this.createMessageSpan() ); this.addFieldClass(); } )
onInvalid (optional) - {Function} - function to execute when field fails validation (DEFAULT: function(){ this.insertMessage( this.createMessageSpan() ); this.addFieldClass(); })
insertAfterWhatNode (optional) - {mixed} - reference or id of node to have the message inserted after (DEFAULT: the field that is being validated)
onlyOnBlur (optional) - {Boolean} - whether you want it to validate as you type or only on blur (DEFAULT: false)
wait (optional) - {Integer} - the time you want it to pause from the last keystroke before it validates (milliseconds) (DEFAULT: 0)
onlyOnSubmit (optional) - {Boolean} - if it is part of a form, whether you want it to validate it only when the form is submitted (DEFAULT: false)


I think that you can use insertAfterWhatNode to place the error message wherever you want it on the page. You could also use the onInvalid parameter to call a function to create and place the message.

Bob
SAGO 25 Apr, 2012
Hi Bob,

I can confirm that it works. Nice find by the way!

For anyone who is interested:

var poster = new LiveValidation('poster3', {
    insertAfterWhatNode : 'messages_poster'
  });


Just add a div somewhere with an id and use the id after insertAfterWhatNode.
I addes a div with id messages_poster after the last radio button and it showed the message below it, just like I wanted.

Thanks.
This topic is locked and no more replies can be posted.