Solved

Dynamically naming conditionally/dynamically added form fields with jQuery

Posted on 2013-12-17
3
234 Views
Last Modified: 2013-12-18
Okay, this what I have working:

I have a list of audio conferences ("audios") that people can sign up for. Next to each audio is a select field allowing them to select the number of people that will be participating. This number will be multiplied by the cost and all added up into a grand total field. If the number of participants is greater than 0, a text field  asking for the names of the participants is appended to that audio.

This is what is almost working:

I'm trying to name the created textfields like registrantNames1, registrantNames2, etc. by drawing the number from the text in the span.audio-number. My selector is obviously not correct since the number can be added if I set the variable directly. I've tried two different methods below and the console is logging nothing. (An empty string, maybe? It's not coming up as undefined.)

This is what's not working:

If someone selects two participants for an audio, the text field appears. If they realize, "Oops! I actually have three," and change their selection, another text field is appended (and so on if they keep changing it.) This is not a surprise, looking at the code... I'm just not sure how to fix it.

Similarly, if someone selects a number of participants then changes their mind and sets it to 0, the form field persists. I'd like to get rid of it.

Here's the HTML:
<div class="audio-row audio-1">
    <div class="audio-info">Audio <span class="audio-number">1</span> &ndash; $<span class="var-conference-cost">100</span> 
        <select name="registrants1" class="select-number-of-attendees">
            <option value="0" selected>number of attendees</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
        </select>
    </div>
</div>
<div class="audio-row audio-2">
    <div class="audio-info">Audio 2 &ndash; $<span class="var-conference-cost">300</span> 
        <select name="registrants2" class="select-number-of-attendees">
            <option value="0" selected>number of attendees</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
        </select>
    </div>
</div>
<div class="audio-row audio-3">
    <div class="audio-info">Audio 3 &ndash; $<span class="var-conference-cost">500</span> 
        <select name="registrants3" class="select-number-of-attendees">
            <option value="0" selected>number of attendees</option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
        </select>
    </div>
</div>
Grand Total: <input name="totalcost" type="text" value="$" class="grandTotal" readonly="readonly">

Open in new window


Here's the jQuery:
$('.select-number-of-attendees').change(function () {
    //total up the price
    var total = 0;
    var thisquantity = $(this).val();
    var thisID = $(this).parent().find('.audio-number').text();
    console.log(thisID);
    var thisID = $(this).closest('div.audio-info').find('span.audio-number').text();
    console.log(thisID);
    $(".audio-row").each(function () {
        var cost = $(this).find('span.var-conference-cost').text();
        var qty = $(this).find('.select-number-of-attendees').val();
        var subtotal = qty * cost;
        if (!isNaN(subtotal)) $(this).find('.subtotal').val((subtotal).toFixed(2));
        if (!isNaN(subtotal)) total += subtotal;
    });
    $(".grandTotal").val("$" + (total).toFixed(2));
    //add the form field
    console.log(thisID);
    if (thisquantity != 0)
        {
            $(this).parent().append( "<p>Please enter the names and emails of your attendees.</p><textarea name=\"registrantNames" + thisID + "\">Test</textarea>" );
        }
});

Open in new window


(And here's the Fiddle: http://jsfiddle.net/r9A76/1/)

The HTML structure isn't set in stone, so divs or classes can be added if needed. (Something I'd considered was creating an empty div to hold the created form field then testing for content of that div when seeing if a field needed to be added, but I'm not sure if that's either necessary or a good idea.) Thank you for any assistance you can give!
0
Comment
Question by:SiobhanElara
  • 2
3 Comments
 
LVL 7

Expert Comment

by:cstsang
Comment Utility
It should be what you need:
<html>
	<head>
		<script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
		<script language=javascript>
			$( document ).ready(function() 
								{
									$("select[id^=registrants]").change(handleOnchange);
								});
			function handleOnchange()
			{
				var total = 0;
				var noOfAttendees=$(this).val();
				var cost = $(this).find('span.var-conference-cost').text();
				var thisID = $(this).parent().find('.audio-number').text();
				if (noOfAttendees==0)
				{	
					$("#registrantNames"+thisID).remove();
				}
				else	
				{
					if ($("#registrantNames"+thisID).length==0)
						$(this).parent().append("<div id=\"registrantNames"+thisID+"\"></div>");
					registrantNamesObj=$("#registrantNames"+thisID);
					for (i=0;i<noOfAttendees;i++)
					{
						if ($("#registrantName_"+thisID+"_"+i).length==0)
						{
							registrantNamesObj.append("<div id=\"registrantName_"+thisID+"_"+i+"\"><p>Please enter the names and emails of your attendees.</p><textarea name=\"registrantNames" + thisID + "\">Test</textarea></div>");
						}
					}
					if ($("#registrantNames"+thisID).children().length>noOfAttendees)
					{
						for (i=noOfAttendees;i<=$("#registrantNames"+thisID).children().length;i++)
						{
							$("#registrantName_"+thisID+"_"+i).remove();
						}	
					}
				}
				$(".audio-row").each(function () {
				        var cost = $(this).find('span.var-conference-cost').text();
				        var qty = $(this).find('.select-number-of-attendees').val();
				        var subtotal = qty * cost;
				        if (!isNaN(subtotal)) $(this).find('.subtotal').val((subtotal).toFixed(2));
				        if (!isNaN(subtotal)) total += subtotal;
				    });								
				$(".grandTotal").val("$" + (total).toFixed(2));		
			}
		</script>
	</head>	
	<body>
		<div class="audio-row audio-1">
		    <div class="audio-info">Audio <span class="audio-number">1</span> &ndash; $<span class="var-conference-cost">100</span> 
		        <select id="registrants1" class="select-number-of-attendees">
		            <option value="0" selected>number of attendees</option>
		            <option value="1">1</option>
		            <option value="2">2</option>
		            <option value="3">3</option>
		            <option value="4">4</option>
		            <option value="5">5</option>
		        </select>
		    </div>
		</div>
		<div class="audio-row audio-2">
		    <div class="audio-info">Audio <span class="audio-number">2</span> &ndash; $<span class="var-conference-cost">300</span> 
		        <select id="registrants2" class="select-number-of-attendees">
		            <option value="0" selected>number of attendees</option>
		            <option value="1">1</option>
		            <option value="2">2</option>
		            <option value="3">3</option>
		            <option value="4">4</option>
		            <option value="5">5</option>
		        </select>
		    </div>
		</div>
		<div class="audio-row audio-3">
		    <div class="audio-info">Audio <span class="audio-number">3</span> &ndash; $<span class="var-conference-cost">500</span> 
		        <select id="registrants3" class="select-number-of-attendees">
		            <option value="0" selected>number of attendees</option>
		            <option value="1">1</option>
		            <option value="2">2</option>
		            <option value="3">3</option>
		            <option value="4">4</option>
		            <option value="5">5</option>
		        </select>
		    </div>
		</div>
		Grand Total: <input name="totalcost" type="text" value="$" class="grandTotal" readonly="readonly">
	</body>
</html>                                  

Open in new window

0
 
LVL 7

Accepted Solution

by:
cstsang earned 500 total points
Comment Utility
Sorry, there are some bugs in the previous coding,here is the bug fix version:
<html>
	<head>
		<script type='text/javascript' src='http://code.jquery.com/jquery-1.9.1.js'></script>
		<script language=javascript>
			$( document ).ready(function() 
								{
									$("select[id^=registrants]").change(handleOnchange);
								});
			function handleOnchange()
			{
				var total = 0;
				var noOfAttendees=$(this).val();
				var thisID = $(this).parent().find('.audio-number').text();
				if (noOfAttendees==0)
				{	
					$("#registrantNames"+thisID).remove();
				}
				else	
				{
					if ($("#registrantNames"+thisID).length==0)
						$(this).parent().append("<div id=\"registrantNames"+thisID+"\"></div>");
					registrantNamesObj=$("#registrantNames"+thisID);
					for (i=0;i<noOfAttendees;i++)
					{
						if ($("#registrantName_"+thisID+"_"+i).length==0)
						{
							registrantNamesObj.append("<div id=\"registrantName_"+thisID+"_"+i+"\"><p>Please enter the names and emails of your attendees.</p><textarea name=\"registrantName_"+thisID+"_"+i+ "\">Test</textarea></div>");
						}
					}
					childCount=$("#registrantNames"+thisID).children().length;
					if (childCount>noOfAttendees)
					{
						for (i=noOfAttendees;i<childCount;i++)
						{
							$("#registrantName_"+thisID+"_"+i).remove();
						}	
					}
				}
				$(".audio-row").each(function () {
				        var cost = $(this).find('span.var-conference-cost').text();
				        var qty = $(this).find('.select-number-of-attendees').val();
				        var subtotal = qty * cost;
				        if (!isNaN(subtotal)) $(this).find('.subtotal').val((subtotal).toFixed(2));
				        if (!isNaN(subtotal)) total += subtotal;
				    });								
				$(".grandTotal").val("$" + (total).toFixed(2));		
			}
		</script>
	</head>	
	<body>
		<div class="audio-row audio-1">
		    <div class="audio-info">Audio <span class="audio-number">1</span> &ndash; $<span class="var-conference-cost">100</span> 
		        <select id="registrants1" class="select-number-of-attendees">
		            <option value="0" selected>number of attendees</option>
		            <option value="1">1</option>
		            <option value="2">2</option>
		            <option value="3">3</option>
		            <option value="4">4</option>
		            <option value="5">5</option>
		        </select>
		    </div>
		</div>
		<div class="audio-row audio-2">
		    <div class="audio-info">Audio <span class="audio-number">2</span> &ndash; $<span class="var-conference-cost">300</span> 
		        <select id="registrants2" class="select-number-of-attendees">
		            <option value="0" selected>number of attendees</option>
		            <option value="1">1</option>
		            <option value="2">2</option>
		            <option value="3">3</option>
		            <option value="4">4</option>
		            <option value="5">5</option>
		        </select>
		    </div>
		</div>
		<div class="audio-row audio-3">
		    <div class="audio-info">Audio <span class="audio-number">3</span> &ndash; $<span class="var-conference-cost">500</span> 
		        <select id="registrants3" class="select-number-of-attendees">
		            <option value="0" selected>number of attendees</option>
		            <option value="1">1</option>
		            <option value="2">2</option>
		            <option value="3">3</option>
		            <option value="4">4</option>
		            <option value="5">5</option>
		        </select>
		    </div>
		</div>
		Grand Total: <input name="totalcost" type="text" value="$" class="grandTotal" readonly="readonly">
	</body>
</html>                                 

Open in new window

0
 

Author Closing Comment

by:SiobhanElara
Comment Utility
Perfect! Thank you so much; I'm still learning jQuery and that was beyond me.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

by Julian Matz As of jQuery (http://jquery.com/) 1.4 the .live() method (http://api.jquery.com/live/) supports custom events as well as some standard JavaScript events that it previously didn't support. Among these is the submit event. Unlike …
Introduction HyperText Transfer Protocol (http://www.ietf.org/rfc/rfc2616.txt) or "HTTP" is the underpinning of internet communication.  As a teacher of web development I have heard many questions, mostly from my younger students who have come to t…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now