Commit 6badb02f authored by Thibaut Vallee's avatar Thibaut Vallee
Browse files

Gestion des inputs macro-compatible

parent f7e5ea47
Loading
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
CHANGELOG
=========
7.0.2
-----
- [update] Code JS, CSS et ViewHelper pour l'ajout des macros
- Test avec TinyMCE 7.6.0 valide

7.0.2
-----
+44 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ Dépendances javascript
----------------------

- Le composant [Select2](https://select2.org) est requis (testé avec la v4.0.13).
- Le moteur de template par défaut nécessite l'éditeur [TinyMCE](https://www.tiny.cloud/) (testé avec la v6.3.0). 
- Le moteur de template par défaut nécessite l'éditeur [TinyMCE](https://www.tiny.cloud/) (testé avec la v6.3.0 et la v7.6.0). 

Si besoin, vous trouverez dans le répertoire [res/](res) les versions utilisées lors des tests.

@@ -48,12 +48,20 @@ echo $rendu->getCorps();
Aides de vue founies
--------------------

La biliothèque fournit un `ViewHelper` pour l'affichage d'un rendu
Un `ViewHelper` pour l'affichage d'un rendu

```php
echo $this->rendu($rendu); 
```

Un `ViewHelper` pour l'ajout des macros dans un input text ou textarea de class .macro-compatible

```php
echo $this->macroInsert(); 
```
_Remarque :_
A faire en fin de fichier une seul fois, le JS s'occupe de l'associer aux différents input

Administration
--------------

@@ -80,6 +88,40 @@ _Remarque :_
+ `variable_name` est recherchée dans le tableau de variable (si non trouvée alors un warning est mis dans le rendu `variable non trouvée`).
+ `methode_name` est appelé sur la variable `variable_name` comme suit `$variable_name->methode_name()` (si non trouvée alors un warning est mis dans le rendu `méthode non trouvée`).

Pour les ajouts des macros dans des inputs `Macro-compatible`:

- Dans le composer.json récuper les fichiers CSS/JS
```"scripts": {
        "post-install-cmd": [
            "mkdir -p public/unicaen && cp -r vendor/unicaen/renderer/public/unicaen public/",
        ]
    },
```

- Dans la page du formulaire :
```
<form>
<input type="text" name="XXX" id="XXX" class="macro-compatible" >
...
</form>
...

<?php echo $this->macroInsert() ?>

<script>
    const macros = <?php echo $macrosJsonValue ?>;
    $(function () {
        installMacrosWidgets(macros);
    });
</script>
```
`$macrosJsonValue` doit être un tableaux JSON
(Cf `TemplateController:generateMacrosJsonValueForTemplate()`) contenant les champs suivant :
+ id : Code de la macro
+ texte : VariableName de la macro
+ value : Valeur du TemplateEngine (ie : `VAR[Class#attr]`)


Template
----

+8 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@ use UnicaenRenderer\Form\Macro\MacroHydratorFactory;
use UnicaenRenderer\Provider\Privilege\DocumentmacroPrivileges;
use UnicaenRenderer\Service\Macro\MacroService;
use UnicaenRenderer\Service\Macro\MacroServiceFactory;
use UnicaenRenderer\View\Helper\MacroInsertViewHelper;
use UnicaenRenderer\View\Helper\RenduViewHelper;

return [
    'bjyauthorize' => [
@@ -140,4 +142,10 @@ return [
            MacroController::class => MacroControllerFactory::class,
        ]
    ],

    'view_helpers' => [
        'invokables' => [
            'macroInsert' => MacroInsertViewHelper::class,
        ],
    ],
];
+21 −0
Original line number Diff line number Diff line


#macro-insert-widget-content{
  display: none;
}
.macro-popover{
  display: none;
}
.macro-insert-widget {
  position: relative;
  top: 32px;
  left: -5px;
  margin-left: 15px;
}

.macro-select {
  width: 15rem;
}
.macro-selection-placeholder{
  display: none;
}
 No newline at end of file
+91 −0
Original line number Diff line number Diff line
// Widget permettant d'utiliser les macros dans des inputs tinymce
// forte dépendance avec select2
// généralement à coupler avec tinymce mais pas obligatoire
// usage :
// - donner à l'input la class .macro-compatible
// - à la fin du formulaire rajouter :
// <script>
// const macros = <?php echo $macrosJsonValue ?>;
// $(function () {
//         installMacrosWidgets(macros);
//     });
//</script>

/**
 * Parcours des textareas "macro compatibles" pour y installer le widget de recherche/insertion de macro.
 * @param macros array
 */
function installMacrosWidgets(macros)
{
    $(".macro-compatible").each(function (index, element) {
        const $textarea = $(element);
        // Pour éviter un chevauchement éventuelle d'input ayant la croix permettant de les vider
        $textarea.parent().find(".form-control-clear").detach();
        $textarea.parent().removeClass('has-clear');

        const id = 'macro-insert-widget-' + index;
        const $widget = $($("#macro-insert-widget-content").html()).attr('id', id);

        // insertion du widget
        $(this).before($widget);

        // installation du popover sur le bouton
        const $popoverContent = $widget.find(".macro-popover-content").attr('id', 'macro-popover-content-' + index);
        const $popoverBtn = $widget.find(".macro-btn").popover({
            html: true,
            sanitize: false,
            content: $popoverContent,
        });

        // installation du select2 dans le popover
        let $macroSelect2;
        const macroSelectTemplate = function (macro) {
            if (!macro) return "Aucune macro sélectionnée.";
            return '<strong class="macro-id">' + macro.text + '</strong> : ' + '<code class="macro-value">' + macro.value + '</code><br>' +
                '<div class="macro-description text-secondary">' + macro.description + '</div>';
        }
        try {
            $macroSelect2 = $widget.find(".macro-select").select2({
                data: macros,
                dropdownParent: $popoverContent,
                placeholder: "Sélectionnez une macro...",
                search: true,
                templateResult: macro => $(macroSelectTemplate(macro))
            });
        } catch (e) {
            alert("Impossible d'activer Select2 ! : " + e);
            console.error(e);
        }

        // bouton déclenchant l'insertion de la macro sélectionnée dans le textarea
        const $macroInsertBtn = $popoverContent.find(".macro-insert-btn").on("click", function () {
            // debugger;
            const macro = $macroSelect2.select2('data')[0];
            if (!macro) {
                return;
            }
            if (tinyMCE && ($ed = tinyMCE.get($textarea.prop('id')))) {
                $ed.selection.setContent(macro.value);
            } else {
                const caretPos = $textarea.prop('selectionStart');
                if (caretPos === undefined) {
                    $textarea.val($textarea.val() + ' ' + macro.value);
                } else {
                    $textarea.val($textarea.val().substring(0, caretPos) + macro.value + $textarea.val().substring(caretPos));
                }
            }
        });

        // bouton de fermeture du popover
        const $macroCancelBtn = $popoverContent.find(".macro-close-btn").on("click", function () {
            $popoverBtn.popover('hide');
        });

        // lorsqu'une macro est sélectionnée dans le select, affichage de ses détails
        $macroSelect2.on("select2:select", function (e) {
            const macro = e.params.data;
            $popoverContent.find(".macro-selection-placeholder").html(macroSelectTemplate(macro)).show();
            $macroInsertBtn.removeAttr("disabled");
        });
    });
}
 No newline at end of file
Loading