views:

307

answers:

2

Another jquery calculation question.

I've this, which is sample code from the plugin site that I am playing with to get this working:

        function recalc(){
    $("[id^=total_item]").calc(
        "qty * price",
        {
        qty: $("input[name^=qty_item_]"), 
        price: $("input[name^=price_item_]"),
        },

        function (s){ return s.toFixed(2);},

        function ($this){ var sum = $this.sum();

            $("#grandTotal").val(
                // round the results to 2 digits
                sum.toFixed(2)
            );
        }
    );
}

Changes in the price fields cause the totals to update:

        $("input[name^=price_item_]").bind("keyup", recalc);
        recalc();

Problem is I won't know the value of the price fields, they will be available to me only as a substring of values entered by the user, call it 'itemcode'. There will be a variable number of items, based on a php query.

I've come up with this to change the price based on the itemcode:

    $("input[name^='itemcode_item_1']").keyup(function () {
    var codeprice = this.value.substring(2,6);
    $("input[name^='price_item_1']").val(codeprice);
});

$("input[name^='itemcode_item_2']").keyup(function () {
    var codeprice = this.value.substring(2,6);
    $("input[name^='price_item_2']").val(codeprice);
});

However while it does that, it also stops the item_total from updating. Also, I feel there must be a way to not need to write a numbered function for each item on the list. However when I just use

    $("input[name^='itemcode_item_']")

updating any itemcode field updates all price fields, which is not good.

Can anyone point me in the right direction? I know I am a bit clueless here, but javascript of any kind is not my thing.

Ok, updating this now to add some html. Basically though this is now just a little piece of sample stuff from the jquery calculator site, which I am using to get the functionality right before puttng it all into the actual functioning script. In reality there will be a variable number of items and they'll be grouped in various ways.

<table>

            <tr><th>Qty</th><th align="left"></th><th>Item code</th><th>Price</th><th>Total</th></tr>
            <tr>
            <td><input type="text" name="qty_item_1" id="qty_item_1" value="1" size="3"/></td>
            <td>Item One</td>
            <td><input type="text" id="itemcode_item_1" name="itemcode_item_1" value="" size="8" /></td>
            <td><input type="text" id="price_item_1" name="price_item_1" value="" size="8" /></td>
            <td><input type="text" id="total_item_1" value=" " size="8"  readonly="readonly"  /></td>

            </tr>

            <tr>
            <td><input type="text" name="qty_item_2" id="qty_item_2" value="1" size="3"/></td>
            <td>Item Two</td>
            <td><input type="text" id="itemcode_item_2" name="itemcode_item_2" value="" size="8" /></td>
            <td><input type="text" id="price_item_2" name="price_item_2" value="" size="8" /></td>
            <td><input type="text" id="total_item_2" value=" " size="8" readonly="readonly" /></td>
            </tr>
            <tr>
            <td colspan="4" align="right"><strong>Grand Total:</strong></td>
            <td><input type="text" id="grandTotal" value=" " size="6" readonly="readonly">    </td>
            </tr>
        </table>
+1  A: 

I've solved the second issue (totals not updating) with this, which I should have thought of before:

        $("input[name^=itemcode_item_]").bind("keyup", recalc);
        recalc();

Now just how to do it without repeating the function for each numbered item.

Katherine
As I said in my comment if you show some sample HTML code we might be able figure out some way. But it depends on the structure ;)
Felix Kling
+1  A: 

You wrote that the elements will be grouped in various ways, but if this pattern is always kept (i.e. the related fields are inside one row):

<tr>
  <td><input type="text" id="itemcode_item_1" name="itemcode_item_1" value="" size="8" /></td>
  <td><input type="text" id="price_item_1" name="price_item_1" value="" size="8" /></td>
</tr>

You can get your functionality this way:

$("input[name^='itemcode_item_']").keyup(function () {
    var codeprice = this.value.substring(2,6);
   // closest(sel) finds the closest ancestor that matches 'sel'
   // find(sel) finds  all descendants that match the selector 'sel'
   $(this).closest('tr').find("input[name^='price_item_']").val(codeprice);
});

In general, try to figure out the realtion between the itemcode_item_ fields and their corresponding price_item_ field.
In this case, they have a common ancestor tr and there is only on price_item_ input field inside it. Another relation would be, that price_item_1 is the first child of the next sibling of itemcode_item_1s parent.

Felix Kling
Good gosh that is clever!! Thank you so much, it works like a charm. Yeah!!
Katherine
@Katherine: :) My pleasure.
Felix Kling