为 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 + `">🔍</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;
}
我正在尝试使用名为 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 theX
by removing theopenPFDialog-
part withreplace
.不过,上面的内容更加复杂。在页面加载时解析的选择器将只匹配当时存在的元素。在这种情况下,您要向页面添加新元素,并且在页面加载时定义的 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 + `">🔍</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;
}