#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    2
    Rep Power
    0

    Unhappy Issue designing dynamic form!


    First of all, I am working with two files.

    test.html
    Code:
    <!DOCTYPE html>
    
    <html><head><title>Test page</title>
    
    <link rel='stylesheet' href='css/style.css'>
    
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    
    <script>
    $(function() {
    
    $("#sides").change(function() {
    	$("#color").load("getter.php?choice=" + escape($("#sides").val()) + "&fetch=color");
    	$("#papertype").load("getter.php?choice=" + escape($("#sides").val()) + "&fetch=papertype");
    	$("#deliverytime").load("getter.php?choice=" + escape($("#sides").val()) + "&fetch=deliverytime");
    	$("#quantity").load("getter.php?choice=" + escape($("#sides").val()) + "&fetch=quantity");
        $.get("getter.php?fetch=price&sides=" + escape($("#sides").val()) + "&choice=" + escape($("#sides")) + "&color=" + escape($("#color").val()) + "&papertype=" + escape($("#papertype").val()) + "&deliverytime=" + escape($("#deliverytime").val()) + "&quantity=" + escape($("#quantity").val())).then(function(response){ $("#price").text(response); })
    });
    
    
    });
    
    </script>
    
    </head><body>
    <div id="page-wrap">
    Sides: <select id="sides">
    	<option selected value="base">Please Select</option>
    	<option value="Single Sided">Single Sided</option>
    	<option value="Double Sided">Double Sided</option>
    </select>
    
    <br /><br />
    
    Color: <select id="color">
    	<option>Please choose from above</option>
    </select>
    <br /><br />
    Paper type: <select id="papertype">
    	<option>Please choose from above</option>
    </select>
    <br /><br />
    Delivery time: <select id="deliverytime">
    	<option>Please choose from above</option>
    </select>
    <br /><br />
    Quantity: <select id="quantity">
    <option>Please choose from above</option>
    </select>
    <br /><br />
    <b>Price:</b> $<p id="price">0</p>
    </div>
    </body>
    </html>
    getter.php
    PHP Code:
    <?php

        $username 
    "root";
        
    $password "";
        
    $hostname "localhost";
        
        
    $dbhandle mysql_connect($hostname$username$password) or die("Unable to connect to MySQL");
        
    $selected mysql_select_db("db"$dbhandle) or die("Could not select examples");
        
    $fetch mysql_real_escape_string($_GET['fetch']);
        
    $choice mysql_real_escape_string($_GET['choice']);
        if (
    $fetch == "price") { 
        echo 
    "yes, i know it";
        
    $color mysql_real_escape_string($_GET['color']);
        echo 
    $color;
        
    $papertype mysql_real_escape_string($_GET['papertype']);
        
    $deliverytime mysql_real_escape_string($_GET['deliverytime']);
        
    $quantity mysql_real_escape_string($_GET['quantity']);
        }
        
        
    //testing

        
    if ($fetch == "color"$query "SELECT DISTINCT color FROM a5letterhead WHERE sides='$choice'";
        if (
    $fetch == "papertype"$query "SELECT DISTINCT papertype FROM a5letterhead WHERE sides='$choice'";
        if (
    $fetch == "deliverytime"$query "SELECT DISTINCT deliverytime FROM a5letterhead WHERE sides='$choice'";
        if (
    $fetch == "quantity"$query "SELECT DISTINCT quantity, rate FROM a5letterhead WHERE sides='$choice'";
        if (
    $fetch == "price"$query "SELECT price FROM a5letterhead WHERE color='$color' AND papertype='$papertype' AND deliverytime='$deliverytime' AND quantity='$quantity'";
        
    $result mysql_query($query);
        
    $row mysql_fetch_array($result);
        echo 
    $row{'price'};
        echo 
    $query;

        while (
    $row mysql_fetch_array($result)) {
               if (
    $fetch == "color") echo "<option value=".$row{'color'}.">" $row{'color'} . "</option>";
            if (
    $fetch == "papertype") echo "<option value=".$row{'papertype'}.">" $row{'papertype'} . "</option>";
            if (
    $fetch == "deliverytime") echo "<option value=".$row{'deliverytime'}.">" $row{'deliverytime'} . "</option>";
            if (
    $fetch == "quantity") echo "<option value=".$row{'quantity'}.">" $row{'quantity'} . " copies (" $row{'rate'} . " per copy)</option>";
             if (
    $fetch == "price") {
        
    $color mysql_real_escape_string($_GET['color']);
        
    $papertype mysql_real_escape_string($_GET['papertype']);
        
    $deliverytime mysql_real_escape_string($_GET['deliverytime']);
        
    $quantity mysql_real_escape_string($_GET['quantity']);
        
    $sides mysql_real_escape_string($_GET['sides']);
        echo 
    $row['price']; echo $query;
        }
            }
            
    ?>
    Now what is happening is that when I select an option from the first drop down menu (id: sides) all the following drop downs change accordingly (fetch values from the database, all good there). But the issue arises when I am trying to update the price, now the algo is supposed to go through each option selected in the form and extract the right price from the database but instead of taking the latest choices of dropdown options ( as can be seen on the display ) it takes the previous one which would give us the price of the last choice of dropdown options selected.

    What can we do about this, I am not an expert in jQuery or anything so please be easy on me
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    101
    Rep Power
    27
    Well, first off let's talk about a higher-level design issue without looking at your code. Your ask is to have the price updated whenever the user changes their selection configuration. The user might change any one of the selections, though, in any order. You need to respond to any change in any selection, by recalculating the displayed price.

    So that would mean, in practice, adding on-change listeners to all of the select elements that the user can modify. Right? Now go back and look at your implementation, and see how many elements you've attached event listeners to: just one of them. Maybe starting over on the client side while keeping that in mind, will help.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    2
    Rep Power
    0
    Originally Posted by mod_speling
    Well, first off let's talk about a higher-level design issue without looking at your code. Your ask is to have the price updated whenever the user changes their selection configuration. The user might change any one of the selections, though, in any order. You need to respond to any change in any selection, by recalculating the displayed price.

    So that would mean, in practice, adding on-change listeners to all of the select elements that the user can modify. Right? Now go back and look at your implementation, and see how many elements you've attached event listeners to: just one of them. Maybe starting over on the client side while keeping that in mind, will help.
    Agree, but I am testing the code with just one selection. That one selection should be sufficient for testing purposes if the rest of the code is working correctly. So when I make the selection, choices for rest of the dropdown change. To calculate the price, all the selected choices are looked up against the database but the problem arises when its picking not the latest but the last choice made after every selection for example:

    I changed Choice # 1 to Choice # 2 for Drop-Down # 1, now choices for all the drop-downs below will change accordingly but the price will be calculated based on Choice # 1. Now if I go ahead and revert Drop-Down # 1 to Choice # 1, it'll show me price for Choice # 2.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    101
    Rep Power
    27
    I think the problem there is the asynchronicity of all those jQuery ajax calls. $.load() doesn't block, so when $.get() call is made none of the load() requests have returned yet - so at that moment, the values for all the select elements are still the "old" values. A few milliseconds later, the requests made by load() finish and update the select lists.

    I think you'd be better off transmitting JSON from your PHP handler to the webpage, and grabbing ALL of the data you need in a single transaction. Your PHP handler script should take all the user input you have, do all the queries, and marshal all that data in an array; then pass the array thru json_encode() and print the result with a text/json content-type header.

    On the client side, you rewrite your JS to make a single request using $.getJSON. You easily grab all the input elements by wrapping them in a form and calling $.serialize() on the form. The success handler walks thru the JSON data coming back from the server, manually adding DOM nodes instead of the server returning HTML. This might seem harder but it's very easy with jquery, and it's better to have all the markup where it belongs: in your view layer.

    I will try to make a dumbed-down example with just a couple variables instead of a half-dozen. PHP handler:
    PHP Code:

    $choice 
    filter_input(INPUT_GET'choice'FILTER_SANITIZE_STRING);
    $color filter_input(INPUT_GET'color'FILTER_SANITIZE_STRING);
    $out = array();
    // pretend we're querying all the color options for $choice value
    // and put them in $out['colors']
    $out['colors'] = array('Red''Blue''Green');

    // Did the user make a selection for $color?  If so look up the price
    if (!empty($color)) {
        
    // querying the database for the price of $choice+$color
        
    $out['price'] = '20 bones';
    }

    $out json_encode($out);
    header('Content-type: text/json');
    print 
    $out;
    exit; 
    Code:
    // Wrap all the inputs in a <form> then attach a submit handler to it
    $("#the-form").submit(function() {
        // grab all the inputs from the form
        var params = $(this).serialize();
        // remember what color the user had selected
        var selectedColor = $("#color option:selected").val();
        // and send them to the PHP handler
        $.getJSON('getter.php', params, function(data) {
            // clear out whatever color options we had before
            $("#colors").empty();
            // add color options
            if (data.colors) for (var i in data.colors)
                $("#colors").append($("<option/>").val(data.colors[i]));
            // reselect the previously selected color
            if (selectedColor)
                $("#colors option[@val='"+selectedColor+"']").attr("selected", "selected");
            // display the price
            if (data.price)
                $("#price").html(data.price);
        });
    });
    I'm not sure all that javascript is 100% correct but hopefully you get the idea.

    Finally you'd do something like attaching onchange listeners to all the select elements, which simply trigger submit() on the containing form. That way the price and all the options get updated every time you make a new selection.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    1
    Rep Power
    0
    For someone reason the board won't sent me my new password after I go to the confirmation link, issue reported.

    Anyways, I've added a submit button to the form and this to JS:
    Code:
    $('#the-form').submit(function() {
      alert('Handler for .submit() called.');
      return false;
    });
    Now whenever I click Submit, just to check the codes it shows me the alert popup but then an empty Colors drop-down menu (I am not doing any DB fetching as of yet, just using the manually entered Red Blue etc. options as shown in the example).

IMN logo majestic logo threadwatch logo seochat tools logo