Ajax form submit. form submitted twice - ajax

I am working with cakePHP and in my view I have a form which has an ajax submit button. I rendered it using the cake helpers.
<form method="post" class="form-class" id="form-id" name="form1" style="display: none">
*[content for the form]*
<?php
echo $ajax->submit('Ok',
array(
'id'=> 'submit1',
'url'=> array('controller'=>'c','action'=>'action1'),
'complete'=> 'jsfunction()'
));
echo $form->button('Submit',array('id'=>'cancel','value'=>'Cancel','onClick'=>'clickCancel()'));
?>
</form>
When I click submit, the controller action is called twice. I searched stackOverlow if this question existed but couldn't find a valid solution. There are no syntax errors.
Help will be really appreciated. Thanks.

It sounds like the ajax event handlers aren't blocking the default behaviour.
Try setting the form's onsubmit behaviour inline to prevent it (as cake's helper does):
<form onsubmit="event.returnValue = false; return false;" method="post" class="form-class" id="form-id" name="form1" style="display: none">
I recommend checking out the FormHelper for some useful shortcuts around this.

This is the auto generated code:
$("#submit1367508668").bind('click', function(){
$.ajax({
async:true,
type:'post',
complete:function(request, json) {
getServerResponse(request)
},
url:'/recipients/add',
dataType:'json',
data:$(this).parents('form:first').serialize()});
blockUI();
})

Related

Play framework write Action with Ok(...) that doesn't load new page

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

Cross Domain Ajax Issue

I have two files
1) index.php(picks data from the code editor and submits for processing via Jquery Ajax to exec.php)
2) exec.php (currently just transfer the data it recieved via index.php using jsonp)
Code of index.php
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
function test() {
var code = document.getElementById('code').value;
var code_data = "code=" + code;
alert(code_data);
$.ajax({
type: "POST",
crossDomain: true,
url: "http://code1.guru99.com/exec.php",
data: code_data,
dataType: "jsonp",
success: function (data) {
alert(data);
}
});
alert("End of Test");
}
</script>
<form name="myform" id="myform" method="POST" class="code-box">
<textarea name="code" id="code"><?
$code='<?php
"Hello";
?>';
echo $code;
?>
</textarea> <!-- for add html tag in text area nad print the code-->
<div class="hint">This code is editable. Click Run to execute.</div>
<input type="submit" value="Run" id="submit" onClick="test();"><!--<img id="ajax-loader" name="ajax-loader" src="/img/ajax-loader.gif" class="hidden" style="vertical-align:middle" />-->
</form>
<div name="label" id="label"> </div>
<div name="out" id="out"> </div>
Code of exec.php
<?php
$code=$_POST['code'];
$fp=fopen("file.txt","w"); // Storing the data into a file just to know that data is passed
fwrite($fp,$code);
fclose($fp);
header('Content-Type: application/jsonp');
echo $_GET['callback']."(".json_encode($code).");"
?>
The problem is data just does not pass into exec.php. I am not sure why...
The code is live at http://code.guru99.com/php/
Please help...
You cannot use AJAX to do this. Instead consider posting from a hidden Iframe using a regular FORM and setting the action to the URL you desire. You can still submit the form using JavaScript.
You can also listen to the onload event on the iframe to detect when your post has completed.
Alternately, you can use a server-side proxy.
The code syntax is correct.
May the problem could be with your server

jQuery Mobile avoid changePage() in ajax form submit

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
});

Ajax form perfect until inside another page

I have a page which uses ajax to submit a comment form, add it to a db, then redisplay the page, hopefully without reloading the page its on.
If I access the script on it's own it works great, yet when I load it into another page it doesn't add the data and also refreshes the page on submit, which I want to avoid, which is the whole point of doing things this way.
Anyway, here's how I load the page:
<div id="wall_comments" class="msgs_holder"></div>
<script type="text/javascript">
$('#wall_comments').load('/pages/comment.php', { wl_id:"<?=$wl_id?>" });
</script>
and then the page itself with jquery code:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<div style="width:100%; overflow:auto;">
<form method=post>
<input type="text" class="inp" name="comment" id="comment">
<input type=submit value="do it" name="action" onclick="update()">
<input type=hidden name="wl_id" value="<?=$_REQUEST[wl_id]?>" id="wl_id">
<input type=hidden name="user_id" value="<?=$userfromcookie?>" id="user_id">
</form>
</div>
<script type="text/javascript">
function update(){
var wl_idVal = $("#wl_id").val();
var commentVal = $("#comment").val();
var user_idVal = $("#user_id").val();
$.ajax({
type: "POST",
url: "/pages/comment.php",
cache: false,
data: { submit: "", wl_id: wi_idVal, comment: commentVal, user_id: user_idVal }
});
}
</script>
And finally enter info into db (I know this should be mysqli and it will be)
if(isset($_POST['action'])){
$wl_id = mysql_real_escape_string($_POST['wl_id']);
$comment = mysql_real_escape_string($_POST['comment']);
$user_id = mysql_real_escape_string($_POST['user_id']);
$addcomment = mysql_query("insert into list_wall (
event_id,
user_id,
comment
) VALUES (
'$wl_id',
'$user_id',
'$comment'
) ",$db);
if(!$addcomment) { echo 'result error add comment'; echo mysql_error(); exit; } // debug
}
The problem is when you click the submit button, the page is submitted and the function update couldn't work. You have to cancel the default submit mechanism by using return false;
<input type=submit value="do it" name="action" onclick="update() return false;">
Another thing.
The onclick on the submitbutton will not work as excpected if the submit is caused without clicking the button.
For example mobile safari on iPhone can submit forms directly without triggering the button.
If you add UmairP's version of the onclick to the form element as an onsubmit method you should get the same result on every platform as far as I know.
You can see more details on iPhone forms in my own question on another issue.
How can I prevent the Go button on iPad/iPhone from posting the form

Suggest an AJAX solution to form submission without reloading page, with action="" instead of action="response.php"

I have a search page: (please excuse the bad syntax, just for demo purposes)
<form action="" method="post" name="form">
//form elements and such with a hidden input name="action" value="search"
</form>
<?php if(isset($_POST['action']) and $_POST['action'] == 'search'): ?>
<?php include results.php ?> //takes form data, build SQL query, puts results in array
<?php foreach($results as result) blah blah //for each result display it ?>
<?php endforeach; ?>
<?php endif; ?>
I've seen solutions where the action attribute is set to a php file. Unfortunately in my example it doesn't have one. Take this one: http://www.simonerodriguez.com/ajax-form-submit-example/
<form name="MyForm" action="response_ajax.php" method="post" onsubmit="xmlhttpPost('response_ajax.php, 'MyForm', 'MyResult', '<img src=\'pleasewait.gif\'>'); return false;">
It looks nice but unfortunately I don't have the first parameter required: reqsponse_ajax.php, mine is just blank.
The JS can be found here: http://www.simonerodriguez.com/wp-content/plugins/downloads-manager/upload/ajaxsbmt.js
If anyone can make modifications to the script or suggest a better solution, that'll be awesome, thanks.
it shouldn't matter at all what's in the action attribute when you're using AJAX. it's the onsubmit or the submit button's onclick attribute that starts the AJAX processing.
you do understand the basics of AJAX, right? instead of actually submitting the form, which would load a new page, you send an XMLHttpRequest to the server, POSTing the data, and wait for an answer back with onreadystatechange, at which point you dynamically update your page. there are literally hundreds if not thousands of examples of this on the web.

Resources