Solved

Dynamically naming conditionally/dynamically added form fields with jQuery

Posted on 2013-12-17
3
243 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 7

Expert Comment

by:cstsang
ID: 39725946
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
ID: 39725976
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
ID: 39726533
Perfect! Thank you so much; I'm still learning jQuery and that was beyond me.
0

Featured Post

Report: Liquid Web beats Amazon, Rackspace & More

A study by performance analyst firm Cloud Spectator finds that Liquid Web beats rivals Amazon, Rackspace and DigitalOcean when it comes to website and cloud application performance.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
HTML editor custom button 3 85
Textbox autocomplete using jquery in asp.net 13 48
Can't see json data in ajax call to Highcharts 2 26
bootstrap collapse 2 17
Hi all! Recently there was EE question and the person wanted to have a multi-column textbox <div> selection, so as a first step to answer I provided a link but that was not complete with JavaScript selection, but had a good style sheet. So as a ques…
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 how to dynamically set the form action using jQuery.
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)
Suggested Courses

732 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