Ajout de champs dans le formulaire et de champs spécifiques à chaque fichier

1/ L'exemple n°1 montre le principe de base pour ajouter des champs dans le formulaire.

Dans la plupart des cas, il suffit de :

- Attribuer dans le HTML la classe UpAbci_inputInfosFileUnic aux boutons de type radio pour les champs spécifiques aux fichiers, afin de permettre différentes sélections dans un upload multiple.

- Configurer si besoin l'option javascript config.inputFormAttrOnSubmit pour geler les inputs durant la transmission du formulaire et signifier ainsi à l'utilisateur que d'éventuelles modifications des champs de saisie ne sont pas prises en compte durant le transfert des fichiers.

Note : En complément des champs de saisie, vous disposez également d'une propriété javascript "join_file" pour transmettre des informations spécifiques à chaque fichier sans utiliser des champs de saisie utilisateur, voir le fichier "UploadAjaxABCI_Infos_Exif.php" pour plus d'informations.

2/ L'exemple n°2 adopte un système de notation graphique (coeurs, étoiles...) implémenté en utilisant les méthodes javascript événementielles.

3/ Un troisième chapitre récapitule les méthodes serveur pour retourner des informations serveur directement dans le html ou dans les objets passés en paramètre de certaines fonctions événementielles.

Le bloc des informations spécifiques à chaque fichier, défini avec la classe UpAbci_infosFile, est inclus dans un bloc conteneur ciblé avec le troisième paramètre passé dans l'initialisation de la classe javascript et auquel j'ai attribué la classe "Content_UpAbci_infosFile" dans mes exemples. Cependant, seuls les champs et les éléments inclus dans UpAbci_infosFile sont spécifiques à chaque fichier et seront dupliqués en cas d'upload multiple.
Voir la note*** si l'on souhaite insérer des champs entre le bloc ayant la classe UpAbci_infosFile et son bloc conteneur défini par le troisième paramètre renseigné dans l'initialisation de la classe javascript.

Principe d'envoi des champs

- Tous les champs extérieurs au bloc UpAbci_infosFile sont communs à tout le formulaire et sont transmis dans toutes les requêtes Ajax.

- Les champs inclus dans UpAbci_infosFile sont transmis uniquement dans les requêtes Ajax qui envoient le fichier correspondant. Cela permet de récupérer ces champs sans ambiguïté côté serveur, même s'ils sont dupliqués dans le html en cas d'upload multiple.

- En cas de conflit de nom entre des champs extérieurs au bloc UpAbci_infosFile et d'autres champs inclus dans ce bloc, les champs inclus dans ce bloc spécifique aux fichiers auront la priorité et écraseront les autres. Néanmoins, les valeurs des champs en conflit de nom et extérieurs au bloc UpAbci_infosFile seront transmises si le formulaire est envoyé sans fichier joint.

- La classe javascript enregistre la valeur de tous les inputs sur l'événement onSubmit du formulaire. Toute modification ultérieure durant le transfert des fichiers n'est pas prise en compte, quelque soit la configuration de l'option javascript "config.inputFormAttrOnSubmit" détaillée plus bas.

Renommage de certains champs

En cas de sélection multiple de fichiers, certains types de champs comme les boutons radio nécessitent d'avoir un nom unique pour chaque fichier, car une seule sélection est possible dans tout le formulaire pour les champs de même nom.

La classe css UpAbci_inputInfosFileUnic est une commande qui indique au script de concaténer le nom de l'input associé, à la propriété javascript id_fich spécifique au fichier.

(Sans cela, si vous supprimer la classe "UpAbci_inputInfosFileUnic" dans les inputs de type radio spécifiques aux fichiers, vous constaterez en cas de sélection de plusieurs fichiers, que le dernier bouton sélectioné pour un fichier annule les précédentes sélections des autres fichiers, car tous les champs ont le même nom)


