为 table 中的每一行创建 jQuery ui 对话框

Create jQuery ui dialog box for each row in a table

我正在尝试使用名为 searchResults 的数组将行附加到 table。在我介绍 jQuery UI 对话框之前,一切都按预期工作。问题是我需要为第一列中的每一行创建一个新对话框。我对所有这一切都很陌生,所以我很确定我有时会错误地使用索引。这只是为了让您了解我要完成的工作。知道如何正确执行此操作吗?

for (var i = 0; i < searchResults.length; i++)
{
    $('#patientFileDialog[i]').dialog();

    $'#openPFDialog[i]').click(function() {
        $('#patientFileDialog[i]').dialog('open');
    });

    var dialog[i] = $(`<div id="patientFileDialog[i]" title="Patient File">${searchResults[i].patientWebLink}</div>`);

    body.append('<tr>'+
            `<td><button id="openPFDialog[i]">Click Here</button></td>` +
            `<td>${searchResults[i].patientFirstName}</td>` +
            `<td>${searchResults[i].patientLastName}</td>` +
            `<td>${searchResults[i].patientDateOfBirth}</td>` +
            `<td>${searchResults[i].patientDataPulseID}</td>` +
            `<td>${searchResults[i].patientLaserFicheID}</td>` +
            '</tr>')
}

在进一步查看您的代码后,我想我可以理解您的意图。 Working JSFiddle,有一些伪造的 searchResults,所以我们可以看到它的实际效果。

您问题中的代码存在一些问题:

  • 使用 select 或 $('#patientFileDialog[i]')$'#openPFDialog[i]') 将尝试将页面上的元素与这些 ID 匹配。 AFAICT 这些实际上还不存在,您正在尝试创建它们。

  • var dialog[i] = ... 将一些 div 设置为字符串,但它们从未添加到页面中;

  • 正如我在评论中提到的,存在一些语法错误,可能只是拼写错误和格式混淆;

