Principle

This library turns a traditional navigation per page, by using ajax navigation tabs in javascript. All pages changes are in tabs (except specific configuration, see below). The mechanism intercepts all links and submit of pages (unless excluded, see below).

schema ajaxify process

Features

  • Opened in JS tab (same or new) the next page
  • Use the HTML5's history object (for the browser previous / next buttons)
  • Automatically reopens tabs of the previous navigation (using localeStorage)
  • Remove the tabs saved after a logout
  • Merges <script>, <style> and <head> elements when loading a new page (lazy loading)
  • Runs inline Javascript on the page (Keeps events and DOM changes)
  • Keyboard navigation between tabs with shortcut: Ctrl + Shift + left / right arrow
  • Allow to display page in modal
  • Managing the server error page (500) for display in errors
  • Can refresh one or more tabs / subparts tabs
  • Closing a tab after a form validation

Browser compatibility

Chrome/Firefox/IE>=10

Accessibility

The mechanism uses the WAI-ARIA API and requires no modification of the server side (non-intrusive)

Dependencies

  • JQuery 1.11+ (not tested with Jquery 2.x)
  • Bootstrap

Operation

We can open only once a same page (comparison of the <title> HTML page). To open the same page multiple times, you need a different <title>.

  • To display a link in a new tab, it must be added the CSS class 'tab'
  • To load a modal page (eg login), add in the head of the target page a <modal />
  • To unable ajaxifier on a link, add CSS class 'noAjax'
  • To close a tab after form validation, add the attribute 'closeable-tab = "true"' on the <form>
  • To refresh a different tab on a form validation or a link, add a tab-refresh attribute = "[url]" on the html link (it is possible to block refresh in case of validation errors by adding the <error > in the head in the same page). It is also possible to refresh several pages (separator ':') or parts of pages (using a CSS selector: /url#.classCSS)

Settings

Option Devault value Description
ajax Links 'a: not (.noAjax)' CSS selector searched for links
tabLink 'tab' CSS class to add on a link to open the target page in a new tab
modalPage 'modal' HTML tag to be added in the head of the page display popup (<modal />) errorTag: 'error' HTML tag to be added in the head of the page in case of input error (prevents refresh another tab if specified)
noAjaxLinks '.noAjax' CSS selector for links not ajaxifier (eg for anchors or links already using ajax)
logoutClass 'logoutApp' CSS selector to ask ajaxifier empty the localStorage and remove beforeunload (if disconnected)
forceQuitClass 'forceQuit' CSS selector for links to exit without confirmation (eg logout link)
errorTitlePage 'Error' Title of the error page (<title>)
errorContentMsg '#MSG' CSS selector of the div containing the error message to be displayed
refreshContent '#mainContent' CSS selector of the portion of the page to refresh
refreshModalContent "#pagecontent" CSS selector part of the page to be displayed in the case of a modal page (may be equal to refreshContent)
excludeModalLinks ["/ j_spring_security_check"] Table exclusion browsing history (eg page 302 after a modal as POST login / password)
reopenHistoryTabs Enable / disable the feature reopen the tabs saved in the localStorage
maxTabs '100' maximum number of open tabs (default: 100)

HTML

sample page structure used by ajaxify

<!-- Target div for display tabs -->
<div id="v-tabs"></div>

<div id="maincontent">
    <!-- HTML CODE -->
    <script>
        <!-- INLINE JS -->
    </script>
</div>

sample HTML resource used by ajaxify

<!-- Modal de warning pour avertir qu'il y a des modifs dans un onglet avant de le fermer -->
<div class="modal fade" id="tabModifsModal" tabindex="-1" role="dialog" aria-labelledby="modifsDetected" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content panel panel-warning">
      <div class="modal-header panel panel-heading">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fermer</span></button>
        <h4 class="modal-title" id="myModalLabel">Modification en cours dans l'onglet</h4>
      </div>
      <div class="modal-body">
        Vous allez perdre toutes vos modifications.
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Laisser ouvert</button>
        <button id="tabCloseConfirm" type="button" class="btn btn-warning">Je ferme quand même</button>
      </div>
    </div>
  </div>
</div>

<!-- Modal de warning pour avertir trop d'onglets ouverts -->
<div class="modal fade" id="maxTabsOpen" tabindex="-1" role="dialog" aria-labelledby="maximumTabExceeded" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content panel panel-warning">
      <div class="modal-header panel panel-heading">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fermer</span></button>
        <h4 class="modal-title" id="myModalLabel">Avertissement</h4>
      </div>
      <div class="modal-body">
        Vous avez dépassé le nombre maximum autorisé d'onglets ouverts. Veuillez en fermer pour continuer votre navigation.
      </div>
      <div class="modal-footer"<
        <button type="button" class="btn btn-default" data-dismiss="modal">D'accord</button>
      </div>
    </div>
  </div>
</div>

<!-- Modal générique pour intégrer une page dans une modal -->
<div class="modal fade" id="pageModal" tabindex="-1" role="dialog" aria-labelledby="modifsDetected" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content panel panel-primary">
      <div class="modal-header panel panel-heading">
        <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Fermer</span></button>
        <h4 class="modal-title" id="myModalLabel"><!-- Titre de la modal --></h4>
      </div>
      <div class="modal-body">
        <!-- Contenu de la modal -->
      </div>
    </div>
  </div>
</div>

© Company 2015