Добавленная новая строка не ведет себя как предыдущая (строка) - PullRequest
6 голосов
/ 25 апреля 2019

У меня есть HTML-таблица в стороне, в которой у меня есть несколько полей td как input, моя таблица динамическая, когда при загрузке страницы я добавляю 1-ю строку моей таблицы и focus в первое поле ввода, в мой случай то есть Item Name

В моей строке 3 поля ввода: Item Name, Unit Qty и Disc%

  • Когда пользователь щелкает внутри ItemName поля ввода, я ищу имена элементов из данных, которые являются объектами внутри массива для заполнения имен элементов
  • После выбора Item NAme я перемещаю свой фокус на следующее поле ввода, равное Unit Qty, затем после этого фокуса на следующее поле ввода, которое находится между значениями Disc%, между ними происходят некоторые вычисления для вычисления Total Amount
  • Затем, после этого, когда пользователь выходит из фокуса с Disc%, я добавляю новую строку, на самом деле у меня есть функция, внутри которой у меня есть код для добавления строки, поэтому я вызываю эту функцию на фокусе из Disc%
  • После фокуса из Disc% я хочу, чтобы мой фокус переместился на ItemName новой строки и должен вести себя так, как он себя ведет (как поиск по данным) и так далее

Я прокомментировал строки в моем коде, чтобы лучше понять, что происходит, где

function rowappend() // this one is appending row
{
  var markup = '<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
    '</td><td id="itemCodetd" class="commantd"></td>' +
    '<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
    '<td id="purRatetd" class="commantd"></td>' +
    '<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
    '<td id="discAmttd" class="commantd"></td>' +
    '<td id="gstPercentagetd" class="commantd"></td>' +
    '<td id="gstAmttd" class="commantd"></td>' +
    '<td id="totalAmttd" class="commantd"></td></tr>'
  $("table tbody").append(markup);
  $("itemNametd").next().focus();
}
rowappend()


var data = [ //data to populate Item Name search input field
  {
    "ItemName": "Butter"
  },
  {
    "ItemName": "Rice"
  },
  {
    "ItemName": "Milk"
  },
  {
    "ItemName": "Ice Cream"
  },
  {
    "ItemName": "Curd"
  }
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
  "ItemName": "Butter",
  "ItemCode": 400564,
  "PurRate": 8,
  "DiscAmt": 6,
  "gstPercentage": 35,
  "gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
  let itemName = data.map(value => { //using autocomplete to for searching input field

    return value.ItemName;
  });
  $("#itemNametd").autocomplete({
    source: itemName
  });
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this

  data1.map(value => {
    $("#itemCodetd").text(value.ItemCode);
    $("#purRatetd").text(value.PurRate);
    $("#discAmttd").text(value.DiscAmt);
    $("#gstPercentahgetd").text(value.gstPercentage);
    $("#gstAmttd").text(value.gstAmt);

  });

});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
  unitQuantity = $("#unitQtytd").val();
  purchaseRate = $("#purRatetd").text();
  totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
  $("#totalAmttd").text(totalAmount);

});
$("#discPercentagetd").focusout(function() { //here when user is focus out i am calling the fuinction which is creating new row

  rowappend()



});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<div class="container commonDivInvoice">
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>


        </tr>
      </thead>
      <tbody>


      </tbody>

    </table>

  </div>
</div>

Со своей стороны, я думаю, что использую неправильный подход для решения этой задачи

ПРИМЕЧАНИЕ: - в будущем при каждой фокусировке я могу делать некоторые расчеты, поэтому, пожалуйста, помогите мне таким образом

Я предоставил всю информацию, если ее недостаточно, тогда вы все можете спросить меня в комментариях

EDIT

согласно Wils's ответу после фокуса из Disc% добавляется новая строка, и фокус также перемещается на Item Name новой строки, но проблема заключается в том, что при добавлении новой строки autocomplete изначально не работает в первой строке когда страница загружается, когда я набираю m внутри поля ввода Item Name, все имя элемента, содержащее m, отображается как раскрывающийся список, но для 2-й строки оно не отображается

function rowappend() // this one is appending row
{
  var markup = $('<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
    '</td><td id="itemCodetd" class="commantd"></td>' +
    '<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
    '<td id="purRatetd" class="commantd"></td>' +
    '<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
    '<td id="discAmttd" class="commantd"></td>' +
    '<td id="gstPercentagetd" class="commantd"></td>' +
    '<td id="gstAmttd" class="commantd"></td>' +
    '<td id="totalAmttd" class="commantd"></td></tr>');

  $("table tbody").append(markup);
  $("#itemNametd", markup).focus();
}
rowappend()


