From db8e5e03cbdf84bf6e405558970c16263a9b4d4a Mon Sep 17 00:00:00 2001 From: Simon Hartley <170740+scrhartley@users.noreply.github.com> Date: Thu, 24 Apr 2025 20:58:31 +0100 Subject: [PATCH] Fix event not being available in hx-vals/hx-vars when hx-trigger has delay (#3196) Fix event not being available in hx-vals/hx-vars when hx-trigger uses delay Co-authored-by: scrhartley --- src/htmx.js | 34 ++++++++++++++++++++++------------ test/attributes/hx-vals.js | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/htmx.js b/src/htmx.js index 16d458f2..3fbace8e 100644 --- a/src/htmx.js +++ b/src/htmx.js @@ -3782,9 +3782,10 @@ var htmx = (function() { * @param {string} attr * @param {boolean=} evalAsDefault * @param {Object=} values + * @param {Event=} event * @returns {Object} */ - function getValuesForElement(elt, attr, evalAsDefault, values) { + function getValuesForElement(elt, attr, evalAsDefault, values, event) { if (values == null) { values = {} } @@ -3810,7 +3811,13 @@ var htmx = (function() { } let varsValues if (evaluateValue) { - varsValues = maybeEval(elt, function() { return Function('return (' + str + ')')() }, {}) + varsValues = maybeEval(elt, function() { + if (event) { + return Function('event', 'return (' + str + ')')(event) + } else { // allow window.event to be accessible + return Function('return (' + str + ')')() + } + }, {}) } else { varsValues = parseJSON(str) } @@ -3822,7 +3829,7 @@ var htmx = (function() { } } } - return getValuesForElement(asElement(parentElt(elt)), attr, evalAsDefault, values) + return getValuesForElement(asElement(parentElt(elt)), attr, evalAsDefault, values, event) } /** @@ -3842,28 +3849,31 @@ var htmx = (function() { /** * @param {Element} elt - * @param {*?} expressionVars + * @param {Event=} event + * @param {*?=} expressionVars * @returns */ - function getHXVarsForElement(elt, expressionVars) { - return getValuesForElement(elt, 'hx-vars', true, expressionVars) + function getHXVarsForElement(elt, event, expressionVars) { + return getValuesForElement(elt, 'hx-vars', true, expressionVars, event) } /** * @param {Element} elt - * @param {*?} expressionVars + * @param {Event=} event + * @param {*?=} expressionVars * @returns */ - function getHXValsForElement(elt, expressionVars) { - return getValuesForElement(elt, 'hx-vals', false, expressionVars) + function getHXValsForElement(elt, event, expressionVars) { + return getValuesForElement(elt, 'hx-vals', false, expressionVars, event) } /** * @param {Element} elt + * @param {Event=} event * @returns {FormData} */ - function getExpressionVars(elt) { - return mergeObjects(getHXVarsForElement(elt), getHXValsForElement(elt)) + function getExpressionVars(elt, event) { + return mergeObjects(getHXVarsForElement(elt, event), getHXValsForElement(elt, event)) } /** @@ -4302,7 +4312,7 @@ var htmx = (function() { if (etc.values) { overrideFormData(rawFormData, formDataFromObject(etc.values)) } - const expressionVars = formDataFromObject(getExpressionVars(elt)) + const expressionVars = formDataFromObject(getExpressionVars(elt, event)) const allFormData = overrideFormData(rawFormData, expressionVars) let filteredFormData = filterValues(allFormData, elt) diff --git a/test/attributes/hx-vals.js b/test/attributes/hx-vals.js index ee8a1249..d4972183 100644 --- a/test/attributes/hx-vals.js +++ b/test/attributes/hx-vals.js @@ -314,6 +314,33 @@ describe('hx-vals attribute', function() { } calledEvent.should.equal(true) }) + + it('using js: with hx-vals has event available', function() { + this.server.respondWith('POST', '/vars', function(xhr) { + var params = getParameters(xhr) + params.i1.should.equal('test') + xhr.respond(200, {}, 'Clicked!') + }) + var div = make('
') + div.click() + this.server.respond() + div.innerHTML.should.equal('Clicked!') + }) + + it('using js: with hx-vals has event available when used with a delay', function(done) { + var params = null + var div = make('
') + htmx.on(div, 'htmx:configRequest', function(evt) { + evt.preventDefault() + params = evt.detail.parameters + }, { once: true }) + div.click() + new Promise(resolve => setTimeout(resolve, 20)).then(function() { + params.i1.should.equal('test') + done() + }).catch(done) + }) + it('hx-vals works with null values', function() { this.server.respondWith('POST', '/vars', function(xhr) { var params = getParameters(xhr)