AMDI
AMDI

Reputation: 975

generate dynamic div and retrieve value of input elements

I am having div with input elements with Add and Cancel buttons. When user clicked on add Button,I need to generate div with the same input elements and capture the value to JSon object.

Here is my code snippet

    <div id="filterfields" class="row collapse">

    <form class="form-inline" id="filterFieldsForm">
        <select class="form-control" name="TypeCode" id="filterType_0">

            <option value="Type">Type</option>
            <option value="SubmittedBy">SubmittedBy</option>
            <option value="Date">Date</option>
            <option value="Description">Description</option>

        </select>
        <select class="form-control" name="Filter" id="filterCondition_0">

            <option value="Equal">Equal</option>
            <option value="StartsWith">Starts With</option>
            <option value="EndsWith">Ends With</option>
            <option value="Greaterthan">Greater Than</option>
            <option value="Lessthan">Less Than</option>
        </select>
        <input type="text" name="caseFilterText" class="form-control" id="filterText_0">
        <input class="form-control" type="radio" name="inlineRadioOptions" id="andRadio_0" value="AND">
        <label for="andRadio">AND</label>
        <input class="form-control" type="radio" name="inlineRadioOptions" id="orRadio_0" value="OR">
        <label for="orRadio">OR</label>
        <button id="addBtn_0" type="button" class="btn btn-secondary">Add</button>
        <button id="cancelBtn_0" type="button" class="btn btn-secondary">Cancel</button>

    </form>


</div>

I tried with clone and trying to retrieve values from the input elements inside div,but I am facing issue with getting values and generating ids.

  $('#addBtn_' + count).click(function () {

            var newel = $("#filterfields").clone(true);

            var jsonData = [];

            $(newel).insertAfter("#filterfields");

            var index;

            $("#filterfields").find('input:text,select').each(function () {

                let str = '{"' + this.id + '":' + (this.value + '}';
                jsonData.push(str);

            }).end()

            newel.find(':input').each(function () {

                var oldId = $(this).attr("id");
                var split = oldId.toString().split('_');
                index = parseInt(split[1]);
                var curId = split[0];

                var newId = curId + "_" + index + 1;
                this.id = newId;

            }).end()

            jsonData.push('"filterClause":' + $('input[name="inlineRadioOptions"]:checked').val() + '"');

        });

Please suggest me if there is better way to achieve the similar function as I am not able to get values of input elements of current row.

Upvotes: 0

Views: 51

Answers (1)

Twisty
Twisty

Reputation: 30883

Consider the following code.

$(function() {
  function formToJson(fObj) {
    var j = [];
    fObj.children().not("button, label").each(function(i, el) {
      // Will avoid buttons and labels
      if (!($(el).is(":radio") && !$(el).is(":checked"))) {
        // Will avoid unselected Radio Buttons
        var d = {
          nodeName: $(el).prop("nodeName"),
          props: {
            class: $(el).attr("class"),
            id: $(el).attr("id")
          },
          value: $(el).val(),
          name: $(el).attr("name")
        };
        if (d.nodeName != "SELECT") {
          d.props.type = $(el).attr("type");
        }
        j.push(d);
      }
    });
    return j;
  }
  $("[id^='addBtn']").click(function() {
    var jsonData = formToJson($("#filterFieldsForm"));
    console.log(jsonData);
    var filter = "Filter: ";
    $.each(jsonData, function(key, item) {
      if (key != 2) {
        filter += item.value + " ";
      } else {
        filter += "'" + item.value + "' ";
      }
    });
    $("<div>", {
      class: "filter-results"
    }).html(filter).appendTo("body");
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filterfields" class="row collapse">
  <form class="form-inline" id="filterFieldsForm">
    <select class="form-control" name="TypeCode" id="filterType_0">
      <option value="Type">Type</option>
      <option value="SubmittedBy">SubmittedBy</option>
      <option value="Date">Date</option>
      <option value="Description">Description</option>
    </select>
    <select class="form-control" name="Filter" id="filterCondition_0">
      <option value="Equal">Equal</option>
      <option value="StartsWith">Starts With</option>
      <option value="EndsWith">Ends With</option>
      <option value="Greaterthan">Greater Than</option>
      <option value="Lessthan">Less Than</option>
    </select>
    <input type="text" name="caseFilterText" class="form-control" id="filterText_0">
    <input class="form-control" type="radio" name="inlineRadioOptions" id="andRadio_0" value="AND">
    <label for="andRadio">AND</label>
    <input class="form-control" type="radio" name="inlineRadioOptions" id="orRadio_0" value="OR">
    <label for="orRadio">OR</label>
    <button id="addBtn_0" type="button" class="btn btn-secondary">Add</button>
    <button id="cancelBtn_0" type="button" class="btn btn-secondary">Cancel</button>
  </form>
</div>

As you are iterating over elements, it is best to use .each(). Using the proper selector, we can target just the form elements you want. You then want a condition to ensure that if a Radio Button is selected (or checked) that it is included and others are excluded.

The result is an Array of Objects that can be used to rebuild the HTML Structure or just build new copies.

Update

$(function() {
  function formToJson(fObj) {
    var j = [];
    fObj.each(function(i, el) {
      var d = {};
      $("select, input", el).each(function(k, v) {
        if (!($(v).is(":radio") && !$(v).is(":checked"))) {
          d[$(v).attr("id")] = $(v).val();
        }
      });
      j.push(d);
    });
    return j;
  }

  $("[id^='addBtn']").click(function() {
    var jsonData = formToJson($("#filterFieldsForm"));
    console.log(jsonData);
    var filter = "Filter: ";
    $.each(jsonData, function(key, item) {
      if (key != 2) {
        filter += item.value + " ";
      } else {
        filter += "'" + item.value + "' ";
      }
    });
    $("<div>", {
      class: "filter-results"
    }).html(filter).appendTo("body");
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="filterfields" class="row collapse">
  <form class="form-inline" id="filterFieldsForm">
    <select class="form-control" name="TypeCode" id="filterType_0">
      <option value="Type">Type</option>
      <option value="SubmittedBy">SubmittedBy</option>
      <option value="Date">Date</option>
      <option value="Description">Description</option>
    </select>
    <select class="form-control" name="Filter" id="filterCondition_0">
      <option value="Equal">Equal</option>
      <option value="StartsWith">Starts With</option>
      <option value="EndsWith">Ends With</option>
      <option value="Greaterthan">Greater Than</option>
      <option value="Lessthan">Less Than</option>
    </select>
    <input type="text" name="caseFilterText" class="form-control" id="filterText_0">
    <input class="form-control" type="radio" name="inlineRadioOptions" id="andRadio_0" value="AND">
    <label for="andRadio">AND</label>
    <input class="form-control" type="radio" name="inlineRadioOptions" id="orRadio_0" value="OR">
    <label for="orRadio">OR</label>
    <button id="addBtn_0" type="button" class="btn btn-secondary">Add</button>
    <button id="cancelBtn_0" type="button" class="btn btn-secondary">Cancel</button>
  </form>
</div>

This will target the various rows and for each row, it will gather all the Select and Inputs.

Upvotes: 1

Related Questions