|
351 | 351 | operator: 'eq', |
352 | 352 | value: '' |
353 | 353 | }; |
354 | | - return Object.assign(defaults, overrides); |
| 354 | + const filter = Object.assign({}, defaults, overrides); |
| 355 | + if (Array.isArray(filter.value)) { |
| 356 | + filter.value = filter.value.slice(); |
| 357 | + } else if (filter.value && typeof filter.value === 'object' && !(filter.value instanceof Date)) { |
| 358 | + try { |
| 359 | + filter.value = JSON.parse(JSON.stringify(filter.value)); |
| 360 | + } catch (err) { |
| 361 | + filter.value = Object.assign({}, filter.value); |
| 362 | + } |
| 363 | + } |
| 364 | + return filter; |
355 | 365 | } |
356 | 366 |
|
357 | 367 | function createEmptyCustomOption(overrides = {}) { |
|
360 | 370 | key: '', |
361 | 371 | value: '' |
362 | 372 | }; |
363 | | - return Object.assign(defaults, overrides); |
| 373 | + const option = Object.assign({}, defaults, overrides); |
| 374 | + if (Array.isArray(option.value)) { |
| 375 | + option.value = option.value.slice(); |
| 376 | + } else if (option.value && typeof option.value === 'object' && !(option.value instanceof Date)) { |
| 377 | + try { |
| 378 | + option.value = JSON.parse(JSON.stringify(option.value)); |
| 379 | + } catch (err) { |
| 380 | + option.value = Object.assign({}, option.value); |
| 381 | + } |
| 382 | + } |
| 383 | + return option; |
364 | 384 | } |
365 | 385 |
|
366 | 386 | function createEmptyWidget(overrides = {}) { |
|
463 | 483 | table: filter.table, |
464 | 484 | column: filter.column, |
465 | 485 | operator: filter.operator, |
466 | | - value: filter.value |
| 486 | + value: coerceFilterValue(filter.value, filter.operator) |
467 | 487 | })) |
468 | 488 | : []; |
469 | 489 |
|
|
516 | 536 | return value; |
517 | 537 | } |
518 | 538 |
|
519 | | - function coerceFilterValue(rawValue) { |
| 539 | + function coerceFilterValue(rawValue, operator) { |
520 | 540 | if (rawValue === undefined || rawValue === null) { |
521 | 541 | return null; |
522 | 542 | } |
523 | 543 | if (typeof rawValue === 'number' || typeof rawValue === 'boolean') { |
524 | 544 | return rawValue; |
525 | 545 | } |
| 546 | + if (Array.isArray(rawValue)) { |
| 547 | + return rawValue.slice(); |
| 548 | + } |
| 549 | + if (rawValue instanceof Date) { |
| 550 | + return new Date(rawValue.getTime()); |
| 551 | + } |
| 552 | + if (typeof rawValue === 'object') { |
| 553 | + try { |
| 554 | + return JSON.parse(JSON.stringify(rawValue)); |
| 555 | + } catch (err) { |
| 556 | + return Object.assign({}, rawValue); |
| 557 | + } |
| 558 | + } |
526 | 559 | const value = String(rawValue).trim(); |
527 | 560 | if (!value) { |
528 | 561 | return ''; |
529 | 562 | } |
530 | 563 | if (value === 'true' || value === 'false') { |
531 | 564 | return value === 'true'; |
532 | 565 | } |
533 | | - if (!Number.isNaN(Number(value))) { |
534 | | - return Number(value); |
| 566 | + const numericValue = Number(value); |
| 567 | + if (!Number.isNaN(numericValue) && String(numericValue) === value) { |
| 568 | + return numericValue; |
535 | 569 | } |
536 | 570 | if ((value.startsWith('[') && value.endsWith(']')) || (value.startsWith('{') && value.endsWith('}'))) { |
537 | 571 | try { |
|
540 | 574 | return value; |
541 | 575 | } |
542 | 576 | } |
| 577 | + if ((operator === 'in' || operator === 'nin') && value.indexOf(',') !== -1) { |
| 578 | + const parts = value.split(',').map((item) => item.trim()).filter((item) => item !== ''); |
| 579 | + if (parts.length > 1) { |
| 580 | + return parts; |
| 581 | + } |
| 582 | + } |
543 | 583 | return value; |
544 | 584 | } |
545 | 585 |
|
546 | | - function formatValueForInput(rawValue) { |
547 | | - if (rawValue === undefined || rawValue === null) { |
| 586 | + function formatValueForInput(rawValue, operator) { |
| 587 | + const normalized = coerceFilterValue(rawValue, operator); |
| 588 | + if (normalized === undefined || normalized === null) { |
548 | 589 | return ''; |
549 | 590 | } |
550 | | - if (typeof rawValue === 'string') { |
551 | | - return rawValue; |
| 591 | + if (typeof normalized === 'string') { |
| 592 | + return normalized; |
552 | 593 | } |
553 | | - if (rawValue instanceof Date) { |
554 | | - return rawValue.toISOString(); |
| 594 | + if (normalized instanceof Date) { |
| 595 | + return normalized.toISOString(); |
555 | 596 | } |
556 | | - if (Array.isArray(rawValue) || (typeof rawValue === 'object' && rawValue !== null)) { |
| 597 | + if (Array.isArray(normalized) || (typeof normalized === 'object' && normalized !== null)) { |
557 | 598 | try { |
558 | | - return JSON.stringify(rawValue); |
| 599 | + return JSON.stringify(normalized); |
559 | 600 | } catch (err) { |
560 | | - return String(rawValue); |
| 601 | + return String(normalized); |
561 | 602 | } |
562 | 603 | } |
563 | | - return String(rawValue); |
| 604 | + return String(normalized); |
564 | 605 | } |
565 | 606 |
|
566 | 607 | function coerceCustomOptionValue(rawValue) { |
|
609 | 650 | table: filter.table, |
610 | 651 | column: filter.column, |
611 | 652 | operator: filter.operator, |
612 | | - value: coerceFilterValue(filter.value) |
| 653 | + value: coerceFilterValue(filter.value, filter.operator) |
613 | 654 | })), |
614 | 655 | group_by: widget.groupBy.map((group) => formatTableColumn(group.table, group.column)).filter((value) => value && value.indexOf('.') !== -1), |
615 | 656 | time_bucket: widget.timeBucket ? widget.timeBucket : undefined, |
|
1157 | 1198 | valueInput.attr('data-section-id', sectionId); |
1158 | 1199 | valueInput.attr('data-widget-id', widgetId); |
1159 | 1200 | valueInput.attr('data-filter-id', filter.id); |
1160 | | - valueInput.val(formatValueForInput(filter.value)); |
| 1201 | + valueInput.val(formatValueForInput(filter.value, filter.operator)); |
1161 | 1202 | valueGroup.append(valueInput); |
1162 | 1203 |
|
1163 | 1204 | const removeGroup = $('<div class="form-group col-lg-1 text-right"></div>'); |
|
2139 | 2180 | return; |
2140 | 2181 | } |
2141 | 2182 | filter.operator = $(this).val(); |
| 2183 | + filter.value = coerceFilterValue(filter.value, filter.operator); |
| 2184 | + rerenderWidget(sectionId, widgetId); |
2142 | 2185 | }); |
2143 | 2186 |
|
2144 | 2187 | $(document).on('input', '.builder-filter-value', function () { |
|
2149 | 2192 | if (!filter) { |
2150 | 2193 | return; |
2151 | 2194 | } |
2152 | | - filter.value = $(this).val(); |
| 2195 | + filter.value = coerceFilterValue($(this).val(), filter.operator); |
| 2196 | + }); |
| 2197 | + |
| 2198 | + $(document).on('blur', '.builder-filter-value', function () { |
| 2199 | + const sectionId = $(this).data('section-id'); |
| 2200 | + const widgetId = $(this).data('widget-id'); |
| 2201 | + rerenderWidget(sectionId, widgetId); |
2153 | 2202 | }); |
2154 | 2203 |
|
2155 | 2204 | $(document).on('change', '.builder-option-display', function () { |
|
0 commit comments