Forums

Need Your Help, Fast

formadmin 07 Feb, 2013
We’ve been asked to make this form somewhat more complex; would it be possible for you guys to help us with the updates? Here's the code: http://pastebin.com/LAMgDHQE

Before you answer, I’ll briefly explain what has to be done:

There is a checkbox array (for now, call the fields "A,B,C,D")
There are 2 fields associated with the selections in the checkbox array; Field X and Field Y. Field X relates ONLY to checkbox fields A&B, while Field Y relates ONLY to checkbox fields C&D.

Condition #1
User selects A and/or B (but not C and/or D) from the checkbox array – a popup tells them that Field X further down the form is now a required field. That field does indeed go from not-required to required.

Or

Condition #2
User selects C and/or D (but not A and/or B) from the checkbox array, a popup tells the user that Field Y has now become required – while the other field mentioned in condition #1 is now set to not be required

Or

Condition #3
User selects A and/or B *PLUS* C and/or D, a popup tells them that both fields are now required and both fields get set to required.


I would really like to have your help on this – it needs to go live this coming Friday (tomorrow) and we're a bit lost in how to write code that works within the Chrono framework. Please let me know if you have the bandwidth and what your rates are.

Thanks,

Jordan
GreyHead 07 Feb, 2013
Hi formadmin,

It's getting on for ten in the evening here and I'm about to pack up for the night.

I can take a look in the morning - or there is some similar code in this FAQ

Bob
formadmin 07 Feb, 2013
Thanks, Bob! I will go over the FAQ you sent to see if I can adopt that. In any event, if you could take a look in your morning and see if you can offer some easy instructions, I'd really appreciate it. If you are open to making the change yourselves, we can pay you for your time.

Thanks,
Jordan
formadmin 08 Feb, 2013
hmm, I worked with this for a couple hours and couldn't get it to work right. Please let me know if you're able to adjust the javascript code to the form html below:

<form id="test" action="/medinfo-thank-you" method="get">

<p>
<div style="margin-bottom:5px;">Select the ones that apply:</div>	
    <div name="" id="choose_npi">
    <input type="radio" name="prof-type-npi" id="md" value="MD" /> MD 
    <input type="radio" name="prof-type-npi" id="do" value="DO" /> DO
    </div>
    
    <div name="" id="">
    <input type="radio" name="prof-type-lic" id="phd" value="PhD" /> PhD 
    <input type="radio" name="prof-type-lic" id="pharmd" value="PharmD" /> PharmD 
    <input type="radio" name="prof-type-lic" id="rph" value="RPh" /> RPh 
    <input type="radio" name="prof-type-lic" id="pa" value="PA" /> PA 
    <input type="radio" name="prof-type-lic" id="rn" value="RN" /> RN
    <input type="radio" name="prof-type-lic" id="np" value="NP" /> NP
    </div>
    
    <div name="" id="choose_other_container">
    <label for="prof-type-other">Other: </label><input type="text" name="prof-type-other" id="choose_other" size="20" value="" />
    </div>
</p>

<p>
<label for="npi">NPI#: </label><input class="validate['required']" size="20" name="prof-type-npi" id="npi" type="text" value="" />  
<label for="lic">State Lic#: </label><input size="20" name="prof-type-lic" id="lic" type="text" value="" />
</p>


<input type="submit" value="Submit" />

</form>


The logic should be:

Condition #1

User selects either of the radio buttons named prof-type-npi from the top radio array – a popup (or tooltip) tells them that text box prof-type-npi further down the form is now a required field. That box does indeed go from not-required to required.



Or

Condition #2

User selects one of the radio buttons named prof-type-lic from the second radio array - a popup (or tooltip) tells them that text box prof-type-lic has now become required – while the other text box mentioned in condition #1 is now set to not be required.



-They are only allowed to select one of these radio buttons, so the whole thing needs to be one array, or have a condition that only one can be selected.

-I hope that's kinda clear; if we can get that far, I can do the rest.

Thanks,

