From e89346c146386a17cc08143fcd113a569152690d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 16 Nov 2018 20:02:16 +0100 Subject: [PATCH] making rename functionality list refresh proof --- scripts/system/html/js/entityList.js | 45 +++++++++++++++++++++++--- scripts/system/html/js/listView.js | 8 +++-- scripts/system/libraries/entityList.js | 2 +- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index ac2a4132ae..328c8c76e1 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -187,6 +187,7 @@ let startThClick = null; let renameTimeout = null; let renameLastBlur = null; let renameLastEntityID = null; +let isRenameFieldIsBeingMoved = false; let elEntityTable, elEntityTableHeader, @@ -210,7 +211,8 @@ let elEntityTable, elNoEntitiesMessage, elColumnsMultiselectBox, elColumnsOptions, - elToggleSpaceMode; + elToggleSpaceMode, + elRenameInput; const ENABLE_PROFILING = false; let profileIndent = ''; @@ -395,7 +397,7 @@ function loaded() { elEntityTableHeaderRow = document.querySelectorAll("#entity-table thead th"); entityList = new ListView(elEntityTableBody, elEntityTableScroll, elEntityTableHeaderRow, - createRow, updateRow, clearRow, WINDOW_NONVARIABLE_HEIGHT); + createRow, updateRow, clearRow, beforeUpdate, afterUpdate, WINDOW_NONVARIABLE_HEIGHT); entityListContextMenu = new EntityListContextMenu(); @@ -407,7 +409,7 @@ function loaded() { } let elCell = entity.elRow.childNodes[getColumnIndex("name")]; - let elRenameInput = document.createElement("input"); + elRenameInput = document.createElement("input"); elRenameInput.setAttribute('class', 'rename-entity'); elRenameInput.value = entity.name; let ignoreClicks = function(event) { @@ -422,6 +424,9 @@ function loaded() { }; elRenameInput.onblur = function(event) { + if (isRenameFieldIsBeingMoved) { + return; + } let value = elRenameInput.value; EventBridge.emitWebEvent(JSON.stringify({ type: 'rename', @@ -429,9 +434,10 @@ function loaded() { name: value })); entity.name = value; - elCell.innerText = value; + elRenameInput.parentElement.innerText = value; renameLastBlur = Date.now(); + elRenameInput = null; }; elCell.innerHTML = ""; @@ -440,6 +446,32 @@ function loaded() { elRenameInput.select(); } + function beforeUpdate() { + // move the rename input to the body + if (elRenameInput) { + isRenameFieldIsBeingMoved = true; + document.body.appendChild(elRenameInput); + // keep the focus + elRenameInput.select(); + } + } + + function afterUpdate() { + if (!elRenameInput || !isRenameFieldIsBeingMoved) { + return; + } + let entity = entitiesByID[renameLastEntityID]; + if (!entity || entity.locked || !entity.elRow) { + return; + } + let elCell = entity.elRow.childNodes[getColumnIndex("name")]; + elCell.innerHTML = ""; + elCell.appendChild(elRenameInput); + // keep the focus + elRenameInput.select(); + isRenameFieldIsBeingMoved = false; + } + entityListContextMenu.setOnSelectedCallback(function(optionName, selectedEntityID) { switch (optionName) { case "Cut": @@ -464,6 +496,11 @@ function loaded() { }); function onRowContextMenu(clickEvent) { + if (elRenameInput) { + // disallow the context menu from popping up while renaming + return; + } + let entityID = this.dataset.entityID; if (!selectedEntities.includes(entityID)) { diff --git a/scripts/system/html/js/listView.js b/scripts/system/html/js/listView.js index f775a4cb24..4336698688 100644 --- a/scripts/system/html/js/listView.js +++ b/scripts/system/html/js/listView.js @@ -14,7 +14,7 @@ debugPrint = function (message) { }; function ListView(elTableBody, elTableScroll, elTableHeaderRow, createRowFunction, - updateRowFunction, clearRowFunction, WINDOW_NONVARIABLE_HEIGHT) { + updateRowFunction, clearRowFunction, beforeRefreshFunction, afterRefreshFunction, WINDOW_NONVARIABLE_HEIGHT) { this.elTableBody = elTableBody; this.elTableScroll = elTableScroll; this.elTableHeaderRow = elTableHeaderRow; @@ -25,6 +25,8 @@ function ListView(elTableBody, elTableScroll, elTableHeaderRow, createRowFunctio this.createRowFunction = createRowFunction; this.updateRowFunction = updateRowFunction; this.clearRowFunction = clearRowFunction; + this.beforeRefreshFunction = beforeRefreshFunction; + this.afterRefreshFunction = afterRefreshFunction; // the list of row elements created in the table up to max viewable height plus SCROLL_ROWS rows for scrolling buffer this.elRows = []; @@ -173,6 +175,7 @@ ListView.prototype = { }, refresh: function() { + this.beforeRefreshFunction(); // block refreshing before rows are initialized let numRows = this.getNumRows(); if (numRows === 0) { @@ -211,6 +214,7 @@ ListView.prototype = { this.lastRowShiftScrollTop = 0; } } + this.afterRefreshFunction(); }, refreshBuffers: function() { @@ -230,7 +234,7 @@ ListView.prototype = { refreshRowOffset: function() { // make sure the row offset isn't causing visible rows to pass the end of the item list and is clamped to 0 - var numRows = this.getNumRows(); + let numRows = this.getNumRows(); if (this.rowOffset + numRows > this.itemData.length) { this.rowOffset = this.itemData.length - numRows; } diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 8942c84f33..eeb16fd60d 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -17,7 +17,7 @@ var profileIndent = ''; const PROFILE_NOOP = function(_name, fn, args) { fn.apply(this, args); }; -PROFILE = !PROFILING_ENABLED ? PROFILE_NOOP : function(name, fn, args) { +const PROFILE = !PROFILING_ENABLED ? PROFILE_NOOP : function(name, fn, args) { console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' ';