0

In a web application, used for registration of rooms and used products, I generate a list of rows with several inputfields (see code #1). The code simply adds a row with some input fields. Also a dynamic dropdown-list generated with PHP echoed into the code (see also code #1).

The rows are nicely generated and the droplist are functioning normally. However the code is used to add products to an order. Those products have a default price into the database (which can be edited by a different page...).

Each row generated does look like code #2, however adjusted for readability. When I pick a product from the list the 2 other fields have to get the price inserted. The input field to change the price for this order only and a text part for reference only.

Code #3 shows the part of code which created the call and returns the value in the required locations.

This code does work great of the first row, but when I change 2nd of any other of the dropdownlist nothing does change.

My question is how do I make it work that when I select any product in any dropdown list generated to show the price into the corresponding input fields / div?

I have not a single to clue to solve this problem. Please help.

Edit 1: Code #2 and #3 changed to use 'class' instead of 'id'. Me as a bad person did use id's and not classes while having the same fields several times... Please forgive my stupid mistake. But this does not solve the problem about only the first row being modified even if I add the row several times.

Maybe asking my question on a different wat makes it more easy to understand my problem, while code stays te same.

I have several rows with a PHP generated select-box, an empty input box type number and a empty div for futher reference only.

Example in dummy mode:

<select class product></select><input type="number" name="price[]" class="price"><div class="ajaxprice">
<select class product></select><input type="number" name="price[]" class="price"><div class="ajaxprice">
<select class product></select><input type="number" name="price[]" class="price"><div class="ajaxprice">
<select class product></select><input type="number" name="price[]" class="price"><div class="ajaxprice">

These rows are added with code #1 while the first is already at the page with and 'add' button and not a 'remove' button. When I change the select in the first row both the input and the div are nicely filled by the script in code #3. If one of the other rows are changed nothing does change at all. Nor an alert I inserted for testing purposes. So how do I enter the required information into the div and input when I change n-th selectbox?

code #1: Inserting and removing rows with input fields

var max_rows = 10; // maximum input fields
var wrapper = $("#wrapper_rows");
var counter = 1;

$(".rowBtn").click(function (e) {
    e.preventDefault();
    if (counter < max_rows) {
        counter++;
        var row =   'some lay out';
        row = row + '<?php echo get_products_add($con, $com); ?>';
        row = row + 'some futher layout / closing tags';
        $(wrapper).append(row );
    }
})

$(wrapper).on("click",".rowminBtn", function(e){ 
    e.preventDefault(); 
    $(this).parent('div').parent('div').remove(); counter--;
})

code #2

    <select class="product" name="product[]" >// LOADS OF OPTIONS</select>
    <input type="number" class="price" name="price[]">
    <div class="ajaxprice"></div>

code #3

$(".product").change(function () {
    var productid = $('.product').val();
    if (productid != '') {
        $.ajax({  
            url:"get_price.php",  
            method:"POST",  
            data: { id:productid },
            dataType:"json",  
            success:function(result){  
                $(".ajaxprice").html("(Original price: " + result + ")");
                $(".price").val(result);
            }
        })
    }
    else { 
        $(".ajaxprice").html('');
        $(".price").val("");
    }
})
Geerius
  • 3
  • 2
  • When you say "each row generated looks like code #2" does every single row have an input with the id `product` ? IDs HAVE to be unique on your page. If you have multiple rows with each one containing an input with the id `product` your selectors in jquery wont work correctly! What happens when you select `$("#product")` is that you always select the first element with that id. Change the `id='product'` to `class="product"` you will have to change the selection too but thats beyond the scope of a comment – Lapskaus Mar 10 '20 at 15:08
  • All those rows have the same id, as the dropdowns are all created with the same php code. But giving a different name is only possible when I'm able to add a number to the php function. But that's not possible as I echo the php function into the jquery code. I can't adjust any number into that one. – Geerius Mar 10 '20 at 15:13
  • You don't have to change the `id` - value, you need to use `class='product'` instead of `id='product'`. Same is true for your `price` and `ajaxprice` input fields. – Lapskaus Mar 10 '20 at 15:16
  • @El_Vanja I've changed my code to classes. Your reply points to an question but your link points to some kind of overview. – Geerius Mar 11 '20 at 10:32
  • @Lapskaus Changing the ids into classess does not change my result in code. Still only the first row is getting changed. I did add some addional info in my question. – Geerius Mar 11 '20 at 10:34
  • Sorry, wrong thing was in the clipboard. I meant to link to [this](https://stackoverflow.com/questions/15864307/one-jquery-change-event-on-multiple-elements/51795276). Anyway, you got your question answered now. – El_Vanja Mar 11 '20 at 11:25

1 Answers1

0

You use an ID where you should use a class. That is because an ID has to be unique. If you use it more than once you usually run into problems like yours.

After changing the id Attribute to a class attribute, you still need to change the way you select your input elements. Which leads to another problem in your HTML.

If you have logically seperated parts like the rows of input fields:

<select class="product"></select>
<input type="number" name="price[]" class="price">
<div class="ajaxprice"></div>

you should make that separation clear in your HTML, that makes it alot easier to read and understand and enables you to select the right inputs.

First wrap your rows in either a div, table row, section like so:

<div class="row">
    <select class="product"></select>
    <input type="number" name="price[]" class="price">
    <div class="ajaxprice"></div>
</div>

Then use that row as a base for the selection of the input fields, when the .product class fires the change event:

$(".product").change(function () {
    // $('.product') does not select the 
    // changed product element,use $(this) to 
    // get the element that fired the event
    var productid = $('this').val(); 
    var $row = $(this).parent('.row'); // select the wrapper element
    if (productid != '') {
        $.ajax({  
            url:"get_price.php",  
            method:"POST",  
            data: { id:productid },
            dataType:"json",  
            success:function(result){  
                // now select the ajaxprice and price elements in the wrapper
                $row.find(".ajaxprice").html("(Original price: " + result + ")");
                $row.find(".price").val(result);
            }
        })
    }
    else { 
        // same here 
        $row.find(".ajaxprice").html('');
        $row.find(".price").val("");
    }
})

EDIT:

These rows are added with code #1 while the first is already at the page with and 'add' button and not a 'remove' button

Dynamically added elements won't have the event handler attached to them - only DOM elements that were present in the DOM when the handler is first attached have it.

There are two possible solutions for this. Either add the event handler when adding the row. Or change the eventhandler to be attached to a parent:

$('body').on('change', '.product', function() {
   // same code as before
});

Now the event gets fired on all child elements of body, that have the .product class

Lapskaus
  • 1,709
  • 1
  • 11
  • 22
  • Thank you! This is very usefull. But I did change the $row into row as I received errors before. – Geerius Mar 11 '20 at 15:37
  • Glad i could help. But the variable name should not interfere with your code or produce errors. It's just a naming convention in jQuery that you name variables containing reference to DOM elements with a leading `$`. Do not mix it up and use it like `$.row`which would reference a parameter `row` in the jQuery ( which is `$`) Object itself, that will most likely lead to an error – Lapskaus Mar 12 '20 at 08:12