Jordan
GreyHead 08 Feb, 2013
Hi Formadmin,

Not straightforward, I spent a couple more hours this morning and got this working fairly well. See the demo form here.

Here's the JavaScript that I ended up with:
window.addEvent('domready', function() {
	var npi, lic, npi_radios, lic_radios, req;
	npi = $('npi');
	lic = $('lic');
	npi_radios = $$('input[name=prof-type-npi]');
	lic_radios = $$('input[name=prof-type-lic]');
	req = "validate['required']";

	npi_radios.each(function(item) {
		item.addEvent('click', makeNpiRequired);
	});
	lic_radios.each(function(item) {
		item.addEvent('click', makeLicRequired);
	});

	function makeNpiRequired() {
		lic_radios.each(function(item) {
			item.checked = false;
		});
		if ( lic.hasClass(req)) {
			lic.setProperty('class', '');
			formCheck_test_form_npi.dispose(lic);
		}
		if ( npi.hasClass(req)) {
			return;
		}
		npi.addClass(req);
		formCheck_test_form_npi.register(npi);
		alert('NPI# is required');
	}
	function makeLicRequired() {
		npi_radios.each(function(item) {
			item.checked = false;
		});
		if ( npi.hasClass(req)) {
			npi.setProperty('class', '');
			formCheck_test_form_npi.dispose(npi);
		}
		if ( lic.hasClass(req)) {
			return;
		}
		lic.addClass(req);
		formCheck_test_form_npi.register(lic);
		alert('State Lic# is required');
	}
});
The little bug I stumbled over is that the MooTools removeClass() method fails with a class name like validate['required'], once I worked that out I used setProperty() to clear the class instead.

Bob
formadmin 08 Feb, 2013
Thanks, Bob! :mrgreen:

I will dig into this and see if I can't get it working on my end.
formadmin 08 Feb, 2013
hmm, if I just copy your html, and copy the javascript you posted, it doesn't work on the test form I set-up. The required field thing doesn't work, nor does the popup functionality.

Does your form rely on a specific version of mootools, or have some other dependency that I don't know about? The site is running Joomla 1.5.25 with mootools 'mtupgrade' ver 1.2.5 plugin enabled.

I can grant you access to the site so you can see what I'm talking about, but we need to do that outside of the forum.

thanks,
GreyHead 08 Feb, 2013
Hi formadmin,

Mine was running on Joomla! 2.5 probably with MooTools 1.4

By all means email or PM me the site URL and a SuperAdmin login and I'll take a quick look.

Bob
formadmin 11 Feb, 2013
Hey Bob,

First, thanks for all your input this past weekend. You have helped enormously!

We do have one more little tweak that needs to happen before this can go into production. All radio buttons must turn-off and NPI and LIC fields must not be required when the "Other" text box is clicked. I have tried to use your javascript to implement this, but I'm afraid it hasn't worked. If you have a moment, please set me on the right path:

Here is the javascript:

function disp_alert(other) {
      if ( npi.hasClass(req) || lic.hasClass(req)) {
         npi.setProperty('class', '');
         formCheck_medical_info.dispose(npi);
         lic.setProperty('class', '');
         formCheck_medical_info.dispose(lic);
      }
      if ( npi.hasClass(req)) {
         return;
      }
      if ( lic.hasClass(req)) {
         return;
      }
      alert('Please describe your professional accreditation in the space provided.\n\nClick OK to continue.');
   }


here is the HTML:

<div name="" id="other" style="float:left;">
    	  
        <label for="other"> Other:</label>
        <input type="text" name="other" id="other" size="20" value="" onclick="disp_alert(other.value) />
    </div>
GreyHead 12 Feb, 2013
Hi formadmin,

This is one of those cases where it's important to think through the design before getting into the coding. It would probably work better with a single set of radio buttons, including an 'other' button.

