javascript - 如何使用 JavaScript 为表中的行创建重新排序功能
问题描述
我目前正在重构一个使用 Python 小部件和 JavaScript 的项目。它目前使用的表格具有重新排序功能,可以进行一些重大改进。使用“reorderRowDown”按钮时,它可以正常工作,当前行向下移动,上一行和下一行相应调整。
但是,在“reorderRowUp”按钮上,当前行只是在当前行和上一行之间来回交替。(我希望我能很好地解释这一点,我很抱歉)将当前行向上移动非常笨拙。
我想实现类似于“reorderRowDown”的功能,当单击“reorderRowUp”时,当前行向上移动,上一行和下一行相应地调整。总之,我想知道如何以正确的方式对表中的行进行重新排序。任何帮助将不胜感激。
(这里是下面发布的 GIF,以更好地展示我所引用的场景)
reorderRowDown 示例:
https://media.giphy.com/media/8WHiGw57pPTK9Zdibk/giphy.gif
reorderRowUp 示例:
https://media.giphy.com/media/Wp7x9GtYDX29cFLT6I/giphy.gif
这是我的代码(如果您需要更多,请告诉我)
PathContext.js
'use strict';
module.exports = () => {
window.reorderRowUp = function(ruleSetIdPriority) {
let ruleSetId;
ruleSetId = ruleSetIdPriority.split('-priority')[0];
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const prevRow = row.previousElementSibling;
table.insertBefore(row, prevRow);
};
window.reorderRowDown = function(ruleSetIdPriority) {
let ruleSetId;
ruleSetId = ruleSetIdPriority.split('-priority')[0];
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const nextRow = row.nextElementSibling;
table.insertBefore(nextRow, row);
};
};
reorder_row_widget.html
<button class="reorder-btn" type="button" onclick=reorderRowUp("{{widget.name}}")>Up</button>
<button class="reorder-btn" type="button" onclick=reorderRowDown("{{widget.name}}")>Down</button>
<input id="{{ widget.name }}" type="hidden" name="{{ widget.name }}" value="{{ widget.value }}"></input>
这是我浏览器控制台中实际表格行的 html
<table>
<tbody>
<tr class="form-row row1 has_original dynamic-rule_set" id="rule_set-0">
<td class="original">
<p>
Rule object (84)
</p>
<input type="hidden" name="rule_set-0-id" value="84" id="id_rule_set-0-id">
<input type="hidden" name="rule_set-0-path_context" value="6" id="id_rule_set-0-path_context">
</td>
<td class="field-priority">
<button class="reorder-btn" type="button" onclick="reorderRowUp("rule_set-0-priority")">Up</button>
<button class="reorder-btn" type="button" onclick="reorderRowDown("rule_set-0-priority")">Down</button>
<input id="rule_set-0-priority" type="hidden" name="rule_set-0-priority" value="-301">
</td>
<td class="field-pattern">
<input type="text" name="rule_set-0-pattern" value="^/$" id="id_rule_set-0-pattern">
</td>
<td class="field-value">
<input class="tgl" id="rule_set-0-value" name="rule_set-0-value" type="checkbox" checked="">
<label class="tgl-btn" for="rule_set-0-value"></label>
</td>
<td class="field-experience">
<select name="rule_set-0-experience" id="id_rule_set-0-experience">
<option value="">---------</option>
<option value="modal" selected="">Modal</option>
<option value="sticky_cta">Sticky CTA</option>
</select>
</td>
<td class="delete"><input type="checkbox" name="rule_set-0-DELETE" id="id_rule_set-0-DELETE"></td>
</tr>
</tbody>
</table>
admin.py(如果需要,python 代码)
class ReorderRowWidget(forms.Widget):
template_name = 'admin/reorder_row_widget.html'
def get_context(self, name, value, attrs=None):
return {'widget': {
'name': name,
'value': value,
}}
def render(self, name, value, attrs=None, renderer=None):
context = self.get_context(name, value, attrs)
template = loader.get_template(self.template_name).render(context)
return mark_safe(template)
解决方案
这是我用来解决我的问题并创建更好的 UI 的实现。我重构了 PathContext.js 文件。
function replaceReorderFunction() {
const reorderRowUp = window.reorderRowUp || function() {};
const reorderRowDown = window.reorderRowDown || function() {};
// when page gets rendered, django creates a hidden row with a special ruleSetId with id __prefix__
// once 'add new row' is clicked, a real ruleSetId is given to the row
// need to replace the reorder function of that row so that it uses the proper ruleSetId so the row can be reordered properly
// should only need to happen once, on the first reordering after the row is added
// therefore I assume that the row in question is always at the bottom of the table
const tableWrapper = document.getElementById('rule_set-group');
const tbody = tableWrapper.querySelector('tbody');
const rowToUpdate = tbody.lastElementChild.previousElementSibling.previousElementSibling;
const priorityField = rowToUpdate.getElementsByClassName('field-priority')[0];
const buttons = priorityField.getElementsByTagName('button');
buttons[0].onclick = () => {reorderRowUp(rowToUpdate.id);};
buttons[1].onclick = () => {reorderRowDown(rowToUpdate.id);};
return rowToUpdate.id;
}
window.reorderRowUp = function(ruleSetIdPriority) {
let ruleSetId;
// it's a new row, ruleSetId is not correct
if (ruleSetIdPriority.match(/__prefix__/)) {
// get the proper ruleSetId and replace existing onclick functions
ruleSetId = replaceReorderFunction();
} else {
ruleSetId = ruleSetIdPriority.split('-priority')[0];
}
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const prevRow = row.previousElementSibling;
if (!prevRow) {
return;
}
table.insertBefore(row, prevRow);
// swap priority values
const prevPriorityValue = getPriorityValueFromRow(prevRow);
const curPriorityValue = getPriorityValueFromRow(row);
setPriorityValueOfRow(row, prevPriorityValue);
setPriorityValueOfRow(prevRow, curPriorityValue);
};
window.reorderRowDown = function(ruleSetIdPriority) {
let ruleSetId;
// it's a new row, ruleSetId is not correct
if (ruleSetIdPriority.match(/__prefix__/)) {
ruleSetId = replaceReorderFunction();
} else {
ruleSetId = ruleSetIdPriority.split('-priority')[0];
}
const row = document.getElementById(ruleSetId);
const table = row.parentNode;
const nextRow = row.nextElementSibling;
if (!nextRow || nextRow.className === 'add-row' || nextRow.id.includes('empty')) {
return;
}
table.insertBefore(nextRow, row);
// swap priority values
const nextPriorityValue = getPriorityValueFromRow(nextRow);
const curPriorityValue = getPriorityValueFromRow(row);
setPriorityValueOfRow(row, nextPriorityValue);
setPriorityValueOfRow(nextRow, curPriorityValue);
};
推荐阅读
- oracle - Oracle - 附加提示并且不检查任何约束
- elasticsearch - 有没有办法在elasticsearch中进行反向分页(使用golang)
- java - 引导层初始化期间发生错误 - Eclips 2020-06
- sql-server - sql server 中的 min 函数无法正常工作,给出 0
- blue-green-deployment - 蓝绿系统:如何处理数据库?
- python - 如何使用ebooklib python创建指向章节药水的链接
- python - python2 与 python3 中 file.read() 的行为
- sql-server - 如何在sql server中删除一个月中的星期六和星期日
- java - 如何对多个 java 文件使用相同的 UI?安卓 JAVA
- swiftui - SwiftUI - 带有私有变量的 PreviewProvider