Home > front end >  Order output value using dynamic input JQuery
Order output value using dynamic input JQuery

Time:04-19

I have a dynamic input field that will show the inputted text to preview element, but when I input in a random order, the preview text order is also random.

For example I have 3 input field, the order of filling starts from the 1st field, the 3rd field then the 2nd field. But the results in the preview are the 1st, 3rd and then 2nd field.

[test 1][test 2][test 3]
test 1 test 3 test 2

What I want is even though the order of filling is random but the results in the preview still match the order of the fields.

[test 1][test 2][test 3]
test 1 test 2 test 3

This is the HTML file

        <div >
      <div >
        <div >
          <label >Description</label>
          <div >
            <div >
              <textarea  data-row="1"></textarea>
              <span >90</span>
            </div>
            <button type="button" >Add More Description  </button>
          </div>
        </div>
      </div>
      <div >
        <div >
          <span >Lorem ipsum dolor sit amet</span>
        </div>
      </div>
    </div>

And this is the JQuery

var row = 1;  
$('.add-description').on('click', function() {
    $('<div >'  
      '<textarea  data-row="'   (row   1)   '"></textarea>'  
      '<span >90</span>'  
      '</div>').insertBefore(this);
    row  ;
  })

  $('.description-form-group').on('keyup', 'textarea.description', function() {
    var val = $(this).val();
    var row = $(this).attr('data-row');
    var length = val.length;
    var count = 90;
    var total_length = count - length;

    $(this).next().text(total_length);
    if (total_length <= 0) {
      $(this).next().removeClass('badge-primary');
      $(this).next().addClass('badge-danger');
    } else {
      $(this).next().addClass('badge-primary');
      $(this).next().removeClass('badge-danger');
    }

    if (val && row > 1) {
      $('.description > .description-'   row).remove();
      $('.description').append('<span >'   val   '</span>');
    } else {
      $('.description-'   row).text(val);
    }
  })

The fiddle is here

Any advice would be appreciated.

CodePudding user response:

Consider the following.

$(function() {
  var rows = [""];

  function showRows(arr) {
    $("div.description").html("");
    $.each(arr, function(key, val) {
      var row = $("<span>", {
        class: "description-"   key
      }).html(val).appendTo($(".description"));
    });
  }

  $('.add-description').on('click', function() {
    var row = $("textarea.description").length;
    var group = $("<div>", {
      class: "input-group mb-2"
    }).insertBefore(this);
    $("<textarea>", {
      class: "form-control description",
      "data-row": row
    }).appendTo(group);
    $("<span>", {
      class: "badge badge-primary"
    }).html("90").appendTo(group);
  });

  $('.description-form-group').on('keyup', 'textarea.description', function() {
    var val = $(this).val();
    var row = $(this).data("row");
    var length = val.length;
    var total_length = 90 - length;

    $(this).next().text(total_length);
    if (total_length <= 0) {
      $(this).next().removeClass('badge-primary');
      $(this).next().addClass('badge-danger');
    } else {
      $(this).next().addClass('badge-primary');
      $(this).next().removeClass('badge-danger');
    }

    rows[row] = val;
    showRows(rows);
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
  <div >
    <div >
      <label >Description</label>
      <div >
        <div >
          <textarea  data-row="0"></textarea>
          <span >90</span>
        </div>
        <button type="button" >Add More Description  </button>
      </div>
    </div>
  </div>
  <div >
    <div ></div>
  </div>
</div>

This uses an Array to store the values of each Textarea. When changes are made it is updating the proper portion of the Array and redrawing all the details.

CodePudding user response:

Maintain the result in dictionary(object), it will help you to do whatever you want with data.

I have modified some of the code to add data in object.

        <div >
          <div >
            <div >
              <label >Description</label>
              <div >
                <div >
                  <textarea  data-row="1"></textarea>
                  <span >90</span>
                </div>
                <button type="button" >Add More Description  </button>
              </div>
            </div>
          </div>
          <div >
           Lorem ipsum dolor sit amet
            <div >
           
            </div>
          </div>
        </div>

  var row = 1;
  var data = {"1": ""}; // it will keep entered data with keys as indexes
  $('.add-description').on('click', function() {
    $('<div >'  
      '<textarea  data-row="'   (row   1)   '"></textarea>'  
      '<span >90</span>'  
      '</div>').insertBefore(this);
    row  ;
    data[row] = ""; // enter new key in dictionary with value as empty string
  })

  $('.description-form-group').on('keyup', 'textarea.description', function() {
    var val = $(this).val();
    var row = $(this).attr('data-row');
    var length = val.length;
    var count = 90;
    var total_length = count - length;
    data[row] = val; // update the value at index(whatever the textarea is)

    $(this).next().text(total_length);
    if (total_length <= 0) {
      $(this).next().removeClass('badge-primary');
      $(this).next().addClass('badge-danger');
    } else {
      $(this).next().addClass('badge-primary');
      $(this).next().removeClass('badge-danger');
    }
        showResult(data);
  })

  // display result
  function showResult(data) {
    let str = '';
    for(let key in data) {
        str  = data[key];
    }
    $('.result').text(str);
  }

Dictionary will maintain the data with indexes as key

{
"1", "test1",
"2", "",
"3", "dfdf",
}

so in future if you need to add ability to delete the textarea you can remove data at that index. It can also be achieved by array.

  • Related