track last clicked button using focus to include value in submission

This commit is contained in:
carson 2021-07-01 13:54:11 -06:00
parent 97ab1098f8
commit 6d1a86836e
3 changed files with 97 additions and 0 deletions

View File

@ -1407,6 +1407,19 @@ return (function () {
}
}
function initButtonTracking(form){
form.addEventListener('focusin', function(evt){
if (matches(evt.target, "button, input[type='submit']")) {
var internalData = getInternalData(form);
internalData.lastButtonClicked = evt.target;
}
})
form.addEventListener('focusout', function(evt){
var internalData = getInternalData(form);
internalData.lastButtonClicked = null;
})
}
function initNode(elt) {
if (elt.closest && elt.closest(htmx.config.disableSelector)) {
return;
@ -1427,6 +1440,10 @@ return (function () {
boostElement(elt, nodeData, triggerSpecs);
}
if (elt.tagName === "FORM") {
initButtonTracking(elt);
}
var sseInfo = getAttributeValue(elt, 'hx-sse');
if (sseInfo) {
processSSEInfo(elt, nodeData, sseInfo);
@ -1770,6 +1787,14 @@ return (function () {
// include the element itself
processInputValue(processed, values, errors, elt, validate);
// if a button or submit was clicked last, include its value
var internalData = getInternalData(elt);
if (internalData.lastButtonClicked) {
var name = getRawAttribute(internalData.lastButtonClicked,"name");
var value = internalData.lastButtonClicked.value;
values[name] = value;
}
// include any explicit includes
var includes = getClosestAttributeValue(elt, "hx-include");
if (includes) {

View File

@ -117,5 +117,51 @@ describe("Core htmx Parameter Handling", function() {
htmx._("urlEncode")({"foo": "bar", "do" : ["rey", "blah"]}).should.equal("foo=bar&do=rey&do=blah");
});
it('form includes last focused button', function () {
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><button id="b1" name="btn" value="bar"></button></form>');
var input = byId('i1');
var button = byId('b1');
button.focus();
var vals = htmx._('getInputValues')(form).values;
vals['foo'].should.equal('bar');
vals['do'].should.equal('rey');
vals['btn'].should.equal('bar');
})
it('form includes last focused submit', function () {
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>');
var input = byId('i1');
var button = byId('s1');
button.focus();
var vals = htmx._('getInputValues')(form).values;
vals['foo'].should.equal('bar');
vals['do'].should.equal('rey');
vals['s1'].should.equal('bar');
})
it('form does not include button when focus is lost', function () {
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>');
var input = byId('i1');
var button = byId('s1');
button.focus();
input.focus();
var vals = htmx._('getInputValues')(form).values;
vals['foo'].should.equal('bar');
vals['do'].should.equal('rey');
should.equal(vals['s1'], undefined);
})
it('form does not include button when focus is lost outside of form', function () {
var form = make('<form hx-get="/foo"><input id="i1" name="foo" value="bar"/><input id="i2" name="do" value="rey"/><input type="submit" id="s1" name="s1" value="bar"/></form>');
var anchor = make('<button id="a1"></button>');
var button = byId('s1');
button.focus();
anchor.focus();
var vals = htmx._('getInputValues')(form).values;
vals['foo'].should.equal('bar');
vals['do'].should.equal('rey');
should.equal(vals['s1'], undefined);
})
});

View File

@ -0,0 +1,26 @@
<html>
<body>
<form id="f1">
input 1: <input id="i1" type = "text" name = "i1" /><br/>
<button id="b1">Button 1</button><br/>
input 2: <input id="i2" type = "text" name = "i1" /><br/>
</form>
<button id="b2" onclick="i1.focus();">Focus i1</button><br/>
</body>
<script>
f1.addEventListener("submit", function(evt){
evt.preventDefault();
console.log("submitted")
return false;
})
f1.addEventListener("focusin", function(evt){
console.log("focusin", evt.target)
return false;
})
f1.addEventListener("focusout", function(evt){
console.log("focusout", evt.target)
return false;
})
</script>
</html>