Côté php, vous disposez de la méthode getInputInfosFileUnic('champ') pour récupérer la valeur de ces champs, voir le fichier "UploadAjaxABCI_Upload_Champs_Sup_Notation.php" dans le répertoire "Php_Upload".

Réinitialisation des champs dans le formulaire

Tous les éléments inclus dans le bloc conteneur renseigné en troisisème paramètre dans l'initialisation de la classe javascript sont rafraichis à chaque sélection de fichiers.

Note***
Si donc vous insérez des champs entre ce bloc conteneur et le bloc d'information spécifique à chaque fichier défini avec UpAbci_infosFile, ils seront également réinitialisés à chaque sélection de fichiers.

Voir le champ "Titre général 2" qui a ce positionnement html particulier dans les exemples ci-dessous : tout étant commun à tout le formulaire, puisque non inclus dans le bloc UpAbci_infosFile, il n'est rendu visible qu'à l'occasion d'une sélection de fichiers. Sans cela, le visiteur pourrait être tenté de renseigner ce champ avant de sélectionner des fichiers mais la valeur saisie dans ce champ sera effacée dès la sélection de fichiers.

Ce positionnement particulier est donc plus adapté pour placer des champs communs à toute la sélection de fichiers, plutôt que communs à tout le formulaire, même si du fait de leur positionnement ils sont par principe communs à tout le formulaire et seront transmis dans toutes les requêtes Ajax.

Configuration javascript optionnelle

Pour signifier au visiteur que la modification de la valeur des inputs ne sera pas prise en compte durant le transfert des fichiers - donc non pas par nécessité technique - je configure le script d'upload avec l'option config.inputFormAttrOnSubmit = "disabled" pour interdire les modifications de saisie durant la soumission des fichiers.

Si la valeur de cette option est différente de false, l'attribut indiqué sera appliqué sur tous les inputs, à l'exception de ceux ayant une classe prédéfinie "UpAbci_stop" ou "UpAbci_stopAll", dès la soumission du formulaire. Les champs inclus dans le bloc conteneur renseigné en troisième paramètre dans l'initialisation de la classe javascript sont de plus formatés avec le style css "cursor:default". L'attribut appliqué par config.inputFormAttrOnSubmit sera supprimé à la fin du traitement du formulaire pour tous les inputs extérieurs à ce bloc, exceptés ceux pour lesquels cet attribut était déjà activé lors de la soumission du formulaire.

J'ai choisi l'attribut "disabled" de préférence à "readonly" car "readonly" est ignoré pour les champs de type "hidden", "range", "color", "checkbox", "radio", "file", "button" ou "submit".

Note
- Si vous souhaitez utiliser cette option tout en laissant certains champs actifs durant la soumission du formulaire, vous pouvez utiliser la méthode événementielle config.func_FormSubmit qui sera appliquée (si définie) postérieurement à cette option et vous permettra de réactiver les champs voulus. Ou encore, vous pourriez ne pas utiliser cette option et vous servir des fonctions événementielles pour désactiver puis réactiver certains champs ciblés en temps voulu. Alternativement, vous pouvez aussi utiliser les fonctions évènementielles pour mettre un attribut "disabled" sur le "fieldset" pour désactiver tous ses champs inclus.
Upload 1

Traitement terminé
Traitement en cours...

Utilisation des fonctions javascript événementielles

Comme le montre la configuration javascript de l'exemple n°1, l'utilisation des fonctions événementielles n'est pas indispensable pour ajouter des champs dans le formulaire, qu'ils soit communs à tout le formulaire ou spécifiques à chaque fichier.

L'exemple n°2 utilise les fonctions javascript événementielles pour interfacer le script avec une classe externe "DrawCanvasABCI" et afficher un système de notation graphique (étoiles, coeurs...) à la place des boutons radios. Il montre comment accéder au contexte html spécifique à chaque fichier (bloc ayant la classe UpAbci_infosFile) par l'intermédiaire des objets disponibles dans la plupart des fonctions événementielles et permettre ainsi de modifier ou programmer le comportement des éléments html pour chaque fichier sélectionné.

