I am using laravel and sammy.js for my application. My login form looks like this:
<form action="#/login" method="post">
<!-- inputs -->
</form>
Now, sammy.js catches it like this:
this.post('#/login',function(){
//handle, send to laravel for login
});
My problem is that if I press the enter key, apparently instead of submitting the form, which would result in this.post('#/login') event to be catched and the function to be executed, an HTTP request is already made, and the laravel route is requested. As the route does not exist, a MethodNotAllowedHttpException is thown.
Now, the question is: why does this happen? While pressing the "submit" button makes the login, hitting the enter key results in the error above.
I would like an actual solution to the problem, as well as an explanation of it, not patches like e.preventDefault() on keypress or return false in js.
Note: sammy is initialized correctly, the form is in the container on which sammy works and submitting using the enter key used to work in a previous version of the site. A lot has changed by now, so reverting is not a good option, so I would like an actual suggestion on how to solve the problem.
Thanks
citing section 4.10.22.2 Implicit submission in the Html5 specification:
User agents may establish a button in each form as being the form's
default button. This should be the first submit button in tree order
whose form owner is that form element, but user agents may pick
another button if another would be more appropriate for the platform.
If the platform supports letting the user submit a form implicitly
(for example, on some platforms hitting the "enter" key while a text
field is focused implicitly submits the form), then doing so must
cause the form's default button's activation behavior, if any, to be
run.
In a nutshell, hitting the Enter key will always submit the form (issue an Http request) regardless of SammyJs. Note that the enter key will submit the form even if there's not Submit button!
Are you returning false from the #/login Sammy route?
Related
I'm having trouble understanding what the form action is used for. It seems like I can handle form data with a Javascript function by setting the onsubmit value to that function. I'm seeing a lot of different examples online that are confusing me even more.
Can someone walk me through what this will do and maybe give me an example of what the form action could do that "onsubmit" can't or shouldn't?
<form onsubmit="someFunction()" action="???"> ... </form>
A user will enter information into the form, then they hit a button to "submit" that information. someFunction() will do stuff with that information... then, the form action is responsible for what? I've seen some examples that look like it just specifies a URL to a page telling the user something like "Thanks for submitting".
I'm sorry if this is confusing. I'm not sure how to ask what I'm confused about. I'm looking for a really simple answer that you might give to a child about what that line of code means for the user and also for the information that was entered into the form.
The difference here is subtle but important:
onsubmit is an event attribute, meaning whatever JS is in it will be called on the submit event.
action tells the browser where to send the contents of the form when it is submitted in either a GET or POST request (POST by default, unless specified otherwise by the method attribute), then reloads the page with the result of the request it sent.
The action attribute is less customizable because it won't run any of your custom JavaScript, all it will do is send the data to your backend. On the other hand, onsubmit runs your custom JavaScript, which can do whatever you want (including sending data to your backend). If all you need to do is run some client-side JavaScript when the form submits, use onsubmit. If all you need to do send data to the server when a form submits, use action.
Generally, you don't want to use both at the same time because if action sends data to your backend, then your page will reload. In fact, even if you don't specify an action attribute, then the page will still reload because it is the default behavior. When using the onsubmit attribute to run JavaScript when a form is submitted, you'll need to override this default behavior with event.preventDefault(), hence why most onsubmit handlers look like this:
function onsubmitHandler(event) {
event.preventDefault()
// ... rest of the code ...
}
onsubmit() function needed to handle the form submit in JavaScript. When we add the URL in action attribute, we can't handle the form data in JavaScript. In this case, we can't validate the form data, so the empty data is sent to the server. This will increase server load and it's really bad.
Correct me if I'm wrong,
but basically the "_token" insert by laravel in each form as hidden field can't be used to avoid multiple submit of the same form?
Ive tried to compare it with the one stored in Session with the one sent in Post, but its always the same!
I've a page with some form, the controller make a redirect to another page if the store is ok, after if the user hits the backwards button the form is still the same (obviously served by cache browser's) and you can send it, again and again.
I've tried to empty all the field manually but this fail in case of "validation" not passed! Even to me set the "submit" button as "inactive" doesn't work for me. Any suggestion?
I'm trying to understand how this login page works by looking at the source from my browser (Chrome).
The source links to some CSS, pictures, and generic JavaScript libraries. Apart from a little jQuery at the very start (for changing the language), I don't see why the page isn't more than just dead HTML elements.
For example, if I click "LOGIN" with an empty username and password, the message "The username or password you entered is incorrect." appears. But I can't see anywhere in source where such behaviour is defined.
What am I missing?
The activity you are observing is one of the core functions of <form> elements. When a form is submitted, the user's browser is directed to the page defined by the action attribute in the form. In addition to directing the user to this page, all of the inputs included in the form are passed to the web server as variables.
One way of submitting a form is by including an input element of type submit within the form, which is what the web designer has done here. When that submit element is invoked (via a click, for example), the form is submitted.
The message you see is not shown by jQuery / Javascript.
Notice that when you click the "LOGIN" button, the page submits your request.
That means it Server Side code starts to run, code that you cant see.
This Server Side code handles your input and generates the Error Message that you see.
When you click the LOGIN button, the form is submitted to the server,which returns a new HTML containing the message. The logic for that is defined in server-side code, which you can't see from outside. 'View source' will only display what the server outputs.
I think the page is simply refreshing.
You can confirm this by opening the network tab in chrome console and watching it as you submit the empty form.
Thanks to http asset caching, this seems as if the page did not refresh - but chrome's network tab confirms it does.
I have a form which, when submitted, is first validated by a function that is bound to the form's "submit" event. If the validation fails, the submit event has it's default action cancelled via e.preventDefault(). If the form submits correctly the first time, it works. If, however, it experiences a preventDefault then subsequent submissions do not send any form data in the POST request. I analyse this in the Chrome code inspector.
FYI it is a multipart/form-data form.
Is there any reason that the form would ignore all the inputs when submitting?
I found my problem. Form elements that have the "disabled" attribute are not included in submission. I was disabling form elements in order to disallow the user from editing things while waiting for response from the server (it is an asynchronous post to an iframe).
I have a popup which asks the user for login information, which means two input text fields for password and username.
Now as I will be verifying the information using ajax I didn't wrap the elements on a because form always needs a php action, correct? or am I missing something?
So I'd like to know if there is a fancier way to check if the user pressed enter, in order to submit the login information, than checking each time a key is pressed, with keydown, if it's the enter key.
Thanks in advance
You still need a form to wrap your user inputs, and that form still has an action. However, you won't do a full page post. Instead, you'll send an AJAX post. jQuery makes this really easy.
$(function() {
$("#myForm").submit(function () {
var data = $(this).serialize();
var url = $(this).attr("action");
$.post(url, data);
return false;
});
});
Now as I will be verifying the information using ajax I didn't wrap the elements on a because form always needs a php action, correct? or am I missing something?
A form requires an action, it doesn't have to point to a URL that is processed by PHP. There are much nicer languages available (this is subjective).
What you are missing, is a fallback for when the JavaScript isn't run for some reason (such as the file not being downloaded due to a network glitch, the client not supporting JS or having JS, etc). Build on things that work.
So I'd like to know if there is a fancier way to check if the user pressed enter, in order to submit the login information, than checking each time a key is pressed, with keydown, if it's the enter key.
If you build on things that work, then you'll have a form anyway, and can run your JS in the submit handler. Then you don't need to care if the form was submitted by a keypress or a button click.
Add attribute to form
<form onSubmit="call your javascript; return false;"> ...
so when enter, or submit button is pressed your javascript will be called and then you can do what ever you want with your form values. Reutrn false will prevent classic form submit.
I hope this helps