398 lines
13 KiB
Markdown
398 lines
13 KiB
Markdown
# Guide des Composants Composites Freya Extension
|
|
|
|
## Vue d'ensemble
|
|
|
|
L'extension Freya fournit 15 composants composites qui appliquent automatiquement les patterns Freya et réduisent le code boilerplate dans vos formulaires Jakarta Faces.
|
|
|
|
### Namespace
|
|
|
|
```xml
|
|
xmlns:fr="http://primefaces.org/freya"
|
|
```
|
|
|
|
### Avantages
|
|
|
|
✅ **Réduction massive du boilerplate** - ~80% de code en moins
|
|
✅ **Pattern Freya garanti** - Structure `field` et `field-checkbox` standardisée
|
|
✅ **Indicateur requis optimal** - Astérisque rouge géré proprement via `h:outputText`
|
|
✅ **Composants modernes** - Utilisation de `p:datePicker`, `p:toggleSwitch`, etc.
|
|
✅ **Fluid Design** - Tous les champs sont optimisés pour `ui-fluid`
|
|
✅ **Validation simplifiée** - Un seul tag pour label + input + message
|
|
|
|
---
|
|
|
|
## Liste des Composants
|
|
|
|
| Catégorie | Composant | Description | PF Natif |
|
|
|-----------|-----------|-------------|----------|
|
|
| **Texte** | `fr:fieldInput` | Champ texte standard | `p:inputText` |
|
|
| | `fr:fieldTextarea` | Zone de texte multiligne | `p:inputTextarea` |
|
|
| | `fr:fieldPassword` | Mot de passe | `p:password` |
|
|
| | `fr:fieldChips` | Saisie de tags | `p:chips` |
|
|
| **Sélection** | `fr:fieldSelect` | Liste déroulante unique | `p:selectOneMenu` |
|
|
| | `fr:fieldMultiSelect`| Liste déroulante multiple | `p:selectCheckboxMenu`|
|
|
| | `fr:fieldRadio` | Boutons radio | `p:selectOneRadio` |
|
|
| **Date & Nombre**| `fr:fieldCalendar` | Sélecteur de date | `p:datePicker` |
|
|
| | `fr:fieldNumber` | Champ numérique | `p:inputNumber` |
|
|
| **Boutons** | `fr:fieldCheckbox` | Case à cocher | `p:selectBooleanCheckbox`|
|
|
| | `fr:fieldSwitch` | Interrupteur | `p:toggleSwitch` |
|
|
| | `fr:fieldToggle` | Bouton bascule | `p:selectBooleanButton` |
|
|
| **Spéciaux** | `fr:fieldRating` | Évaluation | `p:rating` |
|
|
| | `fr:fieldColor` | Couleur | `p:colorPicker` |
|
|
| **Layout** | `fr:actionDialog` | Dialog standardisé | `p:dialog` |
|
|
|
|
---
|
|
|
|
## Détails des Composants
|
|
|
|
### 1. fr:fieldInput
|
|
*(Identique à la version précédente)*
|
|
|
|
### 2. fr:fieldNumber
|
|
Champ numérique pour les montants, prix ou quantités.
|
|
|
|
#### Attributs spécifiques
|
|
| Attribut | Type | Défaut | Description |
|
|
|----------|------|--------|-------------|
|
|
| `symbol` | String | - | Symbole monétaire (ex: " FCFA") |
|
|
| `symbolPosition`| String | "p" | Position du symbole ("p"refix, "s"uffix) |
|
|
| `decimalPlaces` | String | "2" | Nombre de décimales |
|
|
| `minValue` | String | - | Valeur minimale |
|
|
| `maxValue` | String | - | Valeur maximale |
|
|
|
|
### 3. fr:fieldSelect
|
|
*(Identique à la version précédente)*
|
|
|
|
### 4. fr:fieldMultiSelect
|
|
Sélecteur multiple compact.
|
|
|
|
#### Attributs spécifiques
|
|
| Attribut | Type | Défaut | Description |
|
|
|----------|------|--------|-------------|
|
|
| `filter` | Boolean | `false` | Active la recherche |
|
|
| `multiple` | Boolean | `true` | Sélection multiple |
|
|
|
|
### 5. fr:fieldRadio
|
|
Boutons radio pour un choix exclusif visible.
|
|
|
|
#### Attributs spécifiques
|
|
| Attribut | Type | Défaut | Description |
|
|
|----------|------|--------|-------------|
|
|
| `layout` | String | "lineDirection"| Disposition ("lineDirection" ou "pageDirection") |
|
|
|
|
### 6. fr:fieldCalendar
|
|
Sélecteur de date moderne (DatePicker).
|
|
|
|
#### Attributs spécifiques
|
|
| Attribut | Type | Défaut | Description |
|
|
|----------|------|--------|-------------|
|
|
| `showIcon` | Boolean | `true` | Affiche l'icône calendrier |
|
|
| `pattern` | String | - | Format (ex: "dd/MM/yyyy") |
|
|
| `yearRange` | String | - | Plage d'années |
|
|
|
|
### 7. fr:fieldPassword
|
|
*(Identique à la version précédente)*
|
|
|
|
### 8. fr:fieldTextarea
|
|
*(Identique à la version précédente)*
|
|
|
|
### 9. fr:fieldCheckbox
|
|
Case à cocher standard. Utilise le layout `field-checkbox`.
|
|
|
|
### 10. fr:fieldSwitch
|
|
Interrupteur ON/OFF moderne.
|
|
|
|
### 11. fr:fieldToggle
|
|
Bouton avec états ON/OFF personnalisables.
|
|
|
|
#### Attributs spécifiques
|
|
| Attribut | Type | Défaut | Description |
|
|
|----------|------|--------|-------------|
|
|
| `onLabel` | String | "Oui" | Texte état ON |
|
|
| `offLabel` | String | "Non" | Texte état OFF |
|
|
| `onIcon` | String | - | Icône état ON |
|
|
| `offIcon` | String | - | Icône état OFF |
|
|
|
|
### 12. fr:fieldChips
|
|
Saisie de tags/mots-clés.
|
|
|
|
### 13. fr:fieldRating
|
|
Saisie d'une note.
|
|
|
|
### 14. fr:fieldColor
|
|
Sélecteur de couleur graphique.
|
|
|
|
### 15. fr:actionDialog
|
|
*(Identique à la version précédente)*
|
|
|
|
**Dialog personnalisé:**
|
|
```xml
|
|
<fr:actionDialog widgetVar="dlgConfirmDelete"
|
|
header="Confirmer la suppression"
|
|
width="400px"
|
|
cancelLabel="Non"
|
|
confirmLabel="Oui, supprimer"
|
|
confirmIcon="pi pi-trash"
|
|
confirmAction="#{userBean.deleteUser}"
|
|
confirmUpdate="userTable">
|
|
<p>Êtes-vous sûr de vouloir supprimer cet utilisateur ?</p>
|
|
<p><strong>#{userBean.selectedUser.nom}</strong></p>
|
|
</fr:actionDialog>
|
|
```
|
|
|
|
**Ouverture/fermeture:**
|
|
```xml
|
|
<!-- Bouton pour ouvrir -->
|
|
<p:commandButton value="Éditer"
|
|
icon="pi pi-pencil"
|
|
onclick="PF('dlgEditUser').show()"
|
|
update="dlgEditUser" />
|
|
|
|
<!-- Le dialog se ferme automatiquement si la validation réussit -->
|
|
<!-- Ou fermeture manuelle en JavaScript: PF('dlgEditUser').hide() -->
|
|
```
|
|
|
|
**Comportement:**
|
|
- Le bouton **Annuler** ferme le dialog sans exécuter d'action
|
|
- Le bouton **Sauvegarder** exécute l'action et ferme le dialog **uniquement si la validation réussit**
|
|
- Le contenu du dialog utilise `ui-fluid` pour des inputs pleine largeur
|
|
|
|
---
|
|
|
|
## Formulaire complet - Exemple
|
|
|
|
```xml
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
|
xmlns:p="http://primefaces.org/ui"
|
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
|
xmlns:fr="http://primefaces.org/freya">
|
|
|
|
<h:head>
|
|
<title>Inscription utilisateur</title>
|
|
</h:head>
|
|
|
|
<h:body>
|
|
<div class="grid">
|
|
<div class="col-12 md:col-8 md:col-offset-2">
|
|
<div class="card">
|
|
<h3>Créer un compte</h3>
|
|
|
|
<h:form id="registerForm">
|
|
<div class="grid">
|
|
<div class="col-12 md:col-6">
|
|
<fr:fieldInput label="Prénom"
|
|
value="#{registerBean.user.prenom}"
|
|
required="true" />
|
|
</div>
|
|
<div class="col-12 md:col-6">
|
|
<fr:fieldInput label="Nom"
|
|
value="#{registerBean.user.nom}"
|
|
required="true" />
|
|
</div>
|
|
</div>
|
|
|
|
<fr:fieldInput label="Email"
|
|
value="#{registerBean.user.email}"
|
|
required="true" />
|
|
|
|
<fr:fieldPassword label="Mot de passe"
|
|
value="#{registerBean.user.password}"
|
|
feedback="true"
|
|
required="true" />
|
|
|
|
<fr:fieldPassword label="Confirmer le mot de passe"
|
|
value="#{registerBean.passwordConfirm}"
|
|
feedback="false"
|
|
required="true" />
|
|
|
|
<fr:fieldCalendar label="Date de naissance"
|
|
value="#{registerBean.user.dateNaissance}"
|
|
yearRange="1940:2010"
|
|
required="true" />
|
|
|
|
<fr:fieldSelect label="Pays"
|
|
value="#{registerBean.user.pays}"
|
|
filter="true"
|
|
required="true">
|
|
<f:selectItem itemLabel="-- Sélectionnez --" itemValue="" />
|
|
<f:selectItems value="#{referentielBean.paysList}" />
|
|
</fr:fieldSelect>
|
|
|
|
<fr:fieldTextarea label="Présentation (optionnel)"
|
|
value="#{registerBean.user.bio}"
|
|
rows="4"
|
|
maxlength="500" />
|
|
|
|
<fr:fieldCheckbox label="J'accepte les conditions d'utilisation"
|
|
value="#{registerBean.acceptTerms}"
|
|
required="true" />
|
|
|
|
<fr:fieldCheckbox label="Je souhaite recevoir la newsletter"
|
|
value="#{registerBean.user.newsletter}" />
|
|
|
|
<div class="field" style="margin-top: 1.5rem;">
|
|
<p:commandButton value="S'inscrire"
|
|
icon="pi pi-user-plus"
|
|
action="#{registerBean.register}"
|
|
update="registerForm"
|
|
styleClass="ui-button-success" />
|
|
|
|
<p:commandButton value="Annuler"
|
|
icon="pi pi-times"
|
|
action="#{registerBean.cancel}"
|
|
styleClass="ui-button-secondary"
|
|
style="margin-left: 0.5rem;" />
|
|
</div>
|
|
</h:form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</h:body>
|
|
</html>
|
|
```
|
|
|
|
---
|
|
|
|
## Comparaison Avant/Après
|
|
|
|
### Sans l'extension (PrimeFaces standard)
|
|
|
|
```xml
|
|
<div class="field">
|
|
<p:outputLabel for="nom" value="Nom">
|
|
<span class="p-error"> *</span>
|
|
</p:outputLabel>
|
|
<p:inputText id="nom" value="#{bean.nom}" required="true" />
|
|
<p:message for="nom" />
|
|
</div>
|
|
|
|
<div class="field">
|
|
<p:outputLabel for="prenom" value="Prénom">
|
|
<span class="p-error"> *</span>
|
|
</p:outputLabel>
|
|
<p:inputText id="prenom" value="#{bean.prenom}" required="true" />
|
|
<p:message for="prenom" />
|
|
</div>
|
|
```
|
|
|
|
**10 lignes de code**
|
|
|
|
### Avec l'extension (Freya composites)
|
|
|
|
```xml
|
|
<fr:fieldInput label="Nom" value="#{bean.nom}" required="true" />
|
|
<fr:fieldInput label="Prénom" value="#{bean.prenom}" required="true" />
|
|
```
|
|
|
|
**2 lignes de code** ✅
|
|
|
|
### Réduction
|
|
|
|
- **80% moins de code**
|
|
- **Même résultat visuel**
|
|
- **Même fonctionnalité**
|
|
- **Pattern Freya garanti**
|
|
|
|
---
|
|
|
|
## Intégration avec Validation Bean
|
|
|
|
Les composants supportent pleinement Bean Validation (Jakarta Validation):
|
|
|
|
```java
|
|
public class User {
|
|
@NotBlank(message = "Le nom est obligatoire")
|
|
@Size(min = 2, max = 50, message = "Le nom doit contenir entre 2 et 50 caractères")
|
|
private String nom;
|
|
|
|
@Email(message = "Email invalide")
|
|
@NotBlank(message = "L'email est obligatoire")
|
|
private String email;
|
|
|
|
@Past(message = "La date de naissance doit être dans le passé")
|
|
private LocalDate dateNaissance;
|
|
}
|
|
```
|
|
|
|
```xml
|
|
<fr:fieldInput label="Nom" value="#{userBean.user.nom}" required="true" />
|
|
<fr:fieldInput label="Email" value="#{userBean.user.email}" required="true" />
|
|
<fr:fieldCalendar label="Date de naissance" value="#{userBean.user.dateNaissance}" required="true" />
|
|
```
|
|
|
|
Les messages de validation Bean Validation s'afficheront automatiquement via `<p:message>`.
|
|
|
|
---
|
|
|
|
## Personnalisation
|
|
|
|
### Classes CSS additionnelles
|
|
|
|
```xml
|
|
<fr:fieldInput label="Code VIP"
|
|
value="#{bean.codeVip}"
|
|
styleClass="highlight-field" />
|
|
```
|
|
|
|
Génère:
|
|
```xml
|
|
<div class="field highlight-field">
|
|
...
|
|
</div>
|
|
```
|
|
|
|
### Binding de composants
|
|
|
|
Pour accéder au composant PrimeFaces sous-jacent:
|
|
|
|
```xml
|
|
<fr:fieldInput label="Nom"
|
|
value="#{bean.nom}"
|
|
binding="#{bean.nomInput}" />
|
|
```
|
|
|
|
Dans le bean:
|
|
```java
|
|
private InputText nomInput; // PrimeFaces component
|
|
|
|
public void someMethod() {
|
|
nomInput.setDisabled(true);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Bonnes pratiques
|
|
|
|
✅ **DO:**
|
|
- Utiliser `fr:field*` pour tous les champs de formulaire
|
|
- Utiliser `fr:actionDialog` pour les dialogs CRUD standard
|
|
- Combiner avec les grids PrimeFlex (`grid`, `col-*`)
|
|
- Grouper les champs connexes dans `<div class="card">`
|
|
|
|
❌ **DON'T:**
|
|
- Ne pas imbriquer les composants `fr:field*` (ils créent déjà un `<div class="field">`)
|
|
- Ne pas dupliquer les labels (le composant gère déjà le label)
|
|
- Ne pas oublier `widgetVar` sur `fr:actionDialog` (obligatoire)
|
|
|
|
---
|
|
|
|
## Technologies
|
|
|
|
- **Jakarta Faces 4.0** (Composite Components)
|
|
- **PrimeFaces 14.0.0** (Jakarta)
|
|
- **Freya Theme 5.0.0**
|
|
- **PrimeFlex 3.3.1** (Grid système)
|
|
|
|
---
|
|
|
|
## Support
|
|
|
|
Pour plus d'informations:
|
|
- [PrimeFaces Documentation](https://primefaces.github.io/primefaces/)
|
|
- [Freya Theme](https://freya.primefaces.org/)
|
|
- [Jakarta Faces Composite Components](https://jakarta.ee/learn/docs/jakartaee-tutorial/current/web/faces-advanced-cc/faces-advanced-cc.html)
|