POST to php via AJAX with json data - php

Trying to post textbox values to database via json .getJSON - at this point I'm just trying to see if the json post to the page, I have the UPDATE query working fine...
following is not posting as desired:
CODE:
$(document).on("click", ".submit", function(event){
alert($(this).text());
var form_data = {
FDID: $('.fdid-1').val(),
CHOICE1: $('.choice-1').val(),
CHOICE2: $(".choice-2").val()
};
$.getJSON("modify.php",form_data,function(data){
switch(data.retval){
case 0: $("#status").html("Update successful!");
break;
case 1: $("#status").html("Unable to update!");
break;
default: $("#description").html("Database error, please try again.");
break;
}
});
});
modify.php:
<?php
header('content-type: application/json; charset=utf-8');
header("access-control-allow-origin: *");
$fdid = json_decode($_POST['FDID']);
$choice1 = json_decode($_POST['CHOICE1']);
var_dump($choice1);
// This is in the PHP file and sends a Javascript alert to the client
$message = $fdid;
echo "<script type='text/javascript'>alert('$message');</script>";
?>
MORE of CODE:
$.each( data, function ( i, val ) {
($('<div>')
.attr({
'data-role': 'collapsible',
'data-content-theme': 'c',
'data-collapsed': 'true',
'id': 'cResults'
})
.html('<h4>' + this.LastName + ', ' + this.FirstName + '</h4>'
+ '<ul data-role="listview" data-filter="true" data-filter-placeholder="Search Choices..." data-inset="true" class="makecollapsibleul">'
+ '<li><form id="productForm" action="modify.php" method="post">'
+ '<label for="fdid-1">FDID:</label>'
+ '<input type="text" name="fdid-1" class="fdid-1" value=' + this.FDID + '>'
+ '</li><li>'
+ '<label for="text-1">Choice 1:</label>'
+ '<input type="text" name="choice-1" class="choice-1" value=' + this.C1 + '>'
+ '</li><li>'
+ '<label for="text-2">Choice 2:</label>'
+ '<input type="text" name="choice-2" class="choice-2" value=' + this.C2 + '>'
+ '</li><li>'
+ 'IP: ' + this.IPADDRESS + '</li><input type="submit" class="submit" value="UPDATE" /></form><li>'
+ 'Pick Date: ' + this.PICKDATE + '</li>'
+ '</ul>'))
.appendTo('#primary');
//$(".title").append('<li>'+orderNum+' -- '+itemNum+'</li>');
$('#makecollapsible').collapsibleset().trigger('create');
$.mobile.hidePageLoadingMsg();

You should not be calling json_encode() to get the parameters. They're sent using www-form-urlencoded format, and PHP takes care of decoding them.
You need to call json_encode to encode the result you want to send back.
<?php
header('content-type: application/json; charset=utf-8');
header("access-control-allow-origin: *");
$fdid = $_POST['FDID'];
$choice1 = $_POST['CHOICE1'];
//var_dump($choice1);
// This is in the PHP file and sends a Javascript alert to the client
$message = $fdid;
$result = array('retval' => 0,
'code' => "<script type='text/javascript'>alert('$message');</script>");
echo json_encode($result);
?>

You know that $.getJson() does, according to the documentation,
Load JSON-encoded data from the server using a GET HTTP request.
So you won't find any values in $_POST. Use $_GET or $_REQUEST to get your data.
Just noticed that you don't have an element with id="save" but one with class="save". As submit events are only fired by <form> elements, try to attach a click callback to your button like this:
$(".save").click(function(e) {
e.preventDefault();
// your code
});

Related

AJAX call from inside a Widget in Yii2?

I would like to create a Widget for my Yii2 project that will based on a few parameters given in the View create an AJAX call that updates a portion of my View.
Basically I have a Postcode field that when updated will look up the corresponding town in a different PHP file. I created something that works, but I was wondering if this is the right (or only?) way to do what I'm looking for. I don't want to have to rewrite the AJAX call as I want to be able to reuse this functionality on several forms and thus fields in my project.
I call the Widget in my View like this:
<?= SearchWidget::Widget(['id' => 'customerform-postalcode',
'dataTarget' => 'cities',
'targetId' => 'customerform-city',
'targetType' => 'dropdown']);?>
and in the Widget I basically have only a run() function which echoes the AJAX call to the page.
public function run()
{
$jScript =
'<script>'
. '$("#' . $this->id . '").change(function(){'
.'$.ajax({'
. 'url: "../scripts/search.php",'
. 'data: {'
. 'needle: $("#' . $this->id . '").val(),'
. 'haystack: "' . $this->dataTarget . '"'
. '},'
. 'type: "POST"'
. '}).done(function(data){'
.'var targetType = "' . $this->targetType . '";'
.'if (targetType=="dropdown") {'
. '$("#' . $this->targetId . '").empty();'
. 'var obj = jQuery.parseJSON(data);'
. '$.each(obj, function(key, value) {'
. '$("#' . $this->targetId . '").append("<option>" + value + "</option>");'
. '});'
. '} else {'
. 'var obj = jQuery.parseJSON(data);'
. '$("#' . $this->targetId . '").val(obj);'
. '}'
. '});'
. '})'
.'</script>';
echo $jScript;
}
First off, I've only just started working with Yii and frameworks so I'm really unsure if this is the correct way to go about it. My first instinct says this is too messy and there should be a better way to do it. Any help is appreciated.
Personally I don't like to write JS code in my PHP files. So I would try to get the JS in a separate .js file.
I would change my SearchWidget to echo an input field with some additional attributes that will provide the JavaScript with the right variables. So my postcode input field would look something like:
<input type="text" name="postcode" id="postcode" class="search-field" data-target="cities" data-targetid="customerform-city" data-targettype="dropdown" />
Then you can rewrite your JS to something like below (untested).
$('.search-field').change(function() {
var id = $(this).attr('id');
var data_target = $(this).data('target');
var target_id = $(this).data('targetid');
var target_type = $(this).data('targettype');
$.ajax({
url: "../scripts/search.php",
data: {
needle: $("#" + id).val(),
haystack: data_target
},
type: "POST"
}).done(function(data) {
if (target_type == "dropdown") {
$("#" + target_id).empty();
var obj = $.parseJSON(data);
$.each(obj, function(key, value) {
$("#" + target_id).append("<option>" + value + "</option>");
});
} else {
var obj = $.parseJSON(data);
$("#" + target_id).val(obj);
}
});
});
Then put this JS file somewhere and register it in the init part of your widget.

Saving form variables onchange with ajax

I'm trying to save form data into $_SESSION variables with ajax, but I can't seem to run the onchange event properly or send the variable.
The form length varies, so I've tried to use dynamic variables.
<script>
function orderValues(boxValue){
$.post("/ajaxConnect.php",{value: $("qty_" + boxValue).val()},
function( result ) {
console.log('value saved');
});
}
</script>
<php
echo "<div id=\"prodBox\">QTY: <input name=\"qty_".rawurldecode($item->LINE)."\" value=\"" . $_SESSION['box_']['qty_'.rawurldecode($item->LINE)] . "\" type=\"number\" onchange=\"orderValues(this.value)\"/></div>";
?>
ajaxConnect:
<?php
session_start();
$_SESSION['box_']['value'] = $_POST["value"];
?>
The end goal is for input values to be saved to $_SESSION['box_']['qty_LINE'] whenever the value is changed.
If I set the $_SESSION value manually I can get it to show, but not through ajax.
Cheers for any help.
It is a better practice to use jquery to do the event bindings instead of using attributes like onchange, and you also need to make sure you get the right values to send to your server, you need both the line name and the value.
So remove the onchange attribute:
<php
echo "<div id=\"prodBox\">QTY: <input name=\"qty_".rawurldecode($item->LINE)."\" value=\"" . $_SESSION['box_']['qty_'.rawurldecode($item->LINE)] . "\" type=\"number\" /></div>";
?>
And use this jquery code:
$(document).ready(function(){
$('#prodBox input').change(function(){
$.post("/ajaxConnect.php",{line: this.name, value: this.value},
function( result ) {
console.log('value saved');
});
});
});
Finally, update your ajaxConnect file:
<?php
session_start();
$line = isset($_POST["line"]) ? $_POST["line"] : '';
$value = isset($_POST["value"]) ? $_POST["value"] : '';
$_SESSION['box_'][$line] = $value;
?>

timing of JSON AJAX Response in Jquery

I think this is more down to timing than code, so really I am looking for best practice advice on how best to get a JSON response.
<script type="text/javascript">
$(window).load(function() {
$('#messages').append('<img src="images/loading.gif" alt="Currently Loading" id="loading" />');
var ideaid = <?php echo $_GET['ideaid']; ?>;
$.ajax({
url: 'sql/ajaxsql.php',
type: 'POST',
data: 'switch=commentList&ideaid=' + ideaid + '&filter=sortdate',
dataType: 'json',
success: function(result) {
var len = result.length;
var html;
console.log('length= ' + len);
$('#response').remove();
console.log(result);
for(var i = 0; i < len; i++) {
var pic = '<img src="https://graph.facebook.com/' + result[i].user_id + '/picture&type=small" align="middle" />';
var authname;
FB.api('/' + result[i].user_id + '?fields=name', function(AuthName) {
console.log(AuthName);
alert(AuthName.name);
authname = AuthName.name;
});
html = '<p>' + result[i].comment + '<br><hr>Date Added: ' + result[i].date + ' by ' + pic + ' ' + authname + '<br><hr><hr></p>';
$('#comms').append(html);
}
$('#loading').fadeOut(500, function() {
$(this).remove();
});
}
});
return false;
});
</script>
With this code, it fires off to get comments regarding a certain idea (idea_id). The comments only holds the Users ID (facebook). When all the data is back, the success then sorts the data ready to print to the screen in some order.
As part of the success, I have the date, time, FB image and name as part of the Author Info under each comment.
Date and Time, works. Image using the graph works, but the name is a bit late of the window loading, and so misses it's call, so comes back as undefined and then the Alert pops up with the name. I understand ajax is meant to do this.
Whats the best way to get round this.
Thank you in advance.
Andrew
EDIT
I have been unable to make this work, even with the suggestions below.
EDIT AGAIN Just seen bf new updated version as below. would also have worked. But I have spent a day on this one function and dare not to play.
As soon as the FB.api comes into play, I could not get the values from out side it. So I took a different approach.
Rather than ajax, I used the query from the PHP side that gets the data, including the uid and then json queried that, and bolted it onto the (mysql_fetch_array) array as follows:
$gc_result = mysql_query($gc_query);
while ($result = mysql_fetch_array($gc_result)) {
$jsonURL = "https://graph.facebook.com/" . $result['user_id'] . "/";
$json = json_decode(file_get_contents($jsonURL), true);
$result["name"] = $json['name'];
$data[] = $result;
}
echo json_encode($data);
Now I have that, I can then do the following and call it within the jQuery:
for(var i = 0; i < len; i++) {
var pic = '<img src="https://graph.facebook.com/' + result[i].user_id + '/picture?type=small" align="middle" />';
html = '<p>' + result[i].comment + '<br><hr>Date Added: ' + result[i].date + ' by ' + pic + ' ' + **result[i]['name']** + '<br><hr><hr></p>';
$('#comms').append(html);
}
This all works great, and I am a complete novice to programming jquery and using Facebook API and JSON, but even I sit back and am pretty impressed with this solution. Before I get carried away, are there any potential flaws in this, performance or security wise ???
Thanks again in Advance.
Andrew
The call to FB.api is probably asynchronous (another ajax request), so you have to move the code after it to inside the FB.api callback:
FB.api('/' + result[i].user_id + '?fields=name', function(AuthName) {
console.log(AuthName);
alert(AuthName.name);
authname = AuthName.name;
html = '<p>' + result[i].comment + '<br><hr>Date Added: ' + result[i].date + ' by ' + pic + ' ' + authname + '<br><hr><hr></p>';
$('#comms').append(html);
});
You also have a variable scope problem because of the for loop. One of the ways to fix this is to use a separate function to create the callback. Add this right after your $(window).load block, before </script>:
function createFbApiCallback(jsonResult) {
return function(AuthName) {
var authname = AuthName.name;
var pic = '<img src="https://graph.facebook.com/' + jsonResult.user_id + '/picture&type=small" align="middle" />';
var html = '<p>' + jsonResult.comment + '<br><hr>Date Added: ' + jsonResult.date + ' by ' + pic + ' ' + authname + '<br><hr><hr></p>';
$('#comms').append(html);
}
}
Then change your loop to this:
for(var i = 0; i < len; i++) {
FB.api('/' + result[i].user_id + '?fields=name', createFbApiCallback(result[i]));
}
If you have to execute code that relies on a callback function inside another callback function, execute your code inside the most inner callback function. In your case, move all that is out of the FB API callback to be inside it, so all your DOM manipulation is done only when both the AJAX response and the FB.api response has returned.

jQuery Ajax - Alternate XML sources for each request

I have two XML sources to retrieve data from. I want to use them alternately per page load. So when someone visits the page the first source will be used, next time the visit the page the other source will be used. Here is the ajax request I am using to get one data source:
$(document).ready(function() {
$.ajax({
type: "GET",
url: "source1.xml", //how do I alternately load two different xml data sources?
dataType: "xml",
success: function(xml) {
var counter = 0
var output = '<li>';
$(xml).find('person').each(function(){
counter++;
var image = $(this).find('image').text();
var name = $(this).find('name').text();
var title = $(this).find('title').text();
var company = $(this).find('company').text();
output = output + '<div><img src=img/' + image + '.jpg />' + '<br /><label><span>' + name + '</span><br />' + title + '<br />' + company + '</label><br /></div>';
if(counter % 3 === 0){
output = output + '</li><li>';
}
});
output = output + '</li>';
$('#update-target ul').html(output);
}
});
});
For extra info, here is how I am alternately loading 2 flash files using PHP:
if(isset($_SESSION['rotation'])){
$picker = $_SESSION['rotation'];
}else{
$picker = rand(0,1);
}
if($picker == 0){
echo '<script type="text/javascript">
var video1 = new SWFObject("somefile1.swf", "p1", "151", "590", "9", "#ffffff");
video1.addParam("wmode","transparent");
video1.write("meh");
</script>';
$_SESSION['rotation'] = ++$picker;
} else {
echo '<script type="text/javascript">
var video1 = new SWFObject("somefile2.swf", "p1", "151", "590", "9", "#ffffff");
video1.addParam("wmode","transparent");
video1.write("meh");
</script>';
$_SESSION['rotation'] = --$picker;
}
I realize I could just stick the jquery document ready code right in there where I have the js calling the flash but it does not seem like a very efficient way of handling this. What is a "best case" way to do this?
You can just use a variable to keep it short, like this:
echo '<script type="text/javascript">var xmlSource = "source1.xml";</script>';
Use that in an if caluse as well, then just reference that in your code:
url: xmlSource,
There are other ways of course, using a cookie (the cookie plugin), putting the text right in the document.ready handler, etc...whichever seems most elegant to you I suppose.
I recommend the variable from the PHP side or a cookie...both of these options allow the document.ready code to stay outside the page in an external script, and not downloaded by the user each time.

JQuery - Pass variables to PHP script via AJAX call and then display file

I'm trying to generate Outlook event files for my events, doing so on the fly as and when someone requests it by pressing a link on the page.
Here's what i've got so far, but I can't find out how to get the browser to download the content which is returned.
I know how I could do this if I sent everything via _GET, but I'd prefer to do it via _POST, hence I'm going down this route..
Any thoughts?
Thanks!
HTML / Javascript
<script>
$(function() {
$(".button").click(function() {
// validate and process form
// first hide any error messages
var start = $("input#start").val();
var end = $("input#end").val();
var dataString = 'start='+ start + '&end=' + end;
$.ajax({
type: "POST",
url: "/calendar.php",
data: dataString,
success: function(data) {
//Need to return the file contents somehow!
}
});
return false;
});
});
</script>
<form name="calendar" method="post" action="">
<input type="hidden" name="start" id="start" value="<?php echo $start; ?>" />
<input type="hidden" name="end" id="end" value="<?php echo $end; ?>" />
<input type="submit" name="submit" class="button" id="submit_btn" value="Outlook" />
</fieldset>
</form>
PHP File
<?php
if (isset($_POST['start'])) {
$start = $_POST['start'];
$end = $_POST['end'];
$c = header("Content-Type: text/Calendar");
$c .= header("Content-Disposition: inline; filename=calendar.ics");
$c .= "BEGIN:VCALENDAR\n";
$c .= "VERSION:2.0\n";
$c .= "PRODID:-//xxxyyyy//NONSGML //EN\n";
$c .= "METHOD:REQUEST\n"; // requied by Outlook
$c .= "BEGIN:VEVENT\n";
$c .= "UID:". $start . $end ."-" . "-xxxxyyyy.com\n"; // required by Outlook
$c .= "DTSTAMP:".date('Ymd').'T'.date('His')."\n"; // required by Outlook
$c .= "DTSTART:20080413T000000\n";
$c .= "SUMMARY:" . "\n";
$c .= "DESCRIPTION:" . "\n";
$c .= "END:VEVENT\n";
$c .= "END:VCALENDAR\n";
echo $c;
} else {
echo "Sorry you can't access this page directly";
}
?>
The output of the PHP file will be put into the "data" variable in your success callback.
Also, while we're here, you can also shortcut a few things. Instead of concatenating strings to generate the dataString (and hope that no one puts an = or & in there), you can use objects:
dataObj = { start : start, end : end };
And then you just pass that to the data property of .ajax
As in ajax request i did not found any way to work redirection headers, So i used window.location code for download action url in the Ajax success callback. In your case except showing some progress, Their should not be need for send ajax request. So you can directly execute window.location = 'calendar.php?start=' + start + '&end=' + end;.
Alternatively if you are sure that only way you want it to execute through POST, Use direct Form Post instead of using Ajax.
Please check the following code hint. This may help you..
type: "POST",
data: ({"start" : <?php echo $start; ?> , "end" : <?php echo $end; ?>}) ,
success: function() {
//Do something
}
});

Categories