How to make a dynamic form?

7

I've implemented a script that dynamically adds fields to a form, in this case a form to add products and their quantity.

The code is here: link

I am finding this code very bureaucratic, because every time the button "NewProduct" is triggered, it is necessary to do:

  • Clone the div item
  • Change the id of the div and of the productId and quant fields
  • Use a counter to increment ids and names to ensure they are not equal
  • Use a hidden attribute (itemCont) to pass to the server the number of new products that were created, to know how many times I have to call $ _POST ["productId__"], as there may be hundreds of products created. >

    I would like the opinion of colleagues to improve this code, making it leaner. Here is the code:

    HTML:

    <form action="cadastro.php" method="post" id="formulario">
        <input type="button" id="novoProd" value="Novo produto"/>
        <input type="submit" value="enviar"/>
        <div id="item" class="item">
            <label>Selecione o produto:</label>
                <select id="produtoId" name="produtoId">
                    <option value="1">Produto 1</option>
                    <option value="5">Produto 2</option>
                    <option value="9">Produto 3</option>
                </select>
            <label>Quantidade: </label>
            <input type="number" id="quant" name="quant"/>
        </div>
        <input type="hidden" id="itemCont" value="1"/>
    </form>
    

    JAVASCRIPT:

    $(document).ready(function(){
        var itemCont = 1;
        $("#novoProd").click(function(){
            var novoItem = $("#item").clone();
    
            // modifica o id do item recem criado
            $(novoItem).attr("id","item"+itemCont);
            var novoSelect = $(novoItem).children()[1];
            $(novoSelect).attr("id","produtoId"+itemCont);
            $(novoSelect).attr("name","produtoId"+itemCont);
    
            var novoSelect = $(novoItem).children()[3];
            $(novoSelect).attr("id","quant"+itemCont);
            $(novoSelect).attr("name","quant"+itemCont);
    
            $("#formulario").append(novoItem);
            itemCont++;
            $("#itemCont").val(itemCont);
        });
      });
    
        
  • asked by anonymous 07.11.2014 / 19:50

    2 answers

    3

    One suggestion would be to use the names of inputs as Array and treat in PHP, eg

    $(document).ready(function() {
          $("#novoProd").click(function() {
          var novoItem = $("#item").clone().removeAttr('id'); // para não ter id duplicado
          novoItem.children('input').val(''); //limpa o campo quantidade
          $("#formulario").append(novoItem);
        });
      });
    input[type="number"] {
      width: 50px;
    }
    label {
      font-weight: bold;
      margin-left: 10px;
    }
    div.item {
      border: 1px solid black;
      padding: 10px;
      margin: 5px;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><formaction="cadastro.php" method="post" id="formulario">
      <input type="button" id="novoProd" value="Novo produto" />
      <input type="submit" value="enviar" />
      <div id="item" class="item">
        <label>Selecione o produto:</label>
        <select name="produtoId[]">
          <option value="1">Produto 1</option>
          <option value="5">Produto 2</option>
          <option value="9">Produto 3</option>
        </select>
        <label>Quantidade:</label>
        <input type="number" name="quant[]" />
      </div>
    </form>

    PHP

    In PHP you make foreach in POST[produtoId] to make insert in base

    foreach ($_POST['produtoId'] as $key=> $value){
        echo $value; // Id do produto
        echo $_POST['quant'][$key]; // Quantidade
    }
    

    This would prevent manipulations in% of% of id's , reducing your jQuery code and somehow simplifying input's with PHP.

        
    07.11.2014 / 20:19
    0

    Boy, make this more dynamic you would have to write more codes. But the elements could be removed from your html. But when I'm going to do something like I need dynamic id. Here's how:

    $(document).ready(function(){
        $("#novoProd").click(function(){
            var novoItem = $("#item").clone();
            var novoId = Math.floor((Math.random() * 100) + 1);
    
            // modifica o id do item recem criado
            $(novoItem).attr("id","item"+ novoId);
            var novoSelect = $(novoItem).children()[1];
            $(novoSelect).attr("id","produtoId"+ novoId);
            $(novoSelect).attr("name","produtoId"+ novoId);
    
            var novoSelect = $(novoItem).children()[3];
            $(novoSelect).attr("id","quant"+ novoId);
            $(novoSelect).attr("name","quant"+ novoId);
    
            $("#formulario").append(novoItem);
        });
      });
    

    Or instead of saving the counter on a hidden input element. You could create a date attribute. For example:

    <form action="cadastro.php" method="post" id="formulario">
        <input type="button" id="novoProd" value="Novo produto" data-index="1"/>
        <input type="submit" value="enviar"/>
        <div id="item" class="item" >
            <label>Selecione o produto:</label>
                <select id="produtoId" name="produtoId">
                    <option value="1">Produto 1</option>
                    <option value="5">Produto 2</option>
                    <option value="9">Produto 3</option>
                </select>
            <label>Quantidade: </label>
            <input type="number" id="quant" name="quant"/>
        </div>
        <input type="hidden" id="itemCont" value="1"/>
    </form>
    
    $(document).ready(function(){
    
        $("#novoProd").click(function(){
            var itemCont = $("#novoProd").attr("data-index");
            var novoItem = $("#item").clone();
    
            // modifica o id do item recem criado
            $(novoItem).attr("id","item"+itemCont);
            var novoSelect = $(novoItem).children()[1];
            $(novoSelect).attr("id","produtoId"+itemCont);
            $(novoSelect).attr("name","produtoId"+itemCont);
    
            var novoSelect = $(novoItem).children()[3];
            $(novoSelect).attr("id","quant"+itemCont);
            $(novoSelect).attr("name","quant"+itemCont);
    
            $("#formulario").append(novoItem);
            itemCont++;
            $("#novoProd").attr("data-index",itemCont);
        });
      });
    
        
    07.11.2014 / 20:23