/extension/myblog/design/myblog/stylesheets/white.css
/extension/myblog/design/myblog/stylesheets/black.css

Select your style :

A la une // Les blogs sur le développement Web, l'oenologie, Montpellier, etc...

Faire de l'édition frontale AJAX avec eZ Publish & Mootools (Partie 3)

Pour terminer cette série de billet (voir la partie 1 et la partie 2) concernant l'édition frontal AJAX sur eZ Publish, voici des extraits de code et quelques détails de fonctionnement concernant ce qui n'est pas encore décrit à ce stade, à savoir :

  • La génération de masques de saisie en mootools (mes fameux custom captions)
  • La couche eZ Publish et la mise à jour des données

Les custom captions en Mootools

Comme vue dans le précédent billet, la déclaration de la classe ajaxwebin nécessite de renseigner la propriété caption par l'instance d'une classe spécifique permettant de générer le masque de saisie attendu sur clic d'une zone éditable, comme par exemple :

Instance d'une classe pour une liste déroulante

new ajaxcaptionsSelect({  
 'minValue': 0,
 'maxValue': 12,
 'setStyles': {margin: '0 -10px', border: '1px dotted #000', background: '#ffffdd'}
}))
 
 

Instance d'une classe pour un champs de saisie

new ajaxcaptionsInput({  
 'setStyles': {border: '1px dotted #000', background: '#ffffdd'}
})
 
 

Définition de la superclasse et des classes hérités

J'aurais pu exploiter diverses techniques pour définir une superclasse ajaxcaptions et ses classes dérivées ajaxcaptionSelect et ajaxcaptionsInput, comme par exemple l'utilisation du mécanisme de prototype du langage JavaScript. J'ai opté pour le plus scolaire implement, qui reste le plus facile à manipuler dans l'esprit de mootools.

Le principe est trivial, il s'agit de déclarer une classe, en spécifiant que l'ensemble des propriétés et des méthodes d'une autre classe sont à dupliquer. Rien n'empêche par la suite d'exploiter ou de mixer dans l'exécution du code des évolutions du prototype des objets, ou encore d'invoquer à nouveau la méthode implement dynamiquement.

Ce formalisme a pour avantage d'être facilement compréhensible (assez scolaire), et facilement extensible :

// Classe abstraite de génération d'éléments xHTML
var ajaxcaptions = new Class({
    
    Implements: [Options],
 
    options: {
     minValue: 0,
     maxValue: 0,
     setStyles: null,
     myElement: null
    },
    
    // Constructeur de la classe
    initialize: function(options) {
     this.setOptions(options);
     this.process();
    },
    
    // Retourne le caption
    getElement: function() {
      return this.options.myElement;
    }
        
});
 
// Classe de génération xHTML d'un 'select-one', contenant des valeurs de minValue à maxValue
var ajaxcaptionsSelect = new Class({
    
    Implements: ajaxcaptions,
    
    process: function() {
 
      var myElement;
      myElement = new Element('select');
      myElement.setStyles(this.options.setStyles);
      
      for (i=this.options.minValue; i<=this.options.maxValue; i++)
      {
 myElement.adopt(new Element('option').set('text', i));
      }
      
      this.options.myElement = myElement;
    },
    
    getValue: function() {
      return this.options.myElement.selectedIndex;
    },
    
    setValue: function(value) {
      this.options.myElement.selectedIndex = value;
    }
     
});
 
// Classe de génération xHTML d'un 'input'
var ajaxcaptionsInput = new Class({
    
    Implements: ajaxcaptions,
    
    process: function() {
 
      var myElement;
      myElement = new Element('input');
      myElement.setStyles(this.options.setStyles);
 
      this.options.myElement = myElement;
    },
    
    getValue: function() {
      return this.options.myElement.value;
    },
    
    setValue: function(value) {
      this.options.myElement.value = value;
    }
     
});
 
 

La couche eZ Publish de mise à jour des données

Comme décrit dans le précédent billet, l'appel des URL eZ Publish correspond au motif suivant : /ajaxwebin/action/[attribute_id]/[object_id]/[value] :

var url = this.options.ajaxmodule + '/' + this.options.attributeID + '/' + object_id + '/' + value;
 
 
  • ajaxmodule est spécifié en dur dans l'instance des classes mootools, et correspond à la racine du module, par exemple : /ajaxwebin/action
  • attributeID est spécifié en dur dans l'instance des classes mootools, et correspond à l'identifiant eZ Publish du champ à modifier, par exemple stock ou title
  • object_id est fixé dynamiquement dans les classes CSS, et permet de transmettre l'identifiant (objet_id) de l'objet eZ Publish à modifier
  • value correspond à la valeur à appliquer lors de la modification

L'implémentation du module eZ Publish

Je ne reviendrai pas sur l'implémentation du module qui est déjà abordé en détail sur plusieurs articles, comme par exemple le tutoriel de module d'eZPedia.

Quelques précisions concernant le code

  • La méthode de modification est la plus classique, mais il aurait été possible d'utiliser la méthode fromString (voir le billet de Mox), ou encore l'expérimental kernelwrapper et sa classe ezpObject (mais ce sera pour un prochain billet)
  • A noter : L'utilisation de la méthode clearObjectViewCache, qui permet de forcer le rafraîchissement de tous les caches impactés par la modification de l'objet (selon les différentes directives, dont le Smartviewcache)

