通过会话存储获取所有表行值

时间:2017-06-21 12:56:32

标签: javascript jquery html session checkbox

我有一个HTML表,其中一列有复选框。如果选中一个复选框,然后按“结帐”按钮,它将获取指定的行并将其显示在电子邮件正文中。

页面加载时显示前100行。我还有一个搜索功能,用户可以搜索特定的行。用户可以在不同的搜索中进行操作,并且仍然使用会话存储来检查所有复选框。但是,当用户点击“Checkout”时,电子邮件正文仅显示已检查且当前在页面上可见的表格行。

因此,如果用户搜索表格行并对其进行检查,然后导航回原始的前100行,则该检查行将不会显示在电子邮件上,因为它在当前时刻未显示在页面上。

如何修复此问题并显示已检查的所有行,无论它们是否在页面上可见?

我被告知我将复选框存储在会话中,然后返回UI以读取所选项目列表。但是,我不确定如何解决这个问题,并且非常感谢一些帮助!谢谢!

JavaScript,其中包含用于在整个会话期间检查所有复选框的代码:

$(function(){
    $(':checkbox').each(function() {
        // Iterate over the checkboxes and set their "check" values based on the session data
        var $el = $(this);
        //console.log('element id: ',$el.prop('id'),' sessionStorage[id]: ',sessionStorage[$el.prop('id')]);
        $el.prop('checked', sessionStorage[$el.prop('id')] === 'true');
        if ($el.prop('checked')) {          
            //show the quantity cell in the column under header with class num
            $el.closest('tr').find('td.quantity_num').toggle(this.checked);
            var quantity = sessionStorage['value_'+$el.prop('id')];
            if (quantity) {
                $el.closest("tr").find(".spinner" ).spinner( "value", quantity );
            }
        }
    });

    $('input:checkbox').on('change', function() {
        // save the individual checkbox in the session inside the `change` event, 
        // using the checkbox "id" attribute
        var $el = $(this);
        sessionStorage[$el.prop('id')] = $el.is(':checked');
    });
});

将信息发送到电子邮件正文的JavaScript:

function sendMail() {
    var dataItems = [
        { 'clss':'.loc',         'prop':'loc' },
        { 'clss':'.rp-code',     'prop':'rpCode' },
        { 'clss':'.sku',         'prop':'sku' },
        { 'clss':'.special-id',  'prop':'specialId' },
        { 'clss':'.description', 'prop':'description' },
        { 'clss':'.quantity',    'prop':'quantity' },
        { 'clss':'.unit',        'prop':'unit' }
    ];
    var link = "mailto:me@example.com" + "?subject=" + encodeURIComponent("Order") + "&body=";
    link += $('#merchTable tr input[name="check"]:checked').closest('tr').get().map(function(tr) {
            var str = dataItems.map(function(item) {
                return encodeURIComponent($(tr).find(item.clss).data(item.prop)) + '\xa0\xa0';
            }).join('');
            str += encodeURIComponent($(tr).find('.spinner').spinner('value')) + '%0D%0A';
            return str;
        }).join('') + '%0D%0A';
    console.log(link);
    window.location.href = link;
}

HTML表:

<section id="checkout-btn"> 
<button id="checkout" name="order" onclick="sendMail(); return false">Checkout</button>
</section>

<br>

<table id="merchTable" cellspacing="5" class="sortable">
    <thead>
        <tr class="ui-widget-header">
            <th class="sorttable_nosort"></th>
            <th class="sorttable_nosort">Loc</th>
            <th class="merchRow">Report Code</th>
            <th class="merchRow">SKU</th>
            <th class="merchRow">Special ID</th>
            <th class="merchRow">Description</th>
            <th class="merchRow">Quantity</th>
            <th class="sorttable_nosort">Unit</th>
            <th style="display: none;" class="num">Quantity #</th>
        </tr>
    </thead>
    <tbody>

        <?php foreach ($dbh->query($query) as $row) {?>

        <tr>
            <td class="ui-widget-content"><input type="checkbox" class="check" name="check" id="checkid-<?php echo intval ($row['ID'])?>"></td>
            <td class="loc ui-widget-content" data-loc="<?php echo $row['Loc'] ?>"><input type="hidden"><?php echo $row['Loc'];?></td>
            <td class="rp-code ui-widget-content" align="center" data-rp-code="<?php echo $row['Rp-Code'] ?>" id="rp-code-<?php echo intval ($row['Rp-Code'])?>"><?php echo $row['Rp-Code'];?></td>
            <td class="sku ui-widget-content" data-sku="<?php echo $row['SKU'] ?>" id="sku-<?php echo intval ($row['SKU'])?>"><?php echo $row['SKU'];?></td>
            <td class="special-id ui-widget-content" data-special-id="<?php echo $row['Special-ID'] ?>" align="center" id="special-id-<?php echo intval ($row['Special-ID'])?>"><?php echo $row['Special-ID'];?></td>
            <td class="description ui-widget-content" data-description="<?php echo htmlspecialchars($row['Description']) ?>" id="description-<?php echo intval ($row['Description'])?>"><?php echo $row['Description'];?></td>
            <td class="quantity ui-widget-content" data-quantity="<?php echo $row['Quantity'] ?>" align="center" id="quantity-<?php echo intval ($row['Quantity'])?>"><?php echo $row['Quantity'];?></td>
            <td class="unit ui-widget-content" data-unit="<?php echo $row['Unit'] ?>" id="unit-<?php echo intval ($row['Unit'])?>"><?php echo $row['Unit'];?></td>
            <td style="display: none;" class="quantity_num ui-widget-content"><input disabled="true" type="textbox" style="width: 100px;" class="spinner" id="spin-<?php echo intval ($row['ID'])?>"></td>
        </tr>

    <?php } ?>

    </tbody>