On figera également le comportement graphique du système de notation dès la soumission du formulaire, pour signifier à l'utilisateur qu'aucune modification n'est possible durant le transfert des fichiers.

Notes
Si vous souhaitez stopper la soumission du formulaire, par exemple pour ajouter des champs ou modifier leur valeur dynamiquement en javascript avant la soumisson du formulaire etc., utilisez la méthode événementielle config.func_onFormSubmit qui est déclenchée juste avant l'envoi du formulaire, et donc avant la méthode config.func_FormSubmit.

Voir le fichier "UploadAjaxABCI_Custom.php" pour un autre exemple d'utilisation des fonctions javascript événementielles. Il montre comment gérer l'affichage de la boite de téléchargement et utilise la méthode config.func_FormEnd pour afficher un récapitulatif du résultat de l'upload.

En complément du mode d'emploi, utilisez console.log(objet) dans votre code pour visualiser dans la console du navigateur le contenu des objets retournés par les fonctions javascript événementielles.
Upload 2

Note : les fichiers partiellement sauvegardés peuvent être complétés pendant 24h suivant la dernière sauvegarde effectuée.
Traitement terminé
Traitement en cours...

Retours d'informations serveur

Vous constatez côté serveur - voir fichier "UploadAjaxABCI_Upload_Champs_Sup_Notation.php" dans le répertoire "Php_Upload" - que l'on peut envoyer du texte ou du html directement dans le bloc html ayant la classe UpAbci_infosServer (donc sans utiliser des fonctions événementielles), en employant la méthode serveur addInfosServer. Actuellement cette méthode retourne "Aucun fichier traité" si vous envoyez le formulaire sans fichier joint.

En complément, vous disposez également des méthodes addStatusOk, addStatusErreur, et exitStatusErreur cf doc qui permettent de renvoyer du texte ou du html directement dans l'élément html ayant la classe UpAbci_status, comme déjà vu dans les exemples précédents. Les suffixes "Ok" et "Erreur" indiquent les styles css correspondants qui seront déclenchés conjointement.

Vous disposez également de la méthode addMixteServer qui permet de renvoyer tout type de contenu, texte, html, y compris des tableaux php, que l'on pourra récupérer uniquement dans le troisième paramètre des méthodes événementielles config.func_FileEndEach() et config.func_FormEnd().

A titre d'exemple pour l'upload n°2 (cf code source), j'utilise la méthode config.func_FileEndEach() pour récupérer le retour serveur envoyé avec addMixteServer qui contient ici les valeurs saisies pour chaque fichier, que j'ajouterai dynamiquement en javascript dans le bloc d'information spécifique à chaque fichier, à la fin du traitement de chaque fichier. Et j'utilise la méthode config.func_FormEnd() pour afficher le retour serveur du Titre général 1 même si aucun fichier n'est soumis.

Important : Le contenu retourné par les méthodes addStatusOk, addStatusErreur, exitStatusErreur et addInfosServer, est inséré dans le html en utilisant la méthode html() de jQuery pour un maximum de possibilités. Aussi si certaines variables retournées sont susceptibles de contenir des caractères spéciaux qui sont interprétés comme des tag html ("<" et ">" par exemple), vous devez protéger ces variables côté serveur avec la fonction Php htmlspecialchars() sinon le html final pourra être déformé et la réponse vide.

Il n'y a pas de nécessité d'utiliser htmlspecialchars côté serveur pour protéger les variables dans cet exemple, puisque j'emploie la méthode addMixteServer qui n'affiche rien dans le html. En contrepartie, je protége les variables recupérées dans le troisième paramètre de la méthode événementielle config.func_FileEndEach(), en employant la méthode text() de jQuery (qui n'interprête pas les tags html) pour construire la réponse et l'insérer dans le html. Suivant les cas, il sera plus pratique de protéger les variables côté serveur avec htmlspecialchars, notamment si vous construisez une réponse php contenant du html structuré et des variables utilisateur.

Index