objetos - push object javascript
La nueva fila aƱadida no se comporta como la anterior(fila) (3)
Tengo una tabla HTML en el lado que tengo varios
td
como campo de
input
, mi tabla es dinámica, cuando la página se carga, agrego la primera fila de mi tabla y me
focus
en el primer campo de entrada, en mi caso, es decir,
Item Name
Tengo 3 campos de entrada en mi fila que son
Item Name
,
Unit Qty
y
Disc%
-
Cuando el usuario hace clic dentro del campo de entrada
ItemName
estoy buscando nombres de elementos a partir de datos que son objetos dentro de una matriz para llenar nombres de elementos -
Después de seleccionar
Item NAme
estoy moviendo mi enfoque al siguiente campo de entrada, que esUnit Qty
, luego de ese enfoque en el siguiente campo de entrada, que esDisc%
entre estos, algunos cálculos están sucediendo para calcular laTotal Amount
-
Luego de esto, cuando el usuario está enfocado fuera del
Disc%
estoy agregando una nueva fila, en realidad tengo una función dentro de la cual tengo un código para agregar la fila, así que llamo a esa función en foco fuera delDisc%
-
Después de enfocar fuera del
Disc%
quiero que mi enfoque se dirija alItemName
de la nueva fila y se comporte como se estaba comportando (Al igual que la búsqueda de datos), etc.
He comentado las líneas en mi código para que el usuario entienda mejor qué está sucediendo dónde
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>
Por mi parte, creo que estoy usando un enfoque incorrecto para hacer esta tarea
NOTA: - en el futuro, en cada enfoque, podría estar haciendo algunos cálculos, así que ayúdenme de esa manera
He proporcionado toda la información si no es suficiente, entonces todos pueden preguntarme en los comentarios
EDITAR
según
Wils''s
respuesta
Wils''s
después de que el foco fuera del
Disc%
está agregando una nueva fila y el foco también se está moviendo al
Item Name
del
Item Name
la nueva fila, pero el problema es que cuando se agrega una nueva fila, el
autocomplete
no funciona en la primera fila inicialmente cuando la página se carga cuando escribo m dentro del campo de entrada del
Item Name
del elemento, todo el nombre del elemento que contiene
m
se muestra como desplegable, pero para la segunda fila no se muestra
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>
Alguien aquí afuera por favor ayúdame
Creo que deberías asignar una variable a la tabla:
documento. getElementById (''I del cuerpo de la tabla'');
Para crear el registro, compílelo como elementos:
document.createElement (''tr''), document.createElement (''td''); Añadir a tr. repita según sea necesario ...
Luego agregue el nuevo elemento de registro al cuerpo de la tabla. Se puede agregar a cada elemento, como agregar atributos como clase o eventos.
Para este evento de registro final, agregue un controlador de desenfoque. document.addEventHandler (''desenfoque'', devolución de llamada de función);
Hay varios problemas con tu código
Los dos más importantes son
-
Utiliza múltiples elementos con la misma
id
. Pero lasid
deben ser únicas. JavaScript / jQuery siempre usará el primer elemento con la identificación si varios elementos tienen el mismo (CSS es diferente). Usé elname
lugar de laid
aquí -
Agrega oyentes de eventos a elementos que no están allí en tiempo de ejecución.
Solo se crea la primera fila de entrada cuando escucha los eventos de
focusout
. Escucho el evento defocusout
en todo el documento. Si se enfoca en una entrada, el evento aparecerá en eldocument
, donde decida, qué hacer en función de la propiedad detarget
del evento.
Reestructuré un poco tu código e hice algunas mejoras, pero está lejos de ser perfecto.
"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>
Puede asignar el objetivo del selector de elementos en este caso marcado. Debe agregar el oyente nuevamente después de crear un nuevo elemento 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>