Javascript document.getElementById().value='' field executed but no effect - javascript

I'm trying to make a button to clear an input next to it. So far my code is like this,
<input type="file" name="lay4img1" id="lay4img1">
<a href="javascript:;"
onclick="
if(document.getElementById('lay4img1').value != '') {
document.getElementById('lay4img1').value = '';
alert('clear success');
} else {
alert('failed');
}">
<input type="button" value="Clear">
</a>
When I choose a file and make lay4img1 have value, and then push the button, the alert clear success is executed so document.getElementById is also executed, but the field is still not empty? What's wrong from my code?
Other than <input type="file" name="lay4img1" id="lay4img1">, I still have other fields so I don't want and can't use <button type="reset"> for it will clear the whole form, which I consider as not user friendly.

That is a horrible way of binding handlers. Additionally, wrapping a button with an anchor is completely pointless. Consider using JS to add an event listener. This listener removes the old input and replaces it with a new one:
HTML:
<input id="mybutton" type="button" value="Clear">
JS:
function clickhandler(){
var input = document.getElementById('lay4img1');
var replacement = document.createElement('input');
replacement.type = "file";
replacement.id = 'lay4img1';
replacement.name = 'lay4img1';
if(input.value != '') {
input.parentElement.replaceChild(replacement, input);
alert('clear success');
} else {
alert('failed');
}
}
var button = document.getElementById('mybutton');
if (!button.addEventListener) {
button.attachEvent("onclick", clickhandler);
}
else {
button.addEventListener("click", clickhandler, false);
}
Here is a demonstration: http://jsfiddle.net/LHM9V/1/

if the input fields are sibling like below... you can try this javascript code with onClick attribute...
<form>
<input type="file" name="lay4img1" id="lay4img1">
<button type="button" onClick="this.parentNode.getElementsByName('lay4img1')[0].value=new Array();">Clear</button>
</form>

Related

Using ENTER key to replace button click?

<body>
<form>
<label>enter number here: </label>
<input type="number" id="text"/>
<button type="button" id="btn" onclick="calc()">read</button>
</form>
<script>
document.getElementById("text").addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("btn").click();
}
});
</script>
<br>
<label id = "calculated"></label>
<script>
function calc() {
let inputValue = document.getElementById("text").value;
document.getElementById('calculated').innerHTML = 'your number: ' + inputValue;
}
</script>
</body>
I have a very simple HTML file with minimal javascript included. When I click the button, it works perfectly. But when I hit the ENTER on the keyboard to simulate the button click, it will also run through the code, but then an error happens at the end.
On Firefox and Chrome, it'll return an error "Not Found". On w3schools, it'll return "The file you asked for does not exist". And on stackoverflow, it'll just disappear.
What am I missing? Where is the error? What's the trick to making the ENTER key act just like the mouse click?
HTML form has onsubmit attribute on them. onsubmit handles the enter functionality. You have to set the type="submit" on the button, also you need to set the onsubmit on form passing the event to your function so that you can prevent the default action of the form ( that is to send the request to backend ) by doing e.preventDefault.
<body>
<form onsubmit="calc(event)">
<label>enter number here: </label>
<input type="number" id="text"/>
<button type="submit">read</button>
</form>
<br>
<label id = "calculated"></label>
<script>
function calc(e) {
// Will stop the form from sending the request to backend
e.preventDefault()
let inputValue = document.getElementById("text").value;
document.getElementById('calculated').innerHTML = 'your number: ' + inputValue;
}
</script>
</body>
If you want to just prevent ENTER from doing anything including running the code....
The following code (yours with a couple more lines... will prevent Enter from doing anything:
<body>
<form onsubmit="return mySubmitFunction(event)">
<label>enter number here: </label>
<input type="number" id="text"/>
<button type="button" id="btn" onclick="calc()">read</button>
</form>
<script>
document.getElementById("text").addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
return false;
//document.getElementById("btn").click();
}
});
</script>
<br>
<label id = "calculated"></label>
<script>
function mySubmitFunction(e) {
e.preventDefault();
return false;
}
function calc() {
let inputValue = document.getElementById("text").value;
document.getElementById('calculated').innerHTML = 'your number: ' + inputValue;
}
</script>
Why was this happening? since the form element itself has a submit and the enter key is a key pressed which also does a form submit.... so you need to prevent the form from submitting... mySubmitFunction() <- this prevents the form from submitting ... and a change to your keyup event listener - if you do not want enter to even create the click you change this:
event.preventDefault();
document.getElementById("btn").click();
to this :
event.preventDefault();
return false;
//document.getElementById("btn").click();
As I have already did in the code example. or leave it like you had(the event listener keyup) and the Enter key will only act as a click.

