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"
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'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.
cuIzgaraKay is a javascript code I want to use it in sql command as cuIzgaraKay.id(it gets the value correctly I checked it). However, I could not it. I googled it but I can't find what I search . How can i do it ? sorry for asking syntax error but I can't find it maybe ı have logical error
if(cuIzgaraKay){
<?php
include_once('../phps/kutuphane/inc.php');
$result = mysql_query("select id from bolge_db where parent_id="?>+ cuIzgaraKay.id + <?);
As far as I can tell, you're trying to execute an SQL query from the PHP page, using data from the Javascript code you're generating.
The Javascript is only evaluated on the client side of your page. That means that the server-side cannot know anything about the Javascript code.
What you need to do, is to generate the ID, and communicate it to the PHP backend, for example with a HTTP POST/GET request or something.
EDIT:
If you're new to Javascript, I'd suggest you look into the native JS object XMLHttpRequest. You use it like this:
/*
params:
url: relative URL on host, e.g. '/users/morten/data'
method: GET, POST, PUT, DELETE, HEAD or OPTIONS
data: data to send with request, e.g. POST form-data
ok_cb: function to call on success
fail_db: function to call on failure
*/
function http_req(url, method, data, ok_cb, fail_cb) {
var client = new XMLHttpRequest();
client.onreadystatechange = function () {
if(client.readyState == this.DONE) {
if(client.status == 200 || client.status == 302 || client.status == 304)
ok_cb(...);
else
fail_cb(...);
}
};
client.open(method, url, true);
client.send(data);
}
Or you can use jQuery or a ton of other frameworks to do the same thing.
EDIT:
what is method in there how can i write there and how can i get data from php – user1702486
The method is whatever HTTP request method you want to use. See the wikipedia page for more info: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
This code will POST to /page.php sending a data-string along.
If the request returns a successful code, the ok-callback will be called.
// handle HTTP OK
var ok = function(meth, res, url) {
console.log("OK: got " + res);
}
// handle all else
var fail = function(meth, res, url) {
console.log("UTTER UTTER FAILURE!\n" + res);
}
// make a HTTP POST to server/page.php sending the data along
// you can serialize the data and use XML or JSON or whatever instead
http_req("/page.php", "POST", "username=usr&password=passw&userid=12345", ok, fail);
On the PHP page, you will need to handle the POST by checking the data and returning an answer if appropriate. Something like this:
<?php
if (empty($_POST))
{
print_r($_POST);
...
// do something with the data and print something back
}
?>
If you've posted "data1=1234&data2=5678&str=hello%20mum" the $_POST array will look like this:
(
[data1] => 1234
[data2] => 5678
[str] => "hello%20mum"
)
You can't, javascript is client side and php is server side. So the php code gets executed before the javascript.
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.
Hi i would like to use ajax in my website where all requests pass are loaded in index.php (i use htacess for rewriting urls) so when i use ajax i always reload the current page and then use if(expressio) to check if the user has called a function with ajax but this cause that all the page is reloaded each time i use ajax.
I was wondering if there is a method to call a specific php method/function or property in the current page with ajax without reloading all the page.
I'm using the jquery library for ajax
If someone knows some other ways is ok!
A main use of ajax is that you call asynchronously something. Most often functions-methods that are called with ajax do rely on the same php file (if not then it's okay) with other stuff that you do not need to call asynchronously.
For example you have a method that is called via ajax to autocomplete a text field (like google search) in a file that there is other stuff you don't want to execute too.
If you are under some mvc then you have controller check this out and make sure that only the requested method is called (I've done it successfully). So it is easier controlled under an mvc, all things are in classes...
If not under mvc then I guess you have to implement something like controller in order to call only the methods you like. However there is a conition that should be espected, no code should be found out of classes cause it would be executed on "include", it would go like this:
file ajax handler
1.Check if an ajax call
2.if check false return;
3.if true then get the name of the class file
4. call the desired method (or methods, you have an execution flow predefined during to your needs)
So it can be done. It is important not to execute code that is not supposed to be executed since then undesired results (or errors) would occur.
in ajax i use the current url as the action of the request but this
cause the re-load of the whole page.
Since you have your own mvc it could go like this index.php/rt=request/action where request=the name of the controller (which in the end is a class), and action is the name of the action (which in the end is a method inside the class-controller you are requesting) for example
mysite.com/rt=user/create
My point is that you don't care what the current url is, all you care is to call the right method(=action) of the right class(=controller).
The login class is istantiater in all pages because it check if a user
is logged;
I don't really understand this (when you say pages you mean php files?), whatever it is I suggest (if haven't done already) to follow the single entry point (no need to do this for ajax calls) where every request hits only to index.php like I showed you above. Then a few lines of code on the very top can do the login check.
And a last thing what kind of ajax is this that reloads all the page, this an example how I do ajax for autocomplete in a text field:
put this as it is in head-script-javascript to make the connection
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
or even better you can have it in a separate file and include it wherever you need it
then I use a function to do the asunchronous call, what I am doing is similar to your needs because I too get data from html and pass it to php (read the comments) and then execute sql.
function getMatch()
{
//get the form values, I have one value here, you get as need as many as you need
var str = document.getElementById("categ_name").value ;
var url = "internal.php";//php file to execute
//now pass the html form parameters to php
//do you see here controller is defined, it is named asynch
//then see the action (method of controller class) it is called getMatch
//then see how I pass the html form data with str, it is the string to match
//comcateg is the mysql table to get the match
var params = "rt=asynch/getMatch&data=" + (str)+"&from=comcateg";
request.open("POST", url, true);//use post for connect harder to attack, lots of data transfer
//Some http headers must be set along with any POST request.
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.onreadystatechange = updatePage;
request.send(params);
}////////////////////
Then when the answear will be back this function will be called because we defined so above in the code
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200)
{
//test
var r=request.responseText.split("$$");
alert(r[1]);
}
else{
//alert("status is " + request.status);
}
}
}
I think now you can do it without problem, remeber whatever would be echoed by php even errors all of them will come back in the request.responseText. This is a tutorial among others about mvc that I like, https://sites.google.com/site/mhabipi/php-reading-material/superMVC.htm?attredirects=0&d=1 it's written by Kevin Waterson but sadly phpro.org does not work anymore.