lisichatbot 1.2.3 → 1.2.4

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +167 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisichatbot",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "exports": {
package/src/index.js CHANGED
@@ -267,6 +267,10 @@ function renderOptions(options, field, isSingleSelect = true) {
267
267
  return;
268
268
  }
269
269
 
270
+ // Get existing data for this field (for pre-filling when editing)
271
+ const existingData = chatState.data[field];
272
+ console.log(`📝 Pre-filling ${field}:`, existingData);
273
+
270
274
  // Create wrapper to hold all options
271
275
  const optionsWrapper = document.createElement('div');
272
276
  optionsWrapper.setAttribute('data-chat-element', 'options-wrapper');
@@ -284,9 +288,27 @@ function renderOptions(options, field, isSingleSelect = true) {
284
288
  // Make clone visible (remove display:none from template)
285
289
  clone.style.display = '';
286
290
 
287
- // Reset to unchecked state
288
- clone.classList.remove('cf-checked');
289
- clone.style.backgroundColor = 'transparent';
291
+ // Check if this option should be pre-selected
292
+ let shouldBeChecked = false;
293
+ if (isSingleSelect) {
294
+ // For single-select, check if value matches existing data
295
+ shouldBeChecked = existingData !== undefined &&
296
+ JSON.stringify(existingData) === JSON.stringify(optionValue);
297
+ } else {
298
+ // For multi-select, check if value is in array
299
+ shouldBeChecked = Array.isArray(existingData) &&
300
+ existingData.some(v => JSON.stringify(v) === JSON.stringify(optionValue));
301
+ }
302
+
303
+ // Set checked state
304
+ if (shouldBeChecked) {
305
+ clone.classList.add('cf-checked');
306
+ clone.style.backgroundColor = config.selectedBackground;
307
+ console.log(` ✅ Pre-selected: ${optionName}`);
308
+ } else {
309
+ clone.classList.remove('cf-checked');
310
+ clone.style.backgroundColor = 'transparent';
311
+ }
290
312
 
291
313
  // Set data attributes on container
292
314
  clone.setAttribute('data-chat-element', inputTypeAttr);
@@ -301,14 +323,14 @@ function renderOptions(options, field, isSingleSelect = true) {
301
323
  input.setAttribute('data-chat-element', inputTypeAttr);
302
324
  input.name = field;
303
325
  input.value = valueStr;
304
- input.checked = false; // Ensure unchecked initially
326
+ input.checked = shouldBeChecked; // Pre-check if needed
305
327
  input.onclick = (e) => e.stopPropagation(); // Prevent click bubbling
306
328
  }
307
329
 
308
- // Find and ensure tick icon is hidden initially
330
+ // Find and set tick icon visibility
309
331
  const tickIcon = clone.querySelector('[data-chat-input-element="tick-icon"]');
310
332
  if (tickIcon) {
311
- tickIcon.style.display = 'none';
333
+ tickIcon.style.display = shouldBeChecked ? 'block' : 'none';
312
334
  }
313
335
 
314
336
  // Find and set text
@@ -343,6 +365,124 @@ function renderOptions(options, field, isSingleSelect = true) {
343
365
  });
344
366
  }
345
367
 