Code du module eZ Publish de modification de l'objet

<?php
$Module = $Params["Module"];
 
if ( isset( $Params['action'] ) ) {
 $action = $Params['action'];
} else {
 $action = '';
}
 
if ( isset( $Params['object'] ) ) {
 $object_id = $Params['object'];
} else {
 $object_id = null;
}
 
if ( isset( $Params['value'] ) ) {
 $value = $Params['value'];
} else {
 $value = null;
}
 
$Result = array();
$Result['path'] = array();
$Result['pagelayout'] = array();
$Result['content'] = '';
 
if ($action != '') {
 
  if ( (!is_null($object_id)) && (!is_null($value)) ) {
 
    $object = eZContentObject::fetch( $object_id );
 
    if ($object) {
      $data_map = $object->attribute( 'data_map' );
 
      if (isset($data_map[$action])) {
       $attribute = $data_map[$action];
 
       switch ($data_map[$action]->DataTypeString) {
        case 'ezinteger':
          $attribute->setAttribute('data_int', $value);
  
          break;
        case 'ezstring':
          $attribute->setAttribute('data_text', $value);
  
          break;
       }
   
       $attribute->sync();
       eZContentCacheManager::clearObjectViewCache( $object_id );
       
       echo $value;
      }
      else {
       echo '';
      }
 
    }
    else {
      echo '';
    }
 
  }
 
  eZDB::checkTransactionCounter();
  eZExecution::cleanExit();
 
} 
else {
  echo '';
}
 
?>
 
 

Que boire avec ce billet ?

Domaine Cauhapé - La Canopée - Blanc Sec 2006

Région : Sud Ouest
Appellation : Jurançon
Domaine : Domaine Cauhapé
Couleur :
 
Stock : 0
Notation :
Prix : 22 €
Commentaire(s) : 0 Commentaire(s)

Encore plus concentré et plus exubérant que son petit frère (Sève d'Automne), ce vin est à réserver aux amateurs de grand vins blancs, qui recherchent une complexité aromatique et une singularité dans un vin.

Publié par : Jérôme Vieilledent, le 18 Octobre 2009 10:44 am

eZJSCore

Hello et merci pour cette série de posts...
Pour la partie eZ Publish, connais-tu eZJSCore ? Cette extension a été intégrée dans eZ Publish 4.2 (mais est utilisable sur les version > 4.0) et permet une plus grande flexibilité pour les développements AJAX (avec un index_ajax.php plus rapide). J'ai d'ailleurs basé mon Noven Image Cropper dessus Smiling
http://projects.ez.no/ezjscore

Publié par : gandbox, le 18 Octobre 2009 03:17 pm

eZJSCore et l'AJAX

Oui je connais cette extension, d'ailleurs c'est l'essentiel des commentaires sur les parties 1 et 2 du billet (voir le commentaire de André R. l'auteur de l'extension). A vrai dire, j'ai développé cette petite feature il y a quelques mois, avant la publication de eZJSCore, mais promis, mon prochain dév AJAX se fera avec eZJSCore Smiling

Publié par : Sylvain_G, le 16 Novembre 2009 09:04 pm

Dropable Blocks

Tiens je viens de noter une petite fonctionnalité sympa sur ton site
Les blocs de la colonne de droite sont réordonnable en drag-n drop et persiste dans un cookie.

Sympa

Comment tu as fait ca?

Publié par : gandbox, le 16 Novembre 2009 11:50 pm

Dropable Blocks et mootools

@Sylvain_G :
Quelques classes mootools de bases :
- Drag & Drop : http://mootools.net/docs/more/Drag/Sortables
- Cookie : http://mootools.net/docs/core/Utilities/Cookie
- JSON : http://mootools.net/docs/core/Utilities/JSON

J'utilise du JSON pour structurer divers stockages, dont l'ordre des blocks et la sélection du style white / black (boutons en haut à droite, si tu n'avais pas vu)

Voir le code dans le fichier main.js

Publié par : Sylvain_G, le 18 Novembre 2009 08:20 pm

réordonnancement des blocks

Et tu réordonne les blocs en javascript quand le doc est ready ou tu as fait autre chose avec un opérateur spécifique?

Publié par : Gandbox, le 18 Novembre 2009 10:50 pm

Ordre des blocks

@Sylvain_G :
En JavaScript dans le DOMReady, avec un principe de buffer, cad en reconstruisant la colonne par clonage du DOM, puis en switchant la colonne Buffer et la colonne d'origine.

Publié par : Paul Etienney, le 04 Février 2010 01:19 pm

La meme chose pour afficher ?

Bonjour,

Merci beaucoup pour ce post. C'est exactement ce que je cherchais. Un favori de plus.

Je cherche également à faire autre chose : appeler en ajax des morceaux de template. Comme déclencher et affiche un fetch lors d'un click par exemple.

Vous voyez ce que je veux dire ? Vous auriez une piste ou un lien ?

Merci encore.

Publié par : gandbox, le 04 Février 2010 09:42 pm

Appel AJAX d'un Fetch

@Paul Etienney :

Pour les appels AJAX, c'est au choix entre mootools, JQuery, YUI...

Pour le module eZ Publish qui génère des résultats xHTML à partir de Fetch, le plus simple c'est de lire le billet concernant le Widget UWA. Un exemple de code est très similaire : http://tinyurl.com/pb6vpu