Tablesorter总是在内容编辑后重新加载第一页

时间:2015-03-06 10:48:28

标签: javascript contenteditable tablesorter

我有一个带有tablesorter实现的应用程序。它具有内容可编辑,过滤和ajax服务器寻呼机。一切正常,除了一个问题:每次用户在页面上提交编辑后的值> 1,提交内容但tablesorter重新加载第一页。

查看xhr请求很明显,我发出了一个新的get请求(我想,在我的代码中,我不会触发任何更新或重新加载)。无论如何,这对我来说很好,刷新内容很好,但我想在编辑之前将页面保留在用户所在的位置。

正如我所看到的,问题仅出现在页面参数上:如果我更改每页的元素数量,将过滤器放在列中,或者订购一个或多个字段,tablesorter会跟踪它们,并且它们会被正确更新在请求url参数中,页面参数除外,它总是恢复为0。

从xhr请求方面看的进展示例:

第一次请求(默认): vlansummarys?page = 0& size = 10& col [10] = 0& col [8] = 0& col [7] = 0& FCOL

过滤器添加: vlansummarys?page = 0& size = 10& col [10] = 0& col [8] = 0& col [7] = 0& fcol [3 ] = monocos

页面元素从10到20: vlansummarys?page = 0& size = 20& col [10] = 0& col [8] = 0& col [7] = 0& ; FCOL [3] = monocos

添加了新的排序字段: vlansummarys?page = 0& size = 20& col [10] = 0& col [8] = 0& col [7] = 0& col [3] = 0&安培; FCOL [3] = monocos

页面更改为2: vlansummarys?page = 1& size = 20& col [10] = 0& col [8] = 0& col [7] = 0& col [3] = 0&安培; FCOL [3] = monocos

内容编辑,之后调用: vlansummarys?page = 0& size = 20& col [10] = 0& col [8] = 0& col [7] = 0安培;西[3] = 0&安培; FCOL [3] = monocos

修改

根据要求,我发布了我的代码。由于很难将其简化为一个简单的工作示例,因此我将粘贴所有的tablesorter初始化函数。它不能单独工作,因为它依赖于在页面上计算的其他数据和变量,但我想它应该给出一个非常好的主意。请问我任何可能有帮助的细节。

