使用javascript从tablesorter表提取数据

使用javascript从tablesorter表提取数据,javascript,tablesorter,Javascript,Tablesorter,我有一个使用javascript和ajax动态生成的tablesorter表。用户有更改值的输入,当他们单击按钮转到下一条或上一条记录时,需要将表中的信息保存到MySQL表中。我已经查看了这里的许多帖子,并尝试了许多例子,但我仍然无法获得表中的任何数据来发布到我的PHP页面以保存它。 以下是我表格第一行的示例: $("#guides").append('<tr><td id="amCodeOld">'+data.amCodeOld+'</td><td&g

我有一个使用javascript和ajax动态生成的tablesorter表。用户有更改值的输入,当他们单击按钮转到下一条或上一条记录时,需要将表中的信息保存到MySQL表中。我已经查看了这里的许多帖子,并尝试了许多例子,但我仍然无法获得表中的任何数据来发布到我的PHP页面以保存它。 以下是我表格第一行的示例:

$("#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