</table>

修改

检查行时显示Quantity #列的函数:

$(function () {
    $(".check").change(function(){
        $(this).closest('tr').find('td.quantity_num').toggle(this.checked);
        setupSpinner(this);
        console.log('input - checked: ',$('input.check').is(':checked'));
        //var quantity = $(this).closest('tr').find('td.quantity').data('quantity');

        if($('input.check').is(':checked'))
            $(this).closest('table').find('th.num').toggle(true);
        else
            $(this).closest('table').find('th.num').toggle(false);

    });
});

微调器的功能:

function setupSpinner(checkbox) {
     var quantity = $(checkbox).closest('tr').find('td.quantity').data('quantity');
    console.log('quantity: ',quantity);
    $(checkbox).closest("tr").find(".spinner" ).spinner({
      spin: function( event, ui ) {          
        if ( ui.value > quantity ) {
          $( this ).spinner( "value", quantity );
          return false;
        } else if ( ui.value <= 1 ) {
          $( this ).spinner( "value", 1 );
          return false;
        }
          //store value
        var test = ui.value;
        sessionStorage.setItem('value_'+$(checkbox).prop('id'), JSON.stringify(test));
        var testtrue = sessionStorage.getItem('value_'+$(checkbox).prop('id'));
          console.log('testtrue: ', JSON.parse(testtrue));
      }
    });        
}

从已检查表行中的每个单元格获取值的函数:

$(function () {
  $(document).on("click", "#merchTable .check", function () {
  var $this = $(this);
  var tds = $this.closest('tr').find('td').filter(function () {
    return $(this).find('.check').length === 0;
  });
    var isValid = true;
    var errors = '';
    var elements = tds;
    if (tds.find('td').length > 0) {
      elements = tds.find('td');
    }
    var dict = {}; 
    elements.each(function (index, element) {
      var type = $(this).attr('class');
      var value = (element.tagName == 'td') ? $(this).val() : $(this).text();
      console.log(type);
      // ----- Switch statement that provides validation for each table cell -----
      switch (type) {
        case "loc ui-widget-content":
              dict["Loc"] = value;
          break;
        case "rp-code ui-widget-content":
              dict["Rp-Code"] = value;
          break;
        case "sku ui-widget-content":
              dict["SKU"] = value;
          break;
        case "special-id ui-widget-content":
              dict["Special-ID"] = value;
          break;
        case "description ui-widget-content":
              dict["Description"] = value;
          break;
        case "quantity ui-widget-content":
              dict["Quantity"] = value;
          break;
        case "unit ui-widget-content":
              dict["Unit"] = value;
          break;
        case "quantity_num ui-widget-content":
              dict["spinner"] = value;
          break;
      }
    })
    if (isValid) {
        console.log(dict);
    } else {
      alert(errors);
    }
});
});

1 个答案:

答案 0 :(得分:1)

根据这个和之前的问题,我知道你需要一些东西:

  • 将已检查行的状态存储在window.sessionStorage
  • 在分页/搜索后恢复已检查行的状态。
  • 允许电子邮件正文的组成,反映所有已检查的行,无论它们当前是否显示。

没有纪律,代码可能会变得非常混乱。我推荐使用简单API的单例对象,最后得到以下代码。

