If you check it out I have a bit of a problem with the following, I have a form (webbooks.phtml) in which I use a jQuery function
http://pastebin.com/7Pbd43fC -webbooks.phtml ( is actually a menu and in fact a view where you type the product that you are searching for)
http://pastebin.com/q8RJWdb7 -webbookscontroller ( this is a controller, which uses an API to get the data out of an SQL data base based on the string/number...etc given by the webbooks.phtml)
http://pastebin.com/vuy9GUvP -index.phtml (this is the view space where the result should be viewed.)
This is the array that I get:
{"book_title":"Bioethics in the 21st Century",
"id":"1424",
"isbn":"978-953-307-270-8","
unix_name":"bioethics-in-the-21st-century",
"visible_online":"1"}
I can see this array when I
die((json_encode)$result);
and I want this array to get to my view (index.phtml)?
I am new to PHP and I'm trying to do something that may be bad practice and may well be impossible. I'm basically just hacking something together to test my knowledge and see what PHP can do. Is this possible?
This is an example of basic usage of calling Zend Controller with ajax/json and get response to the same phtml,
so you can use it in your code.
In .phtml file I have javascript which call (in IndexController) the action ajaxAction():
<script language = "Javascript">
var param1 = 'first'; //or get value from some DOM element
var param2 = 'second'; //or get value from some DOM element
jQuery.ajax({
url: '/default/index/ajax',
type: 'POST',
data: {param1: param1, param2:param2 },
dataType: "json",
success: function(result){
var return1 = result.return1;
var return2 = result.return2;
// return1 and return2 is value from php file.
// fill out DOM element or do the windows.location()
}
});
</script>
In IndexController the ajaxAction() should get request:
public function ajaxAction(){
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
$param1 = $this->_request->getParam('param1');
$param2 = $this->_request->getParam('param2');
// DO THE OTHER STUFF AND LOGIC HERE
$results = array(
'return1' => 'value1',
'return2' => 'value2'
);
$this->_response->setBody(json_encode($results));
}
In any way I suggest to listen the #jakenoble and look at(learn) Context Switching in Zend.
If the result of your client-side call is just a redirect to another page, then why not do it all on a single controller/action/viewscript, as follows:
Make the form submit a GET request rather than a POST
Submit the form back to the same page, perform your remote API call, and render the results.
Even if you want to do it in two actions - one to show the form, another to display the results - I don't see what value you are getting from the AJAX call.
Am I missing some other requirement?
Doing it with the current structure, you'd have to save the results of the remote API call into the session and then retrieve it after the redirect. Do-able, but it strikes me as unnecessary if it can be done in a single action.
Related
I am trying to develop a form in Joomla. The basic problem is:
How can I alter the form select options depending on what the user has chosen before? I need to make several database requests, while the user fills the form. With AJAX, I will need a processing PHP file. Can someone tell me how to do this in Joomla, because with JCE File browser I can't add any.
Thank You!
Assuming you already know how to write a "normal" Joomla component that retrieves data from database and shows them in a page, here's the proposed solution.
In my example I will dynamically retrieve a list of "products" for the selected "category".
COMPONENT: the server part of the Ajax request
Let's say we use JSON to exchange data in the Ajax call.
Within every Joomla component, you can create a JSON view, creating a file view.json.php alongside the default view.html.php. That view will be used when you add "format=json" to your query string.
So you create these additional views that use the same model to get data, but output them as a JSON string. The JSON view is usually something very simple, like this:
public function display()
{
$this->products = $this->getModel()->getProducts();
echo json_encode($this->products);
}
You also need to add the "tmpl=component" so that the response only contains data from the component and not the rest of the Joomla page (like modules and such).
You should end up in a situation where you can put in the browser:
http://yoursite/index.php?option=mycomponent&view=products&format=json&tmpl=component
and you will get a JSON list of products.
Add filters to your request
Of course you only want products for the selected category so you should modify your "getProducts" model method to check for a querystring parameter like category=xyz.
The URL becomes
http://yoursite/index.php?option=mycomponent&view=products&category=1&format=json&tmpl=component
P.S. a more detailed discussion on how to implement the check is off topic, because it's not related to AJAX.
JQUERY: the client part of the AJAX request
Now that you have a component that accept requests via URL and provide a JSON response you can use jQuery to get new data each time the "category" select is changed:
var category_select = $('#category');
var product_select = $('#product');
var request = jQuery.ajax({
"url": 'index.php?option=mycomponents&view=products&tmpl=component&format=json&category=' + category_select.val()
"type": "GET"
}).done(function (result) {
result.each(function (product) {
var new_option = jQuery('<option/>', {
'value': product.id,
})
.text(product.name)
.appendTo(product_select);
});
})
This JS code should be added in the same page where you show your form.
I am new to Ruby on Rails, and I would like to know a Rails equivalent for something I am used to do using PHP.
When checking if a user input meets certain criteria, I usually make some Ajax calls using javascript to a php page that processes the data and echo a json data. I then use the json data to construct appropriate behaviors.
For instance, let's assume a user submitted a postcode and I want to run some checks on the postcode on server side. I would do something like this in js:
// This is what the user submitted
var postcode = $("#postcode").val();
// Here, I post it to a PHP file
// PHP file examines the data and returns result
// (in this case, if the postcode is covered or not)
$.post("scripts/postcode_handling.php", {postcode: postcode}, function(data) {
var result = jQuery.parseJSON(data);
// Check the coverage
if (result.coverage == true) {
// Do Something
} else {
// Do something
}
And on the php file I will do something like:
...
$result = array('coverage' => false , 'message' => "Your postcode is not covered")
echo json_encode($result);
....
I tried to do something similar in Rails by replacing the php file with an action under a controller, but I could not figure it out. Is this a common practice in Rails, and how can I do something like this?
Let's use your post code example. Let's say you wanted to do an address lookup based on post code.
Create a route
Create a controller and an action to handle the request
Create the Javascript logic to handle sending the request and DOM manipulation
Open a config/routes.rb and add a route:
resources :address_lookups, only: :new
Create a controller to handle the route:
rails g controller AddressLookups
The above command creates a new controller called address_lookups_controller.rb inside app/controllers.
Now add the necessary logic inside the controller to handle the address lookup:
class AddressLookupsController < ApplicationController
def new
# This action will expect a params[:post_code] variable
# that you will pass with your ajax request
post_code = params[:post_code]
address = FindSomeAddress.lookup(post_code)
render json: address
end
end
Now create a JavaScript handler to send the request and handle the return. If you generated the controller there should already be a file called address_lookups.js.coffee inside app/assets/javascripts. Here's some pseudo code.
jQuery ->
$('#post_code').on 'blur', ->
field = $(this)
post_code = field.val()
if post_code.length is 8
xhr = $.ajax
url: "/address_lookups/new"
data:
post_code: post_code
success: (data) ->
# do something with data
dataType: "json"
In my website I will have a "browse catalogue" button, which, onclick will change several elements of the page to display the catalogue element. I dont want a full page reload because several elements such as the nav bars and news feed will stay the same.
My question is how can i change several different divs with ajax onclick?
Essentially im not sure how to do place several different components in different divs across a page.
And i know there's a limit on simultaneous ajax calls, so im sure the proper way to do it wouldnt be to make a unique ajax call for each of my divs.
A little guidance would be great.
Using jQuery, you can get an json array of elements for each block that needs to be updated:
In your html page:
$.get("page.php?id=42",
function(result){
$('#title').text(result['title']);
$('#description').text(result['description']);
$('#price').text(result['price']);
}, "json");
In page.php:
$result = array('title' => 'foo', 'description' => 'bar', 'price' => 3);
echo json_encode($result);
header('Content-Type: application/json');
die();
I'm not sure if the right decision will be to send several ajax requests. Just create a request with unique attribute value, in so shape that server will know which blocks you need. On server side all required blocks concatenate in json object, and return it to client. After just parse object on blocks that should be. For example
$.ajax({
url : 'http://your.server.doment',
data : 'block[]=1&block[]=7&block[]=15',
type : 'post',
dataType : 'json',
success : function (object){
for( el in object) { $('#block_'+el).html(object[el]); }
}
});
you can use json
example
php request ajax
$div1="<table><tr><td>x</td></tr></table>";
$div2="<table><tr><td>x</td></tr></table>";
$div3="<table><tr><td>x</td></tr></table>";
$json = '{"div1":"'.$div1.'","div2":"'.$div2.'","div3":"'.$div3.'"}';
return $json;
uses jquery
$.ajax({url: 'ajax/test.php',
success: function(data) {
var obj = JSON.parse(data);
$("mydiv1").html(obj.div1);
$("mydiv2").html(obj.div2);
$("mydiv3").html(obj.div3);
}});
if you have a error in the parce function
replace spaces
example
$arr =array("\n","\t");
$div1= str_replace($arr,"",$div1);
Practically, ten or more elements updated in parallel on the page (each by a separate ajax) will not make such a big difference (unless you can test it with your website deployed into productive environment and prove I am wrong).
Nonetheless, if you wish to compact all the data exchange to one single request/response ajax call - it is very well possible but does require certain flexibility on the server side (see http://php.net/manual/en/function.json-encode.php).
I.e. one of the possible solutions is to produce json response on the server side, that generates a key-value pairs (JSON - javascript {} object) with keys being id of your elements and values being (new) html.
There are tons of ajax JS frameworks as jQuery, prototype, dojo, etc. (I will pick jQuery for this one).
Ajax request
$.ajax({
...
})
See http://api.jquery.com/jQuery.ajax/
Server response
// Assume we got
// var data = {key1:'html1',key2: 'html2'};
// Ajax handle can look like
success(data) {
$.each(data, function(key, val){
//console.log(key, val);
// Do some checks here.. But key should indicate #id of html elements
$(key).empty().append(html);
});
}
This is a basic outline but should keep you going into the right direction.
I'm working on a PHP / AJAX application and it's quickly becoming unmanageable!
The application is designed to work much like a a desktop application so almost every user action results in an AJAX call.
For every one of these actions I have some jQuery that posts the data to my PHP script and runs a corresponding PHP function that handles the server side actions.
That means in my jQuery file i'll have something like this:
$('.delete-project').on('click', function(){
// Ajax request to http://myapp.co.uk/ajax/delete_project
});
$('.delete-user').on('click', function(){
// Ajax request to http://myapp.co.uk/ajax/delete_user
});
$('.delete-keyword').on('click', function(){
// Ajax request to http://myapp.co.uk/ajax/delete_keyword
});
I'm sure there is a better way of doing things, but how is it generally done to avoid lots of similar code? The above actions could possible rolled into one 'delete' ajax request which posts the item type and a database ID but a lot of my functions post different data and require different parameters so wouldn't fit so neatly under one jQuery handler.
I've tried finding some resources on how an AJAX application should be put together but all I can find is beginner tutorials on making AJAX requests etc, not how to write a scalable AJAX application.
Just to be clear I know how AJAX works, I'm just trying to find the best way of implementing it in terms of reducing the jQuery and PHP needed where possible.
Are there any good resources that deal with this sort of thing?
You can roll all those into one delete function by using attributes in HTML, for example:
$('.delete').on('click', function(){
var delete = $(this).attr('data-delete');
// Ajax request to http://myapp.co.uk/ajax/delete_{delete}
});
Then your HTML would be something like:
Delete
More information on data-attributes
Not sure if this would help but you could create some functions to reduce your code as it grows. For starters you could prevent duplicating of the ajax call by putting the jQuery .ajax function in a custom wrapper function of your own. For example:
function ajaxGet(myUrl, queryString, successCallback, errorCallback) {
if(queryString) myUrl+= "?" + queryString;
$.ajax({
url: myUrl,
type: "GET",
data: null,
success: function (res) {
if(!successCallback) return;
else successCallback(res);
},
failure: function (res) {
if(!errorCallback) return;
else errorCallback(res);
}
},
By creating a wrapper function, you can pass in the needed data without duplicating the $.ajax call code over and over in each of the click functions. You can also create a similar function for an ajax call using post. You could then dynamically build the click functions to further reduce your code:
function buildClicks() {
setupClick([url], [data], [success], [error], [$(elem)]);
setupClick([url], [data], [success], [error], [$(elem)]);
setupClick([url], [data], [success], [error], [$(elem)]);
}
//Setup clicks for each button or link
function setupClick(url, data, success, error, elem) {
elem.click(function () {
ajaxGet(url, data, success, error);
});
}
In this example I'm assuming your using a "GET" and adding a query string. You could easily adapt this to pass, a JSON formatted object for example, using a custom "POST" function. In that case [data] would be an object not a query string.
Sorry this code isn't the clearest. Let me explain it a little more. The buildClicks function would allow you to setup multiple click events on different elements by passing in the required data. I'm not sure if you are passing any data, but the above functions would allow for it. By dynamically creating the clicks you can avoid duplicating the .click code over and over. Just call the buildClicks function on document ready as such.
$(document).ready(function () { buildClicks(); });
NOTE: The success and error callbacks are functions that will be executed when your call either completes successfully or errors out. If you do not wish to use these they can be ommitted or null can be passed in. Make sure if you do pass in functions that you leave off the "()" on the end of the function name. Otherwise the functions will be executed prior to the success or failure of the ajax call. For example:
ajaxGet("http://testurl.com", null, ajaxSuccess, ajaxFailure);
ajaxSuccess() {
}
ajaxFailure() {
}
You could set an ID attributes to that buttons and a class like submit-button.
Then hang a handler on that $('.submit-button') while using an ID attribute value to define the URL to call, like that:
$('.submit-button').on('click', function(){
$action = $(this).attr('id'); //lets say the ID's value is 'delete_project'
$url = 'http://myapp.co.uk/ajax/' + $action;
// Ajax request to http://myapp.co.uk/ajax/delete_project is done
});
Anyway any web application that tends to be like a desktop one is only a bunch of JS and few HTML with some PHP behind... That is always badly maintanable...
I used [extJs][1] once for this, which led to using only jQuery and their modules while no (or just a minimum of) HTML was needed to write...
Not a copy-and-paste-solution, but maybe you find some more ideas how to build a scalable client-server application when looking for how REST APIs are built. I find REST a very good structure to keep a clear server-side API when building such apps, and i'm sure there are tutorials around how to do the corresponding client-part cleanly too.
In my application I do quite a lot of ajax calls too. I found that the easiest way to do things was to create myself a wrapper for all ajax calls such as:
var MySite = function()
{
AjaxWrapper : function(type,url,data,callback,noloading)
{
$.ajax({
type: type,
url: url,
data: data,
success:function(json)
{
if(json.status === true)
{
if(typeof callback === 'function')
{
callback(json);
} else {
// A generic success handler
}
} else {
// An error handler
}
}
});
};
}();
then you'd call it like:
MySite.AjaxWrapper("GET", "somehref", {}, function(json)
{
// json has the result of your json callback
// you could also make this a separate function
// or not have it
});
this let's you call your ajax on just about anything you want. You could then use something like data attributes, or just the standard href for anything that requires ajax and add an event to all links that pass through this function. Or, if you wanted some to do certain things just make the callback function different for those.
I'm finding this hard to explain, but this is what I've used for a couple of ajax-rich projects and it makes things so much easier!
For an example for your case you could then use something like:
$('a[class|="delete"]').on("click", function()
{
MySite.AjaxWrapper("POST", $(this).attr("href"), {param:number1}, DeleteHandler);
});
The way I would do this would be to have a single function for all actions:
$('.actions').on('click', function (e) {
e.preventDefault();
var action = $(this).data('action'),
id = $(this).data('id');
$.get('/local/handler.php', {
'action': action,
'id': id
}, function () {
// Callback stuff here
});
});
And HTML:
Delete Project
Delete User
Delete Keywork
And the PHP file should have if statements based on the action parameter that performs the requested action.
EDIT:
This way your not limited to just delete actions, so you can scale your app in the future.
Also, If the different actions become a large list (e.g. deletes of many kinds, updates, adding), I would create a separate PHP file for each action and include them in one master file. This will allow for easy scaling.
In an earlier post today the answer has led me down the route of using a JSON feed to populate elements in my page.
Something new to learn!!
the JSON data is created from a PHP script which retrieves the data from a Mysql database. The php script retrieves a specific record which I need to pass to the php script with the getJson call.
I've had success with creating the url with the parameters added as a GET method but I can't find an example of a POST method - the parameters should go as an optional parameter. here's what I have so far...
function loadData(index) {
alert(index);//debug
$.getJSON('loadJSONholeData.php' ,
{hole: index} ,
function(data) {
I've found examples for a twitter feed which shows a parameter like option: "cat", but can't find an option where the value is in a variable.
I don't understand how to use the parameters - where am I going wrong. Appreciate this is probably a fundamental issue but I'm learning.
Thanks
Update:
I've revised the code per the responses below and used both suggestions to pass the POST parameter, but the receiving PHP code is not reading the POST parameter and just returns the default query values.
I even used as static value of 1 both as a value and as a string but no joy.
Here's my receiving PHP code which accesses the POST values:
$hole = 3;
if (isset($_POST['hole'])) {
$hole = $_POST['hole'];
}
I'm missing something basic here. The value in 'index' definitely exists as it shows in the debug and JSON data is being returned )(but the default). I can go back to my GET method but want to see this work!!
Thanks
Update: Success!!
I played around further with the revised code. I removed the content type parameter from the code and it all works now, the PHP is returning the correct query.
I assume then that by specifying the JSON type in contentType it passes the POST parameter in a different way to PHP which expects it in anpther way?
Onwards and upwards - thanks
The $.getJSON() method does an HTTP GET and not POST. Try something like this -
$.ajax({
url: 'loadJSONholeData.php',
data: JSON.stringify({hole: index }),
type: 'POST',
contentType: 'application/json;',
dataType: 'json',
success: function (result) {
//(result.d) has your data.
}
});
Each key/value pair in the arguments object will represent a parameter in the HTTP POST. You can use variables as values, but I believe they will be converted to strings, so it's better to do the conversion yourself (so you can make sure they have the correct format). A simple example:
var dynamicValue = foo();
$.post('my/url', { var1:"static value", var2:dynamicValue }, function(data) {
// Your callback; the format of "data" will depend on the 4th parameter to post...
}, "json"); // ...in this case, json
Now, in case your server is expecting a json encoded object/list, you can pass it by using JSON.stringify:
function foo() {
return JSON.stringify({ my:"object" });
}
JSON should be available in most modern browsers, in case it's not, you can get it here (json2.js, under "JavaScript").