I tell you what, getting AJAX to work is one pain in the wazoo! It took me ages to get a simple string to pass and then I got a json array working and felt good, now I've tried to make a little adjustment and broke the whole thing again. Why is following giving an ajax error and how can I get under the hood to see what's going on?
jQuery:
$('#upload_form option[value="addnew"]').click(function(){
// Show modal window
$('#add-new').modal('show');
// Get the class
var Classofentry = $(this).attr("class");
//console.log(Classofentry);
$('#add-new-submit').on('click', function(){
// Get new option from text field
var value = $('#add-new-text').val();
console.log(value);
$.ajax({
type: "POST",
url: "<?php echo site_url(); ?>main/change_options",
data: {new_option: value, new_option_class: Classofentry},
//dataType: "html",
dataType: "json",
error: errorHandler,
success: success
});
function success(data)
{
if (data[1]) // Only add new entry if unique
{
// Add new entry
//$('#animal_species').append("<option value='" + data + "'selected=\"selected\">" + data + "</option>");
$('#'+Classofentry).append("<option value='" + data[0] + "'selected=\"selected\">" + data[0] + "</option>");
//alert(data[0]);
}
else
{
// Select the nonunique value by emptying it and appending
$('#'+Classofentry).empty("<option value=''selected=\"selected\">" + data[0] + "</option>").append("<option value='" + data[0] + "'selected=\"selected\">" + data[0] + "</option>");
//alert(data[1]);
}
alert(data[1]);
//alert('Success!');
}
function errorHandler()
{
//alert('Error with AJAX!');
alert(data[0]);
}
$('#add-new-submit').unbind('click'); // This fixes the problem for multiple entries
$('#add-new').modal('toggle');
});
});
php:
public function change_options()
{
# Receives and sends back user-entered new option and adds it to database
# Get strings from ajax in view
$value = $_POST['new_option'];
$value_class = $_POST['new_option_class'];
#Make array to send to model
$value_array = array('Options' => $value);
$unique = true;
echo json_encode(array($value, $unique));
}
In the console I get: ReferenceError: data is not defined. I've spent the last couple days working on logic to determine $unique and now the ajax won't work, even when I strip it back to it's bare bones. What going on here?
Th code I posted should've worked. I found the issue and it wasn;t with ajax, it was with me passing the wrong thing to the model. Here's the working code, with the logic to determine $unique:
(BTW, this solves the problem posed in Form Validation in Codeigniter: using set_rules to check text input from a modal window without using Form Validation):
public function change_options()
{
# Receives and sends back user-entered new option and adds it to database
# Get strings from ajax in view
$value = $_POST['new_option'];
$value_class = $_POST['new_option_class'];
//print_r($value_class); die;
#Make array to send to model
$value_array = array('Options' => $value);
$unique = true;
$this->load->model('data_model');
$elements = $this->data_model->get_options($value_class);
foreach ($elements as $element)
{
if (preg_match("/$element/", $value, $matches))
{
$unique = false;
break;
}
}
# Add new option to dropdown in database
if ($unique) {$this->data_model->add_option($value_class, $value_array);}
//echo $value;
echo json_encode(array($value, $unique));
}
Related
I have an Ajax script that makes a call to a php file on my server every twenty seconds.
The server then runs a simple mysql query to return the contents of a particular field.
If that field is blank I want the php file to echo the word "pending", which when caught by the success handler will recall the initial function. However if that field is not blank, it will contain a URL to which I want to redirect the user to. That field will update any where between 5 seconds and 5 minutes from the start of the first call and that time cannot be changed.
I think the main issue may be with my php file, in that I dont think it is echoing the data in a way that the success handler recognises. However I have detailed both parts of my code as whilst the success handler seems to be constructed correctly I am not 100% sure.
Very new to this, so apologies if I have not explained myself correctly but if anyone could assist that would be great:
UPDATE - for clarity what I am looking to achieve is as follows:
Ajax call to my php file.
PHP file queries database
If field queried contains no data echo the word "pending" to the ajax success handler (IF) which in turn recalls the original function / ajax call.
If field queried contains data (will be a URL) echo this result to the ajax success handler (ELSE)in a format that will redirect the user via window.location.assign(data).
FURTHER UPDATE
I managed to solve this question with using a combination of the advice from #mamdouhalramadan and #martijn
I also have changed setInterval to setTimeout as the poll function was causing responses to stack up should the server be running slowly and as such cause errors. I also added in cache: false and a further option in the success handler to take into account slightly different behaviour in IE:
AJAX
function poll() {
$.ajax({
url: 'processthree.php?lead_id='+lead_id,
type: "GET",
cache: false,
async: false,
success: function(data3) {
//alert("pending called " + data3)
if(data3.indexOf("pending") >-1 ){
setTimeout(poll, 20000);
}
else if ( (navigator.userAgent.indexOf('MSIE') != -1) ) {
//alert("Submit success - MSIE: " + data3);
parent.window.location.replace(data3);
}
else{
//alert("process three called " + data3)
window.top.location.assign(data3);
}
},
error: function(xhr, error){
//alert("Error");
//alert("Error: " + error + ", XHR status: " + xhr.status);
},
});
}
setTimeout(poll, 20000);
PHP
$query = ("SELECT column FROM table WHERE id = '$lead_id'") or die(mysql_error());
$result = mysql_query($query);
$return = array();
while($row = mysql_fetch_assoc($result))
{
$return = 'pending';
if($row['column'] != '')
{
$return = $row['column'];
}
}
echo $return;
I believe using json might help you out here, not to mention it is safer, like so:
function poll() {
$.ajax({
url: 'processthree.php?lead_id='+lead_id,
type: "GET",
dataType: 'json',//specify data type
success: function(data3) {
if(data3.res.indexOf("pending") >-1 ){
//rest of the code.....
then in your php:
$return = array();
while($row = mysql_fetch_assoc($result))
{
$return['res'] = 'pending';
if($row['column'] != '')
{
$return['res'] = $row['column'];
}
}
echo json_encode($return);
Note: use PDO or MYSQLI instead of mysql as it is deprecated.
I'm trying to build an array of data that will then be ajax using post to php - below is my code:
$('#mainBodySaveSubmitButtonProfilePhotoIMG').click(function() {
var profilePhotoArray = [];
$('.mainUnapprovedProfilePhotoWrapperDIV').each(function() {
var action = '';
alert( this.id );
if($('.mainUnapprovedProfilePhotoAttractiveIMG', this).is(':visible')) {
alert('attractive...');
action = 'attractive';
}
else if($('.mainUnapprovedProfilePhotoDeleteIMG', this).is(':visible')) {
alert('delete...');
action = 'delete';
}else{
alert('normal...');
action = 'normal';
}
profilePhotoArray[this.id+'_'+this.id] = action;
});
alert(profilePhotoArray.length);
for (i=0;i<profilePhotoArray.length;i++) {
console.log("Key is "+i+" and Value is "+array[i]);
}
$.post('scripts/ajax/ajax_approval_functions.php', {
'approvalProfilePhotos': '1',
'approvalProfilePhotosData': profilePhotoArray},
function(data) {
alert(data);
});
});
The if, else if, else section works fine as I can see the alerts.
When I try to alert the array length 'profilePhotoArray' it says 0 so I'm not populating the array correctly. Do I need to use .push()? I thought this format was ok?
Also do I need to do anything to the array before sending to php via ajax?
thankyou
** edit - I'm adding "profilePhotoArray[this.id+'_'+this.id] = action;" this.id twice just to prove this words as I will pass a second variable like this... am I better to use JSON for this?
Javascript arrays use numerical index, therefore your storage is failing. Use a javascript Object to store string based keys.
var lang=new Object();
lang["foo"]="Foo";
lang["bar"]="Bar";
Here is the example delete options I'm using using in a jqGrid. It works just fine and my serverside scripts are working perfectly. The records get deleted, but there is something that goes wrong after the response from the server is received.
// Del Options
{
mtype: "POST",
modal: true,
url: "/internal/backupmanagement/backupmanager/deleteMySQLDB",
reloadAfterSubmit: false,
onclickSubmit: function () {
var post = $("#grid_" + o.id).jqGrid("getGridParam", "postData");
var server = post.serverID;
$.openDialog("load", "Deleting old database entry. Please wait...");
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
var row = $("#grid_" + o.id).jqGrid("getRowData", selrow);
console.log("about to return", row, server);
return {
id: row.recid,
database: row.database,
server: server
};
},
afterSubmit: function (response, postdata) {
response = eval("(" + response.responseText + ")");
console.log(response);
return [true, "success"];
},
afterComplete: function (response, postdata, formid) {
response = eval("(" + response.responseText + ")");
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
$("#grid_" + o.id).jqGrid("delRowData", selrow);
if (response.error == 0) {
$.openDialog("info", "Successfully deleted " + postdata.database + ".");
} else {
$.openDialog("info", "And error occured - " + response.msg + ".");
}
}
}
I get the following error before the afterComplete event is fired in the grid :
Uncaught TypeError: Object [object Array] has no method 'split'
So it seems something is being returned as an object when it was expecting a string. I'm not sure if my response from the server is formatted correctly and I wasn't able to find any expected response in the documentation either.
* UPDATE *
Server-side code as requested. I've just included the controller function that interacts with the jqGrid, the rest is working and happening further on in the application.
function deleteMySQLDB()
{
if (IS_AJAX) {
if (($this->Application->deleteMySQLDBData(
$_POST["id"],
$_POST["database"],
$_POST["server"]
)) === false) {
echo json_encode(
array(
"error" => 1,
"msg" => "Failed Deleting record from database: "
.$this->Application->error
)
);
return false;
}
echo json_encode(
array(
"error" => 0,
"msg" => "success"
)
);
return true;
} else {
header("Location: /");
}
}
I hope this helps to see what I'm currently returning to the grid.
* UPDATE *
What I have done is changed the source in the jqGrid plugin to include a toString() on the value before preforming the split.
On line 331 of jquery.jqGrid.min.4.3.1 :
var A=[];A=H.split(",");
Changed to :
var A=[];A=H.toString().split(",");
It seemed like a harmless change in the grand scheme of things and avoids arrays to be attempted to get split. Thanks a lot for the help guys. You certainly pointed me in the right place to start looking, Oleg!
Let's suppose that the origin of the described error is the code of your afterComplete callback. I think that you are using it in a wrong way. I don't understand some parts of the code, the part (testing of response.error) should be moved in afterSubmit.
The main problem will be clear if you examine the lines of code where afterComplete callback will be called. It will be executed inside of setTimeout with 0.5 sec delay. At the time new data in the grid can be loaded (or could be loading). So it would be wrong to use methods like delRowData and the value of selrow could be changed now.
I would strictly recommend you additionally don't use eval function. Instead of the line
response = eval("(" + response.responseText + ")");
it will be correct to use
response = $.parseJSON(response.responseText);
The code of onclickSubmit callback could be improved if you would use the fact that this inside of the callback (like the most other callbacks o jqGrid) are initialized to DOM element of the grid. So to get selrow option of the grid you can use
var selrow = $(this).jqGrid("getGridParam", "selrow");
instead of
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
Another fact is onclickSubmit will be called by jqGrid with two parameters: options and postdata. The parameter postdata is rowid if you use don't use multiselect: true. In case of usage of multiselect: true the value of postdata parameter of the callback can be comma separated list of rowids of the rows which will be deleted. So the usage of postdata is better as the usage of selrow.
I"m making a good guess since you didn't include your server side code.
On the server you can return something like:
return Json(new { success = false, showMessage = true, message = "Error - You can't have a negative value", title = "Error" });
Then on your client you can have something to display a message (in this example if there was an error)
afterComplete: function (response) {
var DialogVars = $.parseJSON(response.responseText); //parse the string that was returned in responseText into an object
if (!DialogVars.success || DialogVars.showMessage) {
showDialog($('#Dialog'), DialogVars.message, DialogVars.title);
}
} //afterComplete
I have a form that uses ajax to submit data to a mysql database, then sends the form on to PayPal.
However, after submitting, if I click the back button on my browser, change some fields, and then submit the form again, the mysql data isn't updated, nor is a new entry created.
Here's my Jquery:
$j(".submit").click(function() {
var hasError = false;
var order_id = $j('input[name="custom"]').val();
var order_amount = $j('input[name="amount"]').val();
var service_type = $j('input[name="item_name"]').val();
var order_to = $j('input[name="to"]').val();
var order_from = $j('input[name="from"]').val();
var order_message = $j('textarea#message').val();
if(hasError == false) {
var dataString = 'order_id='+ order_id + '&order_amount=' + order_amount + '&service_type=' + service_type + '&order_to=' + order_to + '&order_from=' + order_from + '&order_message=' + order_message;
$j.ajax({ type: "GET", cache: false, url: "/gc_process.php", data: dataString, success: function() { } });
} else {
return false;
}
});
Here's what my PHP script looks like:
<?php
// Make a MySQL Connection
include('dbconnect.php');
// Get data
$order_id = $_GET['order_id'];
$amount = $_GET['order_amount'];
$type = $_GET['service_type'];
$to = $_GET['order_to'];
$from = $_GET['order_from'];
$message = $_GET['order_message'];
// Insert a row of information into the table
mysql_query("REPLACE INTO gift_certificates (order_id, order_type, amount, order_to, order_from, order_message) VALUES('$order_id', '$type', '$amount', '$to', '$from', '$message')");
mysql_close();
?>
Any ideas?
You really should be using POST instead of GET, but regardless, I would check the following:
That jQuery is executing the ajax call after you click back and change the information, you should probably put either a console.log or an alert calls to see if javascript is failing
Add some echos in the PHP and some exits and go line by line and see how far it gets. Since you have it as a get, you can just load up another tab in your browser and change the information you need to.
if $j in your jQuery is the form you should be able to just do $j.serialize(), it's a handy function to get all the form data in one string
Mate,
Have you enclosed your jquery in
$j(function(){
});
To make sure it is only executed when the dom is ready?
Also, I'm assuming that you've manually gone and renamed jquery from "$" to "$j" to prevent namespace conflicts. If that isn't the case it should be $(function and not $j(function
Anyway apart from that, here are some tips for your code:
Step 1: rename all the "name" fields to be the name you want them to be in your "dataString" object. For example change input[name=from] to have the name "order_from"
Step 2:
Use this code.
$j(function(){
$j(".submit").click(function() {
var hasError = false;
if(hasError == false) {
var dataString = $j('form').serialize();
$j.ajax({ type: "GET", cache: false, url: "/gc_process.php?uu="+Math.random(), data: dataString, success: function() { } });
} else {
return false;
}
});
});
You'll notice i slapped a random variable "uu=random" on the url, this is generally a built in function to jquery, but to make sure it isn't caching the response you can force it using this method.
good luck. If that doesn't work, try the script without renaming jquery on a fresh page. See if that works, you might have some collisions between that and other scripts on the page
Turns out the problem is due to the fact that I am using iframes. I was able to fix the problem by making the page without iframes. Thanks for your help all!
This seems like it would have been simple, but what i was doing was creating an array in jQuery and sending it to a php via ajax and inserting the records into a db. But what i want to do now is create the array exactly the same but instead of ajax, i'd like to go to the php page and view what it has received.
How would i go about doing this?
I'm using this jQuery:
$('#preview').live('click',function(){
var postData = {};
$('#items tr').not(':first').each(function(index, value) {
var keyPrefix = 'data[' + index + ']';
postData[keyPrefix + '[index]'] = index;
postData[keyPrefix + '[supp_short_code]'] = $(this).closest('tr').find('.supp_short_code').text();
postData[keyPrefix + '[project_ref]'] = $(this).closest('tr').find('.project_ref').text();
postData[keyPrefix + '[om_part_no]'] = $(this).closest('tr').find('.om_part_no').text();
postData[keyPrefix + '[description]'] = $(this).closest('tr').find('.description').text();
postData[keyPrefix + '[quantity_input]'] = $(this).closest('tr').find('.quantity_input').val();
postData[keyPrefix + '[cost_of_items]'] = $(this).closest('tr').find('.cost_of_items').text();
postData[keyPrefix + '[cost_total_td]'] = $(this).closest('tr').find('.cost_total_td').text();
});
$.ajax
({
type: "POST",
url: "preview.php",
dataType: "json",
data: postData,
cache: false,
success: function()
{
}
});
});
And this PHP:
if (isset($_POST['data']) && is_array($_POST['data'])) {
foreach ($_POST['data'] as $row => $data) {
echo $data['index'];
echo $data['project_ref'];
echo $data['supp_short_code'];
echo $data['om_part_no'];
echo $data['description'];
echo $data['quantity_input'];
echo $data['cost_of_items'];
echo $data['cost_total_td'];
}
}
You can store the received data in a session:
if (isset($_POST['data']) && is_array($_POST['data'])) {
session_start();
$_SESSION['data'] = $_POST['data'];
}
And then link to another PHP page that retrieves the data from the session and displays it:
session_start();
if (isset($_SESSION['data']) && is_array($_SESSION['data'])) {
foreach ($_SESSION['data'] as $row => $data) {
echo $data['index'];
echo $data['project_ref'];
echo $data['supp_short_code'];
echo $data['om_part_no'];
echo $data['description'];
echo $data['quantity_input'];
echo $data['cost_of_items'];
echo $data['cost_total_td'];
}
}
What you can do, following on from what dnagirl said, is to generate the POST form using jQuery and submit it.
$('#preview').live('click',function(){
var cForm = $('<form method="post">').attr('action', "preview.php");
$('#items tr').not(':first').each(function(index, value) {
var keyPrefix = 'data[' + index + ']';
cForm.append($('<input type="hidden">').attr('name', keyPrefix + '[index]').val(index));
cForm.append($('<input type="hidden">').attr('name', keyPrefix + '[supp_short_code]').val($(this).closest('tr').find('.supp_short_code').text());
// etc
});
cForm.hide().append('body').submit();
return false;
});
The reason for using attr() in places rather than inline within the creation string is to avoid issues with escaping, and it looks cleaner in my opinion.
Why not use JSON
PHP JSON
So you are current creating a POST string using jQuery and then sending it using ajax to a php script. Now you actually want to POST directly to PHP. Is that correct?
If I've got that right, there are 2 options:
actually POST from a form that
the user fills out
have a skeleton form consisting of
the <form> tags and a submit
button. Use jQuery to create and
populate hidden form fields when the
user hits the submit button and
before the submit action is
completed.