Chapitre 5 Conception d'un assistant (wizard) avec Dynacase Document UIs

5.1 Principe

Le wizard permet de découper la saisie du document en plusieurs étapes. Chaque étape définit un ensemble de conditions pour pouvoir passer à l'étape suivante.

Chaque étape est implémentée au moyen d'une vue, accompagnée d'un masque. Ces vues sont pilotées au moyen d'un contrôle de rendu, et d'une classe d'accès à un rendu.

La dernière étape atteinte est mémorisée dans un paramètre applicatif du document.

La partie serveur sélectionne la vue en se basant sur les informations envoyées par le client au moyen des customClientData.

Pendant le wizard, le document est à l'état Création.

À la fin du wizard, le document est passé à l'état À jour.

L'état Création n'est plus accessible après achèvement du wizard.

Voici à quoi ressemble le document pendant le wizard :

Wizard

Figure 11. Wizard

Les étapes sont les suivantes :

  • Identité
  • Professionnel
  • Personnel

5.2 Mise en œuvre du wizard

5.2.1 Mise en place des vues

3 vues vont être ajoutées sur le contrôle de rendu. Le contrôle de rendu va également préciser une classe d'accès à un rendu, qui va déterminer la vue suivante en fonction de :

  • la vue en cours (transmise par le client)
  • les vues accessibles à cet utilisateur (calculé au moyen des droits sur le serveur)
  • la vue demandée (précédent, suivant, ou une vue spécifique, demandée par le client)

5.2.1.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-00.

5.2.1.2 Code

Chaque vue est composée de :

De plus, le contrôle de rendu est associé à une classe d'accès à un rendu.

Ces éléments doivent donc être initialisés avant création du contrôle de rendu.

Nous allons donc commencer par initialiser notre classe de rendu, commune aux 3 nouvelles vues :

DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php :

<?php
 
namespace DduiTuto;
 
class ContactWizardRenderConfigEdit extends \Dcp\Ui\DefaultEdit
{
 
}

Nous allons ensuite initialiser la classe d'accès à un rendu dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactCvrenderRenderConfigAccess.php :

<?php
 
namespace DduiTuto;
 
use Dcp\Ui\IRenderConfig;
use Dcp\Ui\IRenderConfigAccess;
 
class ContactCvrenderRenderConfigAccess implements IRenderConfigAccess
{
    /**
     * @param string $mode
     *
     * @return IRenderConfig
     */
    public function getRenderConfig($mode, \Doc $document)
    {
        return null;
    }
}

Nous allons également initialiser les 3 masques qui seront utilisés par chacune des vues. Chaque masque peut être initialisé à l'adresse suivante : http://localhost:8080/?app=GENERIC&action=GENERIC_EDIT&classid=MASK&msk_famid=DDUI_TUTO_CONTACT

Une fois exportés, et correctement ajoutés au fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/DDUI_TUTO_CONTACT__DATA.csv, il peuvent être déployés.

Il est maintenant possible de rajouter nos 3 vues dans le contrôle de rendu, à l'adresse http://localhost:8080/?app=FDL&action=OPENDOC&mode=view&id=DDUI_TUTO_CONTACT__CVRENDER. Les vues sont donc maintenant au nombre de 4 :

  • DEFAULT_VIEW
    • Identifiant de la vue : DEFAULT_VIEW
    • Label : Consultation
    • Type : Consultation
    • Classe de configuration de rendu : \DduiTuto\ContactRenderConfigView
    • Masque : vide
    • Ordre de sélection : 10
    • Affichable : Non
    • Menu : vide
  • WIZARD_IDENT
    • Identifiant de la vue : WIZARD_IDENT
    • Label : Identité
    • Type : Edition
    • Classe de configuration de rendu : \DduiTuto\ContactWizardRenderConfigEdit
    • Masque : Contact (masque WIZARD_IDENT) Contact
    • Ordre de sélection : 10
    • Affichable : Non
    • Menu : vide
  • WIZARD_WORKINFO
    • Identifiant de la vue : WIZARD_WORKINFO
    • Label : Professionnel
    • Type : Edition
    • Classe de configuration de rendu : \DduiTuto\ContactWizardRenderConfigEdit
    • Masque : Contact (masque WIZARD_WORKINFO) Contact
    • Ordre de sélection : 20
    • Affichable : Non
    • Menu : vide
  • WIZARD_HOMEINFO
    • Identifiant de la vue : WIZARD_HOMEINFO
    • Label : Personnel
    • Type : Edition
    • Classe de configuration de rendu : \DduiTuto\ContactWizardRenderConfigEdit
    • Masque : Contact (masque WIZARD_HOMEINFO) Contact
    • Ordre de sélection : 30
    • Affichable : Non
    • Menu : vide
