5

I'm strugglin to make a PHP Form with Dynamic Fields with Auto Fill other fields in JQuery, so far I can add new fields and the autofill works just fine but only for the first field.

enter image description here

The autofill drop down only appears on the first input. How can I make all dynamic form input work with the autofill? For example I have 2 fields. Items_name and Total_stock in dynamic form. I want to if I select Items_name. Autofill for field total_stock.

Here is my ajax code :

<script language="javascript">
    function AddMasterDetail() {
            var idf = document.getElementById("idf").value;
            stre="<div class='form-group'  id='srow" + idf + "'><div class='controls'>";

            stre=stre+" <div class='col-xs-2'>";
            stre=stre+"<select placeholder='Items Name' class='form-control input-sm' name='items_id[]' id='items_id' onchange='return autofill();'>"
                        +"<option value='' disabled selected>Please Select</option>"
                        +"<?php foreach($v_items_stock as $row){ echo "<option value='$row->items_id'>$row->items_name</option>"; } ?></select>";
            stre=stre+"</div>";

            stre=stre+"<div class='col-xs-2'>";
            stre=stre+"<input class='form-control input-sm' id='total_stock' placeholder='Total Stock'  name='total_stock[]' />";
            stre=stre+"</div>";         


            stre=stre+"<div class='col-xs-1'> <button type='button' class='btn btn-danger btn-sm' title='Hapus Rincian !' onclick='removeFormField(\"#srow" + idf + "\"); return false;'><i class='glyphicon glyphicon-remove'></i></button></div>";

            $("#divItems").append(stre);    
            idf = (idf-1) + 2;
            document.getElementById("idf").value = idf;
        }
    function removeFormField(idf) {
            $(idf).remove();
        }

    function autofill(){
        var items_id = document.getElementById('items_id').value;
        $.ajax({
               url:"<?php echo base_url();?>transaction_sending/cari",
               data:'&items_id='+items_id,
               success:function(data){
               var hasil = JSON.parse(data);  

        $.each(hasil, function(key,val){ 

        document.getElementById('items_id').value=val.items_id;
               document.getElementById('total_stock').value=val.total_stock;


            });
        }
               });
    }   

</script>
ADyson
  • 57,178
  • 14
  • 51
  • 63
  • The problem is that you're re-using "items_id" as the ID for lots of elements. But IDs must be unique. When you run `document.getElementById('items_id')` (which can only return one element) the code has no way to know which of the multiple elements with that ID you're actually referring to. – ADyson Feb 20 '19 at 09:02
  • You need to start using classes, or maybe data-attributes, so you can either uniquely identify each copy of the element and apply a specific action to that copy, or apply the same action to all of them at once (it's a bit unclear from your description which of those tasks you're trying to do) – ADyson Feb 20 '19 at 09:04
  • Thanks Adyson, I have revision my question. Please see hope u understand what I means. Thank you.. – Jije's Stackoverflow Feb 20 '19 at 09:19
  • P.S. `idf = (idf-1) + 2;` is...odd. It works, but basically you take away one in order to add 2 back on again. So why not just straightforwardly add one to the value? You can replace that whole line with just `idf++;` – ADyson Feb 20 '19 at 09:21
  • Ok I have a better idea now. But I have a question about this part: `$.each(hasil, function(key,val){ document.getElementById('items_id').value=val.items_id; document.getElementById('total_stock').value=val.total_stock; });` : I see you are looping...so how many values are you expecting in the `hasil` variable? At the moment, your loop just overwrites the first textboxes every time. What is it meant to do? Should it overwrite the boxes of all lines in turn? I thought each ` – ADyson Feb 20 '19 at 09:29
  • I just remove (idf = (idf-1) + 2; document.getElementById("idf").value = idf;) But still working for dynamic add fields. But autofill for second fields still not working. – Jije's Stackoverflow Feb 20 '19 at 09:41
  • The bit about idf was just a minor, unrelated code review point. (Also I didn't say to _remove_ it, just to _change_ it.) Can you answer my last comment please? Once you answer that and I fully understand, I think I can give you the code to solve it. – ADyson Feb 20 '19 at 09:45
  • Ok and can you also answer about the `hasil` data, as I mentioned before? You run a loop over it. So how many entries should be in that data? What do we do when there is more than one entry? Which entry's values should we place into the textboxes? – ADyson Feb 20 '19 at 09:52
  • Adyson, Total Stock field/form is autofill. Getting it from database table if I choose ItemsName. – Jije's Stackoverflow Feb 20 '19 at 10:02
  • Again, that wasn't what I asked you. I already know all that. I'm asking about the **contents** of the `hasil` array **specifically**. I'm confused as to why, if you're asking for the stock level of one item, the server is returning an array of values, and I want to know what is in that array, and whether in reality it will ever have more than one entry. And If it might contain more than one entry, which entry should we use to update the stock field on the screen? Logically it seems it would make more sense and be less confusing if the server returned a single object, not an array. – ADyson Feb 20 '19 at 10:02
  • I made an answer below based on my assumption about what I think is likely to be happening, but it would be helpful if you could clarify it. – ADyson Feb 20 '19 at 10:07

1 Answers1

0

The problem is that you're re-using "items_id" as the ID for lots of elements. But IDs must be unique. When you run document.getElementById('items_id') (which can only return one element) the code has no way to know which of the multiple elements with that ID you're actually referring to.

Now, as I understand it you want to have a relationship between the select and the input box next to it. The value of the select must affect the value of the input box, it seems. Therefore you a way need to identify the correct input box which relates to the select whose value has been changed.

There are many ways you could do this, but one simple way way is to set a data-attribute on the <select containing the unique identifier of the row (you can use idf for this). You then set the same value as the id of the related input box. Then when the "change" event happens, you can get the data-attribute from the select which triggered the event, and use it to select the correct input ID to update.

I've also used more jQuery syntax for this, since you get unobtrusive event handling, and also the syntax is a bit briefer - it works nicely for this scenario.

First, change

stre=stre+"<select placeholder='Items Name' class='form-control input-sm' name='items_id[]' id='items_id' onchange='return autofill();'>"

to

stre=stre+"<select placeholder='Items Name' class='form-control input-sm autofill' name='items_id[]' id='items_id_" + idf + "' data-idf='" + idf + "' >"

Next, change

stre=stre+"<input class='form-control input-sm' id='total_stock' placeholder='Total Stock'  name='total_stock[]' />";

to

stre=stre+"<input class='form-control input-sm' id='total_stock_" + idf + "' placeholder='Total Stock'  name='total_stock[]' />";

And then replace the whole "autofill()" function with this event handler:

$(document).on("change", ".autofill", function(e) {
  var select = $(this);
  var item_id = select.val();
  var idf = select.data("idf");

  $.ajax({
    url:"<?php echo base_url();?>transaction_sending/cari",
    method: "GET",
    data: { items_id: item_id },
    dataType: "json"
  }).done(function(hasil) {
    $("#total_stock_" + idf).val(hasil[0].total_stock);
  });
});

I have made the assumption here (pending a comment from you) that we only ever want to use the stock value from first item of data in the hasil array (and/or that it only ever returns one item, despite being an array). If that's not correct then please clarify the situation with this data - it seems odd for the server to return an array if, in reality, you are only asking for information about one item. It would be more logical for it to just return a single object instead.


P.S. as a minor, unrelated point, you can also simplify this line

idf = (idf-1) + 2;

to

idf++;
ADyson
  • 57,178
  • 14
  • 51
  • 63