Still, here's a version of the code extended - by quite a lot - to handle this extra case:
window.addEvent('domready', function() {
	// !! important !! replace test_form_npi with the name of your form
	var form, npi, lic, npi_radios, lic_radios, req, other;
	npi = $('npi');
	lic = $('lic');
	other = $('choose_other');
	npi_radios = $$('input[name=prof-type-npi]');
	lic_radios = $$('input[name=prof-type-lic]');
	req = "validate['required']";

	npi_radios.each(function(item) {
		item.addEvent('click', makeNpiRequired);
	});
	lic_radios.each(function(item) {
		item.addEvent('click', makeLicRequired);
	});
	other.addEvent('keyup', makeOtherRequired);
	other.addEvent('click', function() {
		alert('Please describe your professional accreditation in the space provided.\n\nClick OK to continue.');
	});

	function makeOtherRequired() {
		if ( !other.value ) {
			lic_radios.each(function(item) {
				item.disabled = false;
			});
			npi_radios.each(function(item) {
				item.disabled = false;
			});
			return;
		}
		lic_radios.each(function(item) {
			item.checked = false;
			item.disabled = true;
			lic.setProperty('class', '');
			formCheck_test_form_npi.dispose(lic);
		});
		npi_radios.each(function(item) {
			item.checked = false;
			item.disabled = true;
			npi.setProperty('class', '');
			formCheck_test_form_npi.dispose(npi);
		});
		other.addClass(req);
		formCheck_test_form_npi.register(other);
	}

	function makeNpiRequired() {
		lic_radios.each(function(item) {
			item.checked = false;
		});
		if ( lic.hasClass(req)) {
			lic.setProperty('class', '');
			formCheck_test_form_npi.dispose(lic);
		}
		if ( other.hasClass(req)) {
			other.setProperty('class', '');
			formCheck_test_form_npi.dispose(other);
		}
		if ( npi.hasClass(req)) {
			return;
		}
		npi.addClass(req);
		formCheck_test_form_npi.register(npi);
		alert('NPI# is required');
	}

	function makeLicRequired() {
		npi_radios.each(function(item) {
			item.checked = false;
		});
		if ( npi.hasClass(req)) {
			npi.setProperty('class', '');
			formCheck_test_form_npi.dispose(npi);
		}
		if ( other.hasClass(req)) {
			other.setProperty('class', '');
			formCheck_test_form_npi.dispose(other);
		}
		if ( lic.hasClass(req)) {
			return;
		}
		lic.addClass(req);
		formCheck_test_form_npi.register(lic);
		alert('State Lic# is required');
	}
});

Bob
formadmin 12 Feb, 2013
HI Bob,

Yes, I know this was an oversight...I'm sorry 😶

I've placed the new javascript in my JS action, and I've correctly changed the form name in that code, but it's not working. Did you alter the HTML at all?
GreyHead 12 Feb, 2013
Hi formadmin,

No - still using your original HTML I think. Test form is here

Bob
formadmin 13 Feb, 2013
hi Bob,

I got the code running, but there seems to be a bit of a problem - the 'Other' field has the popup, which is correct, but when you type inside the Other field the 'NPI#' and 'LIC#' fields are greyed-out and not writeable... it was all the radio buttons that were supposed to turn-off (or be cleared) when the 'Other' field is entered.

Just to be clear, here is the logic:

condition #1:
user selects radio button for either MD or DO, the NPI alert is fired and the NPI# field is required.

condition #2:
user selects any of the other radio buttons, the Lic alert is fired and the LIC# field is now required, the NPI# field is not required.

condition #3:
user clicks the Other text field, the Other alert is fired, all radio buttons are reset to no-selection, neither NPI nor LIC field are required, both fields are writeable.

I know this is all more complicated that you'd probably hoped, but I will gladly pay for your time. And thank you for all your efforts to-date - you're a huge help.

