Drupal Ajaxifying Everything - ajax

Is there any way of ajaxifying Drupal so that page reloads are not reloads but just content modifications?
So menus would be updated, content would be updated and any blocks etc. would be appropriately modified but without the overhead of spitting out the whole page to the the user for client-side fixing up and without losing the nice javascript UI that Drupal has (like collapsible fieldsets, draggable table items and other ajaxified modules etc.).

the simplest solution is to use the ajax pagers in your views (this works only for one block at time or for the main content)
to ajaxify every form you can use http://drupal.org/project/ajax
if you want to ajaxify everything then a page reload is the better option to go =]

Related

What are full page reloads and Why did we need to do full page reloads without ajax?

I was reading up on ajax and how it empowers us to exchange data with a server behind the scenes and consequently avoid full page reloads. My confusion lies here, I don't really understand what full-page reloads mean. I think it's probably cause I've been working with ajax/react since the start I guess and have not really seen any webpage of mine fully reload when I access stuff from a database or an api.
It'd be great if someone could explain what they are and why did we need them before ajax?
A full page load is where the entire page is downloaded from the server. A page typically consists of several sections: header, footer, navigation, and content. In a classic web application without AJAX, a user clicks on a link to another page, and has to download the full page, even though only the main content is changing. The header, footer, and navigation all get downloaded again even though they don't change.
With AJAX there is the opportunity to only change the parts of the page that will change. When a user clicks on the link, JavaScript loads just the content for that link and inserts it into the current page. The header, footer, and navigation don't need to reload.
This introduces other problems that need attention.
When AJAX inserts new content into the page, the URL doesn't change. That makes it difficult for users to bookmark or link to specific content. Well written AJAX applications use history.pushState() to update the URL when loading content via AJAX.
There are then two paths to get to every piece of content. Users can either load the URL containing that content directly, or load the content into some other page by following a link. Web developers need to test and ensure both work.
Search engines have trouble crawling AJAX powered sites. For best compatibility, you need to employ server side rendering (SSR) or pre-rendering to serve initial content on a page load that doesn't require JavaScript.
Even for Googlebot (which executes JavaScript) care must be taken to make an AJAX powered site crawlable. Googlebot doesn't simulate user actions like clicking, scrolling, hovering, or moving the mouse.
Content needs to appear on page load without any user interaction
You must use <a href=...> links for navigation so that Googlebot can find other pages by scanning the document object model (DOM). For users, JavaScript can intercept clicks on those links and prevent a full page load by using return false from the onclick handler or event.preventDefault() in the click handler.

jQuery mobile - after browser refresh page totally messed up

I'm developping a jqm application with spring mobile in the back-end.
Whenever I hit the browser refresh button on my mobile phone the page is completely devastated afterwards. Browsers back-button works properly.
The data are still available due prg pattern (flashAttributes in Spring) after refresh. Only the view is malformed.
Any ideas how to solve this problem?
From jQuery Mobile docs :
The simplest approach when building a jQuery Mobile site is to reference the same set of stylesheets and scripts in the head of every page. If you need to load in specific scripts or styles for a particular page, we recommend binding logic to the pageinit event (details below) to run necessary code when a specific page is created (which can be determined by its id attribute, or a number of other ways). Following this approach will ensure that the code executes if the page is loaded directly or is pulled in and shown via Ajax
So what happens is - in jQuery Mobile, the scripts and styles defined in the head are loaded only once. So, in normal conditions, it works fine, as all the pages will use the scripts loaded from the first page.
But. When you refresh a page in-between, it triggers a page-reload instead of the ajax navigation model thatjqm uses. So all the scripts and styles loaded from the first page will not be included from here on out.
What you need to do is "reference the same set of stylesheets and scripts in the head of every page", so that even if you hit refresh in the middle, the scripts and styles that had been loaded from the head of the first page are loaded again.
I recommend you read the docs from the above link fully to gain a better understanding.

How not to reload footer on page navigation

