Tablesorter 似乎是 运行 两次用于列选择

Tablesorter appears to be running twice for column selection

多年来我一直在使用 Mottie 出色的 Tablesorter 分支。我 运行 遇到了一个我以前从未见过的问题,我不确定从哪里开始寻找这个问题。

所有功能都正常工作,但是当我单击 Column 按钮时,它显示 'auto' 两次,并拉入非列的内容。在下图中,带有红色下划线的项目不属于 headers。它们是灰色的,无法触摸。我不知道他们来自哪里。

headers 派生自动态条目集,粘贴在下面。不确定这是否相关,但我发布了代码以防它有帮助:

 <tr id="sort_data" data-col="{{$col}}">
        @foreach($atts as $cus_att)
           
            @if($cus_att->attribute->visible_in_list_view)
                <th class="center {{$cus_att->attribute->optional_in_list_view? 'columnSelector-false':''}}">
                   
                    {{$cus_att->attribute->name}}

                </th>
            @endif

        @endforeach
        <th class="center col-1" data-filter="false" data-sorter="false">{{__("Action")}}</th>
   </tr>

我不知道我是否遗漏了一些明显的东西,但是任何关于从哪里开始寻找错误的想法都将不胜感激。

谢谢!

已渲染 HTML:

<table id="table1" class="table table-bordered tablesorter tablesorter-blue tablesorterefb7ab942ea838columnselector hasResizable hasFilters hasStickyHeaders" data-sort-name="name" role="grid" aria-describedby="table1_pager_info">
<thead id="thead">

<tr id="sort_data" data-col="0" role="row" class="tablesorter-headerRow">
    <th class="center tablesorter-header tablesorter-headerAsc" data-column="0" tabindex="0" scope="col" role="columnheader" aria-disabled="false" aria-controls="table1" unselectable="on" style="user-select: none;" aria-sort="ascending" aria-label="Name: Ascending sort applied, activate to apply a descending sort"><div class="tablesorter-header-inner">
        Name
    </div></th>
    <th class="center tablesorter-header tablesorter-headerUnSorted" data-column="1" tabindex="0" scope="col" role="columnheader" aria-disabled="false" aria-controls="table1" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="Owner: No sort applied, activate to apply an ascending sort"><div class="tablesorter-header-inner">
        Owner
    </div></th>
    <th class="center tablesorter-header tablesorter-headerUnSorted" data-column="2" tabindex="0" scope="col" role="columnheader" aria-disabled="false" aria-controls="table1" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="Priority: No sort applied, activate to apply an ascending sort"><div class="tablesorter-header-inner">
        Priority
    </div></th>
    <th class="center tablesorter-header tablesorter-headerUnSorted" data-column="3" tabindex="0" scope="col" role="columnheader" aria-disabled="false" aria-controls="table1" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="Data Location: No sort applied, activate to apply an ascending sort"><div class="tablesorter-header-inner">
        Data Location
    </div></th>
    <th class="center tablesorter-header tablesorter-headerUnSorted" data-column="4" tabindex="0" scope="col" role="columnheader" aria-disabled="false" aria-controls="table1" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="Category: No sort applied, activate to apply an ascending sort"><div class="tablesorter-header-inner">
        Category
    </div></th>
    <th class="center columnSelector-false tablesorter-header tablesorter-headerUnSorted" data-column="5" tabindex="0" scope="col" role="columnheader" aria-disabled="false" aria-controls="table1" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="Support: No sort applied, activate to apply an ascending sort"><div class="tablesorter-header-inner">
       Support
    </div></th>
    <th class="center col-1 tablesorter-header sorter-false tablesorter-headerUnSorted" data-filter="false" data-sorter="false" data-column="6" scope="col" role="columnheader" aria-disabled="true" unselectable="on" style="user-select: none;" aria-sort="none" aria-label="Action: No sort applied, sorting is disabled"><div class="tablesorter-header-inner">Action</div></th>
</tr>


<tr role="row" class="tablesorter-filter-row tablesorter-ignoreRow"><td data-column="0" class="pointer center"><input type="search" placeholder="Search..." class="tablesorter-filter" data-column="0" data-lastsearchtime="1628907240814"><span class="glyphicon glyphicon-refresh reset" style="margin-top:4px;"></span></td><td data-column="1"><input type="search" placeholder="Search..." class="tablesorter-filter" data-column="1" data-lastsearchtime="1628907240814"></td><td data-column="2"><input type="search" placeholder="Search..." class="tablesorter-filter" data-column="2" data-lastsearchtime="1628907240814"></td><td data-column="3"><input type="search" placeholder="Search..." class="tablesorter-filter" data-column="3" data-lastsearchtime="1628907240814"></td><td data-column="4"><input type="search" placeholder="Search..." class="tablesorter-filter" data-column="4" data-lastsearchtime="1628907240814"></td><td data-column="5"><input type="search" placeholder="Search..." class="tablesorter-filter" data-column="5" data-lastsearchtime="1628907240814"></td><td data-column="6"><input type="search" placeholder="" class="tablesorter-filter disabled" data-column="6" disabled="" data-lastsearchtime="1628907240814"></td></tr></thead>

<tbody class="tbodyContent reorderDiv" aria-live="polite" aria-relevant="all">

TS 初始化