这是代码的更新版本。显着变化:

  • 与其为每个单独的 openPFDialog 按钮添加一个事件处理程序,不如只添加一个与所有按钮匹配的事件处理程序。然后,该单个处理程序可以计算出单击了哪个按钮,并仅对该按钮而不是所有按钮采取正确的操作。在这种情况下,如果您让所有按钮都使用匹配 openPFDialog-X 的 ID,其中 X 是一个数字,您可以定位任何匹配该模式的内容(使用 starts with selector, and find the X by removing the openPFDialog- part with replace.

  • 不过,上面的内容更加复杂。在页面加载时解析的选择器将只匹配当时存在的元素。在这种情况下,您要向页面添加新元素,并且在页面加载时定义的 selector 将不匹配它们。解决方案是 select 而不是某些 在页面加载时存在的父元素,然后进行过滤。这叫做event delegation(搜索以"Delegated event handlers"开头的段落)。

  • 根据您所拥有的,我猜您创建的 patientFileDialog 应该放置在页面上未显示的某个父元素中?这就是我所做的。

这是代码(和 working JSFiddle):

var dialog, i;

// Single click handler for anything that starts with "openPFDialog-".
// Since those elements don't exist on the page yet, we need to instead
// select a parent object, say the body, and filter for clicks on our
// elements starting with our pattern
$('body').on('click', '[id^=openPFDialog]', function() {
    // We need to find the "i"
    i = $(this).attr('id').replace(/openPFDialog-/,'');
    console.log('clicked on id', i);
    $('#patientFileDialog-' + i).dialog();
});

for (var i = 0; i < searchResults.length; i++) {    
    // Create a new div with ID like "patientFileDialog-1", using the current
    // search result
    dialog = $('<div id="patientFileDialog-' + i + '" title="Patient File">' + searchResults[i].patientWebLink + '</div>');

    // Add it to the page.  I've use a div with ID dialogs which is hidden
    $('#dialogs').append(dialog);

    $('table').append('<tr>'+
        '<td><button id="openPFDialog-' + i + '">Click Here</button></td>' +
        '<td>' + searchResults[i].patientFirstName + '</td>' +
        '<td>' + searchResults[i].patientLastName + '</td>' +
        '<td>' + searchResults[i].patientDateOfBirth + '</td>' +
        '<td>' + searchResults[i].patientDataPulseID + '</td>' +
        '<td>' + searchResults[i].patientLaserFicheID + '</td>' +
        '</tr>');
}

更新

最后一个建议 - 用 adding/removing 元素操作 DOM 很慢。如果您需要为数组中的每个元素执行此操作,最好避免在每次迭代时实际添加您的内容,而只是构建一个字符串。然后,一旦你完成迭代,只需添加大的单个字符串,这样你就只改变了 DOM 一次。这是执行此操作所需的基本更改:

// Add some new variables to hold our big strings
var dialog, dialogs, row, rows, i;

// ... your code ...

for (var i = 0; i < searchResults.length; i++) {

    // Create the dialog ...
    dialog = ...

    // Append it to our big string of all dialogs
    dialogs += dialog;

    // Same approach for rows
    row = '<tr>'+ ... all that stuff
    rows += row;
}

// Finished iterating, nothing added to DOM yet.  Do it all at once::
$('#dialogs').append(dialogs);
$('table').append(rows);

考虑以下代码。

function showPatientDialog(cnt){
  $("#patient-file-dialog").html(cnt).dialog("open");
}

var d = $("<div>", {
  id: "patient-file-dialog",
  title: "Patient File"
})
  .appendTo("body")
  .dialog({
    autoOpen: false
  });
$.each(searchResults, function(i, result) {
  var row = $("<tr>").appendTo(body);
  $("<td>").appendTo(row).html($("<button>", {
    id: "open-pdf-dialog-" + i
  }).click(function() {
    showPatientDialog(result.patientWebLink);
  }));
  $("<td>").appendTo(row).html(result.patientFirstName);
  $("<td>").appendTo(row).html(result.patientLastName);
  $("<td>").appendTo(row).html(result.patientDateOfBirth);
  $("<td>").appendTo(row).html(result.patientDataPulseID);
  $("<td>").appendTo(row).html(result.patientLaserFicheID);
});

这是我最终不得不做的事情:

$(document).ready(function(){
  if ($('[attr="searchResultsJson"]').length)
  {
    $('.approval-outer-wrap').prepend(drawTable());  
    $('.approval-outer-wrap').append('<div id="result-details" title="Search Result Detail"><p></p></div>')
  }

  $('body').on('click', '[id^=openPFDialog]', function() {
      var result = $(this).parents('tr').data('result');
      $('#result-details p').html(result.patientFirstName);
      $('#result-details').dialog();
  });


});

function drawTable(){
    var table = $('<table id="search-results" />');

    var header = $('<thead />');
    table.append(header);

    header.append('<tr><th>Patient File</th><th>First Name</th><th>Last Name</th><th>Date of Birth</th><th>Data Pulse ID</th><th>Laserfiche ID</th></tr>');

    var body = $('<tbody />');
    table.append(body);

    var json = $('[attr="searchResultsJson"] [type="text"]').text();

    var searchResults = JSON.parse(json);

    for (var i = 0; i < searchResults.length; i++) {    

        body.append(`<tr data-result='${JSON.stringify(searchResults[i])}'>`+
            `<td><button id="openPFDialog-` + i + `">&#128269;</button></td>` +
            `<td>${searchResults[i].patientFirstName}</td>` +
            `<td>${searchResults[i].patientLastName}</td>` +
            `<td>${searchResults[i].patientDateOfBirth}</td>` +
            `<td>${searchResults[i].patientDataPulseID}</td>` +
            `<td>${searchResults[i].patientLaserFicheID}</td>` +
            '</tr>');
    }   

  return table;
}