var data = [ //data to populate Item Name search input field
  {
    "ItemName": "Butter"
  },
  {
    "ItemName": "Rice"
  },
  {
    "ItemName": "Milk"
  },
  {
    "ItemName": "Ice Cream"
  },
  {
    "ItemName": "Curd"
  }
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
  "ItemName": "Butter",
  "ItemCode": 400564,
  "PurRate": 8,
  "DiscAmt": 6,
  "gstPercentage": 35,
  "gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
  let itemName = data.map(value => { //using autocomplete to for searching input field

    return value.ItemName;
  });
  $("#itemNametd").autocomplete({
    source: itemName
  });
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this

  data1.map(value => {
    $("#itemCodetd").text(value.ItemCode);
    $("#purRatetd").text(value.PurRate);
    $("#discAmttd").text(value.DiscAmt);
    $("#gstPercentahgetd").text(value.gstPercentage);
    $("#gstAmttd").text(value.gstAmt);

  });

});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
  unitQuantity = $("#unitQtytd").val();
  purchaseRate = $("#purRatetd").text();
  totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
  $("#totalAmttd").text(totalAmount);

});

$('body').on('focusout', '#discPercentagetd', function() {
  rowappend()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<div class="container commonDivInvoice">
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>


        </tr>
      </thead>
      <tbody>


      </tbody>

    </table>

  </div>
</div>

Кто-нибудь здесь, пожалуйста, помогите мне

Ответы [ 3 ]

5 голосов
/ 25 апреля 2019

Есть несколько проблем с вашим кодом

Два самых важных:

  • Вы используете несколько элементов с одинаковым id. Но id должны быть уникальными. JavaScript / jQuery всегда будет использовать первый элемент с идентификатором, если несколько элементов имеют одинаковый (CSS отличается). Я использовал name вместо id здесь
  • Вы добавляете прослушиватели событий к элементам, которых нет во время выполнения. При прослушивании событий focusout создается только первая строка ввода. Я слушаю событие focusout во всем документе. Если вы сфокусируете внимание на входе, событие всплывет до document, где я решаю, что делать на основе свойства target события.

Я немного реструктурировал ваш код и внес некоторые улучшения, но он далек от совершенства.

"use strict";
console.clear()


const data = [ //data to populate Item Name search input field
  {"ItemName": "Butter"},
  {"ItemName": "Rice"},
  {"ItemName": "Milk"},
  {"ItemName": "Ice Cream"},
  {"ItemName": "Curd"}
]

const data1 = {// this data will be dynamic but for now to test i am using this single data
  butter: { 
    "ItemName": "Butter",
    "ItemCode": 400564,
    "PurRate": 8,
    "DiscAmt": 6,
    "gstPercentage": 35,
    "gstAmt": 5
  },
  rice: { 
    "ItemName": "Rice",
    "ItemCode": 400565,
    "PurRate": 3,
    "DiscAmt": 2,
    "gstPercentage": 20,
    "gstAmt": 8
  },
  milk: { 
    "ItemName": "Milk",
    "ItemCode": 200569,
    "PurRate": 1,
    "DiscAmt": 1,
    "gstPercentage": 50,
    "gstAmt": 2
  },
  'ice cream': { 
    "ItemName": "Ice cream",
    "ItemCode": 800002,
    "PurRate": 16,
    "DiscAmt": 2,
    "gstPercentage": 15,
    "gstAmt": 2
  },
  curd: { 
    "ItemName": "Curd",
    "ItemCode": 100289,
    "PurRate": 9,
    "DiscAmt": 1,
    "gstPercentage": 12,
    "gstAmt": 4
  },
}

var totalAmount = "";
var unitQuantity = "";


function rowappend(tbody) {// this one is appending row{
  
  const markup = 
`<tr>
  <td>
    <input type="text" class="form-control commantd" name="itemNametd">
  </td>
  <td name="itemCodetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="unitQtytd">
  </td>
  <td name="purRatetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="discPercentagetd">
  </td>
  <td name="discAmttd" class="commantd"></td> 
  <td name="gstPercentagetd" class="commantd"></td>
  <td name="gstAmttd" class="commantd"></td>
  <td name="totalAmttd" class="commantd"></td>
  
</tr>`
    
  $(tbody).append(markup);
  setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

  const itemName = data.map(value => { //using autocomplete to for searching input field
    return value.ItemName;
  });
  $("[name=itemNametd]", tbody).last().autocomplete({
    source: itemName
  });
}
rowappend($('tbody', '#tableInvoice'))


function getValues(row) {
  const search = ($('[name=itemNametd]', row).val()).toString()
  const value = data1[search.toLowerCase()];
  if (value) {
    $(row).find("[name=itemCodetd]").text(value.ItemCode);
    $(row).find("[name=purRatetd]").text(value.PurRate);
    $(row).find("[name=discAmttd]").text(value.DiscAmt);
    $(row).find("[name=gstPercentahgetd]").text(value.gstPercentage);
    $(row).find("[name=gstAmttd]").text(value.gstAmt);
  }
}



function calc(row) {
  const unitQuantity = $(row).find("[name=unitQtytd]").val();
  const purchaseRate = $(row).find("[name=purRatetd]").text();
  const totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
  
  $(row).find("[name=totalAmttd]").text(totalAmount);
  
}

$(document).on('focusout', (e) => {
  const row = e.target.parentElement.parentElement
  if (e.target.matches('[name=discPercentagetd]')) {
    if ($(row).parent().find('tr').length - $(row).index() === 1) { // only last row
        rowappend(e.target.parentElement.parentElement.parentElement)
    }
  }
  
  if (e.target.matches('[name=unitQtytd]')) {
    calc(e.target.parentElement.parentElement)
  }

  if (e.target.matches("[name=itemNametd]")) {
    getValues(e.target.parentElement.parentElement)
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>

<div class="container commonDivInvoice">
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>
        </tr>
      </thead>
      <tbody>

      </tbody>

    </table>

  </div>
</div>
0 голосов
/ 02 мая 2019

Я думаю, вам следует присвоить таблицу переменной:

document.getElementById ('I'of body table');

Чтобы создать запись, создайте ее как элементы:

document.createElement ('tr'), document.createElement ('td');Добавить к тр.при необходимости повторите ...

Затем добавьте новый элемент записи в тело таблицы.Каждый элемент может быть добавлен, например, добавление атрибутов, таких как класс или события.

Для этого события окончательной записи добавьте обработчик размытия.document.addEventHandler ('blur', обратный вызов функции);

0 голосов
/ 25 апреля 2019

Вы можете назначить цель селектора элемента в этом случае разметки. Вы должны снова добавить слушателя после создания нового элемента DOM.

function rowappend() // this one is appending row
{
  var markup = $('<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
    '</td><td id="itemCodetd" class="commantd"></td>' +
    '<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
    '<td id="purRatetd" class="commantd"></td>' +
    '<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
    '<td id="discAmttd" class="commantd"></td>' +
    '<td id="gstPercentagetd" class="commantd"></td>' +
    '<td id="gstAmttd" class="commantd"></td>' +
    '<td id="totalAmttd" class="commantd"></td></tr>');
    
  $("table tbody").append(markup);
  $("#itemNametd",markup).focus();
}
rowappend()


var data = [ //data to populate Item Name search input field
  {
    "ItemName": "Butter"
  },
  {
    "ItemName": "Rice"
  },
  {
    "ItemName": "Milk"
  },
  {
    "ItemName": "Ice Cream"
  },
  {
    "ItemName": "Curd"
  }
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
  "ItemName": "Butter",
  "ItemCode": 400564,
  "PurRate": 8,
  "DiscAmt": 6,
  "gstPercentage": 35,
  "gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
  let itemName = data.map(value => { //using autocomplete to for searching input field

    return value.ItemName;
  });
  $("#itemNametd").autocomplete({
    source: itemName
  });
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this

  data1.map(value => {
    $("#itemCodetd").text(value.ItemCode);
    $("#purRatetd").text(value.PurRate);
    $("#discAmttd").text(value.DiscAmt);
    $("#gstPercentahgetd").text(value.gstPercentage);
    $("#gstAmttd").text(value.gstAmt);

  });

});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
  unitQuantity = $("#unitQtytd").val();
  purchaseRate = $("#purRatetd").text();
  totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
  $("#totalAmttd").text(totalAmount);

});

    $('body').on('focusout','#discPercentagetd', function(){
      rowappend()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">

<div class="container commonDivInvoice">
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>


        </tr>
      </thead>
      <tbody>


      </tbody>

    </table>

  </div>
</div>
...