Results 1 to 8 of 8

Thread: Problems Validating Multiple Forms on one page with JS, need wildcard for any number.

  1. #1
    Join Date
    Jul 2010
    Location
    Bridport, Dorset
    Posts
    58
    Thanks
    6
    Thanked 1 Time in 1 Post

    Default Problems Validating Multiple Forms on one page with JS, need wildcard for any number.

    Hi Guys,

    I have product pages like this:-
    http://www.steptoes.co.uk/product-di...ZT1XOTA3.ghtml

    On this page is a visible div and a hidden div, when you select the different colours it hides all of them except for the div that you have selected.

    This leads me to problems with the form validation for sizes as it creates more then one form on the page each with unique ID's.

    I have this code for form Validation and it will work if the name of the form is 'main' and the name of the select tag is 'idsize':-
    Code:
    function validateForm(){
    	if(document.main.idsize.selectedIndex==0)
    	{
    	alert("Please select an Item.");
    	document.main.idsize.focus();
    	return false;
    	}
    	return true;
    	}
    My problem is that as there are multiple forms on the page I need to add the ID from the database into the javascript so the select tag looks like this in my code (I use GINAS, so you may not recognise the tags I use to call the DB)
    Code:
    <div class="sizeselect">
    <span style="font-size:11px;">Sizes Available:</span><br />	
    <select id="menu-[_own ID_]" name="idsize_[_own ID_]">
    <option value="0">--Size--</option>
    
    	[_foreach [_own Size_]_]
    <option value="[_value_]">[_value_]</option>
    	[_/foreach_]	
    
    </select>
    </div>
    The [_own ID_] tag replaces it with the number from the ID field in the corresponding entry in the database.
    So my question:
    Is there some sort of wildcard character in JS for any number up to three digits long?
    Could this then be placed into the script to make it work for any form with a select tag with the names 'idsize_1' through to 'idsize_800'.
    Or is there another script someone could suggest that would solve this problem?

    Thanks for your time.
    Best regards,
    Pete

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    28,926
    Thanks
    43
    Thanked 3,192 Times in 3,155 Posts
    Blog Entries
    12

    Default

    The easiest way to find the number in question would be if - say the form had the same number attached to its id. If you have a reference to the form, then using a regular expression function you could know what the name and id of the select would be. This depends upon knowing a little more about the structure of these forms than you've told. But given this sort of structure or one that follows it as far as id's and names go and no other way to submit each form than via its submit button:

    HTML Code:
    <form action="#" id="form-1">
    <div class="sizeselect">
    <span style="font-size:11px;">Sizes Available:</span><br />	
    <select id="menu-1" name="idsize_1">
    <option value="0">--Size--</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    </select>
    </div>
    <input type="submit" value="Submit">
    </form>
    In other words, this demo works:

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript">
    (function(){
    	var re = /^form-(\d+)$/;
    	function validateForm(form){
    		var qualifier;
    		if((qualifier = re.exec(form.id))){
    			qualifier = form.elements['idsize_' + qualifier[1]];
    		} else {return true;}
    		if(qualifier.selectedIndex === 0){
    			alert("Please select an Item.");
    			qualifier.focus();
    			return false;
    		}
    		return true;
    	}
    	document.onclick = function(e){
    		e = e || event;
    		var t = e.target || e.srcElement, form, returnValue = true;
    		if(t.type && t.type.toLowerCase() === 'submit' && (form = t.form)){
    			returnValue = validateForm(form);
    		}
    		if(!returnValue){
    			if(e.preventDefault){e.preventDefault();}	
    		}
    		e.returnValue = returnValue;
    		return returnValue;
    	}
    })();
    </script>
    </head>
    <body>
    <form action="#" id="form-1">
    <div class="sizeselect">
    <span style="font-size:11px;">Sizes Available:</span><br />	
    <select id="menu-1" name="idsize_1">
    <option value="0">--Size--</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    </select>
    </div>
    <input type="submit" value="Submit">
    </form>
    <form action="#" id="form-2">
    <div class="sizeselect">
    <span style="font-size:11px;">Sizes Available:</span><br />	
    <select id="menu-2" name="idsize_2">
    <option value="0">--Size--</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    </select>
    </div>
    <input type="submit" value="Submit">
    </form>
    </body>
    </html>
    You can have as many of these forms as you like numbered 0 or 1 or whatever to whatever. They don't even need to be in sequence. They can even arrive on the page after it's loaded, though your scenario doesn't seem to require that. There can be other forms on the page with id's that don't follow the id="form-###" convention and/or others that do but that don't have such a select element in them. Those forms (if any) will be unaffected, or could be worked into an alternate validation tailored to them.

    One tricky part is the form id as processed by the regular expression highlighted above. I'm assuming:

    Code:
    id="form-###"
    where ### is a number as the id of each form you want to process. If the id is different, let me know and I will adjust the re for you if need be. But it breaks down like so:

    Code:
    var re = /^form-(\d+)$/;
    The green part is the form's id without the number suffix. The red part is the number suffix. The ^ and $ signify the beginning and end of the id string respectively such that it won't match:

    Code:
    id="aform-1"
    because a comes first, but will match:

    Code:
    id="form-2001"
    where 2001 is 0 or any unsigned integer.

    That and perhaps other tweaks to the script might be required if other aspects of the targeted forms deviate too much from the basic structure I've outlined. They can be more complex, but as I say must otherwise follow the naming and iding conventions shown.

    If you want more help, let me know the problem as you see it and give me a link to the page so I can see the actual served source of the forms.
    Last edited by jscheuer1; 12-24-2010 at 12:38 PM.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Dec 2010
    Location
    DD has been asked by me to remove my one post and to cancel my account.
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Maybe I'm missing something

    Maybe I'm missing something?

    Code:
    <html>
    <head>
    	<script type= "text/javascript">
    		// argument {f} is reference to calling form passed using "this" 
    		// keyword in onsubmit calls to validateForm()
    		function validateForm( f ) {
    			// form has one select element - get a reference to it
    			var s = f.getElementsByTagName('SELECT')[0];
    			// record validation state, i.e., whether valid option selected
    			var isSelected = 0 != s.selectedIndex;
    			// if option not valid, advise user, and set focus
    			if (!isSelected) {
    				alert("Please select an Item.");
    				s.focus();
    			}
    			// return state of validation
    			//return isSelected;
    
    			// for testing only
    			alert('would have returned ' + isSelected);
    			return false;
    		};
    	</script>
    </head>
    
    <body>
    	<!-- pass self-reference to form via "this" keyword when calling validateForm() -->
    	<form action="basket.ghtml" method="post" 
    		name="main" target="_self" onsubmit="return validateForm(this)">
    		<div class="buttondiv">
    		<div class="sizeselect">
    			<span style="font-size:11px;">Sizes Available:</span><br />	
    			<select id="menu-110" name="idsize_110">
    			<option>--Size--</option>
    				<option value="36">36</option>
    				<option value="37">37</option>
    				<option value="38">38</option>
    				<option value="39">39</option>
    				<option value="40">40</option>
    				<option value="41">41</option>
    				<option value="42">42</option>
    				<option value="43">43</option>
    				<option value="44">44</option>
    				<option value="45">45</option>
    				<option value="46">46</option>	
    			</select>
    		</div>
    			Price: &pound;125.00
    			<p><input type="submit" name="action" value="Add to Basket" class="button" /></p>
    		</div>
    	</form>
    </body>
    </html>
    Last edited by jscheuer1; 12-25-2010 at 01:11 AM. Reason: format code

  4. #4
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    28,926
    Thanks
    43
    Thanked 3,192 Times in 3,155 Posts
    Blog Entries
    12

    Default

    Quote Originally Posted by richarduie View Post
    Maybe I'm missing something?
    Not really. In fact I missed looking at lilpete's example link. If they're all like that, your solution should be fine provided the "for testing only" lines are commented and the //return isSelected; line is uncommented. I would probably rewrite it to separate the content from script and to free the script from the global scope, but that's a fine point and the original already uses the hard coded onsubmit of the form as well as the global scope.

    Here's closer to what I would do:

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <script type="text/javascript">
    (function(){
    	var re = /^idsize_\d+$/;
    	function validateForm(form){
    		var qualifier = form.getElementsByTagName('select')[0];
    		if(qualifier && re.test(qualifier.name) && qualifier.selectedIndex === 0){
    			alert("Please select an Item.");
    			qualifier.focus();
    			return false;
    		}
    		return true;
    	}
    	function clickEvent(e){
    		e = e || event;
    		var t = e.target || e.srcElement, form, returnValue = true;
    		if(t.type && t.type.toLowerCase() === 'submit' && (form = t.form)){
    			returnValue = validateForm(form);
    		}
    		if(!returnValue){
    			if(e.preventDefault){e.preventDefault();}	
    		}
    		e.returnValue = returnValue;
    		return returnValue;
    	}
    	if (window.addEventListener){
    		document.addEventListener('click', clickEvent, false);
    	}
    	else if (window.attachEvent){
    		document.attachEvent('onclick', clickEvent);
    	}
    })();
    </script>
    </head>
    <body>
    <form action="basket.ghtml" method="post" name="main" target="_self">
    <div class="buttondiv">
    <div class="sizeselect">
    	<span style="font-size:11px;">Sizes Available:</span><br />	
    	<select id="menu-110" name="idsize_110">
    	<option>--Size--</option>
    		<option value="36">36</option>
    		<option value="37">37</option>
    		<option value="38">38</option>
    		<option value="39">39</option>
    		<option value="40">40</option>
    		<option value="41">41</option>
    		<option value="42">42</option>
    		<option value="43">43</option>
    		<option value="44">44</option>
    		<option value="45">45</option>
    		<option value="46">46</option>
    		
    	</select>
    </div>
    	Price: &pound;125.00
    	<p><input type="submit" name="action" value="Add to Basket" class="button" /></p>
    </div>
    </form>
    <form action="basket.ghtml" method="post" name="main" target="_self">
    <div class="buttondiv">
    <div class="sizeselect">
    	<span style="font-size:11px;">Sizes Available:</span><br />	
    	<select id="menu-111" name="idsize_111">
    	<option>--Size--</option>
    		<option value="36">36</option>
    		<option value="37">37</option>
    		<option value="38">38</option>
    		<option value="39">39</option>
    		<option value="40">40</option>
    		<option value="41">41</option>
    		<option value="42">42</option>
    		<option value="43">43</option>
    		<option value="44">44</option>
    		<option value="45">45</option>
    		<option value="46">46</option>
    		
    	</select>
    </div>
    	Price: &pound;125.00
    	<p><input type="submit" name="action" value="Add to Basket" class="button" /></p>
    </div>
    </form>
    </body>
    </html>
    Notes: Even though it's coded for click, this also takes in the ENTER key when used to submit the form. I wanted to use document submit, but that's not supported in IE.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  5. The Following User Says Thank You to jscheuer1 For This Useful Post:

    lilpete (01-05-2011)

  6. #5
    Join Date
    Jul 2010
    Location
    Bridport, Dorset
    Posts
    58
    Thanks
    6
    Thanked 1 Time in 1 Post

    Default

    Hi John,

    Sorry I haven't been back, only just got back to work after Christmas and New Year,
    I have implemented the first suggestion by yourself..
    The JavaScript is in the head of the document,
    I have also added the id attribute to the form element..
    and taken away all the bits I know longer need (onsubmit etc..)

    and it works like a charm!
    Thank you very much for this solution and your explanation of this code,
    its always good to know what I'm cutting and pasting.. :P

    Live Example:-
    http://www.steptoes.co.uk/product-di...GTVdWNDk.ghtml

    All the best!

  7. #6
    Join Date
    Jul 2010
    Location
    Bridport, Dorset
    Posts
    58
    Thanks
    6
    Thanked 1 Time in 1 Post

    Default

    Sorry, but the saga continues.. it appears the script that was lovingly created by yourself has broken the fancy box script I have on the page for the product display.

    Sorry to ask another favour of you, but is there anything instantly noticable that would cause this?
    It happens when the two script are both in the head..
    I have put my site back to the original.

    A mock up Broken page is here:
    http://www.steptoes.co.uk/test.html

    Shame, I was sooo close!

  8. #7
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    28,926
    Thanks
    43
    Thanked 3,192 Times in 3,155 Posts
    Blog Entries
    12

    Default

    Sorry about that, I assumed all other click events would be returning true. This version takes care of that problem:

    Code:
    <script type="text/javascript">
    (function(){
    	var re = /^form-(\d+)$/;
    	function validateForm(form){
    		var qualifier;
    		if((qualifier = re.exec(form.id))){
    			qualifier = form.elements['idsize_' + qualifier[1]];
    		} else {return true;}
    		if(qualifier.selectedIndex === 0){
    			alert("Please select an Item.");
    			qualifier.focus();
    			return false;
    		}
    		return true;
    	}
    	document.onclick = function(e){
    		e = e || event;
    		var t = e.target || e.srcElement, form, returnValue;
    		if(t.type && t.type.toLowerCase() === 'submit' && (form = t.form)){
    			returnValue = validateForm(form);
    			if(!returnValue){
    				if(e.preventDefault){e.preventDefault();}	
    				e.returnValue = returnValue;
    				return returnValue;
    			}
    		}
    	}
    })();
    </script>
    It only takes control of the return if the form and submit button qualify. Otherwise the return set by other scripts, or if none, the default return of the item clicked is respected.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  9. The Following User Says Thank You to jscheuer1 For This Useful Post:

    lilpete (01-05-2011)

  10. #8
    Join Date
    Jul 2010
    Location
    Bridport, Dorset
    Posts
    58
    Thanks
    6
    Thanked 1 Time in 1 Post

    Default

    Awesome! Thank you so much for that John, works like a charm!

    Hopefully I will share your understanding of JavaScript at the same level one day.

    All the best!
    Last edited by lilpete; 01-05-2011 at 10:21 AM.

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
  •