[Paris on Rails 2006] RJS, Ajax, JavaScript : notes

Paris on Rails, vendredi 17 novembre 2006.

4e présentation (après-midi).

== RJS, Ajax, JavaScript - Sébastien Gruhier

L’idée : faire du JavaScript sans écrire une ligne de JavaScript.

  • Exemple de démonstration.

[NdU: La démo en ligne et le code de l’appli de Sébastien
et d’ores et déjà dispo à http://demo-por2006.xilinus.com/
Là il montre l’équivalent de : http://demo-por2006.xilinus.com/html
puis http://demo-por2006.xilinus.com/ajax ]

Création d’un nouveau compte.
on entre son Nom/Prénom et un identifiant → l’appli web nous dit
si le compte est créée et l’identifiant choisi est disponible.

Je réessaie mais généralement au bout de 4 fois, j’abandonne
et je vais voir ailleurs.

  • en HTML classique : Click / Wait / Refresh.

  • en Ajax : traitement asynchrone.

Explication :
(schéma à visualiser avec une police à chasse fixe)


|client | → | actualisation | → | client |
| | XHR | par RJS | | |


                  [2]                [3]

[2] génération de code JS en pur Ruby

[3] Prototype voit que c’est du text/js et interprête le code

grand nombres de helpers

  • Pourquoi utiliser des frameworks JS ?

    • Ne pas réinventer la roue
    • Ecrire moins de code
    • Ecrire du code plus lisible
    • Etre sûr d’être compris par tous les navigateurs
  • Prototype 1.5

    • Extension des objets existants

Object : extends → simule l’héritage de classe
String : sub, gsub, camelize, escapeHTML…
Array : first, last, each
Event, Function

  • Nouveaux objets
    Enumerable, Element, Ajax, Form, Position

  • Sélection par ID avec $ :
    $(‘monID’).show()

  • CSS Sélectors avec $$ :
    var array = $$(‘span selected’)

  • syntaxe très proche de celle de Ruby
    [ obj1, obj2, obj3 ].each(
    function(objet) {

    }
    );

Chaînage des appels : $(‘monID’).next().show();
Gestion simple des événements
Event.observe(document, ‘keydown’, maFonction);

  • Support d’Ajax
    new Ajax.Request(‘/mon_url’, { asynchronous : true,
    evalScripts : true, onComplete : maCompleteFunction });

  • Cross Browser

exemple de ce qu’on devait faire avant :

(gérer les différences d’implémentation, notamment
avec IE)

isLeftClick : function(event) {
return (((event.which) && (event.which == 1)) ||
((event.button) && (event.button == 1)));
}

avec Prototype : Event.isLeftClick(event);

Que se passe si IE7 pas compatible avec IE6 ?
faut rajouter un ((event.machin) && (event.machin == 1)) ?

Là faudra juste mettre à jour Prototype qui se chargera
d’implémenter ça et notre code restera le même.

Event.isLeftClick(event);
(avant et après mise à jour Prototype)

(à mettre en fond d’écran ?)

  • Script.aculo.us

    • effets visuels
    • drag/drop
    • autocomplétion, slider
    • DOMBuilder
    • tests unitaires JS (le seul framework à ma connaissance Ã
      implémenter cela)
    • exemple de drag/drop
      → 2 lignes de code Ruby ou JS
      sortable.element(‘firstlist’)

    (demo en ligne : voir http://demo-por2006.xilinus.com/shop )

entre Prototype/Script.aculo.us, Dojo, DWR, Moofx, jQuery,
Yahoo UI, Atlas, Mochikit, XAJAX, GWT

Prototype en tête. Pas forcément utilisé avec Rails.

(NdU : pas sûr : Atlas, ya que M$ qui l’utilise ?)

  • RJS
    subtile intégration des frameworks JS dans Rails
    côté serveur avec techno client.

    Helper Ajax dans ActionView::Base
    link_to_remote
    form_remote_for
    submit_to_remote

    aussi link_to_function, observe_field, in_place_editor,
    drop_receiving_element

→ écrire le moins de code HTML

  • Vue RJS
    nouveau type de vue avec extension .rjs
    render sans layout ( :layout => false)
    Content-Type mis à text/js
  • Une instance de JavaScriptGenerator (page) dispo dans le template.

    page.insert_html :bottom, ‘list’, “

  • #{@item.name}

  • page.visual_effect :highlight, ‘list’
    page.hide ‘status-indicator’, ‘cancel-link’

Vue RJS

page.select(“p.hint”).each do |hint|
hint.visual_effect :highlight
end

  • Rendu inline

Directement dans le contrôleur :

render :update do |page|
page.visual_effect :blind_up, “user_#{params[:id]}”
end

→ rendu directement dans le contrôleur (viole MVC mais
évite un fichier rjs avec une seule ligne de code)

  • Respond_to
    permet de gérer plusieurs types de requêtes.

    respond_to do |format|
    format.html
    format.js
    format.xml { …}
    end

  • Code de la démo :

vue : un text_field avec un observe_field

<%= observe_field “user_login”, :frequency => 0.5,
:url => {:action => “verify_login” },
:with => “user_login”,
:loading => “$(‘progress’).show()”,
:loaded => “$(‘progress’).hide()” %>

et voir le code de #verify_login dans ajax_controller.rb

render :nothing => true, :status => ‘204 No Content’ and
return unless request.xhr? and request.post?

→ au début de l’action pour être sûr d’avoir du POST ou
de l’XmlHttpRequest (NdU: mmmh on peut pas utiliser verify
à la place ?)

Navigation : Rien à faire !

5 lignes dans le contrôleur et j’ai fait un site Web2.0 !

  • Tests
    ARTS, plugin par Kevin C. (plugin candidat Ã
    l’inclusion dans Rails)

** Conclusion

2 frameworks JavaScript

Rails : premier framework à avoir intégrer Ajax, de manière simple
et complet

90% de JS (NdU: euh… à écrire en moins ? ou couvre 90% des
besoins ?)

demo : http://demo-por2006.xilinus.com
(+ sources)

  • Questions.
    1/ render :partial et page ?

:partial et page, rien à voir. Mais on peut utiliser RJS
pour mettre à jour un partial.

(celui qui pose la question décrit ce qu’il a essayé de faire)

Euh… ça c’est la mauvaise méthode.

2/ Accessibilité d’AJAX, avec Unobstrusive JS

  • plugin avec un statut particulier, DHH est tombé amoureux
    de celui-ci depuis RailsConf Europe, où un talk était consacré
    Ã UJS.
  • Ã terme dans Rails ?

3/ Comment Prototype et Rails sont liés ?
le créateur Sam S. est dans la Core Team, il a dû créer
Prototype pour être intégré à Rails.

4/ Ya pas un Page dans le contrôleur, problème du MVC, c’est gênant ?
(NdU: quand on fait directement un render :update do |page| dans
le contrôleur)

MVC : c’est une aspiration, pas une règle strict.

(NdU: on peut mettre dans un helper, on met tous les unilignes dans
un seul fichier helper, et voilà tout le monde est content. Voir
aussi le talk de Jason Molina Jr à RailsConf Europe)

-- Jean-François.