# Smart Form
# Description
Le composant Smart Form est un composant Vuejs permettant de configurer un formulaire web avec les caractéristiques des Smart Elements.
Le formulaire est décrit avec les caractéristiques suivantes :
- La structure : contient les caractéristiques des champs du formulaire
- La représentation : contient les options de représentations des champs du formulaire
- La barre de menu : contient les caractéristiques des éléments contenus dans le menu
- Les valeurs d'initialisation
# Initialisation
Le composant AnkSmartForm
est défini dans la bibliothèque "@anakeen/user-interfaces/components/lib/AnkSmartForm.esm
"
et la CSS "@anakeen/user-interfaces/components/scss/AnkSmartElement.scss
".
WARNING
Ce composant est asynchrone, il
faut donc le charger manière asynchrone dans vue (avec une closure). De plus, pour accéder au composant il faut attendre
que celui-ci soit monté, un évènement vue @smartElementMounted
est mis à disposition pour pouvoir déclencher une
méthode à ce moment.
WARNING
Ce composant doit être rendu dans un contenant ayant une taille donc pas en height=auto
.
Exemple d'initialisation
<template>
<div>
<ank-smart-form :config="json" />
</div>
</template>
<script>
import AnkSmartForm from "@anakeen/user-interfaces/components/lib/AnkSmartForm.esm";
import "@anakeen/user-interfaces/components/scss/AnkSmartElement.scss";
export default {
components: {
AnkSmartForm: () => AnkSmartForm
},
data: () => {
return {
json: {
title: "Formulaire minimaliste",
type: "Demande de renseignement",
structure: [
{
label: "Identification",
name: "my_fr_ident",
type: "frame",
content: [
{
label: "Objet de la requête",
name: "my_title",
type: "text"
},
{
label: "Description de la requête",
name: "my_request",
type: "longtext"
}
]
}
]
}
};
}
};
</script>
Aperçu du formulaire
# Propriétés
Le composant dispose des propriétés suivantes :
config
. Cette propriété est un objet qui permet de configurer l'ensemble du formulaire hormis les événements. Les événements sont configurables de manière traditionnelle voir le paragraphe ci-dessous.options
: Options supplémentaires :withCloseConfirmation
: booléen : Si l'option est à false, aucune confirmation n'est demandée à l'utilisateur dans le cas où le formulaire à remplacer est modifié. Par défaut, la valeur esttrue
.
# config.structure
(Smart Form Structure)
La structure définit les champs du formulaire et leur organisation. Les champs sont typés comme les Smart Fields.
La structure est soumise aux mêmes contraintes que celles des Smart Fields, à savoir :
- Un champ de structure de type "tab" ne peut pas être contenu dans un autre champ de structure
- Un champ de structure de type "frame" ne peut être contenu que dans un champ de structure de type "tab"
- Un champ de structure de type "array" ne peut être contenu que dans un champ de structure de type "frame"
- Un champ non structurant doit être dans un champ de structure de type "frame" ou de type "array"
Un champ contient les propriétés suivantes:
name
: identifiant du champ unique dans la structurelabel
: libellé du champ (le libellé est égalname
s'il n'est pas défini)type
: type du champ :account
array
,color
,date
,docid
,double
,enum
,file
,frame
,htmltext
,image
,int
,integer
,json
,longtext
,money
,password
,tab
,time
,timestamp
,xml
,text
display
: [write
,read
,none
] - type d'affichage'write
: Affiche le champ modifiableread
: Affiche le champ non modifiablenone
: n'affiche pas le champ
content
: Liste des champs contenus dans le champ de structure (seulement pour les typestab
,frame
,array
)
Configuration JSON
{
"title": "Formulaire standard",
"type": "Demande de renseignement",
"structure": [
{
"label": "Identification",
"name": "my_fr_ident",
"type": "frame",
"content": [
{
"label": "Objet",
"name": "my_title",
"type": "text"
},
{
"label": "Description de la requête",
"name": "my_request",
"type": "longtext"
}
]
},
{
"label": "Informations",
"name": "my_t_info",
"type": "tab",
"content": [
{
"label": "Identité",
"name": "my_fr_info",
"type": "frame",
"content": [
{
"label": "Prénom",
"name": "my_firstname",
"type": "text"
},
{
"label": "Nom",
"name": "my_lastname",
"type": "text"
}
]
}
]
},
{
"label": "Localisation",
"name": "my_t_map",
"type": "tab",
"content": [
{
"label": "Adresse",
"name": "my_fr_address",
"type": "frame",
"content": [
{
"label": "Rue",
"name": "my_street",
"type": "text"
},
{
"label": "Code postal",
"name": "my_postalcode",
"type": "text"
},
{
"label": "Ville",
"name": "my_town",
"type": "text"
}
]
}
]
}
]
}
Résultat
# Spécificité champ docid
Les champs de type docid
ont deux propriétés supplémentaires :
typeFormat
: Nom logique de la Smart Structure pour filtrer l'aide à la saisiemultiple
: (bool) : Indique si le champ peut contenir plusieurs valeurs
Configuration JSON : Docid
{
"title": "Test Docid",
"type": "Demande de renseignement",
"structure": [
{
"label": "Identification",
"name": "my_fr_ident",
"type": "frame",
"content": [
{
"label": "Facture",
"name": "my_request",
"type": "docid",
"typeFormat": "DEVBILL"
},
{
"label": "Collègues",
"name": "my_pfam",
"type": "docid",
"typeFormat": "DEVPERSON",
"multiple": true
}
]
}
]
}
Résultat : Un champ simple et un champ multiple
# Spécificité champ account
Les champs de type account
ont deux propriétés supplémentaires :
typeFormat
: Nom logique de la Smart Structure pour filtrer l'aide à la saisie par défautIUSER
.multiple
: (bool) : Indique si le champ peut contenir plusieurs valeursoptions.match
: ([user, group, role]) : Indique le type de compte à filtrer par défaut "user"
Configuration JSON : Account
{
"title": "Test Account",
"icon": "/api/v2/images/assets/sizes/24x24c/se-iuser.png",
"structure": [
{
"label": "Identification",
"name": "my_fr_ident",
"type": "frame",
"content": [
{
"label": "Workers",
"name": "my_workers",
"type": "account",
"multiple": true
},
{
"label": "Labs",
"name": "my_labs",
"type": "account",
"options": {
"match": "group"
},
"multiple": true
}
]
}
]
}
Résultat : Un champ filtrant les utilisateurs et un champ filtrant les groupes
# Spécificité champ enum
Les champs de type enum
ont deux propriétés supplémentaires :
typeFormat
: Nom logique de la Smart Structure pour filtrer l'aide à la saisiemultiple
: (bool) : Indique si le champ peut contenir plusieurs valeurs
Configuration JSON : Enum
{
"title": "Enum",
"structure": [
{
"content": [
{
"label": "Fruits",
"name": "my_fruit",
"type": "enum",
"enumItems": [
{
"key": "orange",
"label": "Orange"
},
{
"key": "apple",
"label": "Pomme"
},
{
"key": "pear",
"label": "Poire"
}
],
"multiple": true
},
{
"label": "Criticité",
"name": "my_level",
"type": "enum",
"enumItems": [
{
"key": "low",
"label": "Faible"
},
{
"key": "medium",
"label": "Moyen"
},
{
"key": "hight",
"label": "Élevé"
}
]
}
],
"label": "My first frame",
"name": "my_firstframe",
"type": "frame"
}
]
}
Résultat : Enum simple et multiple
# Spécificité champ array
Les champs de type array
ont une propriété supplémentaire :
content
: Contient les champs composant les colonnes du tableaux
Configuration JSON : Tableau
{
"title": "Tableau",
"structure": [
{
"label": "Correspondances",
"name": "my_frame",
"type": "frame",
"content": [
{
"label": "Trajets",
"name": "my_localisation",
"type": "array",
"content": [
{
"label": "Ville",
"name": "my_town",
"type": "text"
},
{
"label": "Quand",
"name": "my_date",
"type": "date"
}
]
}
]
}
]
}
Résultat : Un tableau à 2 colonnes
# config.structure (Autocomplete)
Un sélecteur de proposition peut être ajouté sur les types "text", "docid" et "account". Ce sélecteur permet d'ajouter une autocomplétion comme cela est possible sur les smart fields.
Propriété du champ structure.<field> | Type | Description |
---|---|---|
autocomplete.url | string | (obligatoire) Url d'accès à la route délivrant les données pour l'aide à la saisie |
autocomplete.inputs | object | Liste de correspondances pour les données d'entrées |
autocomplete.outputs | object | (obligatoire) Liste de correspondances pour les données de sorties |
La propriété autocomplete.url
doit indiquer une route valide. Cette route doit retourner des données au format
"autocomplete" attendu. Pour cela, le code de la route doit utiliser la classe Anakeen\SmartAutocomplete
permettant de
renvoyer une réponse standard pour l'aide à la saisie. Cette url peut aussi avoir des parties variables en indiquant le
nom des champs entre accolades simples (ex: "/my/api/{my_field}
")
La déclaration de la route se fait de façon standard. Il faut que la méthode HTTP soit POST
car
les données du formulaire sont transmises via cette méthode à la route afin de pouvoir avoir accès au données du
formulaire qui servent de données d'entrée.
Les méthodes de manipulation de la classeAnakeen\SmartAutocomplete
sont :
Méthode | Argument | Retour | Description |
---|---|---|---|
addMessage | ApiMessage | this | Ajoute un message à afficher sur le sélecteur de liste |
getFilterValue | string | string | Retourne la valeur courante du champ où se trouve l'aide à la saisie |
getInputValue | string | string ou array | Retourne la valeur du champ décrit par autocomplete.inputs . Pour les tableaux, si le champ est dans le même tableau que l'aide à la saisie alors ce sera la valeur de la cellule. Sinon si le champ est multiple le résultat est un tableau de valeur |
getResponse | Aucun | Slim\Http\response | Réponse formatée à retourner au serveur |
setEntryLabel | Closure ou string | this | Spécification des éléments affichés sur la liste (soit une fonction, soit une chaîne Mustache. Les variables sont les index des données fournies dans setEntryData() |
setEntryData | array | this | Enregistre les données de retour de l'aide à la saisie. Les données sont sous la forme d'un tableau indexé. |
setError | string | this | Ajout d'un message d'erreur qui sera affiché sur la liste |
# Exemple basique : aide à la saisie à une seule sortie
Cette exemple montre comme réaliser une aide à la saisie permettant à un champ de choisir parmi une liste de pays provenant du serveur.
L'aide à la saisie nécessite 3 déclarations :
- La déclaration de la configuration de l'aide à la saisie dans le Smart Form
structure.<field>.autocomplete
(référence l'url de la route et les retours) - La déclaration de la route :
/my/countries/
(référence la classe PHP) - Le code de la classe PHP (
My\AutoCountries
) de la route (qui retourne les données indexées)
Déclaration de la route `/my/countries/` . Fichier `src/config/SmartDataEngine/myAutocompletes.xml`
<?xml version="1.0"?>
<sde:config xmlns:sde="https://platform.anakeen.com/4/schemas/sde/1.0">
<sde:routes namespace="My">
<sde:route name="Autocomplete:Countries">
<sde:priority>0</sde:priority>
<sde:callable>My\AutoCountries</sde:callable>
<sde:method>POST</sde:method>
<sde:pattern>/my/countries/</sde:pattern>
<sde:description>Get countries</sde:description>
</sde:route>
</sde:routes>
</sde:config>
Classe PHP `My\AutoCountries` pour retourner les résultats (Fichier `vendor/My/AutoCountries.php`)
<?php
namespace My;
use Anakeen\SmartAutocomplete;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
/**
* Class AutoCountries
*
* Données retournées :
* - "Country"
*/
class AutoCountries
{
public function __invoke(Request $request, Response $response, $args)
{
$autocomplete = new SmartAutocomplete($request, $response);
// Get filter form input value
$inputValue = $autocomplete->getFilterValue();
// Here my data to returns
$countries = ["France", "Italie", "Espagne"];
$autoCompleteData = [];
foreach ($countries as $country) {
if (!$inputValue || preg_match(sprintf("/%s/i", preg_quote($inputValue, "/")), $country) > 0) {
// Return only if match input
$autoCompleteData[] = [
"Country" => $country
];
}
}
$autocomplete->setEntryData($autoCompleteData);
$autocomplete->setEntryLabel("<p>{{Country}}</p>");
return $autocomplete->getResponse();
}
}
L'exemple ci-dessous indique une aide à la saisie sur le champ "my_country". Elle référence la route /my/countries/
.
Cette route renvoie des données dans un attribut nommé "Country". La valeur sélectionnée d'un attribut sera enregistrée
dans le champ "my_country" (indiqué par autocomplete.outputs
).
Déclaration de l'aide à la saisie
{
"title": "Aide basique custom",
"type": "Demande de renseignement",
"structure": [
{
"label": "Localisation",
"name": "my_fr_ident",
"type": "frame",
"content": [
{
"label": "Un pays",
"name": "my_country",
"type": "text",
"autocomplete": {
"url": "/my/countries/",
"outputs": {
"my_country": "Country"
}
}
}
]
}
]
}
Résultat : Sélecteur sur le champ
# Exemple : aide à la saisie à plusieurs sorties et une entrée
Cette exemple montre comme réaliser une aide à la saisie permettant à un champ de choisir un utilisateur parmi un groupe donné.
L'aide à la saisie nécessite 3 déclarations :
- La déclaration de la configuration de l'aide à la saisie dans le Smart Form
structure.<field>.autocomplete
(référence l'url de la route et les retours) - La déclaration de la route :
/my/users/
(référence la classe PHP) - Le code de la classe PHP (
My\AutoUsers
) de la route (qui retourne les données indexées)
Déclaration de la route `/my/users/` . Fichier `src/config/SmartDataEngine/myAutocompletes.xml`
<?xml version="1.0"?>
<sde:config xmlns:sde="https://platform.anakeen.com/4/schemas/sde/1.0">
<sde:routes namespace="My">
<sde:route name="Autocomplete:Users">
<sde:priority>0</sde:priority>
<sde:callable>My\AutoUsers</sde:callable>
<sde:method>POST</sde:method>
<sde:pattern>/my/users/</sde:pattern>
<sde:description>Get countries</sde:description>
</sde:route>
</sde:routes>
</sde:config>
Classe PHP `My\AutoUsers` pour retourner les résultats (Fichier `vendor/My/AutoUsers.php`)
<?php
namespace My;
use Anakeen\Core\SEManager;
use Anakeen\Routes\Core\Lib\ApiMessage;
use Anakeen\SmartAutocomplete;
use SmartStructure\Fields\Igroup;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
/**
* Class AutoUsers
*
* Données d'entrée :
* - "userGroup" (identifiant du groupe)
* Données retournées :
* - "login"
* - "account"
* - "accountId"
* - "mail"
*/
class AutoUsers
{
public function __invoke(Request $request, Response $response, $args)
{
$autocomplete = new SmartAutocomplete($request, $response);
$filter = $autocomplete->getFilterValue();
$inputGroup = $autocomplete->getInputValue("userGroup");
$searchAccount = new \Anakeen\Accounts\SearchAccounts();
$searchAccount->setTypeFilter(\Anakeen\Accounts\SearchAccounts::userType);
if ($filter !== null) {
$searchAccount->addFilter("lastname ~* '%s' OR login ~* '%s'", preg_quote($filter), preg_quote($filter));
}
$group=null;
if ($inputGroup) {
$group = SEManager::getDocument($inputGroup);
if ($group) {
$searchAccount->addGroupFilter($group->getRawValue(Igroup::us_login));
}
}
$searchAccount->setSlice(50);
$groupsData = [];
foreach ($searchAccount->search() as $currentAccount) {
/** @var $currentAccount \Anakeen\Core\Account */
$groupsData[] = [
"login" => $currentAccount->login,
"account" => [
"value" => $currentAccount->fid,
"displayValue" => $currentAccount->getAccountName()
],
"accountId" => $currentAccount->id,
"mail" => $currentAccount->mail
];
}
$autocomplete->setEntryData($groupsData);
$autocomplete->setEntryLabel("<span>{{login}}(<i>{{mail}}</i>)</span>");
if (!$groupsData) {
$autocomplete->setError("Aucun utilisateur trouvé");
}
if ($group) {
$autocomplete->addMessage(new ApiMessage(sprintf("Utilisateurs du groupe \"%s\"", $group->getTitle())));
}
return $autocomplete->getResponse();
}
}
L'exemple ci-dessous indique une aide à la saisie sur le champ "my_user". Elle référence la route /my/users/
. Cette
route renvoie des données dans 4 attributs nommés "login", "account", "accountId", "mail". Seules deux de ces valeurs
("mail" et "account") sont utilisées comme indiqué dans autocomplete.outputs
. La valeur "account" est une
valeur complexe car elle référence un type "docid" où la valeur brute est différente de la
valeur affichée.
La route utilise une donnée d'entrée "userGroup", cette donnée est celle du champ "my_group" (indiqué par
autocomplete.inputs
).
Déclaration de l'aide à la saisie
{
"title": "Aide sur les utilisateurs",
"type": "Demande de renseignement",
"structure": [
{
"label": "Identification",
"name": "my_fr_ident",
"type": "frame",
"content": [
{
"label": "Groupe",
"name": "my_group",
"type": "account",
"needed": true,
"options": {
"match": "group"
}
},
{
"label": "Utilisateur du groupe",
"name": "my_users",
"type": "docid",
"autocomplete": {
"url": "/devdata/users/",
"inputs": {
"my_group": "userGroup"
},
"outputs": {
"my_users": "account",
"my_email": "mail"
}
}
},
{
"label": "Adresse de courriel",
"name": "my_email",
"type": "text",
"display": "read"
}
]
}
],
"renderOptions": {
"fields": {
"my_fr_ident": {
"responsiveColumns": [
{
"number": 2,
"minWidth": "50rem",
"grow": true
}
]
}
}
}
}
Résultat : Sélecteur sur le champ
# config.renderOptions
(Smart Form RenderOptions)
Cette partie permet de configurer l'aspect du formulaire à l'aide des options de rendu des Smart Fields.
Les options peuvent être appliquées à un champ particulier ou pour un type de champ particulier ou de façon générale pour les options communes à tous les champs.
Configuration par champs
{
"title": "Mon formulaire personnalisé",
"renderOptions": {
"fields": {
"my_title": {
"description": {
"collapsed": false,
"htmlContent": "<p>Décrire ici votre requête</p>",
"htmlTitle": "<h3>Objet de la demande</h3>",
"position": "top"
},
"labelPosition": "none",
"placeHolder": "Indiquer l'objet de votre requête"
},
"my_firstframe": {
"responsiveColumns": [
{
"number": 2,
"minWidth": "50rem",
"maxWidth": "70rem",
"grow": true
},
{
"number": 3,
"minWidth": "70rem",
"maxWidth": null,
"grow": true
}
]
},
"my_level": {
"editDisplay": "vertical"
},
"my_comment": {
"ckEditorInline": true,
"toolbar": "Simple"
}
}
},
"structure": [
{
"label": "Informations",
"name": "my_firstframe",
"type": "frame",
"content": [
{
"label": "Title",
"name": "my_title",
"type": "text",
"needed": true
},
{
"label": "Date de rédaction",
"name": "my_date",
"type": "date"
},
{
"label": "Criticité",
"name": "my_level",
"type": "enum",
"enumItems": [
{
"key": "low",
"label": "Faible"
},
{
"key": "medium",
"label": "Moyen"
},
{
"key": "hight",
"label": "Élevé"
}
]
},
{
"label": "Remarques",
"name": "my_comment",
"type": "htmltext"
}
]
}
]
}
Résultat : Un formulaire responsive de 1 à 3 colonnes
Exemple avec les propriétés types
et common
sur les renderOptions.
Configuration générale et par type
{
"title": "Libellé sur le dessus",
"renderOptions": {
"common": {
"labelPosition": "left"
},
"types": {
"enum": {
"editDisplay": "vertical"
},
"htmltext": {
"toolbar": "Basic",
"labelPosition": "up",
"height": "21rem"
}
}
},
"structure": [
{
"label": "Informations",
"name": "my_firstframe",
"type": "frame",
"content": [
{
"label": "Title",
"name": "my_title",
"type": "text",
"needed": true
},
{
"label": "Date de rédaction",
"name": "my_date",
"type": "date"
},
{
"label": "Criticité",
"name": "my_level",
"type": "enum",
"enumItems": [
{
"key": "low",
"label": "Faible"
},
{
"key": "medium",
"label": "Moyen"
},
{
"key": "hight",
"label": "Élevé"
}
]
},
{
"label": "Remarques",
"name": "my_comment",
"type": "htmltext"
}
]
}
]
}
Résultat : Libellés sont sur le dessus des champs
Propriété | Scope | Description |
---|---|---|
labelPosition | * | [up , left , none ] : position du libellé par rapport à la valeur |
attributeLabel | * | Remplace le Libellé défini dans la structure |
description | * | Indique une description |
> description.collapsed | * | Indique si la description doit être repliée |
> description.htmlContent | * | Titre de la description |
> description.htmlTitle | * | Contenu de la description |
> description.position | * | [top , right , bottom , left , topLabel , topValue , bottomLabel , bottomValue , click ] Placement de la description |
placeHolder | text, date, time, timestamp, longtext, int, double, money | Affiche le texte si la valeur est vide (display "write" seulement) |
displayDeleteButton | * | (bool) Affiche le bouton pour effacer le champ (true par défaut) |
inputHtmlTooltip | * | (html) Affiche un message au focus du champ (display "write" seulement) |
template | * | (html) Template de représentation d'un champ |
translatedLabels | *, file, enum | Textes traduisibles utilisés dans l'affichage du champ |
buttons | * | (array) Liste de boutons spécifiques, un bouton est caractérisé par les propriétés suivantes |
> buttons[n].htmlContent | * | (html) Libellé du bouton |
> buttons[n].url | * | Url |
> buttons[n].target | * | Target de l'url (_self, _dialog, ...) |
> buttons[n].title | * | (html) Texte affiché au survol |
> buttons[n].windowHeight | * | Hauteur de la fenêtre ouverte |
> buttons[n].windowWidth | * | Largeur de la fenêtre ouverte |
> buttons[n].windowTitle | * | Titre de la fenêtre ouverte |
transpositionWidth | array | Largeur à partir de laquelle le tableau est affiché en mode transposé |
rowCountThreshold | array | Affichage du nombre de rangées |
rowAddDisable | array | (bool) Désactive la possibilité d'ajouter des rangées dans le tableau (false par défaut) |
rowDelDisable | array | (bool) Désactive la possibilité d'enlever des rangées dans le tableau (false par défaut) |
rowMoveDisable | array | (bool) Désactive la possibilité de déplacer des rangées dans le tableau (false par défaut) |
rowMinLimit | array | (int) Nombre minimum de rangées non supprimable pour un tableau |
rowMaxLimit | array | (int) Nombre maximum de rangées que l'utilisateur peut avoir pour un tableau |
rowMinDefault | array | (int) Nombre minimum de rangées affichées à l'initialisation pour un tableau |
decimalPrecision | double | (int) Nombre de décimales à prendre en compte |
editDisplay | enum | Type d'affichage ("list", "horizontal", "vertical", "bool" ) |
collapse | frame | Si le cadre doit être replié ou non : "expand", "collapse" , "none" |
responsiveColumns | frame | Règles du multi-colonnes en fonction de la largeur du cadre |
Certaines options ne sont applicables qu'à l'ensemble du formulaire. Il faut dans ce cas utiliser le mot clef
document
.
{
"title": "Formulaire",
"renderOptions": {
"document": {
"stickyTabs": "auto",
"tabPlacement": "left"
}
}
}
Propriété | Description |
---|---|
tabPlacement | [top , left , topProportional ] : position du libellé par rapport à la valeur |
stickyTabs | Coller les onglets en haut du formulaire lors d'un scroll vertical |
# config.menu (Smart Form Menu)
La propriété menu
du Smart Form permet d'ajouter des menus dans la formulaire. Trois types d'élément
de menu sont disponibles :
itemMenu
: Élément de menu simplelistMenu
: Menu déroulantseparatorMenu
: Séparateur de menu
Les menus permettent d'envoyer des événements avec l'url #actions/<eventId>
. Si l'url commence par #actions/
alors
la méthode $on
permet de capturer le click.
Par défaut, les éléments de menu sont alignés à droite. Pour aligner un élément de menu à gauche, il faut utiliser la
classe css menu--left
(dans la propriété htmlAttribute
).
Propriété | Type | Description |
---|---|---|
id | string | (obligatoire) Identifiant du menu |
type : | string | "listMenu" , "itemMenu" ,"separatorMenu"; |
beforeContent | string | Fragment html, utilisé souvent pour afficher une icône |
htmlAttributes | object | Attributs html à ajouter à la DOM ({attrName : attrValue, ...}) |
label | string | Texte brut à afficher |
htmlLabel | string | Texte HTML à afficher |
tooltipLabel | string | Texte du tooltip au survol |
tooltipPlacement | string | Placement du tooltip ["top" , "bottom" , "right", "left"]; |
tooltipHtml | boolean | (false par défaut) Le texte du tooltip ne doit pas être encodé |
visibility | string | "visible" "hidden" ,"disabled" |
important | boolean | (false par défaut) le menu ne doit pas être placé dans le menu "Autre" même s'il n'y a plus de place |
iconUrl | string | Url d'une image pour l'icône du menu (placé à gauche du texte) |
target | string | Target window de la cible |
targetOptions.title | string | Titre de la dialog window si target = _dialog |
target.windowWidth | string | Largeur de la fenêtre |
target.windowHeight | string | Hauteur de la fenêtre |
confirmationText | string | Libellé de la confirmation, s'il est non vide cela indique qu'une confirmation sera demandée |
confirmationOptions.cancelButton | string | Libellé du bouton d'annulation |
confirmationOptions.confirmButton | string | Libellé du bouton de confirmation |
confirmationOptions.windowWidth | string | Largeur de la fenêtre de confirmation (32rem par défaut) |
confirmationOptions.windowHeight | string | Hauteur de la fenêtre de confirmation (18rem par défaut) |
Configuration de la barre de menu avec bouton de sauvegarde.
{
"title": "Menu Formulaire",
"type": "Invitation",
"icon": "/api/v2/images/assets/sizes/24x24c/se-image.png",
"menu": [
{
"id": "special",
"beforeContent": "<div class=\"fa fa-superpowers\" />",
"htmlAttributes": {
"class": "menu--left"
},
"label": "Spécial",
"type": "itemMenu",
"url": "#action/my.superpower"
},
{
"id": "image",
"type": "itemMenu",
"label": "Info",
"iconUrl": "/Images/info.svg",
"url": "/api/v2/smart-elements/87527/images/img_file/-1/sizes/800.png?c=20190904095344",
"target": "_dialog",
"targetOptions": {
"title": "Régate",
"windowWidth": "800px",
"windowHeight": "450px"
}
},
{
"id": "mylist",
"beforeContent": "<div class=\"fa fa-heart\" />",
"htmlAttributes": {
"class": "menu--left"
},
"label": "Options",
"type": "listMenu",
"content": [
{
"id": "message",
"type": "itemMenu",
"label": "Send message",
"htmlLabel": "",
"beforeContent": "<div class=\"fa fa-telegram\" />",
"url": "#action/my.sendmessage"
},
{
"id": "detail",
"type": "itemMenu",
"label": "Plus d'information",
"beforeContent": "<div class=\"fa fa-binoculars\" />",
"url": "#action/my.extrainfo"
},
{
"id": "image",
"type": "itemMenu",
"label": "Voile",
"iconUrl": "/api/v2/smart-elements/87527/images/img_file/-1/sizes/48x48c.png?c=20190904095344",
"url": "/api/v2/smart-elements/87527/images/img_file/-1/sizes/800.png?c=20190904095344",
"target": "_dialog",
"targetOptions": {
"title": "Régate",
"windowWidth": "800px",
"windowHeight": "450px"
}
}
]
},
{
"id": "submit",
"beforeContent": "<div class=\"fa fa-save\" />",
"iconUrl": "",
"important": false,
"label": "Soumettre",
"target": "_self",
"type": "itemMenu",
"url": "#action/document.save",
"visibility": "visible"
},
{
"id": "reset",
"htmlLabel": "<span style='color:orange;font-weight:bold'>Réinitialisation</span>",
"iconUrl": "",
"confirmationText": "<h1>Attention <h1><h2>Phase de réinitialisation en approche</h2>",
"confirmationOptions": {
"cancelButton": "Non non",
"confirmButton": "Oui je veux réinitialiser le système",
"windowWidth": "40rem",
"windowHeight": "17rem"
},
"target": "_self",
"type": "itemMenu",
"url": "#action/document.save",
"visibility": "visible"
}
],
"structure": [
{
"name": "my_firstframe",
"label": "My first frame",
"type": "frame",
"content": [
{
"label": "Title",
"name": "my_title",
"type": "text",
"needed": true
},
{
"label": "Date de l'événement",
"name": "my_date",
"type": "date"
},
{
"label": "Remarques",
"name": "my_comment",
"type": "htmltext"
}
]
}
]
}
Résultat : Barre de menu personnalisée
# config.values (Smart Form Values)
Les valeurs sont indiquées en utilisant le nom du smart field. La notation courte de la valeur est juste une chaîne de caractères. La notation longue permet de différencier la valeur affichée de la valeur brute.
Affectation de valeurs simples
{
"title": "Valeurs",
"type": "Invitation",
"icon": "/api/v2/images/assets/sizes/24x24c/se-image.png",
"structure": [
{
"label": "Caractéristiques",
"name": "my_frame",
"type": "frame",
"content": [
{
"label": "Title",
"name": "my_title",
"type": "text",
"needed": true
},
{
"label": "Date de rédaction",
"name": "my_date",
"type": "date"
},
{
"label": "Remarques",
"name": "my_comment",
"type": "htmltext"
},
{
"label": "Criticité",
"name": "my_level",
"type": "enum",
"enumItems": [
{
"key": "low",
"label": "Faible"
},
{
"key": "medium",
"label": "Moyen"
},
{
"key": "hight",
"label": "Élevé"
}
]
}
]
}
],
"values": {
"my_date": "2019-07-24",
"my_title": "Hello world",
"my_level": "medium",
"my_comment": "<p>Ursidae</p>\n <p>\n <img alt=\"Description de cette image, également commentée ci-après\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Ursus_arctos_Dessin_ours_brun_grand.jpg/290px-Ursus_arctos_Dessin_ours_brun_grand.jpg\" style=\"height: 182px; width: 290px; float: right;\"></p><p><a href=\"https://fr.wikipedia.org/wiki/Ours_brun\">Ours brun</a> (<em>Ursus arctos</em>)</p>"
}
}
Résultat : Valeurs dans le formulaire
Les valeurs étendues permettent de définir complètement les caractéristiques de champs plus complexes comme les docid
ou les file
.
Affectation de valeurs étendues
{
"title": "Valeurs étendues",
"type": "Invitation",
"icon": "/api/v2/images/assets/sizes/24x24c/se-image.png",
"structure": [
{
"label": "Caractéristiques",
"name": "my_frame",
"type": "frame",
"content": [
{
"label": "Title",
"name": "my_title",
"type": "text",
"needed": true
},
{
"label": "Facture",
"name": "my_bill",
"type": "docid",
"typeFormat": "DEVBILL"
},
{
"label": "Photo",
"name": "my_picture",
"type": "image"
},
{
"label": "Criticité",
"name": "my_level",
"type": "enum",
"enumItems": [
{
"key": "low",
"label": "Faible"
},
{
"key": "medium",
"label": "Moyen"
},
{
"key": "hight",
"label": "Élevé"
}
]
}
]
}
],
"values": {
"my_title": "Hello world",
"my_bill": {
"value": 98137,
"displayValue": "Bill 0018"
},
"my_picture": {
"creationDate": "2019-09-04 09:53:44",
"displayValue": "regatta-1049741_1280.jpg",
"fileName": "regatta-1049741_1280.jpg",
"icon": "/api/v2/images/assets/sizes/24x24c/mime/png/mime-image.png",
"mime": "image/jpeg",
"size": "399052",
"thumbnail": "/api/v2/smart-elements/87527/images/img_file/-1/sizes/48x48c.png",
"url": "/api/v2/smart-elements/87527/files/img_file/-1/regatta-1049741_1280.jpg?inline=true",
"value": "image/jpeg|1856421439332325192|regatta-1049741_1280.jpg"
}
}
}
Résultat : Valeurs étendues
# Événements
Les événements du Smart Form sont les mêmes que les événements Smart Element.
L'exemple ci-dessous intercepte les événements ready
et
smartFieldChange
qui permettent d'interagir sur toute
modification du formulaire. Le menu déclenche aussi des événements qui sont interceptés par
actionClick
et
beforeSave
<template>
<div>
<ank-smart-form ref="smartFormRef" @smartElementMounted="smartElementMounted" :config="json" />
</div>
</template>
<script>
import AnkSmartForm from "@anakeen/user-interfaces/components/lib/AnkSmartForm.esm";
import "@anakeen/user-interfaces/components/scss/AnkSmartElement.scss";
export default {
components: {
AnkSmartForm: () => AnkSmartForm
},
data: () => {
return {
json: {
title: "Formulaire minimaliste",
type: "Demande de renseignement",
structure: [
{
label: "Identification",
name: "my_fr_ident",
type: "frame",
content: [
{
label: "Objet de la requête",
name: "my_title",
type: "text"
}
]
}
],
menu: [
{
id: "special",
beforeContent: '<div class="fa fa-superpowers" />',
label: "Spécial",
type: "itemMenu",
url: "#action/my.superpower"
},
{
id: "submit",
beforeContent: '<div class="fa fa-save" />',
label: "Soumettre",
type: "itemMenu",
url: "#action/document.save"
}
]
}
};
},
methods: {
smartElementMounted: function() {
this.$refs.smartFormRef.$on("ready", event => {
console.log("The form is ready to be used");
});
this.$refs.smartFormRef.$on("smartFieldChange", (event, formProperties, field, values) => {
console.log("Field", field.id, "has a new value", field.getValue().value);
console.log("The previous value is", values.previous ? values.previous.value : "");
this.$refs.smartFormRef.showMessage({
message: "Smart Field " + field.id + " has changed.",
htmlMessage: "<h2>" + field.getValue().value + "</h2>"
});
});
this.$refs.smartFormRef.$on("actionClick", (event, data, options) => {
console.log("action", options.eventId);
if (options.eventId === "my.superpower") {
alert("Super power actived");
}
});
this.$refs.smartFormRef.$on("beforeSave", (event, data) => {
// Submit button activated
console.log("beforeSave", event, data);
});
}
}
};
</script>