I have music application in which I have simple player in footer. User can choose songs from main page list and play it in footer. Now requirement is even if user moves fro home page to other pages(profile, bookmarks) in application the footer player should not get reloaded and should keep playing audio selected on home page initially.
How do I do that? DO I need to load pages through ajax?
Edit:
I forgot to mention that development is 80% completed and footer reloads on every page load. How much of rework is needed if I have to use Ajax now?
Use PJAX. Reload just the parts of the page that you want: https://github.com/rails/pjax_rails
It's already integrated with Rails and everything you put outside of this block will not be reloaded:
<div data-pjax-container>
<!-- PJAX updates will go here -->
</div>
Here's another solution similar to PJAX and Turbolinks
https://github.com/igor-alexandrov/wiselinks
Some very good answers already, but i just wanted to explain your problem better.
HTTP requests is "stateless", which means that each request are fully independent and their is no way you can know anything about how the page was before you requested a new page. This makes it impossible not to reload the footer on each request, using only HTTP.
You can use cookies to keep information between request, so you could start the player where it stopped before the request, but it will still reload (and stop for a short duration).
You can also have the rest of the page in a iframe, and only change the content of the iframe.
However these solutions is not very good for various reasons, so i would strongly recommend the last and best solution: ajax.
The simples solution is properly pjax as #aledalgrande suggested (or wiselink as suggested by #adbeel). This will i practice make your site a "one-site-application" where you use ajax to replace specific parts of the page instead of the whole page. It should however be fairly simple to integrate, even in a existing rails application.
Since you put jQuery as a tag I suggest you either look at http://api.jquery.com/load/.
You can using plain old HTML and making it easier & faster to deploy since the app is almost 'done'. Later you should implement a better (ajax) option.
Simplified: index.html
<iframe id="mainframe" src="other.html"></iframe>
<footer>
Don't reload me pls :D
</footer>
on page navigation (links) you act only on the mainframe, leaving the footer not reloaded.
NOTE: This is ugly and may will give you problems but might serve you to do minimal modification and having your site live asap.
Then rewriting the whole thing to using ajax could be 'some work required' to 'heavy work required' depending on how the app is already implemented. note that will never be 'few or no work required'.

Ajax content, and noscript alternative- best practice?

I have a content listings page on a site I'm developing that uses ajax to pull items based on filtering picked by the user. (filter by date/ tag/ genre etc)
In order for the page to work for crawlbots and non-javascript users I have a standard listing of content as well, hidden, but with a noscript tag in the header making it display:block
(Have been told this is okay in html5).
Trouble is- the site is doing everything twice now- loading the content via ajax as well as the alternative, only to be hidden with CSS.
I know for sure this isn't best practice, but I'm struggling to think of a solution where the content only loads once. Any thoughts on the matter would be greatly appreciated.
You could display them always with CSS, and then hide them with JS. (Without the use of noscript)

Including CodeIgniter form in existing page

I would like to include a CodeIgniter comment form in an existing php page. Currently I am including the comment form with
$_SERVER["REQUEST_URI"] = "comment/index2/".$page;
require_once($directoryLevelPrefix . "staff/codeigniter/index.php");
However, when codeigniter loads the view to display the results of the form I lose the content on my original php page which contained the form. I have tried adding a redirect after the form data is added to the database to redirect to my original php page e.g.
redirect($_POST['return'])
But I want to pass some variables, such as 'thank you for your comment', and this causes a headers already sent error.
Alternatives might be to use ajax, but I would like the whole page to refresh when the comment is submitted.
I had a similar need and I just loaded the CodeIgniter form in an iframe. This was to put a contact form on a WordPress page. I went with the iframe because my needs were limited to this one form and I felt it didn't require trying to integrate CodeIgniter and WordPress in any way.
One Pro of this method is that the form can be submitted and load a confirmation page, an error page, or even be a multi-page form and all that navigation takes place inside the iframe so you never leave the page that you are on while using the form. Another Pro is that the form is totally portable.
The Cons of course are anything you might not like about using iframes which could be many things based on your needs and preferences.
That is because CodeIgniter is a framework designed to handle displaying entire web pages. You can't just include it, as it tries to send new headers and everything.
Two solutions:
You may be able to load the codeigniter page as the main page, and just include your original php code like a view file. This depends on how your original php file is set up.
You could possibly use cURL to call the page from your own server, to get the html output as a string, then echo it to your current page. This isn't very efficient though.
As C. Scott Asbach mentioned, you could load the whole page in an iframe. Probably not a good idea though, as far as I'm aware iframes are deprecated and make for messy websites.
Probably best is to just try and avoid using CodeIgniter to display a subform in an existing page :-)

Resources