Contrôle de rendu

Figure 12. Contrôle de rendu

Une fois exporté, et correctement ajouté au fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/DDUI_TUTO_CONTACT__DATA.csv, il peut être déployé.

5.2.1.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-10

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.1.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que seul le cadre identité est présenté. En effet, notre classe d'accès à un rendu retourne null, laissant le contrôle de rendu afficher sa vue par défaut, c'est à dire la première vue de modification.

5.2.2 Partie serveur : choix de la vue

La partie serveur sélectionnera la vue en se basant sur les informations suivantes, envoyées par le client au moyen des customClientData :

currentWizardStepName

le nom de l'étape en cours

Si ce nom est vide, alors on sélectionne la dernière vue atteinte (mémorisée au moyen d'un paramètre applicatif), et la première vue si le paramètre applicatif n'est pas renseigné.

goto

Une consigne sur l'étape à atteindre, parmi :

wizard.previous
Indique que l'utilisateur veut revenir vers l'étape précédente.
wizard.next
Indique que l'utilisateur veut aller vers l'étape suivante.
wizard.targetStep

Indique que l'utilisateur veut accéder à une étape spécifique.

Dans ce cas, l'étape en question est passée par le paramètre targetStep.

5.2.2.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-10.

5.2.2.2 Code

Le code de sélection de la vue en fonction des vues disponibles dans le contrôle de rendu, et des consignes envoyées par le client est fourni au moyen de la méthode initWizardInfos depuis la trait TContactWizardRenderConfigEdit.

Il suffit de charger cette trait dans la classe ContactWizardRenderConfigEdit dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php.

La méthode initWizardInfos est une manière d'implémenter un wizard. Sa complexité n'a aucun intérêt particulier pour le compréhension du tutoriel, et elle n'est fournie qu'à titre d'exemple.

<?php
 
namespace DduiTuto;
 
use Dcp\AttributeIdentifiers\cvrender as CvrenderAttributes;
use Dcp\Family\Cvrender as CvrenderFamily;
 
class ContactWizardRenderConfigEdit extends \Dcp\Ui\DefaultEdit
{
    use TContactWizardRenderConfigEdit;
}

Nous pouvons maintenant définir cette configuration de rendu comme étant la configuration de rendu à utiliser pour les vues de création et de modification. Cela se fait dans la classe ContactCvrenderRenderConfigAccess du fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactCvrenderRenderConfigAccess.php :

<?php
 
namespace DduiTuto;
 
use Dcp\Ui\IRenderConfig;
use Dcp\Ui\IRenderConfigAccess;
use Dcp\Ui\RenderConfigManager;
 
class ContactCvrenderRenderConfigAccess implements IRenderConfigAccess
{
    /**
     * @param string $mode
     * @param \Doc   $document
     *
     * @return IRenderConfig
     */
    public function getRenderConfig($mode, \Doc $document)
    {
        switch($mode) {
        case RenderConfigManager::ViewMode:
            //let the CV RENDER do the job
            return null;
        default:
            $wizardRenderConfig = new ContactWizardRenderConfigEdit();
            $wizardRenderConfig->initWizardInfos($document);
            return $wizardRenderConfig;
        }
    }
}

5.2.2.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-20

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.2.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que seul le cadre identité est présenté. En effet, en l'absence de données du client, la première vue est sélectionnée et appliquée.

5.2.3 Partie serveur : mise en place du header

Le menu est surchargé au moyen d'un template personnalisé pour afficher les différentes étapes du wizard au dessus du menu.

5.2.3.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-20.

5.2.3.2 Code

Le template utilisé est le suivant, à enregistrer dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/contactWizardHeader.mustache :

[[#wizardInfos]]<div class="wizard_summary clearfix">[[#steps]]
    <div class="wizard_summary__step [[#current]]wizard_summary__step_current[[/current]]"
         data-viewid="[[cv_idview]]"
         style="width:calc(100% / [[nbSteps]])">
        <div class="wizard_summary__step__label [[#current]]wizard_summary__step__label_current[[/current]]"
             title="[[#i18n]]ddui_tuto:wizard::goto step[[/i18n]] [[cv_lview]]"
             data-viewid="[[cv_idview]]">[[cv_lview]]
        </div>
        <div class="wizard_summary__step__attributes">[[#attributes]][[#fields]]
            <div class="wizard_summary__step__attribute [[#required]]wizard_summary__step__attribute_required[[/required]] [[#filled]]wizard_summary__step__attribute_filled[[/filled]]"
                 data-viewid="[[cv_idview]]"
                 data-attrid="[[attrid]]"
                 data-attrlabel="[[label]]"
                 style="width: calc(100% / [[nbFields]])"
                 title="[[label]]">
            </div>
            [[/fields]][[/attributes]]
        </div>
    </div>
[[/steps]]</div>[[/wizardInfos]]
<nav class="dcpDocument__menu"></nav>

La css correspondante, à enregistrer dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.css, est la suivante :

.wizard_summary__step {
    float: left;
    padding: 2px 0px;
    text-align: center;
    cursor: pointer;
}
 
.wizard_summary__step::before {
    content: "\f054"; /* fa-chevron-right */
    font-size: 2em;
    font-family: FontAwesome;
    font-style: normal;
    font-weight: normal;
    float: right;
    vertical-align: middle;
    width: 30px;
    text-align: center;
    color: green;
}
 
.wizard_summary__step:first-child {
    padding-left: 5px;
}
 
.wizard_summary__step:last-child {
    padding-right: 5px;
}
 
.wizard_summary__step:last-child::before {
    content: "\f024"; /* fa-flag */
}
 
.wizard_summary__step_optional_unfilled::before {
    color: orange;
}
 
.wizard_summary__step_required_unfilled::before {
    color: red;
}
 
.wizard_summary__step:hover,
.wizard_summary__step:active {
    font-style: italic;
    text-decoration: underline;
}
 
.wizard_summary__step_current {
    background-color: WhiteSmoke;
}
 
.wizard_summary__step__label {
    font-weight: bold;
    font-size: 120%;
    padding: 3px;
}
 
.wizard_summary__step__label_current {
    font-style: italic;
}
 
.wizard_summary__step__attributes {
    width: calc(100% - 30px);
    float: left;
}
 
.wizard_summary__step__attribute {
    height: 3px;
    background-clip: content-box;
    float: left;
    padding: 0 2px;
    background-color: orange;
}
 
.wizard_summary__step__attribute_required {
    background-color: red;
}
 
.wizard_summary__step__attribute_filled {
    background-color: green;
}

Enfin, 3 méthodes sont surchargées dans la classe ContactWizardRenderConfigEdit dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php :

getCssReferences
injecte le fichier css précédemment créé.
getTemplates
remplace le menu par le template précédemment créé.
getContextController
injecte les propriétés de wizardInfos dans le moteur de template pour compléter le bandeau de navigation.

Soit :

public function getContextController(\Doc $document)
{
    $this->initWizardInfos($document);
 
    $controller = parent::getContextController($document);
    $controller["wizardInfos"] = $this->wizardInfos;
    return $controller;
}
 
public function getTemplates(\Doc $document = null)
{
    $this->initWizardInfos($document);
 
    $templates = parent::getTemplates($document);
 
    $templates["sections"]["menu"]["file"]
        = "DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/contactWizardHeader.mustache";
 
    return $templates;
}
 
public function getCssReferences(\Doc $document = null)
{
    $version = \ApplicationParameterManager::getParameterValue(
        "CORE", "WVERSION"
    );
 
    $cssReferences = parent::getCssReferences($document);
 
    $cssReferences['DDUI_TUTO_CONTACT_WIZARD']
        = "DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.css?ws="
        . $version;
 
    return $cssReferences;
}

5.2.3.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-30

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.3.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que le bandeau de navigation entre les différentes étapes est maintenant visible.

Ce bandeau n'est pas fonctionnel pour le moment. Les chapitres suivants feront petit à fonctionner chacun des éléments de ce bandeau.

5.2.4 Partie serveur : Personnalisation du menu

Les entrées de menu vont être surchargées :

  • certaines seront masquées
  • les entrées permettant la navigation dans le wizard seront ajoutées

5.2.4.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-30.

5.2.4.2 Code

La méthode getMenu est surchargée dans la classe ContactWizardRenderConfigEdit dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php :

public function getMenu(\Doc $document)
{
    $this->initWizardInfos($document);
 
    $menu = parent::getMenu($document);
 
    //Hide some menus
    foreach(['save', 'create', 'createAndClose', 'close', 'workflow'] as $elementId) {
        $element = $menu->getElement($elementId);
        if (!is_null($element)) {
            $element->setVisibility(ElementMenu::VisibilityHidden);
        }
    }
 
    //add custom menus
    $item = new ItemMenu(
        "wizard_end", ___("End creation", "ddui_tuto:wizard"),
        "#action/wizard.end"
    );
    $item->setBeforeContent('<div class="fa fa-check" />');
    $item->setHtmlAttribute("class", "menu--right");
    if (!empty($this->wizardInfos['nextStep'])) {
        $item->setVisibility($item::VisibilityHidden);
    }
    $item->useConfirm(___("Confirm end creation", "ddui_tuto:wizard"));
    $menu->appendElement($item);
 
    $item = new ItemMenu(
        "wizard_next", ___("Next step", "ddui_tuto:wizard"),
        "#action/wizard.next"
    );
    $item->setBeforeContent('<div class="fa fa-step-forward" />');
    $item->setHtmlAttribute("class", "menu--right");
    if (\DduiTuto\DDUI_TUTO_CONTACT__WFL::e_up_to_date === $document->getState()
        || !empty($this->wizardInfos['nextStep'])) {
        $item->setVisibility($item::VisibilityHidden);
    }
    $menu->appendElement($item);
 
    $item = new ItemMenu(
        "wizard_previous", ___("Previous step", "ddui_tuto:wizard"),
        "#action/wizard.previous"
    );
    $item->setBeforeContent('<div class="fa fa-step-backward" />');
    $item->setHtmlAttribute("class", "menu--right");
    if (empty($this->wizardInfos['previousStep'])) {
        $item->setVisibility($item::VisibilityDisabled);
    }
    $menu->appendElement($item);
 
    $item = new ItemMenu(
        "wizard_cancel", ___("Cancel", "ddui_tuto:wizard"),
        "#action/wizard.cancel"
    );
    $item->setBeforeContent('<div class="fa fa-undo" />');
    $item->setHtmlAttribute("class", "menu--left");
    $menu->appendElement($item);
 
    return $menu;
}

5.2.4.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-40

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.4.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que le menu présente de nouvelles entrées en lieu et place des anciennes.

5.2.5 Partie serveur : Personnalisation du corps du document

Le corps du document sera rendu au moyen d'un template personnalisé afin d'afficher les frames sans afficher les onglets. Ce template sera généré à la volée à partir des informations des vues.

5.2.5.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-40.

5.2.5.2 Code

La méthode getTemplates est mise à jour dans la classe ContactWizardRenderConfigEdit dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php :

public function getTemplates(\Doc $document = null)
{
    $this->initWizardInfos($document);
 
    $templates = parent::getTemplates($document);
 
    $templates["sections"]["menu"]["file"]
        = "DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/contactWizardHeader.mustache";
 
    $contentTemplate = "";
    foreach($this->wizardInfos['currentStep']['attributes']['frames'] as $frame) {
        $contentTemplate .= "{{{document.attributes." . $frame['attrid'] . ".htmlView}}}";
    }
 
    $templates["sections"]["content"]["content"] = $contentTemplate;
 
    return $templates;
}

5.2.5.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-50

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.5.4 Le résultat

Aucun changement n'est perceptible dans cette étape puisque la vue affichée ne contient pas d'onglet.

5.2.6 Partie serveur : Envoi des informations des vues

Les informations sur les vues seront rendues disponibles au client au moyen des customServerData

5.2.6.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-50.

5.2.6.2 Code

La méthode getCustomServerData est surchargée dans la classe ContactWizardRenderConfigEdit dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php :

public function getCustomServerData(\Doc $document)
{
    $this->initWizardInfos($document);
 
    $customServerData = parent::getCustomServerData($document);
 
    $customServerData["wizardInfos"] = $this->wizardInfos;
 
    return $customServerData;
}

5.2.6.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-60

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.6.4 Le résultat

Aucun changement n'est perceptible dans cette étape car ces données seront utilisées plus tard par le code javascript.

5.2.7 Partie client : rafraîchissement du bandeau de navigation

5.2.7.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-60.

5.2.7.2 Code

Le code javascript va être enregistré dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.js :

(function wizardContact(window, $){
    "use strict";
 
    var updateSummaryStatus = function updateSummaryStatus() {
        $('.wizard_summary__step').each(function updateSummaryStatus_stepIteratee() {
            var $this = $(this),
                $unfilledStepAttributes = $('.wizard_summary__step__attribute', $this)
                .not('.wizard_summary__step__attribute_filled');
 
            $this.toggleClass(
                'wizard_summary__step_required_unfilled',
                0 < $unfilledStepAttributes.filter('.wizard_summary__step__attribute_required').length
            ).toggleClass(
                'wizard_summary__step_optional_unfilled',
                0 < $unfilledStepAttributes.not('.wizard_summary__step__attribute_required').length
            );
        });
    };
 
    window.dcp.document.documentController(
        "addEventListener",
        "ready",
        {
            "name": "addWizardEvents",
            "documentCheck": function addWizardEventsDocumentCheck(documentObject)
            {
                return documentObject.family.name === "DDUI_TUTO_CONTACT" &&
                    documentObject.renderMode === "edit";
            }
        },
        function addWizardEvents(/*event, documentObject*/)
        {
            updateSummaryStatus();
        }
    );
})(window, $);

Ce fichier javascript est ensuite injecté en surchargeant la méthode getJsReferences dans la classe ContactWizardRenderConfigEdit dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactWizardRenderConfigEdit.php :

public function getJsReferences(\Doc $document = null)
{
    $version = \ApplicationParameterManager::getParameterValue(
        "CORE", "WVERSION"
    );
 
    $jsReferences = parent::getJsReferences($document);
 
    $jsReferences['DDUI_TUTO_CONTACT_WIZARD']
        = "DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.js?ws="
        . $version;
 
    return $jsReferences;
}

5.2.7.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-70

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.7.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que les chevrons sont colorés en fonction des attributs renseignés.

5.2.8 Partie client : Gestion des menus

Lors du click sur les éléments de menu, un événement de type action est déclenché.

5.2.8.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-70.

5.2.8.2 Code

L'événement déclenché au click sur un menu événement sera capturé par l'ajout d'un écouteur actionClick.wizard.contact dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.js :

this.documentController(
    "addEventListener",
    "actionClick",
    {
        "name": "actionClick.wizard.contact",
        "documentCheck": function actionClickWizardContactDocumentCheck(documentObject)
        {
            return documentObject.family.name === "DDUI_TUTO_CONTACT" &&
                documentObject.renderMode === "edit";
        }
    },
    function actionClickWizardContact(event, documentObject, options)
    {
        var customServerData = this.documentController("getCustomServerData"),
            currentWizardStepName = null;
 
        if(customServerData && customServerData.wizardInfos && customServerData.wizardInfos.currentStep) {
            currentWizardStepName = customServerData.wizardInfos.currentStep.cv_idview;
        }
 
        switch (options.eventId) {
            case 'wizard.cancel':
                this.documentController(
                    "reinitDocument",
                    {
                        viewId: '!defaultConsultation'
                    }
                );
                break;
            case 'wizard.previous':
            case 'wizard.next':
                // save document and send customClientData with goto and currentStepName
                this.documentController(
                    "saveDocument",
                    {
                        customClientData: {
                            goto: options.eventId,
                            currentWizardStepName: currentWizardStepName
                        }
                    }
                ).then(function actionClickWizardContact_success(successInfos)
                {
                    successInfos.element.documentController(
                        "showMessage",
                        "Document has been saved"
                    );
                }, function actionClickWizardContact_error(errorInfos)
                {
                    errorInfos.element.documentController(
                        "showMessage",
                        {
                            type: 'error',
                            message: 'an error occured: ' + errorInfos.errorMessage.contentText
                        }
                    );
                });
                break;
            case 'wizard.end':
                //TODO
                break;
            default:
                return;
        }
        event.preventDefault();
    }
);

5.2.8.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-80

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.8.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons qu'il est possible de naviguer d'étape en étape au moyen du menu.

5.2.9 Partie client : Gestion du clic sur une étape

5.2.9.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-80.

5.2.9.2 Code

Nous utiliserons JQuery pour déclencher un événement lors du clic sur une étape Cet événement sera capturé par l'ajout d'un écouteur actionClick.wizard.contact dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.js :

this.documentController(
    "addEventListener",
    "custom:wizardgotostep",
    {
        "name": "gotoStep.wizard.contact",
        "documentCheck": function gotoStepWizardContactDocumentCheck(documentObject)
        {
            return documentObject.family.name === "DDUI_TUTO_CONTACT" &&
                documentObject.renderMode === "edit";
        }
    },
    function gotoStepWizardContact(event, targetStep)
    {
        var customServerData = this.documentController("getCustomServerData"),
            currentWizardStepName = null;
 
        event.preventDefault();
 
        if (customServerData && customServerData.wizardInfos && customServerData.wizardInfos.currentStep) {
            currentWizardStepName = customServerData.wizardInfos.currentStep.cv_idview;
        }
 
        this.documentController(
            "reinitDocument",
            {
                customClientData: {
                    goto: 'wizard.targetStep',
                    currentWizardStepName: currentWizardStepName,
                    targetStep: targetStep
                }
            }
        );
    }
);
$('.wizard_summary').on('click', '.wizard_summary__step', function stepLabelClick()
{
    window.dcp.document.documentController(
        "triggerEvent",
        "custom:wizardgotostep",
        $(this).data('viewid')
    );
});

5.2.9.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-90

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.9.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons qu'il est possible de naviguer d'étape en étape en cliquant sur le libellé des étapes.

5.2.10 Partie client : rafraîchissement du résumé lors des changements de valeur

5.2.10.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-90.

5.2.10.2 Code

Un écouteur change.wizard.contact, déclenché à chaque changement de valeur, est ajouté au fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.js :

this.documentController(
    "addEventListener",
    "change",
    {
        "name": "change.wizard.contact",
        "documentCheck": function changeWizardContactDocumentCheck(documentObject)
        {
            return documentObject.family.name === "DDUI_TUTO_CONTACT" &&
                documentObject.renderMode === "edit";
        }
    },
    function changeWizardContact(event, documentObject, attributeObject, values)
    {
        $('.wizard_summary__step__attribute[data-attrid=' + attributeObject.id + ']')
            .toggleClass(
                'wizard_summary__step__attribute_filled',
                values.current.value !== ''
            );
 
        updateSummaryStatus();
    }
);

5.2.10.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-100

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.10.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que le bandeau de navigation est bien rafraîchi lors de l'ajout ou de la suppression d'une valeur dans le document.

5.2.11 Partie client : fin du wizard et changement d'état

Lorsque l'utilisateur clique sur le bouton de fin de wizard, le document est enregistré et change d'état.

5.2.11.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-100.

5.2.11.2 Code

Le clic sur ce bouton émet un événement de type action. Cet événement est traité en ajoutant la gestion de l'action wizard.end dans l'écouteur actionClick.wizard.contact dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/Layout/wizard.js. Il suffit de sauver le document puis d'appeler la méthode changeStateDocument du contrôleur de document :

this.documentController(
    "addEventListener",
    "actionClick",
    {
        "name": "actionClick.wizard.contact",
        "documentCheck": function actionClickWizardContactDocumentCheck(documentObject)
        {
            return documentObject.family.name === "DDUI_TUTO_CONTACT" &&
                documentObject.renderMode === "edit";
        }
    },
    function actionClickWizardContact(event, documentObject, options)
    {
        var customServerData = this.documentController("getCustomServerData"),
            currentWizardStepName = null;
 
        if(customServerData && customServerData.wizardInfos && customServerData.wizardInfos.currentStep) {
            currentWizardStepName = customServerData.wizardInfos.currentStep.cv_idview;
        }
 
        switch (options.eventId) {
            case 'wizard.cancel':
                this.documentController(
                    "reinitDocument",
                    {
                        viewId: '!defaultConsultation'
                    }
                );
                break;
            case 'wizard.previous':
            case 'wizard.next':
                this.documentController(
                    "saveDocument",
                    {
                        customClientData: {
                            goto: options.eventId,
                            currentWizardStepName: currentWizardStepName
                        }
                    }
                );
                break;
            case 'wizard.end':
                this.documentController(
                    "saveDocument",
                    {
                        customClientData: {
                            currentWizardStepName: currentWizardStepName
                        }
                ).then(function wizardEnd_changeState() {
                    window.dcp.document.documentController(
                        "changeStateDocument",
                        {
                            "nextState": "ctc_e2",
                            "transition": "ctc_t_e1__e2"
                        },
                        {
                            viewId: '!defaultConsultation',
                            revision: -1
                        }
                    );
                    }
                });
                break;
            default:
                return;
        }
        event.preventDefault();
    }
);

5.2.11.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-110

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.11.4 Le résultat

En accédant au contact Thomas ANDERSON en modification à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultEdition.html, nous constatons que le bouton de fin de wizard est fonctionnel.

5.2.12 Partie serveur : Prise en compte du libellé d'étape en consultation

En consultation, le menu de modification doit afficher l'étape en cours.

5.2.12.1 Récupération des sources

Les sources avant cette étape correspondent au tag step-40-110.

5.2.12.2 Code

Cela se fait en modifiant le libellé du menu de modification par une surcharge de la méthode getMenu dans le fichier DDUI_TUTO/Families/DDUI_TUTO_CONTACT/ContactRenderConfigView.php :

public function getMenu(\Doc $document)
{
    $menu = parent::getMenu($document);
 
    $modifLabel = ___("Modify", "UiMenu");
 
    $wizardTags = $document->getUTag('wizard');
    if (false === $wizardTags) {
        $wizardTags = [];
    } else {
        $wizardTags = json_decode($wizardTags->comment, true);
    }
    if (isset($wizardTags['currentWizardStepName'])) {
        $modifLabel .= " (" . $wizardTags['currentWizardStepLabel'] . ")";
    }
 
    $modifMenu = $menu->getElement("modify");
    if (!is_null($modifMenu)) {
        $modifMenu->setTextLabel($modifLabel);
    }
 
    return $menu;
}

5.2.12.3 Déploiement

Les sources telles que déployées à cette étape correspondent au tag step-40-120

Le déploiement se fait au moyen du developer toolkit (pour plus d'explications sur les outils de développement, se rendre sur leur documentation).

La commande est donc :

  • pour linux :

    php dynacase-devtool.phar deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release
  • pour windows :

    dynacase-devtool.bat deploy -u localhost -p 8080 -c dynacase -s path/to/sources --auto-release

5.2.12.4 Le résultat

En accédant au contact Thomas ANDERSON en consultation à l'adresse http://localhost:8080/api/v1/documents/CONTACT_THOMAS_ANDERSON/views/!defaultConsultation.html, nous constatons que le bouton de modification reflète bien la dernière étape consultée.

5.3 Conclusion

Vous avez vu dans cette partie que tous les comportements par défaut du document sont personnalisables, au niveau serveur par du code PHP, et au niveau client par du code Javascript.

Ce code peut intercepter l'ensemble des comportements prédéfinis pour les modifier, mais il est également possible d'ajouter des données supplémentaires et de les traiter pour non seulement modifier, mais aussi étendre le comportement par défaut.

Enfin, couplés aux fonctionnalités de CSS vues au chapitre précédent, ces surcharges permettent de changer profondément la façon dont les documents sont présentés à l'utilisateur.

Dans la partie suivante, vous apprendrez à intégrer ces documents enrichis à une interface applicative complexe.

×