I have a post form, I want the submit to be done in an AJAX way but I don't want the page URL to change.
For example:
<form action="/countries/change_country" data-ajax="true" method="post">
<select name="country_code">
<option value="FR" selected="selected">France</option>
<option value="DE">Germany</option>
</select>
<input type="submit" value="change country" />
</form>
When I click in the change country button the form is sent through AJAX what is nice but the page URL is changed to /countries/change_country what is not nice because this URL doesn't exist in my server which is very picky with HTTP verbs.
I know it is possible to change this default behavior for the whole application but I would like to deactivate the changePage() only for this form.
Submit the form through Javascript/jQuery instead.
First: Disable the default submit-behaviour
$('#form').on('submit', function (e) {
if (e.preventDefault) e.preventDefault();
return false;
});
Second: Serialize the form data with jQuery
var serializedFormData = $('#form').serialize();
Third: Post your form with $.ajax();
$.ajax({
url: '/countries/change_country',
type: 'POST',
data: serializedFormData
});
Related
Play framework 2.4.x. A button is pressed on my home page that executes some code via Ajax, and returns its results beneath the button without loading a new page. The results wait for a user to input some text in a field and press "submit". Those results Look like this:
<li class="item">
<div>
<h3>Email: </h3>
<a>#email.tail.init</a>
<h3>Name: </h3>
<a>#name</a>
</div>
<div>
<h3>Linkedin: </h3>
<form class="linkedinForm" action="#routes.Application.createLinkedin" method="POST">
<input type="number" class="id" name="id" value="#id" readonly>
<input type="text" class="email" name="email" value="#email" />
<input type="text" class="emailsecondary" name="emailsecondary" value="" />
<input type="text" class="name" name="email" value="#name" />
<input type="text" class="linkedin" name="linkedin" value="" />
<input type="submit" value="submit" class="hideme"/>
</form>
</div>
<div>
<form action="#routes.Application.delete(id)" method="POST">
<input type="submit" value="delete" />
</form>
</div>
</li>
Along with some jquery that slides up a li after submission:
$(document).ready(function(){
$(".hideme").click(function(){
$(this).closest('li.item').slideUp();
});
});
However, since a form POST goes inside an Action that must a return an Ok(...) or Redirect(...) I can't get the page to not reload or redirect. Right now my Action looks like this (which doesn't compile):
newLinkedinForm.bindFromRequest.fold(
errors => {
Ok("didnt work" +errors)
},
linkedin => {
addLinkedin(linkedin.id, linkedin.url, linkedin.email, linkedin.emailsecondary, linkedin.name)
if (checkURL(linkedin.url)) {
linkedinParse ! Linkedin(linkedin.id, linkedin.url, linkedin.email, linkedin.emailsecondary, linkedin.name)
Ok(views.html.index)
}else{
Ok(views.html.index)
}
}
)
Is it possible to return Ok(...) without redirecting or reloading? If not how would you do a form POST while staying on the same page?
EDIT: Here is my attempt at handling form submission with jquery so far:
$(document).ready(function(){
$(".linkedinForm").submit(function( event ) {
var formData = {
'id' : $('input[name=id]').val(),
'name' : $('input[name=name]').val(),
'email' : $('input[name=email']).val(),
'emailsecondary' : $('input[name=emailsecondary]').val(),
'url' : $('input[name=url]').val()
};
jsRoutes.controllers.Application.createLinkedin.ajax({
type :'POST',
data : formData
})
.done(function(data) {
console.log(data);
});
.fail(function(data) {
console.log(data);
});
event.preventDefault();
};
});
This is an issue with the browser's behavior on form submission, not any of Play's doing. You can get around it by changing the behavior of the form when the user clicks submit.
You will first want to attach a listener to the form's submission. You can use jQuery for this. Then, in that handler, post the data yourself and call .preventDefault() on the event. Since your javascript is now in charge of the POST, you can process the data yourself and update your page's HTML rather than reloading the page.
What you need is use ajax to submit a form, check this: Submitting HTML form using Jquery AJAX
In your case, you can get the form object via var form = $(this), and then start a ajax with data from the form by form.serialize()
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize(),
success: function (data) {
alert('ok');
}
});
In order to accomplish this task, i had to use play's javascriptRouting
This question's answer helped a lot.
I'm not experienced with jquery so writing that correctly was difficult. For those that find this, here is my final jquery that worked:
$(document).ready(function(){
$("div#results").on("click", ".hideme", function(event) {
var $form = $(this).closest("form");
var id = $form.find("input[name='id']").val();
var name = $form.find("input[name='name']").val();
var email = $form.find("input[name='email']").val();
var emailsecondary = $form.find("input[name='emailsecondary']").val();
var url = $form.find("input[name='url']").val();
$.ajax(jsRoutes.controllers.Application.createLinkedin(id, name, email, emailsecondary, url))
.done(function(data) {
console.log(data);
$form.closest('li.item').slideUp()
})
.fail(function(data) {
console.log(data);
});
});
});
Note that my submit button was class="hideme", the div that gets filled with results from the DB was div#results and the forms were contained within li's that were class="item". So what this jquery is doing is attaching a listener to the static div that is always there:
<div id="results">
It waits for an element with class="hideme" to get clicked. When it gets clicked it grabs the data from the closest form element then sends that data to my controller via ajax. If the send is successful, it takes that form, looks for the closest li and does a .slideUp()
Hope this helps
I'm trying to convert simple forms such as:
<form action="/api.php", method="get">
... radios, checkboxes etc
<input type="submit" value="Submit">
</form>
To perform ajax submission instead of reloading the page when hitting submit using angular.
I plan on removing the submit button and replacing it with a regular button with ng-click="submit()". My submit function would look something like this:
$scope.submit = function() {
$http.get('/api', { params: ??? })
.success(...));
}
However the difficulty I have here is attaching the get params from my form inputs. I'm not sure how to reference them. Would I have to add ng-model to every single input element?
I have a lot of forms that require "converting" and I was wondering what would be the least intrusive way (least changes to markup) to do this? The reason is because a previous developer has left me with a soup of ugly html changing things will be costly.
Yes, its EASY.
html
<form action="/api.php" ng-submit="submit()">
<input type="text" name="name" ng-model="user.name">
<input type="submit" value="Submit">
</form>
js
$scope.submit = function() {
$scope.user = {};
$http({
method: 'GET',
url: '/api.php?name=' + $scope.user.name
}).
success(function(data, status, headers, config) {
console.log(JSON.stringify(data));
});
};
I am trying to take simple text from a form, pass it to my controller via ajax, and have that send to the data base.
View
<form method="POST">
Email: <input type="text" name="email" id="email">
Question: <input type="text" name="qText" id="qText">
<input id="rate" type="submit">
</form>
<script type = "text/javascript">
$(function(){
$("#rate").click(function(){
dataString = $("#email").serialize();
$.ajax({
type: "POST",
url: "<?php echo base_url();?>index.php/trial/insert_into_db",
data: dataString,
});
});
});
</script>
The controller code and the model code work fine. I am almost sure that it is the ajax code that is not working.
Any information would be greatly appreciated!
Thank you.
One thing missing from your posted code is disabling the default form submission. There still could be other issues.
You don't specify an action so by default the action is the same url as the page.
<form method="POST">
You are doing AJAX but you have not disabled the default behavior with return false or event.preventDefault
$("form").submit(function(event) {
event.preventDefault();
// or
return false;
});
I prefer preventDefault() but the point is you need to prevent the default browser behavior.
Edit: This is how I would submit the form with AJAX.
If you had more than one form button to consider then
$("form").submit(function(e) {
e.preventDefault();
});
$("#rate").click(function(e) {
$.ajax({ ... });
});
But it's (marginally) easier to do it with one handler. I'd also stick the action on the form so the form still submits to the correct url if the javascript failed.
<form id="myform" action="<?php echo base_url();?>index.php/trial/insert_into_db" method="post">
Instead of handling the button click handle the form submission
$("#myform").on("submit", function(e) {
e.preventDefault();
var formData = $(this).serialize();
$.ajax({
type = "post",
url = $(this).attr("action"),
data = formData
})
.done(function(result) {
// do something with the response
});
});
I have a simple "login" form and ajax is working. But every time I load the page freshly in new tab, and "login" page loads, I input the username and password, press "login" button and for some reason page just reloads, but on the reloaded page when I press "login" button, ajax works just fine. Anyone know what does this mean?
Here is simple login form:
<form id="login_form" name="login_form" data-ajax="false">
<label for="basic">Username:</label>
<input type="text" name="usr" id="usr" value=""/>
<label for="basic">Password:</label>
<input type="password" name="psw" id="psw" value=""/>
<input type="submit" value="Login" id="login" name="login"/>
<label><input type="checkbox" name="remember_me" id="remember_me" value="checked_remember"/>Remember me!</label>
</form>
<div id="login_message"></div>
And here is my ajax script:
$(document).ready(function(){
$("#login").click(function(){
username=$("#usr").val();
password=$("#psw").val();
$.ajax({
type: "POST",
url: "http://imes.jzpersonal.com/php/login_check.php",
data: "name="+username+"&pwd="+password,
success: function(html){
if(html=='true')
{
$("#login_message").html("Logged in, congratulation.");
}
else
{
$("#login_message").html("Wrong username or password");
}
},
beforeSend:function()
{
$("#login_message").html("Loading...")
}
});
return false;
});
});
Also I'm using POST method but I still get address in address bar like this:
http://imes.**********.com/login_page.php?usr=Jakub&psw=********&login=Login
Is this an jQueryMobile thing?
Reason for this is you cant use $(document).ready(function(){ with jQuery Mobile. You should use :
$(document).on('pageinit'){
});
or if your page has an id then use it like this:
$('#page_id').on('pageinit'){
});
More info about this problem can be found here: http://jquerymobile.com/test/docs/api/events.html
Read this article to find more about this and jQM page events: https://stackoverflow.com/a/14010308/1848600
I can call an AJAX request when a form submit button is clicked, but if the page reloads/redirects due to the form submission, will the AJAX request still complete? I'm asking this so I could do something like upload a file via AJAX as the form is submitted.
I'm pretty sure I can't get the output of the AJAX call, but could I be wrong?
It's possible, but there's no guarantee that the request would have completed by the time you leave the page. If you're submitting a form via AJAX and also want to submit a file, you might consider placing the file upload in a completely separate form tag, then trigger the form submission after the AJAX call is successful. For example:
<!-- First form with your data -->
<form action="/your/url/here" method="post" id="form1">
<input type="text" name="title" />
<input type="submit" value="Save" />
</form>
<!-- Second form with your file -->
<form action="/uploadfile" method="post" id="form2" enctype="multipart/form-data">
<input type="file" name="fileupload" />
</form>
Then in Javascript (using jQuery example for brevity, note I haven't tested this code at all):
$('#form1').bind('submit', function() {
$.ajax({
url: $(this).attr('action'),
data: $(this).serialize(),
type: 'post',
success: function() {
$('#form2').submit();
}
});
return false;
});