【问题标题】:How to select row from ajax data如何从ajax数据中选择行
【发布时间】:2016-12-27 08:23:22
【问题描述】:

免费 jqgrid 在每一行中都包含按钮。点击按钮进行ajax调用,根据点击的行列值返回客户列表。

用户可以从这些数据中选择客户。选定的客户名称和 ID 应写入 jqgrid 行。

我尝试了下面的代码,但我得到了:

未捕获的类型错误:无法读取未定义的属性“rowIndex”

此错误发生在这行代码上:

var clickedId = $(this).closest('tr')[0].rowIndex,

在选择表单中的任何位置单击时。

如何解决这个问题?应用程序包含来自不同数据的许多此类选择。实现它们以避免代码重复的最佳方法是什么?

表是用 javascript 创建的。是否合理/如何为此使用一些 MVC 部分视图或其他模板?

这段代码可以改进/重构吗?

使用免费的 jqgrid 4.13.3-pre、.NET 4.6、ASP.NET MVC、Bootstrap 3、jQuery、jQuery UI。

选择表单是从引导模式示例中复制的:

<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            </div>
            <div class="modal-body">
                <table class='table table-hover table-striped'>
                    <thead>
                        <tr><td>Customer name</td><td>Customer Id</td></tr>
                    </thead>
                    <tbody></tbody>
                </table>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">close without selection</button>
            </div>
        </div>
    </div>
</div>