Here is the most recent javascript:
window.addEvent('domready', function() {
   // !! important !! replace medical_info with the name of your form
   var form, npi, lic, npi_radios, lic_radios, req, other;
   npi = $('npi');
   lic = $('lic');
   other = $('choose_other');
   npi_radios = $$('input[name=prof-type-npi]');
   lic_radios = $$('input[name=prof-type-lic]');
   req = "validate['required']";

   npi_radios.each(function(item) {
      item.addEvent('click', makeNpiRequired);
   });
   lic_radios.each(function(item) {
      item.addEvent('click', makeLicRequired);
   });
   other.addEvent('keyup', makeOtherRequired);
   other.addEvent('click', function() {
      alert('Please type your professional title in the "Other" field.\n\n*If you are either a Medical Doctor or Doctor of Osteopathic medicine, you must enter your NPI# in the space provided.\n\n*If you are a PhD, PharmD RPh, PA, RN or NP, you must enter your State Lic# in the space provided.\n\nClick OK to continue.');
   });

   function makeOtherRequired() {
      if ( !other.value ) {
         lic_radios.each(function(item) {
            item.disabled = false;
         });
         npi_radios.each(function(item) {
            item.disabled = false;
         });
         return;
      }
      lic_radios.each(function(item) {
         item.checked = false;
         item.disabled = true;
         lic.setProperty('class', '');
         formCheck_medical_info.dispose(lic);
      });
      npi_radios.each(function(item) {
         item.checked = false;
         item.disabled = true;
         npi.setProperty('class', '');
         formCheck_medical_info.dispose(npi);
      });
      other.addClass(req);
      formCheck_medical_info.register(other);
   }

   function makeNpiRequired() {
      lic_radios.each(function(item) {
         item.checked = false;
      });
      if ( lic.hasClass(req)) {
         lic.setProperty('class', '');
         formCheck_medical_info.dispose(lic);
      }
      if ( other.hasClass(req)) {
         other.setProperty('class', '');
         formCheck_medical_info.dispose(other);
      }
      if ( npi.hasClass(req)) {
         return;
      }
      npi.addClass(req);
      formCheck_medical_info.register(npi);
      alert('Based on your selection, to submit this form you must enter your NPI# in the space provided below.\n\nYou may also provide your State Lic#, but it is not required.\n\nClick OK to continue.');
   }

   function makeLicRequired() {
      npi_radios.each(function(item) {
         item.checked = false;
      });
      if ( npi.hasClass(req)) {
         npi.setProperty('class', '');
         formCheck_medical_info.dispose(npi);
      }
      if ( other.hasClass(req)) {
         other.setProperty('class', '');
         formCheck_medical_info.dispose(other);
      }
      if ( lic.hasClass(req)) {
         return;
      }
      lic.addClass(req);
      formCheck_medical_info.register(lic);
      alert('Based on your selection, to submit this form you must enter your State Lic# in the space provided below.\n\nClick OK to continue.');
   }
});


Here is the most recent HTML:

<form id="medical_info" name="medical_info" action="/medinfo-thank-you" method="get">

<p>
	<div style="margin-bottom:5px;"><strong><em>Your personal and professional information:</em></strong></div>

    <div style="margin-bottom:5px;"><label for="from"><span style="color:red;">*</span>Full Name: </label><input class="validate['required']" size="80" name="from" id="from" type="text" value="" /></div>
</p>

<p> 
<span style="float:left;display:inline;width:auto;color:red;">*</span>    
    <div name="" id="choose_npi" style="float:left;">
	    <input type="radio" name="prof-type-npi" id="md" value="MD" /> MD
	    <input type="radio" name="prof-type-npi" id="do" value="DO" /> DO
	</div>
	
	<div name="" id="choose_lic" style="float:left;">
	    <input type="radio" name="prof-type-lic" id="phd" value="PhD" /> PhD
	    <input type="radio" name="prof-type-lic" id="pharmd" value="PharmD" /> PharmD
	    <input type="radio" name="prof-type-lic" id="rph" value="RPh" /> RPh
	    <input type="radio" name="prof-type-lic" id="pa" value="PA" /> PA
	    <input type="radio" name="prof-type-lic" id="rn" value="RN" /> RN
	    <input type="radio" name="prof-type-lic" id="np" value="NP" /> NP
	</div>
	
	<div name="" id="choose_other_container" style="float:left;">
		      
		<label for="prof-type-other"> Other:</label>
	    <input type="text" name="prof-type-other" id="choose_other" size="20" value="" />
	</div>
	
	<div class="clr"></div>
	
	<div>
	    <label for="npi">NPI#:</label>
	    <input class="" size="20" name="prof-type-npi" id="npi" type="text" value="" />
	      
	    <label for="lic">State Lic#:</label>
	    <input class="" size="20" name="prof-type-lic" id="lic" type="text" value="" />
	</div>