$(function() {

    var $table = $("table");

    var sortCol = $("#sort_data").data('col');

    $('button.columnSelectorButton').click(function(){
        $.tablesorter.storage( $table, 'tablesorter-columnSelector', [] );
        $.tablesorter.storage( $table, 'tablesorter-columnSelector-auto', {} );
        // reload the page
        document.location.reload();
    });

    /*** custom css only button popup ***/
    $table.tablesorter({
        theme: 'blue',
        sortList: [[sortCol,0]],
        widgets: ['zebra', 'filter',  'columnSelector', 'resizable', 'stickyHeaders'],
        widgetOptions : {
            resizable: true,
            resizable_addLastColumn: true,
            // Filters:
            filter_columnFilters: true,
            filter_placeholder: {search: 'Search...'},
            filter_saveFilters: false,
            filter_reset: '.reset',

            {{-- number or jquery selector targeting the position:fixed element -- how far from top should header
                sit, or create a class (like black_bar) that should alos be included in the sticky headaer --}}
            stickyHeaders_offset : 45,
            stickyHeaders : '.black_bar',

            {{-- target the column selector markup --}}
            columnSelector_container : $('#columnSelector'),
            {{-- column status, true = display, false = hide
                // disable = do not display on list --}}
            columnSelector_columns : {
                0: 'disable' /* set to disabled; not allowed to unselect it */
            },
            {{-- remember selected columns (requires $.tablesorter.storage) --}}
            columnSelector_saveColumns: true,

            {{-- container layout --}}
            columnSelector_layout : '<label><input type="checkbox">{name}</label>',
            {{-- data attribute containing column name to use in the selector container --}}
            columnSelector_name  : 'data-selector-name',

            {{-- Responsive Media Query settings
                 enable/disable mediaquery breakpoints --}}
            columnSelector_mediaquery: true,
            {{-- toggle checkbox name --}}
            columnSelector_mediaqueryName: 'Auto: ',
            {{-- breakpoints checkbox initial setting --}}
            columnSelector_mediaqueryState: true,
            {{-- hide columnSelector false columns while in auto mode --}}
            columnSelector_mediaqueryHidden: true,
            {{-- responsive table hides columns with priority 1-6 at these breakpoints
            // see http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/#Applyingapresetbreakpoint
            // *** set to false to disable *** --}}
            columnSelector_breakpoints : [ '20em', '30em', '40em', '50em', '60em', '70em' ],
            {{-- data attribute containing column priority
            // duplicates how jQuery mobile uses priorities:
            // http://view.jquerymobile.com/1.3.2/dist/demos/widgets/table-column-toggle/ --}}
            columnSelector_priority : 'data-priority',

            {{-- class name added to checked checkboxes - this fixes an issue with Chrome not updating FontAwesome
                 applied icons; use this class name (input.checked) instead of input:checked --}}
            columnSelector_cssChecked : 'checked'
        }
    })

    {{-- bind to pager events
         ********************* --}}
        .bind('pagerChange pagerComplete pagerInitialized pageMoved', function (e, c) {
            var msg = '"</span> event triggered, ' + (e.type === 'pagerChange' ? 'going to' : 'now on') +
                    ' page <span class="typ">' + (c.page + 1) + '/' + c.totalPages + '</span>';
            $('#display')
                    .append('<li><span class="str">"' + e.type + msg + '</li>')
                    .find('li:first').remove();
        })

    {{-- initialize the pager plugin
         **************************** --}}
        .tablesorterPager(pagerOptions);

TS 寻呼机选项:

var pagerOptions = {

    // target the pager markup - see the HTML block below
    container: $(".pager"),

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

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

    // ajax error callback from $.tablesorter.showError function
    // ajaxError: function( config, xhr, settings, exception ){ return exception; };
    // returning false will abort the error message
    ajaxError: null,

    // add more ajax settings here
    // see http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
    ajaxObject: {dataType: 'json'},

    // process ajax so that the data object is returned along with the total number of rows
    ajaxProcessing: null,

    // Set this option to false if your table data is preloaded into the table, but you are still using ajax
    processAjaxOnInit: true,

    // output string - default is '{page}/{totalPages}'
    // possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
    // also {page:input} & {startRow:input} will add a modifiable input in place of the value
    output: '{startRow:input} to {endRow} ({totalRows})',

    // apply disabled classname (cssDisabled option) to the pager arrows when the rows
    // are at either extreme is visible; default is true
    updateArrows: true,

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

    // Number of visible rows
    size: 30,

    // Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
    savePages: true,

    // fix the column widths
    widthFixed: false,

    // Saves tablesorter paging to custom key if defined.
    // Key parameter name used by the $.tablesorter.storage function.
    // Useful if you have multiple tables defined
    storageKey: 'tablesorter-pager',

    // Reset pager to this page after filtering; set to desired page number (zero-based index),
    // or false to not change page at filter start
    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: false,

    // 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,

    // If true, child rows will be counted towards the pager set size
    countChildRows: false,

    // css class names of pager arrows
    cssNext: '.next', // next page arrow
    cssPrev: '.prev', // previous page arrow
    cssFirst: '.first', // go to first page arrow
    cssLast: '.last', // go to last page arrow
    cssGoto: '.gotoPage', // select dropdown to allow choosing a page

    cssPageDisplay: '.pagedisplay', // location of where the "output" is displayed
    cssPageSize: '.pagesize', // page size selector - select dropdown that sets the "size" option

    // class added to arrows when at the extremes (i.e. prev/first arrows are "disabled" when on the first page)
    cssDisabled: 'disabled', // Note there is no period "." in front of this class name
    cssErrorRow: 'tablesorter-errorRow' // ajax error information row

}

我真的很喜欢这个图书馆,它太棒了。谢谢@Mottie。

我学会了如何使用调试功能,看到了将近 100 个错误,如下所示:

Stopping initialization! No table, thead or tbody 
<table class="phpdebugbar-widgets-params" style="display: table; border: 0; width: 99%">

问题 = 与 phpDebugBar 冲突,我没有意识到这一点,但显然试图在页面上创建自己的 table 并且因此 TS 也在寻找那些 headers。

测试(在 Laravel 或 php 应用中使用类似的 .env):

我通过更改 .env 以显示 APP_ENV=productionAPP_DEBUG=false 使应用退出开发模式。这将从页面中删除 phpDebugBar,并删除问题以及 100 个调试通知。

修复:

在 Tablesorter 初始化文件的第一行,我刚刚将 jQuery 元素从通用的 'table' 更改为特定的 id:

var $table = $("#table1");