lisichatbot 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/index.js +101 -81
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -67,35 +67,43 @@ function disableNextButton() {
|
|
|
67
67
|
function addMessage(content, type = 'bot', isEditable = false, stepNumber = null) {
|
|
68
68
|
if (!elements.messages) return;
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
// Find the wrapper element directly by data-chat-element
|
|
71
|
+
const wrapperSelector = `[data-chat-element="${type}-message-wrapper"]`;
|
|
72
|
+
const existingWrapper = document.querySelector(wrapperSelector);
|
|
73
73
|
|
|
74
|
+
if (!existingWrapper) {
|
|
75
|
+
console.error(`Element with ${wrapperSelector} not found in HTML. Please add it to your HTML.`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Clone the existing wrapper
|
|
80
|
+
const clone = existingWrapper.cloneNode(true);
|
|
81
|
+
|
|
82
|
+
// Add step number if provided
|
|
74
83
|
if (stepNumber !== null) {
|
|
75
|
-
|
|
84
|
+
clone.setAttribute('data-chat-step', stepNumber);
|
|
76
85
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
onclick="editStep(${stepNumber})"
|
|
85
|
-
title="Edit this response">
|
|
86
|
-
✏️
|
|
87
|
-
</button>
|
|
88
|
-
`;
|
|
86
|
+
|
|
87
|
+
// Find text element in clone and set content
|
|
88
|
+
const textElement = clone.querySelector(`[data-chat-element="${type}-message-text"]`);
|
|
89
|
+
if (textElement) {
|
|
90
|
+
textElement.textContent = content;
|
|
91
|
+
} else {
|
|
92
|
+
console.error(`Element with data-chat-element="${type}-message-text" not found in wrapper`);
|
|
89
93
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
|
|
95
|
+
// Handle edit button for user messages
|
|
96
|
+
if (isEditable && type === 'user' && stepNumber !== null) {
|
|
97
|
+
const editButton = clone.querySelector('[data-chat-element="edit-button"]');
|
|
98
|
+
if (editButton) {
|
|
99
|
+
editButton.setAttribute('data-chat-step', stepNumber);
|
|
100
|
+
editButton.onclick = () => editStep(stepNumber);
|
|
101
|
+
editButton.style.display = 'inline-block';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Append to messages container
|
|
106
|
+
elements.messages.appendChild(clone);
|
|
99
107
|
scrollToBottom();
|
|
100
108
|
}
|
|
101
109
|
|
|
@@ -106,56 +114,63 @@ function addMessage(content, type = 'bot', isEditable = false, stepNumber = null
|
|
|
106
114
|
function renderOptions(options, field, isSingleSelect = true) {
|
|
107
115
|
if (!elements.messages) return;
|
|
108
116
|
|
|
109
|
-
const messageDiv = document.createElement('div');
|
|
110
|
-
messageDiv.className = 'cf-message cf-bot';
|
|
111
|
-
messageDiv.setAttribute('data-chat-message', 'bot');
|
|
112
|
-
|
|
113
117
|
// Determine input type attribute value
|
|
114
118
|
const inputTypeAttr = isSingleSelect ? 'single-select-input' : 'multi-select-input';
|
|
119
|
+
|
|
120
|
+
// Find existing option element in HTML by data-chat-element
|
|
121
|
+
const optionSelector = `[data-chat-element="${inputTypeAttr}"]`;
|
|
122
|
+
const existingOption = document.querySelector(optionSelector);
|
|
115
123
|
|
|
116
|
-
|
|
124
|
+
if (!existingOption) {
|
|
125
|
+
console.error(`Element with ${optionSelector} not found in HTML. Please add it to your HTML.`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Create wrapper to hold all options
|
|
130
|
+
const optionsWrapper = document.createElement('div');
|
|
131
|
+
optionsWrapper.setAttribute('data-chat-element', 'options-wrapper');
|
|
132
|
+
|
|
133
|
+
// Clone and fill option element for each option
|
|
134
|
+
options.forEach((option, index) => {
|
|
117
135
|
const optionName = option.name || option;
|
|
118
136
|
const optionValue = option.value !== undefined ? option.value : option;
|
|
119
137
|
const valueStr = typeof optionValue === 'object' ?
|
|
120
138
|
JSON.stringify(optionValue) : String(optionValue);
|
|
121
139
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
`;
|
|
153
|
-
|
|
154
|
-
elements.messages.appendChild(messageDiv);
|
|
140
|
+
// Clone existing option element
|
|
141
|
+
const clone = existingOption.cloneNode(true);
|
|
142
|
+
|
|
143
|
+
// Set data attributes on container
|
|
144
|
+
clone.setAttribute('data-chat-element', inputTypeAttr);
|
|
145
|
+
clone.setAttribute('data-field', field);
|
|
146
|
+
clone.setAttribute('data-value', valueStr);
|
|
147
|
+
clone.setAttribute('data-name', optionName);
|
|
148
|
+
clone.setAttribute('data-index', index);
|
|
149
|
+
|
|
150
|
+
// Find and set input
|
|
151
|
+
const input = clone.querySelector('[data-chat-input-element="input"]');
|
|
152
|
+
if (input) {
|
|
153
|
+
input.setAttribute('data-chat-element', inputTypeAttr);
|
|
154
|
+
input.name = field;
|
|
155
|
+
input.value = valueStr;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Find and set text
|
|
159
|
+
const textElement = clone.querySelector('[data-chat-input-element="text"]');
|
|
160
|
+
if (textElement) {
|
|
161
|
+
textElement.textContent = optionName;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Append to wrapper
|
|
165
|
+
optionsWrapper.appendChild(clone);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Append wrapper to messages
|
|
169
|
+
elements.messages.appendChild(optionsWrapper);
|
|
155
170
|
scrollToBottom();
|
|
156
171
|
|
|
157
|
-
// Add click handlers
|
|
158
|
-
const optionElements =
|
|
172
|
+
// Add click handlers
|
|
173
|
+
const optionElements = optionsWrapper.querySelectorAll('[data-chat-input-element="container"]');
|
|
159
174
|
optionElements.forEach(el => {
|
|
160
175
|
el.onclick = () => handleOptionClick(el, field, isSingleSelect);
|
|
161
176
|
});
|
|
@@ -412,27 +427,32 @@ function init(flowName, flowConfig) {
|
|
|
412
427
|
chatState.history = [];
|
|
413
428
|
chatState.currentSelection = null;
|
|
414
429
|
|
|
415
|
-
//
|
|
416
|
-
elements.container.innerHTML = `
|
|
417
|
-
<div data-chat-element="messages-container"></div>
|
|
418
|
-
<div data-chat-element="navigation-bottom">
|
|
419
|
-
<button data-chat-element="next-button"
|
|
420
|
-
style="opacity: 0.5; cursor: not-allowed;"
|
|
421
|
-
disabled>
|
|
422
|
-
Next →
|
|
423
|
-
</button>
|
|
424
|
-
</div>
|
|
425
|
-
`;
|
|
426
|
-
|
|
427
|
-
// Get elements by data-chat-element
|
|
430
|
+
// Find existing elements (don't create new ones)
|
|
428
431
|
elements.messages = elements.container.querySelector('[data-chat-element="messages-container"]');
|
|
429
432
|
elements.nextBtn = elements.container.querySelector('[data-chat-element="next-button"]');
|
|
430
433
|
|
|
431
|
-
//
|
|
432
|
-
if (elements.
|
|
433
|
-
|
|
434
|
+
// Validate required elements exist
|
|
435
|
+
if (!elements.messages) {
|
|
436
|
+
console.error('messages-container not found. Please add <div data-chat-element="messages-container"></div>');
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (!elements.nextBtn) {
|
|
441
|
+
console.error('next-button not found. Please add <button data-chat-element="next-button"></button>');
|
|
442
|
+
return null;
|
|
434
443
|
}
|
|
435
444
|
|
|
445
|
+
// Clear ONLY messages container (not entire chat-wrapper)
|
|
446
|
+
elements.messages.innerHTML = '';
|
|
447
|
+
|
|
448
|
+
// Reset button state
|
|
449
|
+
elements.nextBtn.disabled = true;
|
|
450
|
+
elements.nextBtn.style.opacity = '0.5';
|
|
451
|
+
elements.nextBtn.style.cursor = 'not-allowed';
|
|
452
|
+
|
|
453
|
+
// Add event listener
|
|
454
|
+
elements.nextBtn.onclick = handleNext;
|
|
455
|
+
|
|
436
456
|
// Expose editStep globally for onclick handlers
|
|
437
457
|
if (typeof window !== 'undefined') {
|
|
438
458
|
window.editStep = editStep;
|