368
+ // =============================================================================
369
+ // MULTI-SELECT-COLOR OPTIONS RENDERING
370
+ // =============================================================================
371
+
372
+ function renderColorOptions(options, field) {
373
+ if (!elements.messages) return;
374
+
375
+ // Find existing color option element in HTML by data-chat-element
376
+ const optionSelector = '[data-chat-element="multi-select-color"]';
377
+ const existingOption = document.querySelector(optionSelector);
378
+
379
+ if (!existingOption) {
380
+ console.error(`Element with ${optionSelector} not found in HTML. Please add it to your HTML.`);
381
+ return;
382
+ }
383
+
384
+ // Get existing data for this field (for pre-filling when editing)
385
+ const existingData = chatState.data[field];
386
+ console.log(`📝 Pre-filling ${field} (color):`, existingData);
387
+
388
+ // Create wrapper to hold all options
389
+ const optionsWrapper = document.createElement('div');
390
+ optionsWrapper.setAttribute('data-chat-element', 'options-wrapper');
391
+
392
+ // Clone and fill option element for each option
393
+ options.forEach((option, index) => {
394
+ const optionName = option.name || option;
395
+ const optionValue = option.value !== undefined ? option.value : option;
396
+ const optionColor = option.color || '#cccccc'; // Default gray if no color
397
+ const valueStr = typeof optionValue === 'object' ?
398
+ JSON.stringify(optionValue) : String(optionValue);
399
+
400
+ // Clone existing option element
401
+ const clone = existingOption.cloneNode(true);
402
+
403
+ // Make clone visible (remove display:none from template)
404
+ clone.style.display = '';
405
+
406
+ // Check if this option should be pre-selected (multi-select behavior)
407
+ const shouldBeChecked = Array.isArray(existingData) &&
408
+ existingData.some(v => JSON.stringify(v) === JSON.stringify(optionValue));
409
+
410
+ // Set checked state
411
+ if (shouldBeChecked) {
412
+ clone.classList.add('cf-checked');
413
+ clone.style.backgroundColor = config.selectedBackground;
414
+ console.log(` ✅ Pre-selected color: ${optionName}`);
415
+ } else {
416
+ clone.classList.remove('cf-checked');
417
+ clone.style.backgroundColor = 'transparent';
418
+ }
419
+
420
+ // Set data attributes on container
421
+ clone.setAttribute('data-chat-element', 'multi-select-color');
422
+ clone.setAttribute('data-field', field);
423
+ clone.setAttribute('data-value', valueStr);
424
+ clone.setAttribute('data-name', optionName);
425
+ clone.setAttribute('data-index', index);
426
+ clone.setAttribute('data-color', optionColor);
427
+
428
+ // Find and set input
429
+ const input = clone.querySelector('[data-chat-input-element="input"]');
430
+ if (input) {
431
+ input.setAttribute('data-chat-element', 'multi-select-color');
432
+ input.name = field;
433
+ input.value = valueStr;
434
+ input.checked = shouldBeChecked; // Pre-check if needed
435
+ input.onclick = (e) => e.stopPropagation(); // Prevent click bubbling
436
+ }
437
+
438
+ // Find and set tick icon visibility
439
+ const tickIcon = clone.querySelector('[data-chat-input-element="tick-icon"]');
440
+ if (tickIcon) {
441
+ tickIcon.style.display = shouldBeChecked ? 'block' : 'none';
442
+ }
443
+
444
+ // Find and set color block
445
+ const colorBlock = clone.querySelector('[data-chat-input-element="color-block"]');
446
+ if (colorBlock) {
447
+ colorBlock.style.backgroundColor = optionColor;
448
+ colorBlock.style.display = ''; // Make sure it's visible
449
+ } else {
450
+ console.warn('Color block element not found in multi-select-color template');
451
+ }
452
+
453
+ // Find and set text
454
+ const textElement = clone.querySelector('[data-chat-input-element="text"]');
455
+ if (textElement) {
456
+ textElement.textContent = optionName;
457
+ textElement.style.display = ''; // Make sure text is visible
458
+ } else {
459
+ console.error('Text element not found in option');
460
+ }
461
+
462
+ // Append to wrapper
463
+ optionsWrapper.appendChild(clone);
464
+ });
465
+
466
+ // Append wrapper to messages
467
+ elements.messages.appendChild(optionsWrapper);
468
+ scrollToBottom();
469
+
470
+ // Add click handlers with proper event handling
471
+ const optionElements = optionsWrapper.querySelectorAll('[data-chat-input-element="container"]');
472
+ optionElements.forEach(el => {
473
+ // Clear any existing onclick
474
+ el.onclick = null;
475
+
476
+ // Add new click handler with stopPropagation
477
+ el.onclick = (e) => {
478
+ e.stopPropagation(); // Prevent bubbling
479
+ e.preventDefault(); // Prevent default behavior
480
+ // Use multi-select behavior (isSingleSelect = false)
481
+ handleOptionClick(el, field, false);
482
+ };
483
+ });
484
+ }
485
+
346
486
  // =============================================================================
347
487
  // TEXT/NUMBER INPUT RENDERING
348
488
  // =============================================================================
@@ -362,6 +502,10 @@ function renderTextInput(field, inputType = 'text') {
362
502
  return;
363
503
  }
364
504
 
505
+ // Get existing data for this field (for pre-filling when editing)
506
+ const existingValue = chatState.data[field];
507
+ console.log(`📝 Pre-filling ${field}:`, existingValue);
508
+
365
509
  // Clone existing input element
366
510
  const clone = existingInput.cloneNode(true);
367
511
 
@@ -376,7 +520,15 @@ function renderTextInput(field, inputType = 'text') {
376
520
  if (inputElement) {
377
521
  inputElement.setAttribute('data-field', field);
378
522
  inputElement.name = field;
379
- inputElement.value = '';
523
+
524
+ // Pre-fill value if it exists
525
+ if (existingValue !== undefined && existingValue !== null) {
526
+ inputElement.value = existingValue;
527
+ console.log(` ✅ Pre-filled with: ${existingValue}`);
528
+ } else {
529
+ inputElement.value = '';
530
+ }
531
+
380
532
  inputElement.type = inputType === 'number' ? 'number' : 'text';
381
533
 
382
534
  // Add input event to enable Next button when user types
@@ -668,6 +820,14 @@ async function showNextStep() {
668
820
  } else {
669
821
  enableNextButton();
670
822
  }
823
+ } else if (inputType === 'multi-select-color') {
824
+ // Render color options with color blocks
825
+ renderColorOptions(nextStep.input.options, nextStep.input.field);
826
+
827
+ // Enable Next button if input not required (default behavior)
828
+ if (!inputRequired) {
829
+ enableNextButton();
830
+ }
671
831
  } else {
672
832
  // Render options (single-select or multi-select)
673
833
  const isSingleSelect = inputType === 'single-select';