$(function($) {
    // **************************************************************
    // RowData acts as an interface beteween high level 
    // application code and sessionStorage.
    // *************************
    // RowData is phrased as a singleton object with private data,
    // and a bunch of functions, some of which are exposed as methods.
    // *************************
    // Inner member `rowData` is a javascript representation of all 
    // checked rows in the session.
    // A JSON-encoded version of `rowData` is stored in sessionStorage.
    // **************************************************************
    var RowData = (function(storage, storageKey) {
        var rowData = readFromSession();
        var dataItems = ['loc', 'rp-code', 'sku', 'special-id', 'description', 'quantity', 'unit'];
        var emailDelimiters = {
            'row': '%0D%0A',
            'dataItem': '\xa0\xa0'
        };

        function readFromSession() {
            return JSON.parse(storage.getItem(storageKey) || '{}');
        }
        function writeToSession() {
            storage.setItem(storageKey, JSON.stringify(rowData));
        }
        function writeRow(tr) {
            var $tr = $(tr),
                id = $tr.prop('id');
            if($tr.find('.check').is(':checked')) {
                rowData[id] = {};
                for(var i=0; i<dataItems.length; i++) {
                    rowData[id][dataItems[i]] = $tr.find('.' + dataItems[i]).text();
                }
                // rowData[id].quantity_num = $tr.find('.spinner').spinner('value'); // if using spinner widget
                rowData[id].quantity_num = $tr.find('.spinner').val(); // if using HTML5 <input type="number">
            } else {
                delete rowData[id];
            }
            writeToSession();
        }
        function readRow(tr) {
            // restore tr's checkbox and spinner value from stored data
            var $tr = $(tr),
                id = $tr.prop('id'),
                row = rowData[id];
            if(row) {
                $tr.find('.check').prop('checked', true).end()
                     // .find('.spinner').spinner('value', row.quantity_num); // if using spinner widget
                     .find('.spinner').val(row.quantity_num); // if using HTML5 <input type="number">
            }
        }
        function toEmailString() {
            return $.map(rowData, function(row, id) {
                return $.map(row, window.encodeURIComponent).join(emailDelimiters.dataItem);
            }).join(emailDelimiters.row);
        }
        // selectively expose functions as methods of RowData
        return {
            'writeRow': writeRow,
            'readRow': readRow, 
            'toEmailString': toEmailString
        };
    })(window.sessionStorage, 'checkedRowData');

    // **********************************************************************************************
    // With RowData in place to do the hard stuff, the high level application code is really simple
    // **********************************************************************************************
    $('#merchTable').on('change', '.check', function() { // on changing a table row ...
        RowData.writeRow($(this).closest('tr').get(0)); // ... set the corresponding row object in RowData and sessionStorage
    }).on('blur', '.spinner', function() { // on leaving a spinner widget
        RowData.writeRow($(this).closest('tr').get(0));
    });
    $('#checkout').on('click', function() { // on clicking the [Checkout] button
        var link = "mailto:me@example.com" + "?subject=" + encodeURIComponent("Order") + "&body=" + RowData.toEmailString();
        console.log(link);
        window.location.href = link;
    });

    // Call this function on completion of every pagination/search
    function restoreVisibleRows() {
        $('#merchTable tbody tr').get().forEach(RowData.readRow);
    }

    // ...
    // here, set up table pagination/search, and spinners.
    // ...


    restoreVisibleRows();
});

经过最低限度的测试

请注意,上面的所有内容都依赖于表行如下:

<tr id="<?php echo intval ($row['ID'])?>">
    <td class="ui-widget-content"><input type="checkbox" class="check" name="check" /></td>
    <td class="loc ui-widget-content"><input type="hidden"><?php echo $row['Loc'];?></td>
    <td class="rp-code ui-widget-content" align="center"><?php echo $row['Rp-Code'];?></td>
    <td class="sku ui-widget-content"><?php echo $row['SKU'];?></td>
    <td class="special-id ui-widget-content" align="center"><?php echo $row['Special-ID'];?></td>
    <td class="description ui-widget-content"><?php echo $row['Description'];?></td>
    <td class="quantity ui-widget-content" align="center" ><?php echo $row['Quantity'];?></td>
    <td class="unit ui-widget-content" ><?php echo $row['Unit'];?></td>
    <td style="display: none;" class="quantity_num ui-widget-content"><input disabled="true" type="number" min="1" max="<?php echo $row['Quantity'];?>" step="1" style="width: 100px;" class="spinner" /></td>
</tr>

在这里,我:

  • id="<?php echo intval ($row['ID'])?>"添加到<tr>代码 - RowData界面在没有它的情况下无法正常工作。
  • data-***标记中删除了id<td>属性 - 它们似乎没有必要,但如果出于其他目的需要可以重新引入。