I need to have a user input field in the #wmd-button-bar
of the SE editor, along with a button. The user can enter some data in the input field, and then press a button to process that data. I am using a userscript to achieve this. I have created a separate MVCE of that, and here is its direct install link for Tampermonkey/Greasemonkey.
To reproduce the issue, install the userscript. Reload this page and then click "Edit". You'll notice a new blank input box with a button. Focus the the "Edit summary" box blank, leave it blank, and hit Enter. Instead of submitting the answer box, your caret will now instead focus on the new blank input box.
The same happens if you press Enter inside the "Question title" box.
From the console.log
messages, you'll notice that there has been instead a MouseClick
event on the button! This is not expected behavior. In fact, how is this even possible? We just pressed Enter inside the Edit summary box, and didn't even touch either the new blank input or its button. How did it then register a mouse click?
How to fix this?
Note: The e.preventDefault();
inside the button onclick
handler is necessary. Otherwise, when the user presses the button to process their input data, the answer box submits itself instead.
The Userscript Code:
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.innerHTML = "Button";
btn.onclick = function(e){
e.preventDefault();
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500)
I need to have a user input field in the #wmd-button-bar
of the SE editor, along with a button. The user can enter some data in the input field, and then press a button to process that data. I am using a userscript to achieve this. I have created a separate MVCE of that, and here is its direct install link for Tampermonkey/Greasemonkey.
To reproduce the issue, install the userscript. Reload this page and then click "Edit". You'll notice a new blank input box with a button. Focus the the "Edit summary" box blank, leave it blank, and hit Enter. Instead of submitting the answer box, your caret will now instead focus on the new blank input box.
The same happens if you press Enter inside the "Question title" box.
From the console.log
messages, you'll notice that there has been instead a MouseClick
event on the button! This is not expected behavior. In fact, how is this even possible? We just pressed Enter inside the Edit summary box, and didn't even touch either the new blank input or its button. How did it then register a mouse click?
How to fix this?
Note: The e.preventDefault();
inside the button onclick
handler is necessary. Otherwise, when the user presses the button to process their input data, the answer box submits itself instead.
The Userscript Code:
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.innerHTML = "Button";
btn.onclick = function(e){
e.preventDefault();
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500)
Share
Improve this question
edited Jun 15, 2018 at 13:58
Gaurang Tandon
asked Jun 9, 2018 at 5:20
Gaurang TandonGaurang Tandon
6,75311 gold badges50 silver badges94 bronze badges
4
|
3 Answers
Reset to default 8Its default HTML behaviour. All the buttons
inside a form
are of type="submit"
. On pressing enter
, the most recent button of the form
is clicked and their handlers are called, by default. To fix this, the buttons are created with type="button"
.
console.log(document.querySelector("#a").type)
console.log(document.querySelector("#b").type)
console.log(document.querySelector("#c").type)
<form>
<input type="text">
<button id="a" onclick="console.log('a')">Submit type</button>
<button id="b" onclick="console.log('b')" type="button">Button type</button>
<input id="c" type="submit" value="Input Submit type">
</form>
You can refer this to understand the behaviour of <button>
and <input type="button">
.
If you just check in console like, document.querySelector("#box").children[1].type
it will show as submit
.
Button, by default, acts as submit
type unless it is specified explicitly (either submit
(default)/reset
/button
). Just run document.querySelector("#box").children[1].type=button
. You find it working as expected.
The behaviour is same in cross-browser and tested in Firefox Nightly
(developer version), Chrome
and Safari
and works a little bit different in IE
.
Also you can see the click is by default by seeing console.log(event.detail)
is 0
as it is triggered internally. When triggered with a left click, it would be 1
. MDN Docs on click event
The short and simple answer, is to force type for your button element:
<button type="button"></button>
It defaults to type="submit"
, and that's why it acts accordingly.
i tried the following code in firefox browser and it works as expected.
function createModal(buttonBar){
var div = document.createElement("div"),
input = document.createElement("input"),
btn = document.createElement("button");
div.id = "box";
input.type = "text";
btn.type = "button";
btn.innerHTML = "Button";
btn.onclick = function(e){
console.log("I was called");
input.focus();
console.dir(e);
console.trace();
};
div.appendChild(input);
div.appendChild(btn);
return div;
}
setInterval(function () {
var cont = document.querySelector(".wmd-container:not(.processed)"), ul, buttonBar, div;
if (cont && (ul = cont.querySelector(".wmd-button-bar ul"))) {
cont.classList.add("processed");
buttonBar = cont.querySelector("div[id^=wmd-button-bar]");
div = createModal(buttonBar);
buttonBar.appendChild(div);
}
}, 500);
notice that i have set the btn.type="button";
this makes sure the form is not submitted and also removed e.preventDefault();
as button will never submit the form now.
keep in mind that by default if you don't give a type
to a button
element then it will behave like a submit
button.
also the MouseClick
event was firing because the click event is triggered on submit buttons present within the form when submitting the form. as you had the button without the type
attribute it was working like a submit button. so the MouseClick
event was fired when you hit enter (as its submitting the form).
you can verify this by adding an onclick
handler from your browser developer tool to the Save edits
submit button and hit enter on the text field.
form
containing onlyinput
text gets submitted on Enter press. And this is triggering all submit activities like click maybe. If this is the case then you can either remove parent form element or have one more hidden input element. Or addstopPropagation
to trigger only one submit event through enter press. – Harshali Talele Commented Jun 19, 2018 at 11:11