Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 15 of 15
  1. #1
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Need help writing subtotal/get/put script

    Hi folks. There have been several requests on this forum for subtotal/tax/total forms, but I know so little about Java scripts that I haven't been able to adapt your provided solutions to my needs. I know it seems like a cop-out to just ask someone else to do it for me, but I need to get this form functioning as soon as possible, since I'll be running business through this site (which, until now, I've designed on my own). I would like to learn JS eventually, or at least have a working knowledge of it, but I'm short on time right now.

    I know that a Java script should be able to do what I need it to, so if there's anyone out there who can help, I would be incredibly grateful. I hope it's not too much trouble.

    Here's the web page. I've kept my html nice and clean, so hopefully it's very easy to read: link

    What I need is to multiply the price of either size options by the quantity, add the sales tax and shipping, and the total will update automatically. The paper choice will not affect the price. Ideally, I would like the "submit request" button to send an email with all supplied information to my email address, and also send a copy to the supplied customer address. (I think that's considered a get/put script?) Again, if there's anyone who can help with this, I would be very grateful.

    Thanks,
    Jon

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    And what do you do if the user has JavaScript disabled in their browser?

    And you can't rely upon JavaScript (or HTML) to send mail for you. It will only work about half the time.

    So you *NEED* server-side code that will both make sure that the total is correct (that is, it will duplicate the work of the JS code, ignoring the total that JS comes up with) *AND* send the email(s). That server-side code can be written in PHP/ASP/JSP/etc., but you really do need it.

    The JS code is not at all a bad idea to have, but it's trivial compared to creating the server-side code.

    Anyway, nice to see you already have the calls to update_total in there. Though I *THINK* that for the radio buttons you should use onclick= instead of onchange= (try it both ways, if you like). So all you need is the JS code:
    Code:
    <script type="text/javascript">
    function update_total( )
    {
        var form = document.getElementById("orderform");
        var isLarge = form.size[1].checked;
        var price = isLarge ? 40 : 30;
        var qty = parseInt( form.quantity.value );
        if ( isNaN(qty) ) 
        {
            alert("You must enter a number for the quantity");
            qty = 0;
        }
        form.quantity.value = qty; // put it back, just in case
        var subtotal = qty * price;
        document.getElementById("subtotal").innerHTML = subtotal.toFixed(2);
        var tax = subtotal * 0.07;
        document.getElementById("tax").innerHTML = tax.toFixed(2);
        var total = subtotal + tax;
        document.getElementById("total").innerHTML = total.toFixed(2);
        
        return qty > 0;
    }
    </script>
    I added that last line (the return line) because I think you really need to *ALSO* call update_total when the form is submitted and no allow the submit if the quantity is zero.

    To do that, just change your <form>, thus:
    Code:
    <form id="orderform" name="orderform" method="post" onsubmit="return update_total();">
    I haven't actually checked this code, because it's so simple. If you find a glitch, though, I will.

    By the by...it's not really important, but:
    -- your <form> does not need a name
    -- none of your form fields need an id
    -- the price=xxx in the radio buttons and the one <span> is spurious and ignored
    -- <span>s don't have names
    -- you forgot the dollar sign on the total

  • Users who have thanked Old Pedant for this post:

    jonathanmayer (08-08-2011)

  • #3
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Thanks and follow-up

    First, thanks for taking the time to help me. I much appreciate it.

    Can you explain what you mean about server-side code? This is the first I've heard of it, so I don't know what it is, or where to look for it. But thanks for pointing that out; I probably wouldn't have known that until 20 emails had been lost in cyberspace or not sent.

    The only problem I notice with the script is that the shipping isn't included in the total. Simple fix?

    Some of the other things you pointed out (and thanks, by the way!): I've put names and ids on most of my elements, because I was taught to do that for accessibility screen readers. I know most of those doesn't have a visible effect otherwise. I couldn't find a spurious span, but I did remove the span names and "price" elements. (I think those were leftover from another JS that I was trying to make work for me.) I haven't updated the file on the server though, so you won't see anything different on the website.

    As far as the dollar sign on the total, that will bother me, because I'm anal about little things. The reason it isn't there is because the "total" span is styled to be the white box. So putting a dollar sign outside the span would put it outside the box. Is there a way to make the JS include the dollar sign with the total? (Or else maybe I could try putting a span inside a div inside a table cell... but that seemed kind of ridiculous.)

  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Code:
    <script type="text/javascript">
    var SHIPPING = 7.34; // change when/if you change the HTML of web page
    
    function update_total( )
    {
        var form = document.getElementById("orderform");
        var isLarge = form.size[1].checked;
        var price = isLarge ? 40 : 30;
        var qty = parseInt( form.quantity.value );
        if ( isNaN(qty) ) 
        {
            alert("You must enter a number for the quantity");
            qty = 0;
        }
        form.quantity.value = qty; // put it back, just in case
        var subtotal = qty * price;
        document.getElementById("subtotal").innerHTML = subtotal.toFixed(2);
        var tax = subtotal * 0.07;
        document.getElementById("tax").innerHTML = tax.toFixed(2);
        var total = subtotal + tax + SHIPPING;
        document.getElementById("total").innerHTML = "$" + total.toFixed(2);
        
        return qty > 0;
    }
    </script>
    If you have no idea about server side scripting, then ask you ISP if they have a "mailer" that you can use. If so, you'll simply change the <form> to add an action to it, something like this:
    Code:
    <form action="path/to/mailer.php" id="orderform" method="post" onsubmit="return update_total();">
    Though if you aren't going to write your own server-side code then you probably should extend your javascript checking to do a check at onsubmit time to make sure that the name, email, and artwork title are filled in, as well. JS checking isn't as good as server-side checking, but it's better than nothing.

  • Users who have thanked Old Pedant for this post:

    jonathanmayer (08-08-2011)

  • #5
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Should mention that usually you only charge sales tax on in-state shipments. Amazon, for example, has been fighting that issue tooth and nail with the various states and has so far prevailed.

  • #6
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts
    My web host uses PHP, so I guess I'll try to include the server-side code. It will probably be slow going, though, because I've no idea what I'm doing.

    I appreciate your help, though. Thanks for the JS and the advice.

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Chances are pretty good that they have a built-in PHP page that will mail a <form> for you.

    Ask them.

    Often, such pages are named something like "mail_form.php" or "form_mailer.php" or similar.

    All they do is take all the fields from the form and mail them to the address which is also specified by the form. Usually, the mailto address is specified in a hidden form field and is your own email addrss.

    But if you don't ask, you can't receive.

  • Users who have thanked Old Pedant for this post:

    jonathanmayer (08-10-2011)

  • #8
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Will do. Thanks.

  • #9
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Before emailing support, I did some searching in the Help articles on my cPanel. I did find some kind of built-in email function, like you were talking about. I've done some testing, and so far it works just fine. Unfortunately, it doesn't include the scripted "total" in the email, but that's not a deal-breaker. If nothing else, I can just recalculate the total based on the options they selected.

    I'm not anxious to take up any more of your time, but how should I go about the javascript checking, then?

  • #10
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Oh, that's easy to fix!!!

    Sorry.

    All we need to do is add a HIDDEN form field that copies the displayed total.

    Even hidden form fields are sent to the server and will then be emailed. (In fact, the server has no idea which fields are hidden ones and which are visible.)

    So add this line RIGHT BEFORE your </form> line:
    Code:
        ...
        <input type="hidden" name="total" />
    </form>
    And then, in the JavaScript code, add the code in red right after the existing code in black:
    Code:
        document.getElementById("total").innerHTML = "$" + total.toFixed(2);
        form.total.value = total.toFixed(2);
    If there are any other values you want sent via email, pull the same trick!

  • Users who have thanked Old Pedant for this post:

    jonathanmayer (08-10-2011)

  • #11
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts
    You are truly a glorious beacon of light. Thank you. When this is up and running, can I send you some homemade cookies or anything?

    About the javascript checking? Right now, you can submit the form without entering any data. How would you keep it from submitting the form unless all fields are filled out (and maybe even have an error message pop up)?

  • #12
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Now why did I know you were going to ask that?

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="description" content="Order prints of artwork by Christian illustrator Jonathan Mayer." />
    
    <title>Scapegoat Studio - Prints</title>
    
    <link href="styles.css" rel="stylesheet" type="text/css" />
    
    <script type="text/javascript">
    var shipping = 7.34;
    
    function update_total( )
    {
        var form = document.getElementById("orderform");
        var price = isLarge ? 40 : 30;
        var qty = parseInt( form.quantity.value );
        var isSmall = form.size[0].checked;
        var isLarge = form.size[1].checked;
    
        if ( !isSmall && !isLarge )
        {
            alert("You must choose a print size");
            qty = 0;
        }
        else if ( isNaN(qty) || qty == 0 ) 
        {
            alert("You must enter a number for the quantity");
            qty = 0;
        }
        form.quantity.value = qty;
        var subtotal = qty * price;
        document.getElementById("subtotal").innerHTML = subtotal.toFixed(2);
        var tax = subtotal * 0.07;
        document.getElementById("tax").innerHTML = tax.toFixed(2);
        var total = subtotal + tax + shipping;
        document.getElementById("thetotal").innerHTML = "$ " + total.toFixed(2);
        form.total.value = total.toFixed(2)
        
        return qty > 0;
    }
    
    function checkForm( )
    {
        var form = document.getElementById("orderform");
        if ( form.name.value.replace(/\s/g,"").length < 5 ) 
        {
            alert("You must enter your name");
            return false;
        }
        var emre = /^\w[\w\'\-\.]+\@(\w[\w\'\-]*\.)+[a-z]{2,6}$/i;
        if ( ! emre.test( form.mailfrom.value ) )
        {
            alert("You must enter a valid email address");
            return false;
        }
        if ( form.Title.value.replace(/\s/g,"").length < 5 ) 
        {
            alert("You must enter the title of the work you wish to purchase");
            return false;
        }
        return update_total();
    }
    </script>
    
    <!--[if !IE 7]>
    	<style type="text/css">
    		#container {height:100%}
    	</style>
    <![endif]-->
    
    </head>
    
    <body>
    
    <div id="container">
    	<ul id="nav">
    		<li><a href="index.html">Home</a></li>
    		<li><a href="illustration.html">Illustration</a></li>
    		<li><a href="liturgical-art.html">Liturgical Art</a></li>
    		<li><a href="prints.html" class="active">Prints</a></li>
    		<li><a href="contact.html">Contact</a></li>
    	</ul>
    	<div id="stage">
     		<div class="directions">
    			<p>To purchase unframed, autographed prints, please fill out the request form on the right. All fields are 
    
    required.</p>
    			<p>Only image descriptions marked with <i>†</i> will be available to purchase as prints.</p>
    
    			<p>The dimensions of the print will vary depending on the original, but the maximum size cannot exceed 
    
    11x17 in. The size you indicate will be the length of the longest dimension of the image. </p>
    			<p>After your request is submitted, you will receive an email with final pricing and payment instructions.* 
    
    Items will be shipped once payment has been received. Shipped items will be sent USPS Priority Mail in a mailing tube. After order 
    
    confirmation, please allow 3 to 5 business days for shipping.</p>
    			<p>*I accept payment by Paypal or check.</p>
     		</div>
    		<form action="http://bluehost.com/bluemail" 
    			enctype="multipart/form-data" id="orderform" 
    			method="POST" onsubmit="return checkForm();">
      			<fieldset>
      			<legend>Request Form</legend>
    
    			<div>
      				<label for="name"><i>*</i>Name :</label><br  />
        				<input type="text" id="name" name="Name" />
    			</div>
    			<div>
       				<label for="email"><i>*</i>Email :</label><br />
        				<input type="text" id="email" name="mailfrom" />
    			</div>
    			<div>
        				<label for="title"><i>*</i>Title of Artwork :</label><br />
    				<input type="text" id="title" name="Title" />
    			</div>
    			<div>
            	       		<label for="size"><i>*</i>Size :</label><br />
    				<input type="radio" id="size" name="Size" value="small" onclick="update_total();" />12 in. : $30
    				<br />
    	    			<input type="radio" id="size" name="Size" value="large" onclick="update_total();" />17 in. : $40
                    	</div>
    			<div>
       				<label for="paper"><i>*</i>Paper :</label><br />
       				<select name="Paper">
            	            	<option value="">--- Select One ---</option>
    				<option value="Semi-gloss">Semi-gloss</option>
         				<option value="Matte">Matte</option>
         				</select>
    			</div>
    			<div>
        				<label for="quantity"><i>*</i>Quantity :</label>
        				<input type="text" id="quantity" name="Quantity" value="1" onchange="update_total();" />
    
    	                </div>
        			<div>
        				<table cellspacing="0">
        					<tr class="alt">
        						<td>Subtotal :</td>
        						<td class="total">$<span id="subtotal">0.00</span></td>
        					</tr>
    
        					<tr>
        						<td>Sales Tax (7%) :</td>
        						<td class="total">$<span id="tax">0.00</span></td>
        					</tr>
        					<tr class="alt">
        						<td>Shipping (US only) :</td>
        						<td class="total">$<span id="shipping" value="7.34">7.34</span></td>
    
        					</tr>
        					<tr>
        						<td>Estimated Total :</td>
        						<td class="total"><span id="thetotal">0.00</span></td>
        					</tr>
        				</table>
        			</div>
        			<div>
    	               	<input type="hidden" name="redirect" value="http://www.scapegoatstudio.com/print-confirmation.html" />
            	        <input type="hidden" name="subject" value="Print request" />
                            <input type="hidden" name="sendtoemail" value="jonathan@scapegoatstudio.com" />
    			<input type="hidden" name="total" />
        			<input type="submit" id="submit" value="Submit request" />
        			</div>
       			</fieldset>
     		</form>
     		<div class="description">
    	        </div>
    
     
    	</div>
    
    	<div id="footer">
    		<p>All images are copyright © Jonathan Mayer 2011</p>
    	</div>
    
    </div>
    </body>
    </html>

  • Users who have thanked Old Pedant for this post:

    jonathanmayer (08-10-2011)

  • #13
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts
    Even though I was kidding about the cookies, is there any way I can pay you for this? I do appreciate it, and I don't want to be a whiny type who expects something for nothing. You've done me a professional service, and I'd like to give you something in return, if that's possible.

  • #14
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    26,202
    Thanks
    80
    Thanked 4,453 Times in 4,418 Posts
    Let it go, please. Trust me, I spent a *LOT* less time on this than I have on questions that looked simpler when I made the mistake of first answering them and then the people revealed huge hidden agendas.

    At least you gave me a nice clean HTML page to work with and no hidden problems. Made it so much easier.

    I almost gave you the name/email/validation code the first time I posted, but at that time I thought you might end up writing your own server-side code. My total time invested here isn't huge. I'm happy if you are.

  • #15
    New to the CF scene
    Join Date
    Aug 2011
    Posts
    8
    Thanks
    5
    Thanked 0 Times in 0 Posts

    Thumbs up

    Thanks. I certainly am.
    Last edited by jonathanmayer; 08-11-2011 at 06:18 PM.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •