From 14c3c952599853d61049360ad5c0ec55788b14e2 Mon Sep 17 00:00:00 2001 From: labmecanicatec Date: Sun, 5 Apr 2026 13:09:29 -0500 Subject: [PATCH] refactor(inlineAttributeEdit): simplify inline DATETIME editing with native Flatpickr Replaces the inline DATETIME editing flow based on x-editable/combodate with a simpler implementation using DatePickerSetupControl. Refactors the inline script to use native browser APIs (no jQuery in this block) and fetch for persistence. Unifies markup for attribute types and improves picker open/close handling (external click and Escape key) to avoid duplicate listeners. Keeps compatibility with deferred datepicker initialization using a fallback wait mechanism. --- tpl/Admin/InlineAttributeEdit.tpl | 269 +++++++++++++++--- tpl/Admin/Resources/manage_resource_types.tpl | 2 +- tpl/Admin/Resources/manage_resources.tpl | 13 +- tpl/Admin/Resources/view_resources.tpl | 2 +- 4 files changed, 237 insertions(+), 49 deletions(-) diff --git a/tpl/Admin/InlineAttributeEdit.tpl b/tpl/Admin/InlineAttributeEdit.tpl index 7f2a03b3c..39055832a 100644 --- a/tpl/Admin/InlineAttributeEdit.tpl +++ b/tpl/Admin/InlineAttributeEdit.tpl @@ -1,48 +1,235 @@ {if $attribute->AppliesToEntity($id)} + {assign var=type value=$attribute->Type()} {assign var=attributeId value="inline{$attribute->Id()}{$id}"} -
- {assign var=datatype value='text'} - {if $attribute->Type() == CustomAttributeTypes::CHECKBOX} - {assign var=datatype value='checklist'} - {elseif $attribute->Type() == CustomAttributeTypes::MULTI_LINE_TEXTBOX} - {assign var=datatype value='textarea'} - {elseif $attribute->Type() == CustomAttributeTypes::SELECT_LIST} - {assign var=datatype value='select'} - {elseif $attribute->Type() == CustomAttributeTypes::DATETIME} - {assign var=datatype value='combodate'} - {assign var=value value={formatdate date=$value key=fullcalendar}} + {assign var=datatype value='text'} + {assign var=inlineClass value='inlineAttribute'} + {assign var=pickerValue value=$value} + + {if $type == CustomAttributeTypes::CHECKBOX} + {assign var=datatype value='checklist'} + {elseif $type == CustomAttributeTypes::MULTI_LINE_TEXTBOX} + {assign var=datatype value='textarea'} + {elseif $type == CustomAttributeTypes::SELECT_LIST} + {assign var=datatype value='select'} + {elseif $type == CustomAttributeTypes::DATETIME} + {assign var=AltFormat value='short_datetime'} + {assign var=pickerControlId value="inlinePickerInput{$attributeId}"} + {assign var=inlineClass value='inlineAttributeDateTime'} + {if $value != ''} + {assign var=pickerValue value={formatdate date=$value format='Y-m-d H:i'}} {/if} + {/if} + +
- - {translate key=Edit} - Type() == CustomAttributeTypes::SELECT_LIST} data-source='[{if !$attribute->Required()}{ldelim}value:"",text:""{rdelim},{/if} - {foreach from=$attribute->PossibleValueList() item=v name=vals} - {ldelim}value:"{$v}",text:"{$v}"{rdelim}{if not $smarty.foreach.vals.last},{/if} - {/foreach}]' {/if} {if $attribute->Type() == CustomAttributeTypes::CHECKBOX} data-source='[{ldelim}value:"1",text:"{translate key=Yes}"{rdelim}]' - {/if}> - {if $attribute->Type() == CustomAttributeTypes::DATETIME} - - {/if} -
-{/if} \ No newline at end of file + + button.addEventListener('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + pendingValue = display.dataset.value || ''; + show(); + if (input._flatpickr) { + input._flatpickr.setDate(display.dataset.value || null, false); + } + }); + + // Close on outside click / ESC — keyed registry avoids duplicate listeners + // when multiple pickers are rendered on the same page + if (!document._pickerHandlers) document._pickerHandlers = {}; + + if (document._pickerHandlers[namespace + '_mousedown']) { + document.removeEventListener('mousedown', document._pickerHandlers[namespace + '_mousedown']); + } + document._pickerHandlers[namespace + '_mousedown'] = function(e) { + if (container.classList.contains('d-none')) return; + if (container.contains(e.target) || button.contains(e.target)) return; + saveIfChanged(); + }; + document.addEventListener('mousedown', document._pickerHandlers[namespace + '_mousedown']); + + if (document._pickerHandlers[namespace + '_keydown']) { + document.removeEventListener('keydown', document._pickerHandlers[namespace + '_keydown']); + } + document._pickerHandlers[namespace + '_keydown'] = function(e) { + if (e.key !== 'Escape') return; + if (container.classList.contains('d-none')) return; + pendingValue = display.dataset.value || ''; + if (input._flatpickr) { + input._flatpickr.setDate(display.dataset.value || null, false); + } + hide(); + }; + document.addEventListener('keydown', document._pickerHandlers[namespace + '_keydown']); + })(); + + {/if} +
+{/if} diff --git a/tpl/Admin/Resources/manage_resource_types.tpl b/tpl/Admin/Resources/manage_resource_types.tpl index e0a4d366a..0a1694688 100644 --- a/tpl/Admin/Resources/manage_resource_types.tpl +++ b/tpl/Admin/Resources/manage_resource_types.tpl @@ -75,7 +75,7 @@ {if $AttributeList|default:array()|count > 0} {foreach from=$AttributeList item=attribute} - {include file='Admin/InlineAttributeEdit.tpl' id=$id attribute=$attribute value=$type->GetAttributeValue($attribute->Id())} + {include file='Admin/InlineAttributeEdit.tpl' url="{$smarty.server.SCRIPT_NAME}?action={ManageResourceTypesActions::ChangeAttribute}" id=$id attribute=$attribute value=$type->GetAttributeValue($attribute->Id())} {/foreach} {/if} diff --git a/tpl/Admin/Resources/manage_resources.tpl b/tpl/Admin/Resources/manage_resources.tpl index 43f17d49b..e2c38c669 100644 --- a/tpl/Admin/Resources/manage_resources.tpl +++ b/tpl/Admin/Resources/manage_resources.tpl @@ -398,10 +398,9 @@ class="inline fw-bold">{translate key='Contact'} {if $ResourceContactIsUser} {if $resource->HasContact()} {$resource->GetContact()} @@ -585,9 +584,11 @@ class="bi bi-chevron-down">
-
+
{/if} - {include file='Admin/InlineAttributeEdit.tpl' id=$id attribute=$attribute value=$resource->GetAttributeValue($attribute->Id())} + {include file='Admin/InlineAttributeEdit.tpl' url="{$smarty.server.SCRIPT_NAME}?action={ManageResourcesActions::ActionChangeAttribute}" + id=$id attribute=$attribute + value=$resource->GetAttributeValue($attribute->Id())} {/if} {/foreach} {if $hasResults} diff --git a/tpl/Admin/Resources/view_resources.tpl b/tpl/Admin/Resources/view_resources.tpl index 5b092c719..81ca17bad 100644 --- a/tpl/Admin/Resources/view_resources.tpl +++ b/tpl/Admin/Resources/view_resources.tpl @@ -377,7 +377,7 @@
{if $AttributeList|default:array()|count > 0} {foreach from=$AttributeList item=attribute} - {include file='Admin/InlineAttributeEdit.tpl' id=$id attribute=$attribute value=$resource->GetAttributeValue($attribute->Id())} + {include file='Admin/InlineAttributeEdit.tpl' url="{$smarty.server.SCRIPT_NAME}?action={ManageResourcesActions::ActionChangeAttribute}" id=$id attribute=$attribute value=$resource->GetAttributeValue($attribute->Id())} {/foreach} {/if}