Listen for blank inputs and add a "disabled" attribute to a button until an input is noticed

I have a user input field that, if blank, I would like the submit button to be disabled until a key press in the input box is noticed. But, if they blank out the input box, then the button is disabled again.
So, I'd like to add the "disabled" attribute to this input button:
<input type="submit" id="mapOneSubmit" value="Submit" [add attribute "disabled" here]>
The input is from this HTML here:
<input type="text" id="mapOneUserInput" onkeypress="return isNumberKey(event)" oninput="validate(this)">
Note: I have onkeypress and oninput validation to prevent non-number inputs and allow only 2 decimal places.
I assume my JS would look like this to add the disabled attribute:
document.getElementById("mapOneSubmit").setAttribute("disabled");
My problem is, I can't find what event listener listens for "blank" inputs? Can you help me with that?
Thanks kindly!
Check this one as well.
function checkvalid(el)
{
//e.g i am preventing user here to input only upto 5 characters
//you can put your own validation logic here
if(el.value.length===0 || el.value.length>5)
document.getElementById("mapOneSubmit").setAttribute("disabled","disabled");
else
document.getElementById("mapOneSubmit").removeAttribute('disabled');
}
<input type='text' id ='inp' onkeyup='checkvalid(this)'>
<button id='mapOneSubmit' disabled>
Submit
</button>
Yet using the input event:
<input type="text" id="mapOneUserInput" onkeypress="return isNumberKey(event)" oninput="validate(this);updateSubmit(this.value)">
Then in js
function updateSubmit(val) {
if (val.trim() == '') {
document.getElementById('mapOneSubmit').disabled = true;
}
else {
document.getElementById('mapOneSubmit').disabled = false;
}
}
You can find the below code to find the blank inputs
function isNumberKey(event) {
console.log(event.which)
}
var value;
function validate(target) {
console.log(target);
}
<form>
<input type="text" id="mapOneUserInput" onkeypress="return isNumberKey(event)" oninput="validate(this)">
<input type="submit" id="mapOneSubmit" value="Submit" [add attribute "disabled" here]>
</form>
You can you set the enable/disable inside validate function.
function validate(elem) {
//validation here
//code to disable/enable the button
document.getElementById("mapOneSubmit").disabled = elem.value.length === 0;
}
Set the button disable on load by adding disabled property
<input type="submit" id="mapOneSubmit" value="Submit" disabled>
On your validate function just check if value of input field is blank then enable/disable the button
function validate(input){
input.disabled = input.value === "" ;
}
My problem is, I can't find what event listener listens for "blank" inputs?
You can disable the submit button at render, after that you can use the input event to determine whether the input value is empty or not. From there, you can set state of the submit button.
document.addEventListener('DOMContentLoaded', () => {
const textInput = document.getElementById('mapOneUserInput');
textInput.addEventListener('input', handleTextInput, false);
textInput.addEventListener('keydown', validateInput, false);
});
function handleTextInput(event) {
const { value } = event.target;
if (value) {
enableSubmitButton(true);
} else {
enableSubmitButton(false);
}
}
// Refer to https://stackoverflow.com/a/46203928/7583537
function validateInput(event) {
const regex = /^\d*(\.\d{0,2})?$/g;
const prevVal = event.target.value;
const input = this;
setTimeout(function() {
var nextVal = event.target.value;
if (!regex.test(nextVal)) {
input.value = prevVal;
}
}, 0);
}
function enableSubmitButton(isEnable) {
const button = document.getElementById('mapOneSubmit');
if (isEnable) {
button.removeAttribute('disabled');
} else {
button.setAttribute('disabled', '');
}
}
<input type="number" value="" id="mapOneUserInput">
<!-- Note that the input blank at render so we disable submit button -->
<input type="submit" id="mapOneSubmit" value="Submit" disabled>

