diff --git a/resources/public/js/htmx-disable.js b/resources/public/js/htmx-disable.js index c3186e49..98cbff52 100644 --- a/resources/public/js/htmx-disable.js +++ b/resources/public/js/htmx-disable.js @@ -128,7 +128,40 @@ initDatepicker = function(elem) { } -initMultiDatepicker = function(elem) { +function formatDateMMDDYYYY(date) { + const month = String(date.getMonth() + 1).padStart(2, '0'); // Get month (1-12), pad with leading zero if necessary + const day = String(date.getDate()).padStart(2, '0'); // Get day (1-31), pad with leading zero if necessary + const year = date.getFullYear(); // Get full year + + return `${month}/${day}/${year}`; +} + +function parseMMDDYYYY(dateString) { + const parts = dateString.split('/'); + if (parts.length !== 3) { + throw new Error('Invalid date format. Expected mm/dd/yyyy'); + } + const month = parseInt(parts[0], 10) - 1; // Months are zero-based in JavaScript + const day = parseInt(parts[1], 10); + const year = parseInt(parts[2], 10); + + return new Date(year, month, day); +} + +const getFourWeekPeriods = endDate => { + if (!endDate) { + endDate= formatDateMMDDYYYY(new Date()) + } + let periods = []; + for (let i = 0; i < 13; i++) { + const currentDate = new Date(parseMMDDYYYY(endDate).getTime()); + currentDate.setDate(currentDate.getDate() - 28 * (i + 1)); + periods.push(formatDateMMDDYYYY(new Date(currentDate))); + } + return periods; +}; + +initMultiDatepicker = function(elem, startingValue) { const modalParent = elem.closest('#modal-content'); if (modalParent) { return new Datepicker(elem, {format: "mm/dd/yyyy", autohide: false, container: "#modal-content .modal-card", maxNumberOfDates: 12, dateDelimiter: ", "}); diff --git a/src/clj/auto_ap/ssr/components/inputs.clj b/src/clj/auto_ap/ssr/components/inputs.clj index 67c69c6e..3a76f128 100644 --- a/src/clj/auto_ap/ssr/components/inputs.clj +++ b/src/clj/auto_ap/ssr/components/inputs.clj @@ -356,22 +356,28 @@ (for [v (:value params) :when v] (some-> v (atime/unparse-local atime/normal-date))))] - (println "MY VALUE IS" value) - [:div.shrink {:x-data (hx/json {:value value})} - [:input + [:div.shrink {:x-data (hx/json {:value value + :dp nil }) + :x-modelable "value" + :x-model (:x-model params) } + [:template {:x-for "v in value"} + [:input {:type "hidden" :name (:name params) :x-model "v"}]] + [:div (-> params (update :class (fnil hh/add-class "") default-input-classes) - (assoc :x-modelable "value") (assoc :type "text") - (assoc :x-data (hx/json {:dp nil}) ) (assoc :value value) - (assoc :x-init " dp = initMultiDatepicker($el);") + ;; the data-date field has to be bound before the datepicker can be initialized + (assoc :x-init "$nextTick(() => { dp = initMultiDatepicker($el, value); ;}); ") + (assoc "x-effect" "setTimeout(()=> { if(dp) { dp.setDate(Array.from(value), {clear: true}); }}, 2000) ") + (assoc ":data-date" "Array.prototype.join.call(value, ', ')") (assoc "@htmx:before-history-save" "destroyDatepicker(dp)" ) (assoc "@htmx:before-cleanup-element" "destroyDatepicker(dp)" ) - (assoc "@change" "value = $event.target.value;") - (assoc "hx-on" (hiccup/raw "changeDate: htmx.trigger(this, \"change\") ")) + (assoc "x-destroy" "destroyDatepicker(dp)") + (assoc "@change-date.camel" "console.log('date changing'); value = dp.getDate(\"mm/dd/yyyy\");") + (update :class #(str % (use-size size) " w-full")) - (dissoc :size))]])) + (dissoc :size :name :x-model :x-modelable))]])) diff --git a/src/clj/auto_ap/ssr/ledger/balance_sheet.clj b/src/clj/auto_ap/ssr/ledger/balance_sheet.clj index 53b78911..f90b4d3a 100644 --- a/src/clj/auto_ap/ssr/ledger/balance_sheet.clj +++ b/src/clj/auto_ap/ssr/ledger/balance_sheet.clj @@ -290,9 +290,33 @@ (fc/with-field :date (com/validated-inline-field {:label "Date" :errors (fc/field-errors)} - (com/multi-date-input {:placeholder "12/21/2020" - :name (fc/field-name) - :value (fc/field-value)}))) + [:div {:x-data (hx/json {:dates (map #(atime/unparse-local % atime/normal-date) (fc/field-value))}) } + [:template {:x-for "v in dates"} + [:input {:type "hidden" + :name (fc/field-name) + :x-model "v"}] ] + (com/a-button {"x-tooltip.on.click.theme.dropdown.placement.bottom.interactive" "{content: ()=> $refs.tooltip.innerHTML, allowHTML: true, appendTo: $root}"} + + [:template {:x-if "dates.length == 0"} + [:span.text-left.text-gray-400 "None selected"]] + [:template { :x-if "dates.length < 3 && dates.length > 0"} + [:span.inline-flex.gap-2 + [:template {:x-for "v in dates" } + (com/pill {:color :secondary} + [:span {:x-text "v"}])]]] + [:template {:x-if "dates.length >= 3"} + (com/pill {:color :secondary} + [:span {:x-text "dates.length"}] + " dates")] + [:div {:class "w-3 h-3 m-1 inline ml-1 justify-self-end text-gray-500 self-center"} + svg/drop-down]) + [:template {:x-ref "tooltip"} + [:div.p-4 {:class "bg-gray-100 dark:bg-gray-600 rounded-lg shadow-2xl w-max z-50 ring-1 p-4"} + [:div.flex.flex-col.gap-2 + (com/multi-date-input {:placeholder "12/21/2020" + :x-model "dates" }) + (com/a-button {"@click" "dates=getFourWeekPeriods(dates[dates.length -1])"} "13 periods") + (com/a-button {"@click" "dates=[]"} "Clear")]]]])) (com/button {:color :primary :class "w-32"} "Run")