jqgrid colmodel:
    formatter: "showlink",
    formatoptions: {
        onClick: function (options) {
            var nimeosa = getColumnValue('customername', options.rowid);
            if (nimeosa == null) {
                return false;
            }
            $.ajax('api/Customers/FromRegister?' + $.param({ namepart: nimeosa }), {
                type: 'GET',
                dataType: 'json',
                contentType: "application/json",
                async: false
            }).done(function (data, textStatus, jqXHR) {
                var valik = "";
                for (var i = 0; i < data.customerlist.length; i++) {
                    valik += '<tr><td>' + data.customerlist[i].customerName + '</td><td>' +
                        data.customerlist[i].customerId + '</td></tr>';
                }
                $('#exampleModal').on('show.bs.modal', function (event) {
                    $('.modal-body tbody').html(valik);
                });

                $('#exampleModal').on('click.bs.modal', function (event) {
                    // how to fix Uncaught TypeError: Cannot read property 'rowIndex' of undefined in this line:
                    var clickedId = $(this).closest('tr')[0].rowIndex,                                    clickedElem = data.customerlist[clickedId];
                    $('#' + options.rowid + '_customername').val(clickedElem.customerName);
                    $('#' + options.rowid + '_customerid').val(clickedElem.customerId);
                });
                $('#exampleModal').modal();
            );
            return false;
        }
    }

// gets column value from jqgrid row
function getColumnValue(valjaNimi, rowId) {
    var
        iNimi = getColumnIndexByName($grid, valjaNimi),
        $nimi = $('#' + rowId + '>td:nth-child(' + (iNimi + 1) + ')'),
        nimiVal;

    if ($nimi.find('>input').length === 0) {
        // the cell is not in editing mode 
        nimiVal = $nimi.text();
    }
    else {
        nimiVal = $nimi.find('>input').val();
    }

    if (nimiVal === undefined || nimiVal.trim() === '') {
        alert('No value');
        return null;
    }
    return nimiVal;
}

更新

我尝试了答案中的代码。 行比引导模态宽度更宽。 宽行变得比表格更宽:

如何解决这个问题? 如何强制行出现在模态中? 如果行数超出屏幕大小,如何创建滚动条?

【问题讨论】:

  • 您尚未显示 html,但 $(this).parent('tr') 获取按钮的直接父级,除非您的 html 无效,否则该按钮不会是 &lt;tr&gt; 元素。你可能想要var clickedId = $(this).closest('tr')[0].rowIndex;
  • 我将线路改为var clickedId = $(this).closest('tr')[0].rowIndex,但仍然出现同样的错误。如何解决这个问题? html 是在相关的 done 方法代码中生成的。它包含简单的 tr 元素。
  • 有点难以理解您生成的最终 html 是什么,但 $(this) 是父元素(您似乎将行添加到 &lt;div class="modal fade" id="exampleModal" ... &gt; 元素内的 &lt;tbody&gt; 元素中。在这种情况下,它可能需要是$(this).find('tbody tr')[0].rowIndex;
  • 使用$(this).find('tbody tr')[0].rowIndex 总是选择表中的第二行,如果在任何地方点击。如何选择点击的行?也许为每个 tr 元素添加点击处理程序是合理的?
  • 您当前的所有处理都是父 div 的点击事件。如果您想从特定行获取值,那么您需要处理该行的点击事件 - 例如$('exampleModal tbody').on('click', 'tr', function() { var row = $(this); // returns the row you clicked }); 然后row.children('td').eq(0).text(); 将返回customerNamerow.children('td').eq(1).text(); 将返回customerId (我假设这就是你想要得到的?)

标签: jquery asp.net-mvc twitter-bootstrap jqgrid free-jqgrid


【解决方案1】:

为了从行中获取客户的值,您需要处理&lt;tr&gt; 元素的点击事件,而不是其父模态。由于行是动态添加的,因此您需要使用事件委托来处理。

$('#exampleModal tbody').on('click', 'tr', function() {
    var cells = $(this).children('td');
    $('#' + options.rowid + '_customername').val(cells.eq(0).text());
    $('#' + options.rowid + '_customerid').val(cells.eq(1).text());
    $('exampleModal').hide(); // assuming you want to close the modal
});

注意上面应该是一个单独的脚本,但不清楚options.rowid是什么以及是否可以将其存储在全局变量中或传递给模态以便可以在上述函数中访问(请参阅以下建议)

附带说明,您的某些功能似乎没有必要(您每次都重新附加相同的事件),我相信代码可以只是

// declare rowID as a global var and then in the above script you can use
// $('#' + rowID + '_customername').val(cells.eq(0).text());
var rowID;
var table = $('#exampleModal tbody'); // cache it

....
onClick: function (options) {
    rowID = options.rowid; // set the row ID
    ....
    $.ajax('api/Customers/FromRegister?' + $.param({ namepart: nimeosa }), {
        type: 'GET',
        dataType: 'json',
        contentType: "application/json",
        async: false
    }).done(function (data, textStatus, jqXHR) {
        table.empty(); // clear any existing rows
        $.each(data, function(index, item) {
            var row = $('<tr></tr>');
            row.append($('<td></td>').text(item.customerName ));
            row.append($('<td></td>').text(item.customerId));
            table.append(row);
        });
        $('#exampleModal').modal(); // display the mpday
    );
    return false;
}

【讨论】:

  • 谢谢。行出现在引导模式之外。如何解决这个问题?我用这个问题更新了问题。
  • 注释编辑设置行ID。那肯定是一个CSS问题。除非你能制作一个小提琴来重现它,否则它真的不可能帮助你
  • 这增加了两个全局变量rowIDtable。应用程序有很多 js 库和 js 代码。一些库也可能使用具有相同名称的变量,因此会发生冲突。为什么这些变量没有在 onClick 方法中定义。为什么它们是全球性的?
  • 看起来引导模式表单宽度是在使用 thead 元素宽度创建 html 页面时定义的。如果它由 $.ajax 显示,它的宽度不会改变。是否有一些简单的方法可以强制在 Bootstrap modal 中为比模式窗口更宽的内容启用滚动条或文本换行?
  • 您应该能够通过设置overflow 属性来使用css 设置样式 - 例如overflow: scroll; 但您可能需要尝试将其应用于哪个元素(可能在&lt;div class="modal-body"&gt; 上)
猜你喜欢
  • 2020-03-02
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 2017-10-30
  • 2018-07-12
  • 2015-10-17
  • 1970-01-01
相关资源
最近更新 更多