I’m using Zend framework (php) and I’m trying to submit a from using ajax/jquery.
Here’s the .phtml:
<form id="find">
<input type="text" name="name">
<input type="submit" id="submit" value="Submit">
</form>
Here’s the ajax/jquery part:
$(document).ready(function() {
$("#submit").click(function(){
$.ajax({
type:'POST',
url: "<?php echo SITE_URL;?>Training/test",
data:$('#find').val(),
success: function(response) {
alert (response);
}
});
});
});
Here, “Training” is the controller and “test” is the action inside the controller. The action has just 1 line of code which is echo “hello”. After the user types a number in the box and clicks on “submit”, the control has to go to the controller thus displaying “hello” on success. However, nothing happens when I click on it. Please help me. Thanks in advance.
You didn't name parametr in Ajax call
data:$('#find').val(),
change it to
data:{'param': $('#find').val()},
About Zend it doesn't matter if it's zend or not. You can handle request just providing proper URL. You can access param value in Zend via $this->getParam('param') method.
Also you don't prevent default submit action. Change your function to:
$("#submit").click(function(ev){
ev.preventDefault();
or use in the end of function return false;
I did not test your jQuery. But note you need the instruction event.preventDefault to ensure you haven't the normal form submit action.
The main problem is at your zend Controller because you need a
special response. I suppose you have a controller to perform the request logics. I'll name it AjaxController and I'll name the action ajaxrecuestAction to illustrate how to send a proper response.
<?php
// Filename: yourProject/module/ModuleName/src/Controller/AjaxController.php
namespace ModuleName\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class AjaxController extends AbstractActionController {
public function ajaxrecuestAction(){
// This function is called by zend to procces your ayax request
// you must test if it's an xmlHttpRequest
$request = $this->getRequest();
$is_xmlHttpRequest = ($request->isXmlHttpRequest()) ? 1 : 0;
if(!$is_xmlHttpRequest){
// If not you must return a normal page, a message page
// perhaps a forgiven message page, etc. It depends on your site
// logics
}else{
// The solution's KEY
// You must disable the zend's normal output
$viewmodel = new ViewModel();
$viewmodel->setTerminal($is_xmlhttprequest);
// Proccess the input and prepare your output
$output = CallTheLogicsToPrepareIt($request->getContent());
// send your response
$response = $this->getResponse();
$response->setContent($output);
return $response;
}
}
**EDIT: Just noted that, in your HTML, you didn't give an ID attribute to the "find" field. Therefore $('#find').val() will give you an error, something like "cannot find method val() of undefined. Add the id=find tag to your and it should work.
** Other Edit: Sorry about the confusion. Your form has id=find but what you want to send to the server (I believe), is the value of the fields. So give an ID=name to your input then use:
var data = {find: $('#name').val()};
You should start by using your console to see if the event is triggered. Something like:
<script>
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
console.log('Hello');
});
});
</script>
(You do use Fire bug or the Chrome dev tools, right) ? If not, look at the end of this post.
If you can see the Hello in your console, you're on the right path. Then try to set your url in a variable and try to check it in your console:
<script>
var url = "<?php echo SITE_URL;?>Training/test";
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
console.log(url);
});
});
</script>
Then you should see the url in the console, meaning you're still doing good.
If that works, try to set the data and check the output in the same way:
<script>
var url = "<?php echo SITE_URL;?>Training/test";
var data = {
find: $('#find').val()
};
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
console.log(data);
});
});
</script>
Hoping everything still works (you saw the data), then try the actual full code and see if you have an error or something. Also, be sure to include an error function to your ajax call so you will have a response if something went wrong on the server.
<script>
var url = "<?php echo SITE_URL;?>Training/test";
$(document).ready(function() {
$("#submit").click(function(e){
e.preventDefault ? e.preventDefault() : e.returnValue = false; //This will prevent the regular submit
var url = "<?php echo SITE_URL;?>Training/test";
var data = {
find: $('#find').val()
};
$.ajax({
type:'POST',
url: url,
data: data,
success: function(response) {
alert (response);
},
error: function(resp) {
alert(resp.responseText);
}
});
});
});
</script>
Some tools to help you out:
If you are using FireFox, use FireBug for your debugging: https://addons.mozilla.org/fr/firefox/addon/firebug/
If you are using Chrome (my personal favorite), learn a bit more about Chrome Developer Tools: https://developers.google.com/chrome-developer-tools/?hl=fr
If you are using IE, please switch to something else for development purposes, then try it in IE to make sure you code is compatible (most likely won't be but it will be easier to find out why it doesn't work afterwards).
As for the line e.preventDefault......, look into this SO post for more details: https://stackoverflow.com/a/15913969/1483513
Hope this helps !
Related
<form>
<input type="text" id="user"/>
<input type="button" value="Submit" onClick="post();" />
</form>
<div id="result"> </div>
<script type="text/javascript">
function post()
{
var username = $('#user').val();
$.post('battlephp.php',
{postuser:user}
)
}
</script>
Its a simple Ajax code.. It should take username and display the Php code!
But don't know why its not running?? Actually I am learning...so I cant rectify the error or fault??
I am running ii on localhost.. so is there any problem with using:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
display the Php code
No, it shouldn't.
First, you've changed your mind about the variable name you are using (user, username) half way through your script, so you are going to throw a reference error.
Second, you haven't provided a function (the third argument) to $.post, so you aren't doing anything (such as displaying it) with the returned data.
Third, the server should execute the PHP and return its output. You shouldn't get the actual PHP code.
function post() {
var username = $('#user').val();
$.post(
'battlephp.php',
{postuser:username}, // Be consistent about your variable names
function (data) {
alert(data);
}
);
}
Instead
document.ready()
you can use
jQuery(function($){...});
Try to do this:
<script>
$(document).ready(function() {
function post() {
var username = $('#user').val();
$.ajax({
type : 'post',
url : 'batttlephp.php',
data : {
postuser : user
},
success : function(data) {
alert(data);
},
error : function(data) {
alert(data);
}
});
});
});
</script>
if you're doing a ajax request then is good also handle success and error...
Also I suggest to you "to start the document".
Try the code above and let us know if worked
My code works fine when I run the php script without ajax as a GET request. I get prompted to download the rendered pdf and all is well. However, I need to use ajax because I need to send more info from an html page to the php script than can be handled in a GET request.
What do I need to put into my ajax to make this work?
Thanks
js
function makePDF()
{
var x;
if(window.event) // IE8 and earlier
{
x=event.keyCode;
}
else if(event.which) // IE9/Firefox/Chrome/Opera/Safari
{
x=event.which;
}
keychar=String.fromCharCode(x);
alert(keychar);
if (keychar == 'p' || keychar == 'P')
{
var charSheetHTML = characterSheet.innerHTML;
$.ajax({
url: 'pdf.php',
data: {'charactersheet': charSheetHTML,},
type: 'post',
success: function (data) {**WHAT_DO_I_PUT_HERE??**},
error: function (data) { alert("error\n" + data.toString()); }
});
}
}
pdf.php
<?php
include_once( "bxcharacter/PDFChar.php.inc" );
PDFChar();
?>
PDFChar.hph.inc
<?php
require_once('./tcpdf/tcpdf.php');
function PDFChar(){
$pdf = new TCPDF();
$pdf->AddPage('P');
$pdf->writeHTML($_POST['charactersheet']);
$pdf->Output("character.pdf", 'D');
}
?>
This is not an ajax solution, but you can send your data with this way and if no error occurs, your page will not change.
Create a form element with inputs hidden which contains your data you want to send:
example format:
<form id="myForm" method="GET" action="pdf.php">
<input type="hidden" name="data1" type="hidden" value="your JSON.stringify() data">
</form>
js code (call these where your ajax request is):
var myForm = '<form id="myForm" method="GET" action="pdf.php">';
myForm += '<input type="hidden" name="data1" type="hidden" value="JSON.stringify() data">';
myForm += '</form>';
$("body").append(myForm); // temporarily appending
$("#myData-form").submit(); // submitting form with data
$("#myData-form").remove(); // remove form after submit
And as you said, force download will force file to download and page will remain same. However, if an error occurs, your page will change of course.
I don't know whether this is an effective way or not but in my case, this does the trick.
Old question, but I was trying to do something similar with Laravel PDF extension, and stumbled across this question. I did successfully do this asynchronously with the help of a nice blog post
https://nehalist.io/downloading-files-from-post-requests/
https://github.com/nehalist/download-post-requests
The using the form method, like the previous answer works fine too, but maybe this will help anyone else trying to achieve this with AJAX. The author's XMLHttpRequest method worked great for me!
The code that worked for me (almost verbatim from the blog post) ->
document.getElementById('exportpdf').addEventListener('click', function () {
var request = new XMLHttpRequest();
request.open('POST', '/your/post/endpoint/here', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.responseType = 'blob';
request.onload = function() {
if(request.status === 200) {
var disposition = request.getResponseHeader('content-disposition');
var matches = /"([^"]*)"/.exec(disposition);
var filename = (matches != null && matches[1] ? matches[1] : 'file.pdf');
var blob = new Blob([request.response], { type: 'application/pdf' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
};
I tried to get it to work with jQuery AJAX but failed, so I went with XMLHttpRequest. With jQuery, The download would work, but the content was always empty. I tried to do something like in this post -
https://keyangxiang.com/2017/09/01/HTML5-XHR-download-binary-content-as-Blob/
$.ajax does not support either arraybuffer or blob as its dataType. Thus we need write a beforeSend handler:
//setup ajax
$.ajaxSetup({
beforeSend:function(jqXHR,settings){
if (settings.dataType === 'binary'){
settings.xhr().responseType='arraybuffer';
settings.processData=false;
}
}
})
//use ajax now
$.ajax({
url:url,
dataType:"binary",
success:function(data){
console.log(data); //ArrayBuffer
console.log(new Blob([data])) // Blob
}
})
But never got it to work. Maybe someone smarter can figure out the jQuery method :)
I have an application that I'm writing that, in one aspect of it, you click on a checkmark to complete a task, a popup window is displayed (using bootstrap), you enter your hours, and then that is sent to a PHP page to update the database. I'm using FF (firebug) to view the post. It's coming up red but not giving me an error. The only thing I'm doing is echoing out "sup" on the PHP page, and it's still showing errors, and I can't figure out why.
This is my initial click function:
$('.complete').on('click', function(event) {
var id = $(this).attr('data-id');
var tr = $(this).parent().parent();
var span = $(tr).children('td.task-name');
var r = (confirm('Are you sure you want to complete this task?'));
if (r){
addHours(id);
} else {
return false;
} // end else
});
That works fine, and it fires my next function which actually fires the bootstrap modal:
function addHours(id) {
var url = 'load/hours.php?id='+id;
$.get(url, function(data) {
$('<div class="modal hide fade in" id="completeTask">' + data + '</div>').modal()
.on('shown', function() {
pendingTask(id);
}); // end callback
}).success(function() {
$('input:text:visible:first').focus();
});
} // end function
This is also working, and the modal is displayed just fine. However, whenever I post the form to my logic page, it fails for no reason. This is the function to post the form to the logic page:
function pendingTask(id) {
$('.addHours').on('click', function(event) {
var formData = $('form#CompleteTask').serializeObject();
$.ajax({
url:'logic/complete-with-hours.php',
type: 'POST',
dataType: 'json',
data: formData,
success: function(data) {
if (data.status == 'error') {
$(this).attr('checked', false);
//location.reload();
} // end if
else {
$(this).attr('checked', true);
//location.reload();
} // end else
},
dataType: 'json'
});
}); // end click
} // end function
When this is fired, I see this in my Firebug console:
I know this is a lot of information, but I wanted to provide as much information as I could. Every other post function in the application is working fine. It's just this one. Any help would be appreciated.
Thanks in advance.
The jQuery.ajax data parameter takes a simple object of key value pairs. The problem could be that the object created by serializeObject() is too complex. If that's the case, you could either process the formData object to simplify it or try data: JSON.stringify(formData)
Does serializeObject() even exist in jQuery? is that a function you wrote yourself? Can you use jQuery functions like serialize() or serializeArray() to serialize the form data and see how it goes.
Usually the red indicates a 404 response error. We can't tell in this screen shot. Check your php code by directly calling the requested page and getting a proper response.
Also make sure your dataType is application/json which is the proper mime type header (though I don't think this is causing the error). You also should only have dataType once (you have it again at the bottom)
I figured it out. I changed the post type from the structure I entered above to a standard post:
$("#CompleteTask").validate({
submitHandler: function(form) {
var hours = $('#hours').val();
$.post('logic/complete-with-hours.php', {'hours': hours, 'id':id},
function(data){
if (data.status == 'success') {
$(checkmark).attr('checked', false);
$('.message').html(data.message).addClass('success').show();
} // end if
if (data.status == 'error') {
$('.message').html(data.message).addClass('error').show();
} // end else
},
"json"
); //end POST
} // end submit handler
}); // end validate
That seemed to do the trick
I just started learning using AJAX with Codeigniter. On my view, I have a textarea and a button which uses AJAX to submit the text in the textarea to my controller, which retrieves data from the database and returns this data to the view. However I am getting the error "disallowed key characters" in the callback function. This happens even when I simply echo a string. What is happening?
Btw, should I use return $result or echo $result in the controller to pass the data back to the webpage?
AJAX
$(function() {
$("#search_button").click(function(e){
e.preventDefault();
var search_location = $("#search_location").val();
$.get('index.php/main/get_places', search_location, function(data){
$("#result").html(data);
console.log(data);
});
});
});
Controller
function get_places($address) {
$search_latlng = $this->geocode_address($address);
$this->load->model('main_model.php');
$result = $this->main_model->get_places($search_latlng);
echo "test";
}
CodeIgniter has restricted the characters in the url to:
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; //Inside config.php
Chances are you are putting in characters that not in this list in the address when you send the AJAX request. My suggestion would be change the $.get to $.post and then get the post data out in the controller. Something like this:
AJAX
$(function() {
$("#search_button").click(function(e){
e.preventDefault();
var search_location = $("#search_location").val();
$.post('index.php/main/get_places', {'search_location': search_location}, function(data){
$("#result").html(data);
console.log(data);
});
});
});
Controller
function get_places() {
$address = $this->input->post('search_location');
$search_latlng = $this->geocode_address($address);
$this->load->model('main_model.php');
$result = $this->main_model->get_places($search_latlng);
echo $result;
}
As for the echo vs return, use echo.
You're probably not allowing querystrings in your URL and the Ajax function adds querystring to the url. Take a look at the following url to learn how to turn querystrings on:
http://www.askaboutphp.com/58/codeigniter-mixing-segment-based-url-with-querystrings.html
Why doesn't the following pick up the form? All it does is just to do a normal PHP post without throwing any errors...
I'm using blockUi on this as well, hence block/unblock.
$(document).ready(function(){
$("input.update").click(function(){
var str = $(this).parent().serialize();
$(this).parent().parent().block({ message: "<span class=\"loading\"><img src=\"<?php echo $siteUrl ?>/admin/template/images/loading.gif\" alt=\"loading...\" /><p>Updating...</p></span>" });
$.ajax({
type: "POST",
url: "forms/update.php",
data: str,
success: function(){
$("div.edit_box").unblock();
$("div.edit_box").append("<span class=\"success\">This has been updated!</span>");
}
});
return false;
});
});
This is my first attempt at using jQuery's Ajax functionality so please bear with me.
("input.update").click(function(){
should be
$("input.update").click(function(){
Since it seems you're only using the 'success' callback of post you could use the .post method, which is a bit easier on the eyes. Also you can put those block calls inside ajaxStart and ajaxStop. To me it's neater.
The $(this).parent().parent().block seemed wrong to me, I changed it to reference the same element that is used for unblocking. I'd also be checking the output of the PHP script, to make sure that whatever you are 'updating' actually is updated (just echo XML from PHP and you'll see it on your console log).
$(function() {
// Apply click handlers to anchors
$("input.update").click(function(e){
// Stop normal link click
e.preventDefault();
var str = $(this).parent().serialize();
// Send request
var action = "forms/update.php";
$.post(action, {data:str}, function(xml) {
console.log(xml);
$("div.edit_box").append("<span class=\"success\">This has been updated!</span>");
})
});
// Adds a wait indicator to any Ajax requests
$(document.body).ajaxStart(function() {
$("div.edit_box").block({ message: "<span class=\"loading\"><img src=\"<?php echo $siteUrl ?>/admin/template/images/loading.gif\" alt=\"loading...\" /><p>Updating...</p></span>" });
}).ajaxStop(function() {
$("div.edit_box").unblock();
$("div.edit_box").append("<span class=\"success\">This has been updated!</span>");
});
});