</p>

<input type="submit" value="Submit" />

</form>
GreyHead 13 Feb, 2013
Hi formadmin,

I took a quick look and this appears to happen because the radio buttons and the corresponding text input have the same name e.g. 'prof-type-npi' and the code I wrote is searching by name. Generally duplicating names isn't a good idea. Is it deliberate here? If not then I'd suggest that you change the name of the inputs. If it is deliberate then changing the selectors to
	npi_radios = $$('input[name=prof-type-npi][type=radio]');
	lic_radios = $$('input[name=prof-type-lic][type=radio]');
should make it work OK.

Bob
formadmin 13 Feb, 2013
I've re-named as per your suggestion. The radio buttons now do turn-off when text is entered in the Other box... however...

-Unrelated to the Other field; after randomly clicking several radio buttons in succession, the alerts completely stop working. Usually after two or three different buttons are clicked, the alerts don't show-up any more.

Is this a bug related to how the inputs are named?
GreyHead 13 Feb, 2013
Hi formadmin,

I had a long clicking session on my test form with no problems. What do you see in the JavaScript Console when the form locks up?

Bob
formadmin 13 Feb, 2013
On your test form it also stops working after several (3 clicks) different radio buttons are clicked. -To test, try this; click MD (then OK), then click PhD (then OK), then RPh. When you click RPh, does the alert fire?

