使用javascript从tablesorter表提取数据
我有一个使用javascript和ajax动态生成的tablesorter表。用户有更改值的输入,当他们单击按钮转到下一条或上一条记录时,需要将表中的信息保存到MySQL表中。我已经查看了这里的许多帖子,并尝试了许多例子,但我仍然无法获得表中的任何数据来发布到我的PHP页面以保存它。 以下是我表格第一行的示例:使用javascript从tablesorter表提取数据,javascript,tablesorter,Javascript,Tablesorter,我有一个使用javascript和ajax动态生成的tablesorter表。用户有更改值的输入,当他们单击按钮转到下一条或上一条记录时,需要将表中的信息保存到MySQL表中。我已经查看了这里的许多帖子,并尝试了许多例子,但我仍然无法获得表中的任何数据来发布到我的PHP页面以保存它。 以下是我表格第一行的示例: $("#guides").append('<tr><td id="amCodeOld">'+data.amCodeOld+'</td><td&g
$("#guides").append('<tr><td id="amCodeOld">'+data.amCodeOld+'</td><td><input type="text" class="qty" id="amOldQty"/></td><td>'+data.amOldPrice+
'</td><td>'+data.am+
'</td><td>'+data.amCodeNew+'</td><td><input type="text" class="qty" id="amNewQty"/></td><td>'+data.amNewPrice+
'</td><td><input type="checkbox" id="amS" '+
'"/></td><td><input type="checkbox" id="amR"'+'"/></td><td><input type="checkbox" id="amCall"'+
'"/></td><td><input type="text" id="amComm" value="'+
'"/></td></tr>');
我试过:
var amOldQty;
$('#guides tbody tr').each(function() {
amOldQty = $(this).find('td:nth-child(1) input').val();
});
console.log(amOldQty);
日志显示未定义。我还尝试了更直接的方法,使用
$('#guides tbody tr').each(function() {
amOldQty = $(this).find('#amOldQty').val();
});
还是一无所获。我收到搜索警报,但在console.logamqtyld中,它显示的并不是一个数字。我甚至尝试在第一次创建表时填充输入,但它仍然找不到该数字。
如果我将td添加到:
$(guides tr td).each(function(){...
它甚至没有提醒我搜索。
如何从该表中获取所有数据以便保存?似乎我正在尝试的一切都应该正常工作。如果您的用户使用了,那么您可以查看我的“我有”功能
如果不想使用contenteditable元素,则可以尝试从contenteditable演示中复制和修改但未经测试的以下代码
var $table = $('table');
$table.children('tbody').on('change', 'input', function(event){
var $input = $(this),
$cell = $input.closest('td'),
newContent = $input.val(),
cellIndex = $cell[0].cellIndex, // there shouldn't be any colspans in the tbody
rowIndex = $this.closest('tr').attr('id'); // unique row id
// update tablesorter
$table.trigger("updateCell", [$cell]);
$.post("mysite.php", {
"row" : rowIndex,
"cell" : cellIndex,
"content" : newContent
});
});
希望您在该专栏中也使用了一个。目前还不清楚您希望以何种方式呈现数据。然而,这正是你想要的 函数createRowsForTesting只创建表中的行,并填充字段以使测试更容易 函数getDataFromTable遍历一行或所有行,将所需数据发送到控制台。从您自己对这个问题的回答中可以清楚地看出,您确实希望访问比您的问题中提到的更多的元素。因此,该函数现在构建一个对象数组,其中包含字段中数据的键:值对。数组中每行有一个对象。数组返回给调用函数 函数wrapGetDataFromTable包装getDataFromTable,提供表ID,我们只查看标记中的行,并希望输出到控制台。getDataFromTable返回的数组是输出的,因此我们可以看到数据结构。该功能设置为在每次按下[打印到控制台]按钮时运行 对于类似于标题行的表: 输出为:
amOldQty=amOldQty0_text amNewQty=amNewQty0_text amS=on amR=off amCall=off amComm=amComm0_text
amOldQty=amOldQty1_text amNewQty=amNewQty1_text amS=off amR=on amCall=off amComm=amComm1_text
amOldQty=amOldQty2_text amNewQty=amNewQty2_text amS=off amR=off amCall=on amComm=amComm2_text
The array of row input data objects is:
[0] Object { amOldQty="amOldQty0_text", amNewQty="amNewQty0_text", amS="on", more...}
amOldQty: "amOldQty0_text"
amNewQty: "amNewQty0_text"
amS: "on"
amR: "off"
amCall: "off"
amComm: "amComm0_text"
[1] Object { amOldQty="amOldQty1_text", amNewQty="amNewQty1_text", amS="off", more...}
amOldQty: "amOldQty1_text"
amNewQty: "amNewQty1_text"
amS: "off"
amR: "on"
amCall: "off"
amComm: "amComm1_text"
[2] Object { amOldQty="amOldQty2_text", amNewQty="amNewQty2_text", amS="off", more...}
amOldQty: "amOldQty2_text"
amNewQty: "amNewQty2_text"
amS: "off"
amR: "off"
amCall: "on"
amComm: "amComm2_text"
JavaScript:
/**
* Runs through a table getting the values from <input> fields.
* It only looks in the <tbody>, not the <thead>
* @param tableId
* The DOM ID of the table from which we desire to obtain the
* input values.
* If tableId is not a string, then look in all table rows in all tables.
* @param keyAttr
* The attribute of the <input> which contains the value which will
* be used as the key for the key:value pair within the Object returned.
* This needs to be a value which is unique, wihin the table row.
* A normal use would be "id".
* If a value is duplicated a message is sent to the console and only
* the last value is kept.
* The default is "id".
* @param justBody
* If true, look only within the <tbody> tag, not any other part of
* the table (e.g. <thead>).
* The default is true.
* @param includeBlank
* Boolean indicating if the returned array should contain an entry for
* rows which are found to be blank.
* The default is true.
* @param consoleOutput
* Send a line to the console with the key:value pairs separated by
* tabs for each row.
* The default is false.
* @return Object
* Returns an Array of Objects with key:value pairs for the rows.
* If there were no <input>
* Copyright 2014 by Makyen.
* Released under the MPL 2.0. http://mozilla.org/MPL/2.0/.
*/
function getDataFromTable(tableId, keyAttr, justBody, includeBlank, consoleOutput) {
//This assumes that within the row each input has a unique attribute keyAttr.
//Set defaults:
var tableSelector = (typeof tableId === "string") ? "#" + tableId : "table";
keyAttr = (typeof keyAttr === "string") ? keyAttr : "id";
includeBlank = (typeof includeBlank === "boolean") ? includeBlank : true;
justBody = (typeof justBody === "boolean") ? justBody : true;
consoleOutput = (typeof consoleOutput === "boolean") ? consoleOutput : false;
var bodySelector = (justBody) ? " tbody" : "";
var toReturn = [];
var selector = tableSelector + bodySelector + ' tr';
$(selector).each(function () {
var inputs = {};
$(this).find('input').each(function () {
//Get the value for all inputs on this line.
var attrValue = $(this).attr(keyAttr);
if (typeof inputs[attrValue] !== "undefined") {
console.log("Warning: When attempting to get data from the table id=" //
+ tableId + " the value of the key attribute, " + keyAttr //
+ ", was not unique for value=" + attrValue);
}
//Get the value of the <input>.
if ($(this).is(':checkbox')) {
//Special case the checkboxes because .val() does not return
//the correct informaiton for them.
//First indicate that all checkboxes are off.
inputs[attrValue] = "off";
//Specifically determine if the current one is checked.
if ($(this).is(':checked')) {
inputs[attrValue] = "on";
}
} else {
//Add this input to the object
inputs[attrValue] = $(this).val();
}
});
var inputKeys = Object.keys(inputs);
if (inputKeys.length > 0) {
//There were <input> tags on this row.
var outputText = "";
if (consoleOutput) {
inputKeys.forEach(function (value) {
outputText += value + "=" + inputs[value] + "\t";
});
console.log(outputText);
}
toReturn.push(inputs);
} else {
//No <input> tags on this row
if (includeBlank) {
if (consoleOutput) {
console.log("A row without <input> tags was found.");
}
toReturn.push(inputs);
}
}
});
return toReturn;
}
function wrapGetDataFromTable() {
//This wraper is so the getDataFromTable() function remains
// generic. The wrapper merely defines which table from which to
// get the data,
// the attribute to use for unique keys = "id"
// to look only in the <tbody>
// to not include an object for the lines which are blank
// and output the row data to the console.
var toReturn = getDataFromTable("guides", "id", true, false, true);
if (typeof console.dir === "function") {
//Make sure console.dir() exists prior to using it.
console.log("The array of row input data objects is:");
console.dir(toReturn); //Let us see the Object in the console for checking.
}
return toReturn;
}
$('#to-console-button').click(wrapGetDataFromTable);
//The rest is setup for creating the table header and rows.
//It is only for testing.
function createRowsForTesting() {
const numRowsToCreate = 3;
var i;
var data = {
amCodeOld: "amCodeOld",
amOldPrice: "amOldPrice",
am: "am",
amCodeNew: "amCodeNew",
amNewPrice: "amNewPrice"
};
//Create the table
//First add a header.
$("#guides thead").append('<tr><th>amCodeOld_H</th>' //
+ '<th>amOldQty_H</th>' //
+ '<th>amOldPrice_H</th>' //
+ '<th>am_H</th>' //
+ '<th>amCodeNew_H</th>' //
+ '<th>amNewQty_H</th>' //
+ '<th>amNewPrice_H</th>' //
+ '<th>amS_H</th>' //
+ '<th>amR_H</th>' //
+ '<th>amCall_H</th>' //
+ '<th>amComm_H</th></tr>');
//Now the body rows.
for (i = 0; i < numRowsToCreate; i++) {
//From stackoverflow question: http://stackoverflow.com/questions/25998929/extract-data-from-a-tablesorter-table-with-javascript
$("#guides tbody").append('<tr><td id="amCodeOld">'+data.amCodeOld+'</td><td><input type="text" class="qty" id="amOldQty"/></td><td>'+data.amOldPrice+ //
'</td><td>'+data.am+ //
'</td><td>'+data.amCodeNew+'</td><td><input type="text" class="qty" id="amNewQty"/></td><td>'+data.amNewPrice+ //
'</td><td><input type="checkbox" id="amS" '+ //
'"/></td><td><input type="checkbox" id="amR"'+'"/></td><td><input type="checkbox" id="amCall"'+ //
'"/></td><td><input type="text" id="amComm" value="'+ //
'"/></td></tr>');
}
//*
//Fake having the table filled in, as I am tired of entering the input
//You have to try it without this, but with manual input in order to truly verify
var row = 0;
$('#guides tbody tr').each(function () {
$(this).find('#amOldQty').val("amOldQty" + row + "_text");
$(this).find('#amNewQty').val("amNewQty" + row + "_text");
$(this).find('#amComm').val("amComm" + row + "_text");
row++;
});
//*/
}
createRowsForTesting();
HTML:
注意:选择器$guides.append'。。。在行中用于将表行添加到表中可能是您的问题。它当前将您的行添加为中的最后一个元素,而不是中的最后一个元素。虽然浏览器应该对此进行补偿,但在您的环境中可能没有这样做。请尝试$tbody.append'
但是,问题更可能是标题行或列表中没有输入单元格的行。现在,代码说明了这种可能性。最终的答案似乎是对输入值$amOldQty:.val进行硬编码,并通过ajax将其作为数据传递到我的php文件以保存信息。以下是完成的代码,以防任何人出现类似问题:
function save() {
function GuidesSave(){
this.update();
}
GuidesSave.prototype.list = ['am','fol','tich','book','neb','ster','c','byte','ing'];
GuidesSave.prototype.update = function(){
for( var i = 0 ; i < this.list.length ; i++ ){
var guide = this.list[i];
this[ guide + 'S' ] = $("#" + guide+'S' ).is(":checked") ? 1 : 0;
this[ guide + 'R' ] = $("#" + guide+'R' ).is(":checked") ? 1 : 0;
this[ guide + 'Call' ] = $("#" + guide+'Call' ).is(":checked") ? 1 : 0;
}// end of for loop
}
var guides = new GuidesSave();
$.ajax({
type: "POST",
url: "poSave.php",
dataType: "json",
data: ({po: $('#po').val(),isbn:$("#isbn13").val(),amOldQty:$("#amOldQty").val(),amNewQty:$("#amNewQty").val(),amS:guides.amS,amR:guides.amR, amCall:guides.amCall,amComm:$("#amComm").val(),
folOldQty:$("#folOldQty").val(),folNewQty:$("#folNewQty").val(),folS:guides.folS,folR:guides.folR, folCall:guides.folCall,folComm:$("#folComm").val(),
tichOldQty:$("#tichOldQty").val(),tichNewQty:$("#tichNewQty").val(),tichS:guides.tichS,tichR:guides.tichR, tichCall:guides.tichCall,tichComm:$("#tichComm").val(),
bookOldQty:$("#bookOldQty").val(),bookNewQty:$("#bookNewQty").val(),bookS:guides.bookS,bookR:guides.bookR, bookCall:guides.bookCall,bookComm:$("#bookComm").val(),
nebOldQty:$("#nebOldQty").val(),nebNewQty:$("#nebNewQty").val(),nebS:guides.nebS,nebR:guides.nebR, nebCall:guides.nebCall,nebComm:$("#nebComm").val(),
sterOldQty:$("#sterOldQty").val(),sterNewQty:$("#sterNewQty").val(),sterS:guides.sterS,sterR:guides.sterR, sterCall:guides.sterCall,sterComm:$("#sterComm").val(),
cheggOldQty:$("#cOldQty").val(),cheggNewQty:$("#cNewQty").val(),cheggS:guides.cS,cheggR:guides.cR, cheggCall:guides.cCall,cheggComm:$("#cComm").val(),
byteOldQty:$("#byteOldQty").val(),byteNewQty:$("#byteNewQty").val(),byteS:guides.byteS,byteR:guides.byteR, byteCall:guides.byteCall,byteComm:$("#byteComm").val(),
ingOldQty:$("#ingOldQty").val(),ingNewQty:$("#ingNewQty").val(),ingS:guides.ingS,ingR:guides.ingR, ingCall:guides.ingCall,ingComm:$("#ingComm").val(),
qty1: $('#topqty').val(),price1: $('#topVal').html(),comp1:$('#topCo').html(),
qty2: $('#secqty').val(),price2: $('#secVal').html(),comp2: $('#secCo').html(),
qty3: $('#thrqty').val(),price3: $('#thrVal').html(),comp3: $('#thrCo').html()}),
success: function(data){
}
});
}// END OF SAVE FUNCTION
GuideSave函数循环检查所有复选框27个不同的复选框,查看哪些复选框被选中,这样我就可以将它们保存为1或0,然后在调用记录时将它们选中或不选中。如果每次更新单元格时我都想保存信息,那就太好了,但是有很多单元格可以更改,所以当他们单击“下一步”、“上一步”或“打印”按钮时,我尝试将其保存一次。嗨,Makyen,谢谢你花了这么多时间在这方面,但是,当我尝试你的建议时,我发现amoldQuantity没有定义,而3个复选框没有定义。我准确地复制了printToConsole函数,并手动将一个数字输入到amOldQty框中。请查看更新。其他两个输入已更新。表格创建代码中有个错误,不是打印错误。-好的。鉴于你看到了你这边的问题,但我没有看到任何问题,我们需要找出差异。您是在上还是在自己的代码中看到未定义/关闭问题?如果您没有尝试过JSFIDLE,或者它对您不起作用,请再试一次。您使用的是什么操作系统和浏览器?jQuery/tablesorter的哪个版本?您正在使用哪些tablesorter加载项?您对tablesorter设置排序的确切调用是什么?我假设您有一个表的标题行,请也提供它。这些东西将有助于复制您的问题。我已经更新了代码,以考虑在实际任何行中都可能出现标题行,而没有标题行。中的此类非输入行将导致报告的未定义行。这可能就是问题所在。
<table class="tablesorter" id="guides">
<thead></thead>
<tbody></tbody>
</table>
<button type="button" id="to-console-button">print to console</button>
<!-- values to use to fill input:
amOldQty0_text
amOldQty1_text
amNewQty0_text
amNewQty1_text
amComm0_text
amComm1_text -->
function save() {
function GuidesSave(){
this.update();
}
GuidesSave.prototype.list = ['am','fol','tich','book','neb','ster','c','byte','ing'];
GuidesSave.prototype.update = function(){
for( var i = 0 ; i < this.list.length ; i++ ){
var guide = this.list[i];
this[ guide + 'S' ] = $("#" + guide+'S' ).is(":checked") ? 1 : 0;
this[ guide + 'R' ] = $("#" + guide+'R' ).is(":checked") ? 1 : 0;
this[ guide + 'Call' ] = $("#" + guide+'Call' ).is(":checked") ? 1 : 0;
}// end of for loop
}
var guides = new GuidesSave();
$.ajax({
type: "POST",
url: "poSave.php",
dataType: "json",
data: ({po: $('#po').val(),isbn:$("#isbn13").val(),amOldQty:$("#amOldQty").val(),amNewQty:$("#amNewQty").val(),amS:guides.amS,amR:guides.amR, amCall:guides.amCall,amComm:$("#amComm").val(),
folOldQty:$("#folOldQty").val(),folNewQty:$("#folNewQty").val(),folS:guides.folS,folR:guides.folR, folCall:guides.folCall,folComm:$("#folComm").val(),
tichOldQty:$("#tichOldQty").val(),tichNewQty:$("#tichNewQty").val(),tichS:guides.tichS,tichR:guides.tichR, tichCall:guides.tichCall,tichComm:$("#tichComm").val(),
bookOldQty:$("#bookOldQty").val(),bookNewQty:$("#bookNewQty").val(),bookS:guides.bookS,bookR:guides.bookR, bookCall:guides.bookCall,bookComm:$("#bookComm").val(),
nebOldQty:$("#nebOldQty").val(),nebNewQty:$("#nebNewQty").val(),nebS:guides.nebS,nebR:guides.nebR, nebCall:guides.nebCall,nebComm:$("#nebComm").val(),
sterOldQty:$("#sterOldQty").val(),sterNewQty:$("#sterNewQty").val(),sterS:guides.sterS,sterR:guides.sterR, sterCall:guides.sterCall,sterComm:$("#sterComm").val(),
cheggOldQty:$("#cOldQty").val(),cheggNewQty:$("#cNewQty").val(),cheggS:guides.cS,cheggR:guides.cR, cheggCall:guides.cCall,cheggComm:$("#cComm").val(),
byteOldQty:$("#byteOldQty").val(),byteNewQty:$("#byteNewQty").val(),byteS:guides.byteS,byteR:guides.byteR, byteCall:guides.byteCall,byteComm:$("#byteComm").val(),
ingOldQty:$("#ingOldQty").val(),ingNewQty:$("#ingNewQty").val(),ingS:guides.ingS,ingR:guides.ingR, ingCall:guides.ingCall,ingComm:$("#ingComm").val(),
qty1: $('#topqty').val(),price1: $('#topVal').html(),comp1:$('#topCo').html(),
qty2: $('#secqty').val(),price2: $('#secVal').html(),comp2: $('#secCo').html(),
qty3: $('#thrqty').val(),price3: $('#thrVal').html(),comp3: $('#thrCo').html()}),
success: function(data){
}
});
}// END OF SAVE FUNCTION