X post from http://drupal.org/node/953016
The Drupal 7 AJAX system is great, it works very smoothly for forms and even for links.
What I can't work out how to do in a sane way is to call it from javascript. I may want to have a dynamic page without a form and as part of that make a Drupal ajax call, specifically so that the ajax commands get run on return.
The most effective way I have found to do this so far is:
dummy_link = $('Loading Vars');
$(vars_div).append(dummy_link);
Drupal.attachBehaviors(vars_div);
dummy_link.click();
Which is effective but a huge hack. I havn't found a way to perform an ajax call and have the Drupal ajax framework do it, rather than the standard jquery framework.
I would have thought that it was possible to invoke the drupal ajax api directly, does anyone know how?
The short short answer is you'll want to get yourself to something like:
$.ajax(ajax.options);
Which is the jQuery part, but with a set of options that help you hook into the Drupal Goodness in terms of success handling, effects, etc. This is what is effectively what's hapening for you in your "huge hack" example.
Creating a new Drupal.ajax function programatically still requires a synthetic element:
base = 'someid'
element = $('Loading Vars');
element_settings = {'url': uri, 'event': 'click'}
myAjax = new Drupal.ajax(base, element, element_settings)
But you can at least trigger it without simulating a click in the UI:
myAjax.eventResponse(element, 'click')
It feels like there should be a better way to do this, but it requires another way to set up the initial ajax prototype that doesn't require a DOM element. Because so much of the interaction-set hinges on how to move data back into the DOM, I don't think this use-case is well-supported yet.
It may also be possible to go direct to jQuery with a proper set of options and get the effect you want, but the Drupal.ajax protoype functions self-refer quite a lot so doing it without a Drupal.ajax class seems dicey.
Related
I want to create a page with will be filled with dynamic info using Ajax (JQuery). The info will come from various GETs I need to do in other URLs.
I'll be using Sinatra + JQuery to to that, but as my WEB experience is almost null and don't have any idea how do to it right.
The requisites for this are:
Each time a GET completes, a new line of information should appear on the page.
If the GET could not be complete, a default info appear on the page.
My idea so far is to do something like this:
Have my controller performing each GET inside a thread.
Each time a thread ends, with success or not, I inform the view of the result and render a partial
I'll have as many partial as I need (for each GET I must do)
The first time I load the page I fill in the default info, them I update via AJAX with the successful GET responses
This does not seem the correct approach, so I'm asking someone that already did something similar or has more experience on this some help.
You start off with a simple get('/'){} route that holds the default message (or any other GET route). Then you have your other GET routes that you want to display on your default route. In Sinatra you can check whether a request is an xhr-request or not with a request.xhr? If you have an xhr request you return a json value to your view, otherwise reject the request or render a view with proper html. This is on your sinatra backend. In your views you can use JQuery or any other JS library or plain JS to handle asynchronous data requests. You can use the ajax function in JQuery to request data from your routes and then add them to your DOM. It's as simple as that :)
Now you will have to investigate on the JQuery site how to make ajax requests and how to append data to existing DOMs. That's all there is to it.
I put a Ajax link using the following code:
echo chtml::ajaxLink('GO', 'http://localhost/index.php?r=user/delete', array('method'=>'POST'));
But, regardless of giving the second parameter as URL i,e 'http://localhost/index.php?r=user/delete'. It generates link with the current URL in the browser not the URL I just specified.
What is the issue? How could I create AJAX link? Google several hours but can't solve the issue.
Any kind of help is highly appreciated.
First of all, you should always try and create normalized urls.
But i think your doubt lies in the # that is generated/appended. If you go and check the source of yii ajaxLink you'll see this:
public static function ajaxLink($text,$url,$ajaxOptions=array(),$htmlOptions=array())
{
if(!isset($htmlOptions['href']))
$htmlOptions['href']='#';
$ajaxOptions['url']=$url;
$htmlOptions['ajax']=$ajaxOptions;
self::clientChange('click',$htmlOptions);
return self::tag('a',$htmlOptions,$text);
}
so if you don't set the href property of the a tag in the htmloptions array, the # will be appended.
You should also understand that yii uses jquery, so if you check out the source of the page, you'll see at the bottom, how jquery is used to carry out an ajax request, your actual url that is called will also be seen in that script. So the third option/parameter in ajaxLink is for options for jquery's ajax function. You can create better ajax links using this option.
Regardless of where(which controller) your url points to in your project, the action associated with that url will be called.
So anyway, you can modify your code like this if you want the url to be shown and not a # :
echo CHtml::ajaxLink('GO', 'http://localhost/index.php?r=user/delete',
array('type'=>POST), //there are various other options for jquery ajax
array('href'=>'http://localhost/index.php?r=user/delete'));
To make better ajax links i would suggest going through jquery's ajax documentation. There is an option for a success function, that you can use to let the user know that the operation was completed.
Hope this helps, don't hesitate to leave comments if i haven't answered your question completely.
Have you tried:
echo CHtml::ajaxLink('GO', array('/user/delete'), array('method'=>'POST'));
as the ajaxLink documentation suggests...? Look also at the normalizeUrl method.
Using these methods, which in turn are using createUrl, is usually better since it will take care to create a valid url for your site.
I had the same issue(or maybe similar).
I've used renderPartial to load view and later in that view i was using ajaxLink and it was not working.
What i have found, that when using renderPartial, there was no jquery script for ajax action.
What you have to do is to add 4th argument(true) in renderPartial function to generate jquery script.
See the documentation: http://www.yiiframework.com/doc/api/1.1/CController/#renderPartial-detail
Hope it helps and saves time to figure it out.
Does teh whole page reload when this is set to false?
My main question is what the asynchronous does. yes i know what the word means but what does it do in code?
xmlhttp.open("GET","ajax_info.txt",true);
The word "asynchronous" is best described as "done in the background" in this context. It means that if you set this parameter to true, the request will be sent in the background and the user will be able to continue interacting with the page. If you set it to false, the page will BLOCK and the user won't be able to do anything until the request returns.
Note that this is different from the whole page reloading. The amount of traffic going over the wire is still much smaller than the whole page reload, so many of the AJAX benefits are preserved.
One reason why you might want to use synchronous (blocking) AJAX requests is when there's nothing to really do on the page while the request is loading.
BTW, since we're already on this subject: I encourage you to use a javascript framework for your AJAX needs. jQuery is fantastic. Don't use the XMLHttpRequest object directly.
Having used jQuery's ajax I found some issues with IE compatibility, so if you have to support IE6, it may be a good idea to avoid that and use straight JS.
Here's a good tutorial on it:
http://daniel.lorch.cc/docs/ajax_simple/
It's pretty nice to sort a dataset by a number of filters and get the results shown instantly, right?
My solution to do this would be to POST the "filter" (read forms) parameters to a page called dataset.php, which returns the appropriate dataset in compiled HTML, that can be loaded straight into my page.
So, besides this being a total no-no for SEO and for people having deactivated Javascript, It appears as a quite good solution to easily build on in the future.
However, I have yet not the experience to consider it a good or bad overall solution. What should be our concerns with an AJAX-fetched dataset?
So, besides this being a total no-no for SEO and for people having deactivated Javascript, It appears as a quite good solution to easily build on in the future.
Not entirely true, there are solutions out there like jQuery Ajaxy which enable AJAX content with History tracking while remaining SEO and javascript disabled friendly. You can see this in action on my own site Balupton.com with evidence it's still SEO friendly here.
However, I have yet not the experience to consider it a good or bad overall solution. What should be our concerns with an AJAX-fetched dataset?
Having Ajax loaded content is great for the user experience it's fast quick and just nice to look at. If you don't have history tracking then it can be quite confusing especially if you are using ajax loaded content for things like pages, rather than just sidebar content - as then you break away from consistency users are experienced with. Another caveat is Google Analytics tracking for the Ajax pages. These shortcomings, those you've already mentioned as well as some others mentioned elsewhere are all quite difficult problems.
jQuery Ajaxy (as mentioned before) provides a nice high level solution for nearly all the problems, but can be a big learning curve if you haven't worked with Controller architecture yet but most people get it rather quickly.
For instance, to enable history trackable ajax content for changing a set of results using jQuery Ajaxy, you don't actually need any server side changes. You could do something like this at the bottom of your page: $('#results ul.pages li.page a').addClass('ajaxy ajaxy-resultset').ajaxify();
Then setup a Ajaxy controller like so to fetch just the content we want from the response:
'resultset': {
selector: '.ajaxy-resultset',
request: function(){
// Hide Content
$result.stop(true,true).fadeOut(400);
// Return true
return true;
},
response: function(){
// Prepare
var Ajaxy = $.Ajaxy; var data = this.State.Response.data; var state = this.state;
// Show Content
var Action = this;
var newResultContent = $(data.content).find('#result').html();
$result.html(newResultContent).fadeIn(400,function(){
Action.documentReady($result);
});
// Return true
return true;
}
}
And that's all there is too it, with most of the above being just copy and pasted code from the demonstration page. Of course this isn't ideal as we return the entire page in our Ajax responses, but this would have to happen anyway. You can always upgrade the script a bit more, and make it so on the server side you check for the XHR header, and if that is set (then we are an ajax request) so just render the results part rather than everything.
You already named the 2 big ones. Now all you need to do is make sure all the functionality works without javascript (reload the page with the requested dataset), and use AJAX to improve it (load the requested dataset without reloading the page).
This largely depends on the context. In some cases people today may expect the results to be delivered instantly without the page refreshing itself. It does also improve overall user-experience - again, this largely depends on the context.
However, it does also have its pitfalls. Would the user have a need to return to the previous pages after the ajax content was delivered? Since this may not be as simple as pressing the Back button in the browser.
i am using cakephp in my project. in this at one section i need to update the particular row onclick of the image. using ajax. i used mootools as javascript library. so please help me how could i do this.
thanks in advance
Simply speaking:
Create a CakePHP controller action that performs the row update.
Determine the URL of the controller action you just created. (ie. /controllername/actionname)
Determine if you need to do a GET or POST request to this URL for it to work.
Put code in your view that attaches an "onclick" event that makes and AJAX (GET/POST) request to the above controller.
CakePHP has a javascript helper that traditionally produced Prototype code, but in v1.3 it is now able to produce code for other Javascript frameworks (such as Mootools, jQuery, etc.)
However, many suggest writing your javascript in javascript (eg. actually using the Mootools framwork), rather than writing your javascript in PHP (like using CakePHP's helper to produce Mootools code).
Either way, in your view you need to have something like: <?php echo $js->link(.. or <script>Moo.. or <a onclick="Moo.. to attach your Javascript to that link.
You may also wish for your controller action to return some sort of response indicating whether or not the row update failed or succeeded. In that case you need to make sure the CakePHP controller action you are calling has a view that outputs this. JSON seems to be the ideal format for this (eg. { success: true }), but you need to remember to turn off Cake's debug output. This response can be captured into a variable by your Mootools code where you can decide what to do with it (eg. displaying an error).
As i know most programmer work with protype.js library.
i am giving you link see
go to there