mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-25 07:05:43 -03:00
Refactor trigger words UI handling: improve event listener management, restore original words on cancel, and enhance dropdown update logic. See #147
This commit is contained in:
@@ -190,14 +190,14 @@ export function renderTriggerWords(words, filePath) {
|
|||||||
<span class="no-trigger-words">No trigger word needed</span>
|
<span class="no-trigger-words">No trigger word needed</span>
|
||||||
<div class="trigger-words-tags" style="display:none;"></div>
|
<div class="trigger-words-tags" style="display:none;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-trigger-word-form" style="display:none;">
|
|
||||||
<input type="text" class="new-trigger-word-input" placeholder="Type to add or click suggestions below">
|
|
||||||
</div>
|
|
||||||
<div class="trigger-words-edit-controls" style="display:none;">
|
<div class="trigger-words-edit-controls" style="display:none;">
|
||||||
<button class="save-trigger-words-btn" title="Save changes">
|
<button class="save-trigger-words-btn" title="Save changes">
|
||||||
<i class="fas fa-save"></i> Save
|
<i class="fas fa-save"></i> Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="add-trigger-word-form" style="display:none;">
|
||||||
|
<input type="text" class="new-trigger-word-input" placeholder="Type to add or click suggestions below">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -224,14 +224,14 @@ export function renderTriggerWords(words, filePath) {
|
|||||||
`).join('')}
|
`).join('')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="add-trigger-word-form" style="display:none;">
|
|
||||||
<input type="text" class="new-trigger-word-input" placeholder="Type to add or click suggestions below">
|
|
||||||
</div>
|
|
||||||
<div class="trigger-words-edit-controls" style="display:none;">
|
<div class="trigger-words-edit-controls" style="display:none;">
|
||||||
<button class="save-trigger-words-btn" title="Save changes">
|
<button class="save-trigger-words-btn" title="Save changes">
|
||||||
<i class="fas fa-save"></i> Save
|
<i class="fas fa-save"></i> Save
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="add-trigger-word-form" style="display:none;">
|
||||||
|
<input type="text" class="new-trigger-word-input" placeholder="Type to add or click suggestions below">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@@ -283,8 +283,18 @@ export function setupTriggerWordsEditMode() {
|
|||||||
// Disable click-to-copy and show delete buttons
|
// Disable click-to-copy and show delete buttons
|
||||||
triggerWordTags.forEach(tag => {
|
triggerWordTags.forEach(tag => {
|
||||||
tag.onclick = null;
|
tag.onclick = null;
|
||||||
tag.querySelector('.trigger-word-copy').style.display = 'none';
|
const copyIcon = tag.querySelector('.trigger-word-copy');
|
||||||
tag.querySelector('.delete-trigger-word-btn').style.display = 'block';
|
const deleteBtn = tag.querySelector('.delete-trigger-word-btn');
|
||||||
|
|
||||||
|
if (copyIcon) copyIcon.style.display = 'none';
|
||||||
|
if (deleteBtn) {
|
||||||
|
deleteBtn.style.display = 'block';
|
||||||
|
|
||||||
|
// Re-attach event listener to ensure it works every time
|
||||||
|
// First remove any existing listeners to avoid duplication
|
||||||
|
deleteBtn.removeEventListener('click', deleteTriggerWord);
|
||||||
|
deleteBtn.addEventListener('click', deleteTriggerWord);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load trained words and display dropdown when entering edit mode
|
// Load trained words and display dropdown when entering edit mode
|
||||||
@@ -324,8 +334,16 @@ export function setupTriggerWordsEditMode() {
|
|||||||
editControls.style.display = 'none';
|
editControls.style.display = 'none';
|
||||||
addForm.style.display = 'none';
|
addForm.style.display = 'none';
|
||||||
|
|
||||||
// BUGFIX: Restore original trigger words when canceling edit
|
// Check if we're exiting edit mode due to "Save" or "Cancel"
|
||||||
restoreOriginalTriggerWords(triggerWordsSection, originalTriggerWords);
|
if (!this.dataset.skipRestore) {
|
||||||
|
// If canceling, restore original trigger words
|
||||||
|
restoreOriginalTriggerWords(triggerWordsSection, originalTriggerWords);
|
||||||
|
} else {
|
||||||
|
// If saving, reset UI state on current trigger words
|
||||||
|
resetTriggerWordsUIState(triggerWordsSection);
|
||||||
|
// Reset the skip restore flag
|
||||||
|
delete this.dataset.skipRestore;
|
||||||
|
}
|
||||||
|
|
||||||
// If we have no trigger words, show the "No trigger word needed" text
|
// If we have no trigger words, show the "No trigger word needed" text
|
||||||
// and hide the empty tags container
|
// and hide the empty tags container
|
||||||
@@ -363,14 +381,43 @@ export function setupTriggerWordsEditMode() {
|
|||||||
|
|
||||||
// Set up delete buttons
|
// Set up delete buttons
|
||||||
document.querySelectorAll('.delete-trigger-word-btn').forEach(btn => {
|
document.querySelectorAll('.delete-trigger-word-btn').forEach(btn => {
|
||||||
btn.addEventListener('click', function(e) {
|
// Remove any existing listeners to avoid duplication
|
||||||
e.stopPropagation();
|
btn.removeEventListener('click', deleteTriggerWord);
|
||||||
const tag = this.closest('.trigger-word-tag');
|
btn.addEventListener('click', deleteTriggerWord);
|
||||||
tag.remove();
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Update status of items in the trained words dropdown
|
/**
|
||||||
updateTrainedWordsDropdown();
|
* Delete trigger word event handler
|
||||||
});
|
* @param {Event} e - Click event
|
||||||
|
*/
|
||||||
|
function deleteTriggerWord(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
const tag = this.closest('.trigger-word-tag');
|
||||||
|
tag.remove();
|
||||||
|
|
||||||
|
// Update status of items in the trained words dropdown
|
||||||
|
updateTrainedWordsDropdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset UI state for trigger words after saving
|
||||||
|
* @param {HTMLElement} section - The trigger words section
|
||||||
|
*/
|
||||||
|
function resetTriggerWordsUIState(section) {
|
||||||
|
const triggerWordTags = section.querySelectorAll('.trigger-word-tag');
|
||||||
|
|
||||||
|
triggerWordTags.forEach(tag => {
|
||||||
|
const word = tag.dataset.word;
|
||||||
|
const copyIcon = tag.querySelector('.trigger-word-copy');
|
||||||
|
const deleteBtn = tag.querySelector('.delete-trigger-word-btn');
|
||||||
|
|
||||||
|
// Restore click-to-copy functionality
|
||||||
|
tag.onclick = () => copyTriggerWord(word);
|
||||||
|
|
||||||
|
// Show copy icon, hide delete button
|
||||||
|
if (copyIcon) copyIcon.style.display = '';
|
||||||
|
if (deleteBtn) deleteBtn.style.display = 'none';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,11 +532,7 @@ function addNewTriggerWord(word) {
|
|||||||
|
|
||||||
// Add event listener to delete button
|
// Add event listener to delete button
|
||||||
const deleteBtn = newTag.querySelector('.delete-trigger-word-btn');
|
const deleteBtn = newTag.querySelector('.delete-trigger-word-btn');
|
||||||
deleteBtn.addEventListener('click', function() {
|
deleteBtn.addEventListener('click', deleteTriggerWord);
|
||||||
newTag.remove();
|
|
||||||
// Update dropdown after removing
|
|
||||||
updateTrainedWordsDropdown();
|
|
||||||
});
|
|
||||||
|
|
||||||
tagsContainer.appendChild(newTag);
|
tagsContainer.appendChild(newTag);
|
||||||
|
|
||||||
@@ -558,8 +601,10 @@ function updateTrainedWordsDropdown() {
|
|||||||
* Save trigger words
|
* Save trigger words
|
||||||
*/
|
*/
|
||||||
async function saveTriggerWords() {
|
async function saveTriggerWords() {
|
||||||
const filePath = document.querySelector('.edit-trigger-words-btn').dataset.filePath;
|
const editBtn = document.querySelector('.edit-trigger-words-btn');
|
||||||
const triggerWordTags = document.querySelectorAll('.trigger-word-tag');
|
const filePath = editBtn.dataset.filePath;
|
||||||
|
const triggerWordsSection = editBtn.closest('.trigger-words');
|
||||||
|
const triggerWordTags = triggerWordsSection.querySelectorAll('.trigger-word-tag');
|
||||||
const words = Array.from(triggerWordTags).map(tag => tag.dataset.word);
|
const words = Array.from(triggerWordTags).map(tag => tag.dataset.word);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -568,9 +613,11 @@ async function saveTriggerWords() {
|
|||||||
civitai: { trainedWords: words }
|
civitai: { trainedWords: words }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update UI
|
// Set flag to skip restoring original words when exiting edit mode
|
||||||
const editBtn = document.querySelector('.edit-trigger-words-btn');
|
editBtn.dataset.skipRestore = "true";
|
||||||
editBtn.click(); // Exit edit mode
|
|
||||||
|
// Exit edit mode without restoring original trigger words
|
||||||
|
editBtn.click();
|
||||||
|
|
||||||
// Update the LoRA card's dataset
|
// Update the LoRA card's dataset
|
||||||
const loraCard = document.querySelector(`.lora-card[data-filepath="${filePath}"]`);
|
const loraCard = document.querySelector(`.lora-card[data-filepath="${filePath}"]`);
|
||||||
@@ -595,8 +642,8 @@ async function saveTriggerWords() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we saved an empty array and there's a no-trigger-words element, show it
|
// If we saved an empty array and there's a no-trigger-words element, show it
|
||||||
const noTriggerWords = document.querySelector('.no-trigger-words');
|
const noTriggerWords = triggerWordsSection.querySelector('.no-trigger-words');
|
||||||
const tagsContainer = document.querySelector('.trigger-words-tags');
|
const tagsContainer = triggerWordsSection.querySelector('.trigger-words-tags');
|
||||||
if (words.length === 0 && noTriggerWords) {
|
if (words.length === 0 && noTriggerWords) {
|
||||||
noTriggerWords.style.display = '';
|
noTriggerWords.style.display = '';
|
||||||
if (tagsContainer) tagsContainer.style.display = 'none';
|
if (tagsContainer) tagsContainer.style.display = 'none';
|
||||||
|
|||||||
Reference in New Issue
Block a user