How do I change a "button" button to a "submit" button onclick without submitting after the onclick event is completed?

I have a button that, when clicked, prompts the user for more info dynamically through an onclick JavaScript function:
<button type="button" id="create" onclick="addFields()">create?</button>
Once new info has been loaded into the page, I want the button to submit the form:
// .js file
function addFields(){
var container = document.getElementById("initialinfo");
var newInfo = document.createElement('div');
newInfo.setAttribute("id", "createDetails");
newInfo.innerHTML += "divs and checkboxes and radios"
container.appendChild(newInfo);
document.getElementById("create").removeAttribute("onclick");
document.getElementById("create").setAttribute('type', 'submit');
}
Unfortunately, when I do this, the form doesn't submit on the next click. Instead, after the onclick event, the button (which is now of type submit) submits the form. How do I prevent this behavior?
Prevent Default
The Event interface's preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be.
<form id="my-form">
<input id="first-field" type="text"/>
<input id="second-field" class="hidden" type="text"/>
<button type="submit" id="submit">
<span class="continue">Continue</span>
<span class="submit hidden">Submit</span>
</button>
</form>
.hidden {
display: none;
}
let allFieldsShown = false;
const myForm = document.querySelector('#my-form'),
secondField = myForm.querySelector('#second-field),
continueText = myForm.querySelector('span.continue'),
submitText = myForm.querySelector('span.submit');
myForm.addEventListener('submit', submitHandler);
function submitHandler(e) {
if (!allFieldsShown) {
e.preventDefault();
showNode(secondField);
hideNode(continueText);
showNode(submitText);
allFieldsShown = true;
}
}
function showNode(node) {
if (node.classList.contains('hidden')) {
node.classList.remove('hidden');
}
}
function hideNode(node) {
node.classList.add('hidden');
}
You can trigger the form programmatically on your second button click
<form id="myForm" action="..." >
<button type="button" onclick="addFields(event)">continue?</button>
</form>
function addFields({target}){
var container = document.getElementById("initialinfo");
var newInfo = document.createElement('div');
newInfo.setAttribute("id", "createDetails");
newInfo.innerHTML += "divs and checkboxes and radios"
container.appendChild(newInfo);
// here we change the onclick event handler
target.onclick = () => {
const form = document.getElementById('myForm')
form.reportValidity() && form.submit()
}
}
Firstly you put button type submit first and call function through onclick.
Browser will get function definition first then it will submit form
<button type="submit" id="continue" onclick="addFields()">Continue></button>

Unable to get the value of the clicked button when two button elements shared the same name [duplicate]

I have a .submit() event set up for form submission. I also have multiple forms on the page, but just one here for this example. I'd like to know which submit button was clicked without applying a .click() event to each one.
Here's the setup:
<html>
<head>
<title>jQuery research: forms</title>
<script type='text/javascript' src='../jquery-1.5.2.min.js'></script>
<script type='text/javascript' language='javascript'>
$(document).ready(function(){
$('form[name="testform"]').submit( function(event){ process_form_submission(event); } );
});
function process_form_submission( event ) {
event.preventDefault();
//var target = $(event.target);
var me = event.currentTarget;
var data = me.data.value;
var which_button = '?'; // <-- this is what I want to know
alert( 'data: ' + data + ', button: ' + which_button );
}
</script>
</head>
<body>
<h2>Here's my form:</h2>
<form action='nothing' method='post' name='testform'>
<input type='hidden' name='data' value='blahdatayadda' />
<input type='submit' name='name1' value='value1' />
<input type='submit' name='name2' value='value2' />
</form>
</body>
</html>
Live example on jsfiddle
Besides applying a .click() event on each button, is there a way to determine which submit button was clicked?
I asked this same question: How can I get the button that caused the submit from the form submit event?
I ended up coming up with this solution and it worked pretty well:
$(document).ready(function() {
$("form").submit(function() {
var val = $("input[type=submit][clicked=true]").val();
// DO WORK
});
$("form input[type=submit]").click(function() {
$("input[type=submit]", $(this).parents("form")).removeAttr("clicked");
$(this).attr("clicked", "true");
});
});
In your case with multiple forms you may need to tweak this a bit but it should still apply
I found that this worked.
$(document).ready(function() {
$( "form" ).submit(function () {
// Get the submit button element
var btn = $(this).find("input[type=submit]:focus" );
});
}
This works for me:
$("form").submit(function() {
// Print the value of the button that was clicked
console.log($(document.activeElement).val());
}
When the form is submitted:
document.activeElement will give you the submit button that was clicked.
document.activeElement.getAttribute('value') will give you that button's value.
Note that if the form is submitted by hitting the Enter key, then document.activeElement will be whichever form input that was focused at the time. If this wasn't a submit button then in this case it may be that there is no "button that was clicked."
There is a native property, submitter, on the SubmitEvent interface.
Standard Web API:
var btnClicked = event.submitter;
jQuery:
var btnClicked = event.originalEvent.submitter;
Here's the approach that seems cleaner for my purposes.
First, for any and all forms:
$('form').click(function(event) {
$(this).data('clicked',$(event.target))
});
When this click event is fired for a form, it simply records the originating target (available in the event object) to be accessed later. This is a pretty broad stroke, as it will fire for any click anywhere on the form. Optimization comments are welcome, but I suspect it will never cause noticeable issues.
Then, in $('form').submit(), you can inquire what was last clicked, with something like
if ($(this).data('clicked').is('[name=no_ajax]')) xhr.abort();
Wow, some solutions can get complicated! If you don't mind using a simple global, just take advantage of the fact that the input button click event fires first. One could further filter the $('input') selector for one of many forms by using $('#myForm input').
$(document).ready(function(){
var clkBtn = "";
$('input[type="submit"]').click(function(evt) {
clkBtn = evt.target.id;
});
$("#myForm").submit(function(evt) {
var btnID = clkBtn;
alert("form submitted; button id=" + btnID);
});
});
I have found the best solution is
$(document.activeElement).attr('id')
This not only works on inputs, but it also works on button tags.
Also it gets the id of the button.
Another possible solution is to add a hidden field in your form:
<input type="hidden" id="btaction"/>
Then in the ready function add functions to record what key was pressed:
$('form#myForm #btnSubmit').click(function() {
$('form#myForm #btaction').val(0);
});
$('form#myForm #btnSubmitAndSend').click(function() {
$('form#myForm #btaction').val(1);
});
$('form#myForm #btnDelete').click(function() {
$('form#myForm #btaction').val(2);
});
Now in the form submition handler read the hidden variable and decide based on it:
var act = $('form#myForm #btaction').val();
Building on what Stan and yann-h did but this one defaults to the first button. The beauty of this overall approach is that it picks up both the click and the enter key (even if the focus was not on the button. If you need to allow enter in the form, then just respond to this when a button is focused (i.e. Stan's answer). In my case, I wanted to allow enter to submit the form even if the user's current focus was on the text box.
I was also using a 'name' attribute rather than 'id' but this is the same approach.
var pressedButtonName =
typeof $(":input[type=submit]:focus")[0] === "undefined" ?
$(":input[type=submit]:first")[0].name :
$(":input[type=submit]:focus")[0].name;
This one worked for me
$('#Form').submit(function(){
var btn= $(this).find("input[type=submit]:focus").val();
alert('you have clicked '+ btn);
}
Here is my solution:
$('#form').submit(function(e){
console.log($('#'+e.originalEvent.submitter.id));
e.preventDefault();
});
If what you mean by not adding a .click event is that you don't want to have separate handlers for those events, you could handle all clicks (submits) in one function:
$(document).ready(function(){
$('input[type="submit"]').click( function(event){ process_form_submission(event); } );
});
function process_form_submission( event ) {
event.preventDefault();
//var target = $(event.target);
var input = $(event.currentTarget);
var which_button = event.currentTarget.value;
var data = input.parents("form")[0].data.value;
// var which_button = '?'; // <-- this is what I want to know
alert( 'data: ' + data + ', button: ' + which_button );
}
As I can't comment on the accepted answer, I bring here a modified version that should take into account elements that are outside the form (ie: attached to the form using the form attribute). This is for modern browser: http://caniuse.com/#feat=form-attribute . The closest('form') is used as a fallback for unsupported form attribute
$(document).on('click', '[type=submit]', function() {
var form = $(this).prop('form') || $(this).closest('form')[0];
$(form.elements).filter('[type=submit]').removeAttr('clicked')
$(this).attr('clicked', true);
});
$('form').on('submit', function() {
var submitter = $(this.elements).filter('[clicked]');
})
You can simply get the event object when you submit the form. From that, get the submitter object. As below:
$(".review-form").submit(function (e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
let submitter_btn = $(e.originalEvent.submitter);
console.log(submitter_btn.attr("name"));
}
In case you want to send this form to the backend, you can create a new form element by new FormData() and set the key-value pair for which button was pressed, then access it in the backend. Something like this -
$(".review-form").submit(function (e) {
e.preventDefault(); // avoid to execute the actual submit of the form.
let form = $(this);
let newForm = new FormData($(form)[0]);
let submitter_btn = $(e.originalEvent.submitter);
console.log(submitter_btn.attr("name"));
if (submitter_btn.attr("name") == "approve_btn") {
newForm.set("action_for", submitter_btn.attr("name"));
} else if (submitter_btn.attr("name") == "reject_btn") {
newForm.set("action_for", submitter_btn.attr("name"));
} else {
console.log("there is some error!");
return;
}
}
I was basically trying to have a form where user can either approve or disapprove/ reject a product for further processes in a task.
My HTML form is something like this -
<form method="POST" action="{% url 'tasks:review-task' taskid=product.task_id.id %}"
class="review-form">
{% csrf_token %}
<input type="hidden" name="product_id" value="{{product.product_id}}" />
<input type="hidden" name="task_id" value="{{product.task_id_id}}" />
<button type="submit" name="approve_btn" class="btn btn-link" id="approve-btn">
<i class="fa fa-check" style="color: rgb(63, 245, 63);"></i>
</button>
<button type="submit" name="reject_btn" class="btn btn-link" id="reject-btn">
<i class="fa fa-times" style="color: red;"></i>
</button>
</form>
Let me know if you have any doubts.
Try this:
$(document).ready(function(){
$('form[name="testform"]').submit( function(event){
// This is the ID of the clicked button
var clicked_button_id = event.originalEvent.submitter.id;
});
});
$("form input[type=submit]").click(function() {
$("<input />")
.attr('type', 'hidden')
.attr('name', $(this).attr('name'))
.attr('value', $(this).attr('value'))
.appendTo(this)
});
add hidden field
For me, the best solutions was this:
$(form).submit(function(e){
// Get the button that was clicked
var submit = $(this.id).context.activeElement;
// You can get its name like this
alert(submit.name)
// You can get its attributes like this too
alert($(submit).attr('class'))
});
Working with this excellent answer, you can check the active element (the button), append a hidden input to the form, and optionally remove it at the end of the submit handler.
$('form.form-js').submit(function(event){
var frm = $(this);
var btn = $(document.activeElement);
if(
btn.length &&
frm.has(btn) &&
btn.is('button[type="submit"], input[type="submit"], input[type="image"]') &&
btn.is('[name]')
){
frm.append('<input type="hidden" id="form-js-temp" name="' + btn.attr('name') + '" value="' + btn.val() + '">');
}
// Handle the form submit here
$('#form-js-temp').remove();
});
Side note: I personally add the class form-js on all forms that are submitted via JavaScript.
Similar to Stan answer but :
if you have more than one button, you have to get only the
first button => [0]
if the form can be submitted with the enter key, you have to manage a default => myDefaultButtonId
$(document).on('submit', function(event) {
event.preventDefault();
var pressedButtonId =
typeof $(":input[type=submit]:focus")[0] === "undefined" ?
"myDefaultButtonId" :
$(":input[type=submit]:focus")[0].id;
...
}
This is the solution used by me and work very well:
// prevent enter key on some elements to prevent to submit the form
function stopRKey(evt) {
evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
var alloved_enter_on_type = ['textarea'];
if ((evt.keyCode == 13) && ((node.id == "") || ($.inArray(node.type, alloved_enter_on_type) < 0))) {
return false;
}
}
$(document).ready(function() {
document.onkeypress = stopRKey;
// catch the id of submit button and store-it to the form
$("form").each(function() {
var that = $(this);
// define context and reference
/* for each of the submit-inputs - in each of the forms on
the page - assign click and keypress event */
$("input:submit,button", that).bind("click keypress", function(e) {
// store the id of the submit-input on it's enclosing form
that.data("callerid", this.id);
});
});
$("#form1").submit(function(e) {
var origin_id = $(e.target).data("callerid");
alert(origin_id);
e.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<form id="form1" name="form1" action="" method="post">
<input type="text" name="text1" />
<input type="submit" id="button1" value="Submit1" name="button1" />
<button type="submit" id="button2" name="button2">
Submit2
</button>
<input type="submit" id="button3" value="Submit3" name="button3" />
</form>
This works for me to get the active button
var val = document.activeElement.textContent;
It helped me https://stackoverflow.com/a/17805011/1029257
Form submited only after submit button was clicked.
var theBtn = $(':focus');
if(theBtn.is(':submit'))
{
// ....
return true;
}
return false;
I was able to use jQuery originalEvent.submitter on Chrome with an ASP.Net Core web app:
My .cshtml form:
<div class="form-group" id="buttons_grp">
<button type="submit" name="submitButton" value="Approve" class="btn btn-success">Approve</button>
<button type="submit" name="submitButton" value="Reject" class="btn btn-danger">Reject</button>
<button type="submit" name="submitButton" value="Save" class="btn btn-primary">Save</button>
...
The jQuery submit handler:
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
$(document).ready(function() {
...
// Ensure that we log an explanatory comment if "Reject"
$('#update_task_form').on('submit', function (e) {
let text = e.originalEvent.submitter.textContent;
if (text == "Reject") {
// Do stuff...
}
});
...
The jQuery Microsoft bundled with my ASP.Net Core environment is v3.3.1.
Let's say I have these "submit" buttons:
<button type="submit" name="submitButton" id="update" value="UpdateRecord" class="btn btn-primary">Update Record</button>
<button type="submit" name="submitButton" id="review_info" value="ReviewInfo" class="btn btn-warning sme_only">Review Info</button>
<button type="submit" name="submitButton" id="need_more_info" value="NeedMoreInfo" class="btn btn-warning sme_only">Need More Info</button>
And this "submit" event handler:
$('#my_form').on('submit', function (e) {
let x1 = $(this).find("input[type=submit]:focus");
let x2 = e.originalEvent.submitter.textContent;
Either expression works. If I click the first button, both "x1" and "x2" return Update Record.
I also made a solution, and it works quite well:
It uses jQuery and CSS
First, I made a quick CSS class, this can be embedded or in a seperate file.
<style type='text/css'>
.Clicked {
/*No Attributes*/
}
</style>
Next, On the click event of a button within the form,add the CSS class to the button. If the button already has the CSS class, remove it. (We don't want two CSS classes [Just in case]).
// Adds a CSS Class to the Button That Has Been Clicked.
$("form :input[type='submit']").click(function ()
{
if ($(this).hasClass("Clicked"))
{
$(this).removeClass("Clicked");
}
$(this).addClass("Clicked");
});
Now, test the button to see it has the CSS class, if the tested button doesn't have the CSS, then the other button will.
// On Form Submit
$("form").submit(function ()
{
// Test Which Button Has the Class
if ($("input[name='name1']").hasClass("Clicked"))
{
// Button 'name1' has been clicked.
}
else
{
// Button 'name2' has been clicked.
}
});
Hope this helps!
Cheers!
You can create input type="hidden" as holder for a button id information.
<input type="hidden" name="button" id="button">
<input type="submit" onClick="document.form_name.button.value = 1;" value="Do something" name="do_something">
In this case form passes value "1" (id of your button) on submit. This works if onClick occurs before submit (?), what I am not sure if it is always true.
A simple way to distinguish which <button> or <input type="button"...> is pressed, is by checking their 'id':
$("button").click(function() {
var id = $(this).attr('id');
...
});
Here is a sample, that uses this.form to get the correct form the submit is into, and data fields to store the last clicked/focused element. I also wrapped submit code inside a timeout to be sure click events happen before it is executed (some users reported in comments that on Chrome sometimes a click event is fired after a submit).
Works when navigating both with keys and with mouse/fingers without counting on browsers to send a click event on RETURN key (doesn't hurt though), I added an event handler for focus events for buttons and fields.
You might add buttons of type="submit" to the items that save themselves when clicked.
In the demo I set a red border to show the selected item and an alert that shows name and value/label.
Here is the FIDDLE
And here is the (same) code:
Javascript:
$("form").submit(function(e) {
e.preventDefault();
// Use this for rare/buggy cases when click event is sent after submit
setTimeout(function() {
var $this=$(this);
var lastFocus = $this.data("lastFocus");
var $defaultSubmit=null;
if(lastFocus) $defaultSubmit=$(lastFocus);
if(!$defaultSubmit || !$defaultSubmit.is("input[type=submit]")) {
// If for some reason we don't have a submit, find one (the first)
$defaultSubmit=$(this).find("input[type=submit]").first();
}
if($defaultSubmit) {
var submitName=$defaultSubmit.attr("name");
var submitLabel=$defaultSubmit.val();
// Just a demo, set hilite and alert
doSomethingWith($defaultSubmit);
setTimeout(function() {alert("Submitted "+submitName+": '"+submitLabel+"'")},1000);
} else {
// There were no submit in the form
}
}.bind(this),0);
});
$("form input").focus(function() {
$(this.form).data("lastFocus", this);
});
$("form input").click(function() {
$(this.form).data("lastFocus", this);
});
// Just a demo, setting hilite
function doSomethingWith($aSelectedEl) {
$aSelectedEl.css({"border":"4px solid red"});
setTimeout(function() { $aSelectedEl.removeAttr("style"); },1000);
}
DUMMY HTML:
<form>
<input type="text" name="testtextortexttest" value="Whatever you write, sir."/>
<input type="text" name="moretesttextormoretexttest" value="Whatever you write, again, sir."/>
<input type="submit" name="test1" value="Action 1"/>
<input type="submit" name="test2" value="Action 2"/>
<input type="submit" name="test3" value="Action 3"/>
<input type="submit" name="test4" value="Action 4"/>
<input type="submit" name="test5" value="Action 5"/>
</form>
DUMB CSS:
input {display:block}
I write this function that helps me
var PupulateFormData= function (elem) {
var arr = {};
$(elem).find("input[name],select[name],button[name]:focus,input[type='submit']:focus").each(function () {
arr[$(this).attr("name")] = $(this).val();
});
return arr;
};
and then Use
var data= PupulateFormData($("form"));

enable buttons in javascript/jquery based on regex match

I'm having trouble getting the match to bind to the oninput property of my text input. Basically I want my submit button to be enabled only when the regular expression is matched. If the regex isn't matched, a message should be displayed when the cursor is over the submit button. As it stands, typing abc doesn't enable the submit button as I want it to. Can anyone tell me what I'm doing wrong? Thank you.
<div id="message">
</div>
<form method="POST">
<input type="text" id="txt" oninput="match()" />
<input type="submit" id="enter" value="enter" disabled />
</form>
<script>
var txt = $("#txt").value();
var PATTERN = /abc/;
var REQUIREMENTS = "valid entries must contain the string 'abc'";
// disable buttons with custom jquery function
jQuery.fn.extend({
disable: function(state) {
return this.each(function() {
this.disabled = state;
});
}
});
$('input[type="submit"]).disable(true);
var match = function(){
if (txt.match(PATTERN)){
$("#enter").disable(false)
}
else if ($("#enter").hover()){
function(){
$("#message").text(REQUIREMENTS);
}
}
</script>
Your code would be rewrite using plain/vanille JavaScript.
So your code is more clean and better performance:
<div id="message"></div>
<form method="POST">
<input type="text" id="txt" oninput="match()" />
<input type="submit" id="enter" value="enter" disabled />
</form>
<script>
var txt;
var enter = document.getElementById('enter');
var message = document.getElementById('message');
var PATTERN = /abc/;
var REQUIREMENTS = "valid entries must contain the string 'abc'";
function match() {
txt = document.getElementById('txt').value;
if (PATTERN.test(txt)) {
enter.disabled = false;
} else if (isHover(enter)) {
enter.disabled = true;
message.innerHTML = REQUIREMENTS;
} else {
enter.disabled = true;
}
}
function isHover(e) {
return (e.parentElement.querySelector(':hover') === e);
}
</script>
If you wanted to say that you want handle the events in different moments, your code should be the following.
Note: the buttons when are disabled doesn't fired events so, the solution is wrapper in a div element which fired the events. Your code JavaScript is more simple, although the code HTML is a bit more dirty.
<form method="POST">
<input type="text" id="txt" oninput="match()" />
<div style="display: inline-block; position: relative">
<input type="submit" id="enter" value="enter" disabled />
<div id="buttonMouseCatcher" onmouseover="showText(true)" onmouseout="showText(false)" style="position:absolute; z-index: 1;
top: 0px; bottom: 0px; left: 0px; right: 0px;">
</div>
</div>
<script>
var txt;
var enter = document.getElementById('enter');
var message = document.getElementById('message');
var PATTERN = /abc/;
var REQUIREMENTS = "valid entries must contain the string 'abc'";
function match() {
txt = document.getElementById('txt').value;
if (PATTERN.test(txt)) {
enter.disabled = '';
} else {
enter.disabled = true;
}
}
function showText(option) {
message.innerHTML = option ? REQUIREMENTS : "";
}
</script>
Two problems here:
The variable txt is defined once outside the function match, so the value is fixed to whatever the input with id txt has when the script/page is loaded.
You should move var txt = $("#txt").val(); into the match function.
Notice I changed the function value() to val().
Problems identified:
jQuery events don't happen on disabled inputs: see Event on a disabled input
I can't fix jQuery, but I can simulate a disabled button without it actually being disabled. There's other hacks you could do to get around this as well, for example, by overlaying a transparent element which actually captures the hover event while the button is disabled.
Various syntactical errors: format your code and read the console messages
.hover()){ function() { ... } } is invalid. It should be .hover(function() { ... })
else doesn't need to be followed by an if if there's no condition
.hover( handlerIn, handlerOut ) actually takes 2 arguments, each of type Function
$('input[type="submit"]) is missing a close '
Problems identified by #Will
The jQuery function to get the value of selected input elements is val()
val() should be called each time since you want the latest updated value, not the value when the page first loaded
Design issues
You don't revalidate once you enable input. If I enter "abc" and then delete the "c", the submit button stays enabled
You never hide the help message after you're done hovering. It just stays there since you set the text but never remove it.
https://jsfiddle.net/Lh4r1qhv/12/
<div id="message" style="visibility: hidden;">valid entries must contain the string 'abc'</div>
<form method="POST">
<input type="text" id="txt" />
<input type="submit" id="enter" value="enter" style="color: grey;" />
</form>
<script>
var PATTERN = /abc/;
$("#enter").hover(
function() {
$("#message").css('visibility', $("#txt").val().match(PATTERN) ? 'hidden' : 'visible');
},
$.prototype.css.bind($("#message"), 'visibility', 'hidden')
);
$('form').submit(function() {
return !!$("#txt").val().match(PATTERN);
});
$('#txt').on('input', function() {
$("#enter").css('color', $("#txt").val().match(PATTERN) ? 'black' : 'grey');
});
</script>

Categories

Resources