(Unfortunately, in the Firebug Console I don't see any actual javascript errors when it stops working.)
GreyHead 13 Feb, 2013
Hi formadmin,

No it doesn't fire the alert - but nothing has changed so it doesn't need to - at least that's how I interpreted your spec.

So nothing is broken here?

Bob
formadmin 14 Feb, 2013
I think the client is just concerned that if someone clicked 3 different radio buttons, then didn't see the alert, they may find it confusing... I don't have an issue with how it is currently, you don't either, but they do.

I'd also like to know why it stops? Is there some limit being placed on how many clicks can happen for the alert?

thank you again!
GreyHead 14 Feb, 2013
Hi formadmin,

There's no limit built in, and, as I said, as far as I can see it doesn't stop. Is this a different problem?

Does your client realistically expect that any serious user is going to click more than one radio button?

Bob
GreyHead 14 Feb, 2013
Hi formadmin,

I rewrote this code block to be a bit more friendly. See test form here

Here's the code. HTML:
<div style="margin-bottom:5px;">Select the ones that apply:</div>
<div name="" id="choose_npi">
    <input type="radio" name="prof-type" id="md" data-type='npi' value="MD" />
    MD
    <input type="radio" name="prof-type" id="do" data-type='npi' value="DO" />
    DO
    <input type="radio" name="prof-type" id="phd" data-type='lic' value="PhD" />
    PhD
    <input type="radio" name="prof-type" id="pharmd" data-type='lic' value="PharmD" />
    PharmD
    <input type="radio" name="prof-type" id="rph" data-type='lic' value="RPh" />
    RPh
    <input type="radio" name="prof-type" id="pa" data-type='lic' value="PA" />
    PA
    <input type="radio" name="prof-type" id="rn" data-type='lic' value="RN" />
    RN
    <input type="radio" name="prof-type" id="np" data-type='lic' value="NP" />
    NP
    <input type="radio" name="prof-type" data-type='other' id="other" value="Other" />
    Other
</div>
<div>
    <label for="npi">NPI#: </label>
    <input class="" size="20" name="prof-type-npi" id="npi"
    type="text" value="" /> <span id='npi_req' style='display:none;'>Required</span>
</div>
<div>
    <label for="lic">State Lic#: </label>
    <input size="20" name="prof-type-lic" id="lic" type="text" value="" /> <span id='lic_req' style='display:none;'>Required</span>
</div>
<div>
    <label for="prof-type-other">Other: </label>
    <input type="text" name="prof-type-other" id="choose_other" size="20" value="" /> <span id='other_req' style='display:none;'>Required</span>
</div>
Note that the radio buttons now all have the same name and the attribute data-type is used to group them.

JavaScript:
window.addEvent('domready', function() {
  var radios;
  radios = $$('input[name=prof-type]');
  radios.each(function(item) {
    item.addEvent('click', makeRequired);
  });
  function makeRequired() {
    var radio, type;
    radio = $$('input[name=prof-type]:checked')[0];
    type = radio.getProperty('data-type');
    switch(type) {
      case 'lic':
        $('npi_req').setStyle('display', 'none');
        $('lic_req').setStyle('display', 'inline');
        $('other_req').setStyle('display', 'none');
        $('lic').disabled = false;
        $('npi').disabled = true;
        break;
      case 'npi':
        $('npi_req').setStyle('display', 'inline');
        $('lic_req').setStyle('display', 'none');
        $('other_req').setStyle('display', 'none');
        $('lic').disabled = true;
        $('npi').disabled = false;
        break;
      case 'other':
        $('npi_req').setStyle('display', 'none');
        $('lic_req').setStyle('display', 'none');
        $('other_req').setStyle('display', 'inline');
        $('lic').disabled = false;
        $('npi').disabled = false;
        break;
    }
  }
});
Hopefully this is much easier to read and to amend.

Bob
formadmin 14 Feb, 2013
That's so much easier to work with...however, the form can now be submitted if the required fields are left blank... that's kinda bad.

If you have time, maybe address that, if not, I feel you've gone above and beyond already.

You're the MAN!

cheers,
GreyHead 14 Feb, 2013
Hi formadmin,

Sorry, I was in a rush and didn't add the code to turn the validation on and off. I'll take a look in the morning.

Bob
GreyHead 15 Feb, 2013
Hi formadmin,

Updated JavaScript
window.addEvent('domready', function() {
  var radios, req, npi, lic, other;
  npi = $('npi');
  lic = $('lic');
  other = $('choose_other');
  req = "validate['required']";
  radios = $$('input[name=prof-type]');
  radios.each(function(item) {
    item.addEvent('click', setRequired);
  });
  function setRequired() {
    var radio, type;
    radio = $$('input[name=prof-type]:checked')[0];
    type = radio.getProperty('data-type');
    switch(type) {
      case 'lic':
        $('npi_req').setStyle('display', 'none');
        $('lic_req').setStyle('display', 'inline');
        $('other_req').setStyle('display', 'none');
        makeRequired(lic);
        makeDisabled(npi);
        break;
      case 'npi':
        $('npi_req').setStyle('display', 'inline');
        $('lic_req').setStyle('display', 'none');
        $('other_req').setStyle('display', 'none');
        makeRequired(npi);
        makeDisabled(lic);
        break;
      case 'other':
        $('npi_req').setStyle('display', 'none');
        $('lic_req').setStyle('display', 'none');
        $('other_req').setStyle('display', 'inline');
        makeOptional(npi);
        makeOptional(lic);
        break;
    }
  }
  function makeRequired(el){
    el.disabled = false;
    el.addClass(req);
    formCheck_test_form_npi_b.register(el);
  }
  function makeDisabled(el){
    el.disabled = true;
    el.setProperty('class', '');
    formCheck_test_form_npi_b.removeError(el);
    formCheck_test_form_npi_b.dispose(el);
  }
  function makeOptional(el){
    el.disabled = false;
    el.setProperty('class', '');
    formCheck_test_form_npi_b.removeError(el);
    formCheck_test_form_npi_b.dispose(el);
  }
});
This topic is locked and no more replies can be posted.