function LoadTable() {
    $('#table').tablesorter({
        theme: 'bootstrap',
        //widthFixed: true,
        zebra: [
            "even",
            "odd"],
        dateFormat: "ddmmyyyy",
        headerTemplate: '{content}',
        sortList: [[10, 0], [8, 0], [7, 0]], //Order by AdR del Kit ASC, AdR ASC, Centrale ASC
        initWidgets: true,
        widgets: bReadOnly ? ['zebra', 'columns', 'filter', 'uitheme'] : ['zebra', 'columns', 'filter', 'uitheme', 'editable'],
        widgetOptions: {
            filter_columnFilters: true,
            filter_cssFilter: arrHeaderFields,
            editable_columns: (bReadOnly ? null : [21]),       // or "0-2" (v2.14.2); point to the columns to make editable (zero-based index)
            editable_enterToAccept: true,          // press enter to accept content, or click outside if false
            editable_autoAccept: false,          // accepts any changes made to the table cell automatically (v2.17.6)
            editable_autoResort: false,         // auto resort after the content has changed.
            editable_noEdit: 'no-edit',     // class name of cell that is not editable
            editable_editComplete: 'editComplete', // event fired after the table content has been edited
            editable_validate: null,          // return a valid string: function(text, original){ return text; }
            editable_focused: null,/*function (txt, columnIndex, $element) {
                // $element is the div, not the td
                // to get the td, use $element.closest('td')
                //$element.addClass('focused');
                $element.removeClass("emptyPlaceholder");
                //SelectActivationDateText($element.closest('td'));
            },*/
            editable_blur: null,/*function (txt, columnIndex, $element) {
                // $element is the div, not the td
                // to get the td, use $element.closest('td')
                //$element.removeClass('focused');
                RestoreCellStyle($element);
            },*/
            editable_selectAll: null,/*true,function (txt, columnIndex, $element) {
                // note $element is the div inside of the table cell, so use $element.closest('td') to get the cell
                // only select everthing within the element when the content starts with the letter "B"
                //return /^b/i.test(txt) && columnIndex === 0;
            },*/
            editable_wrapContent: null,//'<div>',       // wrap all editable cell content... makes this widget work in IE, and with autocomplete
            /*reorder_axis: 'x', // 'x' or 'xy'
            reorder_delay: 300,
            reorder_helperClass: 'tablesorter-reorder-helper',
            reorder_helperBar: 'tablesorter-reorder-helper-bar',
            reorder_noReorder: 'reorder-false',
            reorder_blocked: 'reorder-block-left reorder-block-end',
            reorder_complete: null // callback*/
        },
    }).tablesorterPager({
        // target the pager markup - see the HTML block below
        container: $(".pager"),

        // use this url format "http:/mydatabase.com?page={page}&size={size}" 
        ajaxUrl: "/application/vlansummarys?page={page}&size={size}&{sortList:col}&{filterList:fcol}",

        // modify the url after all processing has been applied
        customAjaxUrl: function(table, url) { return url; },

        ajaxProcessing: function (data) {
            if (data && data.hasOwnProperty('rows')) {
                var str = "", d = data.rows,
                    // total number of rows (required)
                    total = data.total_rows,
                    // len should match pager set size (c.size)
                    len = d.length;

                for (var i = 0; i < len; i++) {
                    str += '<tr>';
                    for (var column = 0; column < orderedFieldMapping.length; column++) {
                        //Distinzione temporanea per gestire i casi di dato non presente (Data Attivazione) e handler di selezione
                        if (orderedFieldMapping[column].toUpperCase() != 'ACTIVATIONDATE' || bReadOnly)
                            str += '<td class="' + orderedFieldMapping[column].toUpperCase() + '"' + ($('#' + orderedFieldMapping[column].toUpperCase()).prop('checked') ? '' : 'style="display:none;"') + '><div>' + (eval('d[i].' + orderedFieldMapping[column]) != null ? eval('d[i].' + orderedFieldMapping[column]) : '') + '</div></td>';
                        else
                            str += '<td title="Inserire la data nel formato gg/mm/aaaa (click per inserimento)" class="' + orderedFieldMapping[column].toUpperCase() + '"' + ($('#' + orderedFieldMapping[column].toUpperCase()).prop('checked') ? '' : 'style="display:none;"') + '><div contenteditable="true" ' + (eval('d[i].' + orderedFieldMapping[column]) != null ? '' : 'class="emptyPlaceholder" ') + 'onmouseup="javascript:SelectActivationDateText(this);" onblur="javascript:RestoreCellStyle(this);">' + (eval('d[i].' + orderedFieldMapping[column]) != null ? eval('d[i].' + orderedFieldMapping[column]) : emptyTextString) + '</div></td>';
                    }
                    str += '</tr>';
                }

                // in version 2.10, you can optionally return $(rows) a set of table rows within a jQuery object
                return [total, $(str)];
            }
        },

        ajaxObject: {
            dataType: 'json'
        },

        // output string - default is '{page}/{totalPages}';
        // possible variables:
        // {page}, {totalPages}, {startRow}, {endRow} and {totalRows}
        output: '{startRow} to {endRow} ({totalRows})',

        // apply disabled classname to the pager arrows when the rows at
        // either extreme is visible - default is true
        updateArrows: true,

        // starting page of the pager (zero based index)
        page: 0,

        // Number of visible rows - default is 10
        size: 20,

        //Reset pager to this page after filtering; set to desired page number (zero-based index), or false to not change page at filter start (Updated v2.16). 
        pageReset: false,

        // if true, the table will remain the same height no matter how many
        // records are displayed. The space is made up by an empty 
        // table row set to a height to compensate; default is false 
        fixedHeight: true,

        // remove rows from the table to speed up the sort of large tables.
        // setting this to false, only hides the non-visible rows; needed
        // if you plan to add/remove rows with the pager enabled.
        removeRows: false,

        // css class names of pager arrows
        // next page arrow
        cssNext: '.next',
        // previous page arrow
        cssPrev: '.prev',
        // go to first page arrow
        cssFirst: '.first',
        // go to last page arrow
        cssLast: '.last',
        // select dropdown to allow choosing a page
        cssGoto: '.gotoPage',
        // location of where the "output" is displayed
        cssPageDisplay: '.pagedisplay',
        // dropdown that sets the "size" option
        cssPageSize: '.pagesize',
        // class added to arrows when at the extremes 
        // (i.e. prev/first arrows are "disabled" when on the first page)
        // Note there is no period "." in front of this class name
        cssDisabled: 'disabled'
    }).children('tbody').on('editComplete', 'td', function() {
        var $this = $(this),
            //$allRows = $this.closest('table')[0].config.$tbodies.children('tr'),
            newContent = $this.text(),
            /*cellIndex = this.cellIndex, // there shouldn't be any colspans in the tbody
            rowIndex = $allRows.index($this.closest('tr')),*/
            id = $this.closest('tr').find('td.ID').text();

        $.ajax({
            type: "POST",
            crossDomain: true,
            url: '/application/vlansummarys/update/' + id,
            data: JSON.stringify({ activationDate: newContent }),
            dataType: "text",
            contentType: "application/json; charset=utf-8",
            error: function(xhr, textStatus, errorThrown) {
                alert("Errore durante l'inserimento: il dato inserito non è corretto. Contattare sistemi informativi se si ritiene che il messaggio d'errore sia sbagliato.");
            },
            success: function(data, textStatus, xhr) {
                //console.log(xhr);
                if ($this.find('div').hasClass('emptyPlaceholder'))
                    $this.find('div').removeClass('emptyPlaceholder');
            },
        });
    });
}

1 个答案:

答案 0 :(得分:1)

所以问题原来是寻呼机插件/小部件的问题。编辑单元格时,可编辑窗口小部件会触发“updateCell”事件以更新内部缓存。完成此过程后,核心插件会触发“updateComplete”事件。

在寻呼机代码中,当触发“updateComplete”事件时,它会不恰当地更新总行数和总页数,因为正在使用ajax,它只计算当前表中的行。

所以基本上,我添加了一个检查,以防止在使用ajax时重新计算页面/行数。

从GitHub存储库主分支获取此latest update for the pager