How to load a php file correctly using jquery - javascript

So allow me to first say I have looked at previous questions, and none of them have helped me out. My problem is as follows, I have an html file with a form which calls a javascript function to load a php file.
The form looks as following:
<form method="GET" id="submission" >
<div class="form-group">
<label for="q">Search Term:</label>
<input type="text" class="form-control" id="q" name="q" placeholder="enter a keyword">
</div>
<div class="form-group">
<label for="location">location</label>
<input type="text" class="form-control" id="location" name="location" placeholder="lat,long">
</div>
<div class="form-group">
<label for="locationRadius">Location Radius:</label>
<input type="text" class="form-control" id="locationRadius" name="locationRadius" placeholder="25km">
</div>
<div class="form-group">
<label for="maxResults">Max Results:</label>
<input type="number" class="form-control" id="maxResults" name="maxResults" placeholder="0 to 50">
</div>
<button type="submit" id="submitButton" >Submit</button>
</form>
The JS function responsible for sending is the following:
function sendData() {
var keyword = document.getElementById("q").value;
var location = $('#location').value;
var locationRadius = $('#locationRadius').value;
var maxResult = $('#maxResults').value;
alert("keyword is: " + locationRadius);
$.get(
{
type: 'GET',
url: '../php/geolocation.php',
data : {q: keyword, location: location, locationRadius: locationRadius, maxResults: maxResult}
},
function (data) {
//alert("Data loaded " + data);
document.getElementById("geolocation-results").innerHTML = data;
}
);
}
$(document).ready(function() {
$("#submission").submit(function() {
sendData();
return false;
});
});
SO my problem is two fold, how to call it in an ajax like manner as the above format worked for my old code, but for some reason refuses to function correctly for this one. And how should I fetch the php data? The php code is below:
It is a modified version of youtube's geolocation example code.
<?php
/**
* This sample lists videos that are associated with a particular keyword and are in the radius of
* particular geographic coordinates by:
*
* 1. Searching videos with "youtube.search.list" method and setting "type", "q", "location" and
* "locationRadius" parameters.
* 2. Retrieving location details for each video with "youtube.videos.list" method and setting
* "id" parameter to comma separated list of video IDs in search result.
*
* #author Ibrahim Ulukaya
*/
/**
* Library Requirements
*
* 1. Install composer (https://getcomposer.org)
* 2. On the command line, change to this directory (api-samples/php)
* 3. Require the google/apiclient library
* $ composer require google/apiclient:~2.0
*/
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
$htmlBody = null;
// This code executes if the user enters a search query in the form
// and submits the form. Otherwise, the page displays the form above.
if (isset($_GET['q'])
&& isset($_GET['maxResults'])
&& isset($_GET['locationRadius'])
&& isset($_GET['location'])) {
/*
* Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$DEVELOPER_KEY = 'AIzaSyC6q-84bJv9HWCUDT4_SQ5Bp9WFJW2Z-e4';
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
try {
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'type' => 'video',
'q' => $_GET['q'],
'location' => $_GET['location'],
'locationRadius' => $_GET['locationRadius'],
'maxResults' => $_GET['maxResults'],
));
$videoResults = array();
# Merge video ids
foreach ($searchResponse['items'] as $searchResult) {
array_push($videoResults, $searchResult['id']['videoId']);
}
$videoIds = join(',', $videoResults);
# Call the videos.list method to retrieve location details for each video.
$videosResponse = $youtube->videos->listVideos('snippet, recordingDetails', array(
'id' => $videoIds,
));
$videos = '';
// Display the list of matching videos.
foreach ($videosResponse['items'] as $videoResult) {
$videos .= sprintf('<li>%s,%s (%s,%s)</li>',
$videoResult['id'],
$videoResult['snippet']['title'],
$videoResult['recordingDetails']['location']['latitude'],
$videoResult['recordingDetails']['location']['longitude']);
echo $videos;
}
//$htmlBody = <<<END
// <h3>Videos</h3>
// <ul>$videos</ul>
//END;
} catch (Google_Service_Exception $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
}
?>

It appears that the problem is your attempt to specify an non asynchronous request. I believe these are blocked by current/modern browsers. If you check your javascript console, you will probably see an error like this:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.
If you remove that, I believe it will work as before (if it worked earlier, as you indicated). jQuery ajax requests are asynchronous by default, so if you remove that line, it will operate asynchronously.
(This wasn't part of your question, but you might consider leaving your input field's value="" blank, and put your helper text in placeholder="" attributes instead. These will provide the clue to your users without the risk of having that information passed in your request.)
As for displaying the result of the call, having your call return HTML and simply displaying that HTML on your calling page should work. Since you're using jQuery you could simplify your code like so: $('#geolocation-results').html(data); You may need/want to specify dataType: 'html' in your call as well. (https://api.jquery.com/jquery.get/)
Oh my. So obvious now. I believe your structure of the .get call is wrong. Should be like this:
$.get(
"../php/geolocation.php",
{
q: keyword,
location: location,
locationRadius: r,
maxResults: maxResult
},
function (data) {
$('#geolocation-results').html(data);
}
);
Checking that now... Okay, after rushing a bit too much I can confirm that the $.get() call was just structured wrong. Correct it as shown above and it will call the PHP file correctly and display the output in the geolocation-results element.

I think there are some mistakes in your code. You don't need to put async (and not asynch) as false because it's blocking the client browser for nothing. Be also careful to your url parameter which should not contains any quotes. Finally, you should put your trigger on the submit event more than on the onclick event because you can submit the form just by pressing Enter without clicking on your button.
You can try with this javascript :
function sendData() {
var keyword = document.getElementById("q").value;
var location = $('#location').value;
var locationRadius = $('#locationRadius').value;
var maxResult = $('#maxResults').value;
alert("keyword is: " + keyword);
$.get(
'../php/geolocation.php',
{q: keyword, location: location, locationRadius: locationRadius, maxResults: maxResult},
function (data) {
alert("Data loaded " + data);
document.getElementById("geolocation-results").innerHTML = data;
}
);
}
$(document).ready(function() {
$("#submission").submit(function() {
sendData();
return false;
}
});

Related

Basic form submission with jquery/ajax not working

I'm new to jquery and ajax. I'm trying to get my first ajax script to work, but it's not working and I need some assistance, please.
I have a php page that is supposed to post to another php page, where the latter will do some processing and get some files to get zipped and download. The user needs to input a starting and ending date, and the second php script will use this information to prepare the data. This functionality works perfectly fine without jquery, but doesn't work when I add jquery.
What do I want to achieve? I want to post in the to the same php page and get the post output in a <div></div> tag.
My first php page contains (downloadPage.php):
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<form action="doDownload.php" method="post" id="dateRangeID">
<input id='time1' class='input' name="datefield1" style="text-align:center;"/>
<input id='time2' class='input' name="datefield2" style="text-align:center;"/>
<input type="submit" value="Download Data" name="submit" id="submitButton">
</form>
<div id="result"></div> <!-- I would like it to post the result here //-->
The second page (doDownload.php),
<div id="content">
<?php
if(isset($_POST['submit']))
{
$dateVal1 = $_POST['datefield1'];
$dateVal2 = $_POST['datefield2'];
if($dateVal1 != $dateVal2)
{
header('Content-Type: application/zip');
header('Content-disposition: attachment; filename="file.zip"');
$fullListOfFiles = $downloadFullTmpFolder.$filesList;
$command = "sudo $ldlib -u myuser /usr/bin/python3 $downloadScriptFile -datadir $gnomeDataDir -time1 $dateVal1C -time2 $dateVal2C -outdir $downloadFullTmpFolder > debug_download.txt 2>&1";
$output = shell_exec($command);
$fp = popen('cat '.$fullListOfFiles.' | sudo -u myuser zip -# -9 - ', 'r');
$bufsize = 1024;
$buff = '';
while( !feof($fp) )
{
$buff = fread($fp, $bufsize);
echo $buff;
}
pclose($fp);
}
else
{
echo("<p>Dates have to be different in order for the download to start.</p>");
}
}
else
{
echo("<p>Error: Page called without submit.</p>");
}
?>
</div>
Finally, the jquery part in downloadPage.php, which if I add it doesn't work anymore (which I'd like to learn how to do right, and I mainly learned from the manual of jquery, the last example in the link)
<script>
/* attach a submit handler to the form */
$("#dateRangeID").submit(
function(event)
{
event.preventDefault();
var $form = $(this),
t1 = $form.find("input[name='datefield1']").val(),
t2 = $form.find("input[name='datefield2']").val(),
subm = $form.find("input[name='submit']").val(),
url = $form.attr('action');
var posting = $.post(url, { datefield1: t1, datefield2: t2, submit: subm} );
/* Put the results in a div */
posting.done(function(data) {
var content = $(data).find('#content'); // <--- So this turns out to be wrong. Right is only $(data);
$("#result").empty().append(content);
});
});
</script>
What is wrong in this? Please assist. Thank you.
If you require any additional information, please ask.
Looking at the obvious, you have:
var content = $(data).find('#content');
where, you're trying to find an element with the ID content in one of the following results:
<p>Dates have to be different in order for the download to start.</p>
or
<p>Error: Page called without submit.</p>

Form Information to Appear On Another Page

I am trying to create a form that, once submitted, will be sent to my index.html page for other users to view. I want it so multiple users anywhere in the world can submit information and so the website displays all their information at once.
Here is my submit page's PHP code:
<form action="submit_a_message.php" method="post">
<textarea name="message" cols="60" rows="10" maxlength="500"></textarea><br>
<input type="submit">
</form>
I am trying to figure out how to make the information submited via that form appear on my index.html page. This is the code I found online, but it doesn't work. Why?
<?php>
string file_get_contents ( string $submit_a_message.php [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] )
<?>
Any help would be greatly appreciated.
To make submitted text avaliable on your index page, you need a place where you would store it. You can use MySQL base to do that, or (if you can't or you really don't want) you can use text file with your texts/posts (that is not really good way, i warned you).
To do that with MySQL you can use a code like this on your submit_a_message.php:
<?php
//connection to database and stuff
...
if $_POST['message'] {
$message = $_POST['message'];
$sql = "insert into `mytable` values $message"; //that is SQL request that inserts message into database
mysql_query($sql) or die(mysql_error()); // run that SQL or show an error
}
?>
In order to show desired vaues from table use above-like idea, your SQL request would be like select * from mytable where id = 123
if your not married to the idea of using php and learning how to manage and access a database you could use jquery and a trird party backend like parse.com
If your new to storing and retrieving data, I would definately reccomend the services that https://parse.com/ offeres. It makes storing and retrieving data trivial. Best of all, the service is free unless your app makes more than 30 API requests per second. I have an app that 61 users use daily and we have never come close to the 30 req per second limit.
To save your info, you could write:
$('document').ready(function(){
$('#submit_btn').on('click',function(){ // detect button click, need to add "submit_btn" as the id for your button
var Message = Parse.Object.extend("Message"); //create a reference to your class
var newObject = new EventInfo(); //create a new instance of your class
newObject.set("messageText", $("#myMessage").val()); //set some properties on the object, your input will need the id "myMessage"
newObject.save(null, { //save the new object
success: function(returnedObject) {
console.log('New object created with objectId: ' + returnedObject.id);
},
error: function(returnedObject, error) {
console.log('Failed to create new object, with error code: ' + error.message);
}
});
});
});
Retrieving that info later would be as easy as:
var Message = Parse.Object.extend("Message"); //create a reference to your class
var query = new Parse.Query(Message); //create a query to get stored objects with this class
query.find({
success: function(results) { //"results" is an array, you can fine tune your queries to retrieve specific saved objects too
for (var i = 0; i < results.length; i++) {
var object = results[i];
$(body).append("Message #" + (i+1) + object.get("messageText");
}
},
error: function(error) {
console.log("Failed to complete Query - Error: " + error.code + " " + error.message);
}
});

Trigger cross domain YQL ajax request with input onBlur

I have a form to collect information about a product (i.e. from Amazon). I am attempting to trigger a YQL ajax request on blur of the URL input. Currently, no errors in console, but no results either. Here is my form input:
<div class="uk-form-row">
<div class="uk-form-label"><?php echo $this->form->getLabel('item_url'); ?></div>
<div class="uk-form-controls "><input type="text" name="jform[item_url]" id="jform[item_url]" value="<?php if (!empty($this->item->id)) { echo $this->item->item_url;}; ?>" class="uk-form-large uk-width-medium-1-1" placeholder="http://" aria-required="required" required="required"/></div>
</div>
<script type="text/javascript">
jQuery( "#jform[item_url]" ).blur(function() {
var path = jQuery('#jform[item_url]').val();
requestCrossDomain(path, function(results) {
jQuery('#url_results').html(results);
});
});
</script>
<div id="url_results">
</div>
My function:
// Accepts a url and a callback function to run.
function requestCrossDomain( site, callback ) {
// If no url was passed, exit.
if ( !site ) {
alert('No site was passed.');
return false;
}
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + site + '"') + '&format=xml&callback=cbFunc';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
jQuery.getJSON( yql, cbFunc );
function cbFunc(data) {
// If we have something to work with...
if ( data.results[0] ) {
// Strip out all script tags, for security reasons.
// BE VERY CAREFUL. This helps, but we should do more.
data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
// If the user passed a callback, and it
// is a function, call it, and send through the data var.
if ( typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else throw new Error('Nothing returned from getJSON.');
}
}
Here's the fiddle: http://jsfiddle.net/FLY66/2/
This issue is more related to your server. You can simply set the Access-Control-Allow-Origin header on your server. Look for your server language to see how to set Access-Control-Allow-Origin
Setting it to * will accept cross-domain AJAX requests from any domain.
Another alternative is use 'JSONP' data type for returned data.
References
http://en.wikipedia.org/wiki/Same_origin_policy
https://developer.mozilla.org/en/http_access_control

Executing php script on button click and returning value by ob_start

I have button which in enclosed by <a> tag. When clicked, it executes redirect.php script.
login.php - contains
<input type = "button" id = "loginButton2" class = "btn btn-primary" value = "Login | Twitter " style = "left:650px; margin-top: -32px; position:relative"/>
redirect.php contains twitter authentication code. If authenticated successfully then gives id and name. I want to fetch these both value in index.php
Using ob_start(); I can receive values from php script to JS function via json.
But I am confused about how to manage the code in index.php to execute script on button click and receiving these two value also.
redirect.php
<?php
session_start();
require_once('twitteroauth/twitteroauth.php');
require_once('config.php');
if (empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) {
header('Location: ./clearsessions.php');
}
$access_token = $_SESSION['access_token'];
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']);
$content = $connection->get('account/verify_credentials');
$twitteruser = $content->{'screen_name'};
$notweets = 5;
$tweets = $connection->get("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=".$twitteruser."&count=".$notweets);
$id = $content->{'id'};
$name = $content->{'name'};
?>
Please let me know if you need further explaination.
Bottomline:
Rather executing redirect.php script on link click, I want it to execute via function on button click event.
Getting id and name from redirect.php to index.php after redirect script executed
I already have session_start() to manage the twitter session. So dont want to mess up using mutiple session if not necessary ..
UPDATE after david's answer
<body>
<input type="button" value="Run somePHPfile.php" id = "b1" />
<script>
$('#b1').click(function () {
window.location.href = 'redirect.php';
$.get('index.php', function(data) { //If I put this out side click then it gives undefined value for name and id before redirect.php gets executed
// data.id is the id
var id= data.id;
var name = data.name;
alert(name);
});
});
</script>
</body>
Apologize to say:
On button click redirect.php script executed. redirect.php includes other files, which finally reach to index.php. And index.php returns name and id.
So is this enough to manage it : $.get('index.php', function(data) { ... }
To bind to a click event of an HTML button, you would use JavaScript. Since you tagged the question with jQuery, I'll assume its use. The event handler would look something like this:
$('#loginButton2').click(function () {
window.location.href = 'redirect.php';
});
Note: This simulates an anchor click effectively. If you instead want to more closely resemble an HTTP redirect, you might want to use this instead:
window.location.replace('redirect.php');
As for the id and name values, how exactly does this flow return the user to index.php in the first place? Your redirect.php has, well, a redirect (though not all code paths result in that) so it kind of assumes non-AJAX interaction. (I think XHR follows redirects sometimes, but the behavior is different from one browser to another.)
If the redirect isn't terribly important and you just want to make an AJAX call to redirect.php, then you can do that with a simple AJAX request:
$.get('redirect.php');
In order to get those values back to the page, they'll need to be emitted from redirect.php. Something like this:
echo json_encode((object) array('id' => $id, 'name' => $name));
Then in the client-side code you would have those values available in the AJAX callback:
$.get('redirect.php', function(data) {
// data.id is the id
// data.name is the name
// use these values client-side however you need
});
<script>
$("#loginButton2").on('click',function(){
window.location.href="redirect.php";
});
</script>
and in redirect.php file
$_SESSION['id']=$id ;
$_SESSION['name']=$name;
and also
<input type = "button" id = "loginButton2" class = "btn btn-primary" value = "Login | Twitter " style = "left:650px; margin-top: -32px; position:relative"/>
to
<input type = "button" id = "loginButton2" class = "btn btn-primary" value = "Login | Twitter " style = "left:650px; margin-top: -32px; position:relative"/>

Zend_Form Jquery & fileUploadErrorIniSize

Edit, I fixed it by changing my JS to:
$('.zend_form input:not([type="file"]), .zend_form textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
Hello,
As I posted earlier, I followed a ZendCast that allowed you to use jQuery to detect and display to users problem with their form.
However, file fields always return: fileUploadErrorIniSize (File 'image_front_url' exceeds the defined ini size" even if the file is within size limits.
TPL For Forms:
<?php $this->headScript()->captureStart(); ?>
$(function() {
$('.zend_form input, .zend_form textarea').blur(function() {
var formElementId = ($(this).parent().prev().find('label').attr('for'));
doValidation(formElementId);
});
});
function doValidation(id) {
var url = '/<?php echo MODULE; ?>/json/validateform/form_name/<?php echo get_class($this->form); ?>';
var data = {};
$('.zend_form input, .zend_form textarea').each(function() {
data[$(this).attr('name')] = $(this).val();
});
$.post(url, data, function(resp) {
$('#'+id).parent().find('.errors').remove();
$('#'+id).parent().append(getErrorHtml(resp[id], id));
}, 'json');
};
function getErrorHtml(formErrors, id) {
var o = '';
if (formErrors != null) {
var o = '<ul id="errors-'+id+'" class="errors">';
for (errorKey in formErrors) {
o += '<li>'+formErrors[errorKey]+'</li>';
}
o += '</ul>';
}
return o;
}
<?php $this->headScript()->captureEnd(); ?>
<?php
if (is_object($this->form) && $this->form->getErrorMessages()) {
echo $this->partial('partials/errors.phtml', array('errors' => $this->form->getErrorMessages(), 'translate' => $this->translate));
}
?>
<?php if (isset($this->errorMsg)) { ?>
<p><?php echo $this->errorMsg; ?></p>
<?php } ?>
<?php echo $this->form; ?>
Which is directed to
<?php
class Administration_JsonController extends Zend_Controller_Action {
public function validateformAction() {
$form_name = $this->_getParam('form_name');
$form = new $form_name();
$data = $this->_getAllParams();
$form->isValidPartial($data);
$json = $form->getMessages();
$this->_helper->json($json);
}
}
Example of returned json:
{"name":{"isEmpty":"Value is required and can't be empty"},"name_url":{"isEmpty":"Value is required and can't be empty"},"image_site_url":{"fileUploadErrorIniSize":"File 'image_site_url' exceeds the defined ini size"},"image_url":{"fileUploadErrorIniSize":"File 'image_url' exceeds the defined ini size"},"image_front_url":{"fileUploadErrorIniSize":"File 'image_front_url' exceeds the defined ini size"},"image_back_url":{"fileUploadErrorIniSize":"File 'image_back_url' exceeds the defined ini size"}}
I noticed a few people had this issue and they said that isValidPartial fixes it, so I changed
$form->isValid($data);
to
$form->isValidPartial($data);
but it didn't fix this issue.
Any ideas?
The problem is that you can't treat file fields in the same manner as regular text fields.
When you call $('input').val(), you get an actual text value for the text field, but for the file field you get the file name - and not the file contents.
Then your script tries to validate your file name as a file and, apparently, fails. In order for file validator to succeed you need to pass actual file contents to the script.
So, basically, you need to upload a file asynchronously to the server to perform all the necessary validations.
Unfortunately, uploading files via Ajax is not quite a trivial thing to do. Your basic options are uploading files via iFrame or swfObject. You can take a look at the broad selection of plugins suitable for this purpose here.
My personal choice for asynchronous file upload would be file-uploader jQuery plugin.
Are you putting an Encrypt type on your form?
I have found two different forum posts about this, including a stack post:
odd Zend_Form_Element_File behavior
You need to add enctype="multipart/form-data" to your form tag.
Basically what is happening is the form is using its default "application/x-www-form-urlencoded" method of encryption before it is sent to the server. File uploading is not supported with this method.

Categories

Resources