Le composant InputSelector est un input synchroniser a votre api qui permet a l'utilisateur de sélectionner un ou des elements de votre base de données.
Pour reproduire ce composant vous devez créer un fichier racine du composant. Ici dans notre
exemple le fichier racine est ProductInput.svelte
Il sera necessaire dans la balise script de déclaré 3 choses :
limit : Il sagit de la limite d'element que votre serveur peut récupérer en une fois
getMultipleElement(search, offset) : Il sagit de la fonction qui va appeller votre serveur
afin de récuperer la liste d'element cette fonction dois renvoyé un objet avec la clé rows qui est un array des elements de notre liste et la clé totalOfRows qui est un int
qui représente le nombre total disponible dans la base de données tant que la liste ne contient
pas le nombre total un bouton "charger plus" sera affiché.
Quand on clique sur un element de la liste il execute la fonction getElement(data) en
lui passant dans le parametre data l'element de la liste rows en question
et ce afin de récuperer les details de cette element coté serveur.
getElement(data) : Cette fonction permet de récuperer les details d'un element précis. Elle est éxecuter soit quand on selectionne un element soit au onMount() si la props value est set
Ces 3 choses doient etre passer en props a notre composant InputSelector
Il faut noter que chacune des deux fonctions getMultipleElement(search, offset) et getElement(data) doit renvoyé dans les elements une clé id c'est par cette clé que le composant va identifier
les elements selectionné ou non et c'est cette clé qu'il va injecter dans un input:hidden afin de pouvoir
récuperer coté serveur les ou l'element selectionner par son id
Ensuite il faut importer 2 composants ces 2 composant sont les boutons representant votre element en question :
ProductCard : Ici dans notre exemple il sagit de produit. Ce composant sera passer dans la props component de InputSelector il represente notre composant dans la liste deroulante. Le composant InputSelector va se charger d'injecter en props les données fournies dans les element que contient rows envoyé par la fonction getMultipleElement(search, offset) il injecte en plus une props selected (bool) si l'element fais partie de la selection afin de pouvoir styliser le composant lorsqu'il est deja selectionné.
ProductCardSelection : Ce composant sera passer dans la props selectionComponent de InputSelector il represente notre composant quand il est selectionné. Le composant InputSelector va se charger d'injecter en props les données fournies par la fonction getElement(data)
Il ne reste plus qu'a set les props pour le style :
<script>
import { InputSelector, sendRequest } from 'hamzus-ui';
import ProductCard from './ProductCard.svelte';
import ProductCardSelection from './ProductCardSelection.svelte';
export let value = null
let limit = 20;
async function getMultipleElement(search, offset) {
const request = await sendRequest({
path:"/get-all-products",
data:{
globalSearch:search,
offset:offset,
<script>
export let props = {...$$restProps}
export let id;
export let name;
export let selected;
function handleClick() {
console.log("click");
props.onClick({
...props,
id:id,
name:name,
})
<script>
import { IconButton } from "hamzus-ui";
export let props = {...$$restProps}
export let id;
export let name;
function handleClick() {
props.onClick({
...props,
id:id,
name:name,
})
}
</script>
Vous pouvez activer la selection multiple via la props multiple set a true
Si elle est true l'input hidden injecter ne portera pas comme name la props name mais portera comme name "name[]" le name sera suivie de "[]" ce qui permetra dans le cas d'un serveur php d'etre interpreter comme un array d'id.
La seul chose que j'ai decidé de changer pour le composant multiple est le style de mon ProductCardSelection
Il sagit donc du meme code sauf qu'a la place de mettre "width:100%;" j'ai mis "max-width: 270px;". et j'ai set la props multiple sur le composant InputSelector dans le fichier ProductInput.svelte
<style>
.card {
display: flex;
justify-content: space-between;
max-width: 270px;
/* width: 100%; */
align-items: center;
gap: var(--pad-s);
padding: var(--pad-xs) var(--pad-m);
border-radius: var(--radius-m);
border: 1px solid var(--stroke);
cursor: pointer;
}
</style>
<InputSelector
{value}
{limit}
multiple
placeholder="rechercher un produit"
label="produit"
name="productId"
component={ProductCard}
selectionComponent={ProductCardSelection}
{getMultipleElement}
{getElement}
></InputSelector>
Il est possible d'injecter une valeur par defaut via la props value.
Dans le cas d'un input multiple alor la value doit etre un array d'id et dans le cas d'un input a selection unique alors la value sera un int qui representent l'id de l'element.