Edition multiples d'éléments - Quelle méthode ?

Salut,


 


J'aimerais avoir votre avis sur l'édition multiples de X éléments contenants Y champs.


 


Quand on veut éditer plusieurs éléments à  la fois, après une sélection multiple par exemple, et que chaque élément contient plusieurs champs, c'est assez problématique.


 


Dans les programmes, on a l'habitude de voir "Multiple values" si un champ contient des valeurs différentes dans les différents éléments.


 


Pour l'instant, moi, je me contentais de passer à  nil les champs avec des valeurs différentes avant l'affichage:


- si le champ était modifié et donc plus à  nil, tous les éléments étaient modifiés en conséquence


- si le champ n'était pas modifié et restait à  nil, on ne touchait pas à  la valeur originale du champ de l'élément


 


Cela marche bien.


Le problème se pose si on veut passer des champs à  nil volontairement (pour remettre des valeurs à  "vide"), mon test sur nil n'est plus efficace.


 


Le problème, c'est que ces champs sont différents (date, texte, nombre) et je ne vois pas comment implémenter le coup de l'affichage de "Multiple values", et comment le réprésenter temporairement dans le modèle.


 


Donc, quelle est la façon habituelle de faire ?


Réponses

  • AliGatorAliGator Membre, Modérateur
    Tu as essayé d'utiliser un marqueur significatif (comme [NSNull null] par exemple) comme valeur plutôt que nil ?
  • muqaddarmuqaddar Administrateur
    septembre 2013 modifié #3


    Tu as essayé d'utiliser un marqueur significatif (comme [NSNull null] par exemple) comme valeur plutôt que nil ?




     


    J'y ai pensé, mais ça veut aussi donc dire que je dois tester dans chaque champ, au niveau affichage, si la valeur est:


    - nil (champ jamais rempli), donc ne rien écrire


    - [NSNull null] => écrire "multiple values"


    - ou la valeur réelle du champ et affichage en conséquence (date, nombre, texte...)


     


    Il faut aussi traiter "l'édition du champ", et faire le même test.


    Et si on a [NSNull null] pour une date par exemple, on affiche quoi ? La première des dates des éléments ou rien ?


     


    Enfin, il faut aussi faire le test à  l'enregistrement.


     


    C'est du travail, mais si y'a pas mieux je ferai ça.




  • J'y ai pensé, mais ça veut aussi donc dire que je dois tester dans chaque champ, au niveau affichage, si la valeur est:


    - nil (champ jamais rempli), donc ne rien écrire


    - [NSNull null] => écrire "multiple values"


    - ou la valeur réelle du champ et affichage en conséquence (date, nombre, texte...)




     


    C'est factorisable ça non ?


    Par curiosité, du point de vue de l'utilisateur, c'est quoi la différence entre NULL et nil en terme d'édition ?

  • muqaddarmuqaddar Administrateur

    Si valeur, afficher la valeur.


    Si nil, rien n'est affiché (aucune valeur pour tous les enregistrements).


    Si [NSNull null] ou une autre valeur à  choisir, les valeurs sont différentes (multiples values).


     


    Mais p-e que je n'ai pas compris ta question.


  • En fait je cherche à  savoir comment l'utilisateur distingue une propriété qui n'a jamais reçu de valeur (nil), d'une propriété qu' il a fixé à  une valeur vide.

    Par exemple, si c'est une chaine de caractère, que se passe-t-il si l'utilisateur vide le champ ? Cela correspond à  une chaine vide ou à  nil pour toi ? Du coup est-ce que l'utilisateur va voir un champ vide ou une absence de champs ?


    C'est pas facile de discuter de GUI sans écran...
  • muqaddarmuqaddar Administrateur
    septembre 2013 modifié #7

    OK, j'ai compris.


     


    Dès que l'utilisateur vide complètement un champ texte (aucun caractère), je passe la valeur à  nil. Je n'ai jamais de chaà®ne vide en base (@"").


    Comme ça c'est propre.


     


    Ici, le champ input currency est plein, et le champ input comment est nil.


     


  • FKDEVFKDEV Membre
    septembre 2013 modifié #8

    Du coup je comprends mieux ton problème.


    C'est le coup classique de la même valeur qui sert à  deux choses, ça finit toujours mal.


    En général cette valeur c'est zéro ou NULL. 


    Dès le départ c'est bien de prévoir une valeur nulle et une valeur "neutre" (qui signifie "pas de valeur" ou valeur non significative).


    En fonction du langage et du type, parfois c'est nil, parfois c'est NaN, parfois c'est -1, parfois c'est un booléeen à  côté quand la variable doit garder toute son amplitude de valeur possible.


     


    Ton problème c'est que tu fais le passage de la valeur nulle à  la valeur neutre au mauvais moment, c'est-à -dire je suppose au moment de la saisie, du coup tu perds une information dont tu aurais besoin dans le cas des valeurs multiples :


     


    A/l'utilisateur place input à  chaà®ne vide.


    B/ton code place input à  nil


    C/si sélection simple : Si nil => pas de valeur en base, sinon une valeur en base


      si multi-sélection : si nil =>champ pas touché, sinon valeur en base. 


     


     


    Si tu pouvais intervertir B et C tu aurais une valeur en plus à  tester pour le cas de la multi-sélection.


  • muqaddarmuqaddar Administrateur

    J'ai vraiment du mal à  te suivre.


     


    Un champ veut être vide ou plein. Il est non nil ou nil. ça s'arrête là  dans ma classe métier. nil ne sert pas à  2 choses, mais juste une.


     


    Moi, je cherchai une astuce de marquage pour indiquer au vue-contrôleur quand écrire "multiple values" (et il faut donc que je compare tous les champs des items de ma multi-sélection).


     


    Si on compare 3 items sur le champ prix avec 3 valeurs différentes 10.59,12.00,nil ou bien encore nil,nil,13.00, je dois indiquer multiple values à  ma vue. Dans ce cas, je crée un item "fictif" temporaire, qui contient, soit les valeurs communes, soit multiple values, soit nil si aucun des 3 prix n'a une valeur. Mon problème était de symboliser les multiples values. Pour un prix, j'ai mis -1, puisque c'est un NSNUmber qui le gère.


    Pour l'instant, ça marche très bien. Il faut juste faire une moulinette dans ma classe métier en entrée (comparer les champs de tous les items) et en sortie (prendre les nouvelles valeurs ou non).

  • FKDEVFKDEV Membre
    septembre 2013 modifié #10

    En lisant ton premier post, je comprenais que :


    nil veut dire champs multiple avec valeur différentes,


    alors que nil devrait vouloir dire champs multiples avec toutes les valeurs à  nil.


     


    d'où deux utilisations différentes pour la valeur nil.


  • La réponse rapide à  ta question initiale est "utilise le pattern decorator".


     


    La version longue :


    C'est un problème de conception intéressant sur la manière de représenter une valeur dans différents contextes.


    Tu as la valeur brute qui correspond au prix, dont les valeurs possibles vont de 0 à  N.


    Tu as la valeur affichée où tu dois te soumettre  aux attentes de l'utilisateur : gratuit, X €, non fixéet aussi "valeurs multiples"  (et peut-être une conversion dans une devise particulière)


    Tu as la valeur stockée en base donnée où tu te dois te soumettre aux attentes de ta base de donnée : un INT sur N bits avec possibilité d'une valeur NULL (ou "non fixée").


     


     


     


    C'est intéressant de représenter le flux de la donnée pour voir à  quel moment, tu dois introduire de l'abstraction :


     


    DB ---> NSNumber ---> Controller --> Vue (UITextField).


     


    Dans ton cas le mapping entre la DB et NSNumber est assez direct (mais on pourrait imaginer des cas complexes où il y aurait des soldes ou des prix différents en fonction du fournisseur, etc), donc tu peux faire un mapping direct, pas de soucis.


     


    Par contre le mapping NSNumber vers la vue est plus complexe parce que tu peux en fait combiner plusieurs NSNumber dans la même ligne quand tu as des valeurs multiples.


    Bien sûr tu as des solutions rapides (j'utilise nil, -1, etc) mais je pense que la solution raisonnable, ici,  est d'introduire un objet intermédiaire (pattern decorator) pour gérer les besoins de la vue :


     


    DB ---> NSNumber(s) ---> DisplayableNumber ---> Controller ---> Vue (UITextField )


     


    DisplayableNumber dérive peut-être d'une classe de base (ou d'un protocol) DisplayableField.


     


    Du coup, une bonne partie du code un peu crado qui utilise des conventions implicites (du type -1 veut dire "valeurs multiples") va se retrouver dans une classe bien précise et non "all over the place" dans ton controller. 


     


    Cette classe decorator pourra fournir des méthodes bien explicites à  ton controller, par exemple IsMultiple, valueAsString, localizedValue, etc.


     


    Cette nouvelle classe te permet de garder ton modèle propre, de garder ton controller compréhensible et d'isoler à  un seul endroit le code qui utilise des conversions basées sur des conventions que tu auras oubliées dans 6 mois ("multiples" == -1 pour un NSNumber, vide == 1er janvier 1970 pour une date, ou je ne sais quoi...).


     


     


    Parfois on appelle cette abstraction intermédiaire, entre le stockage et l'affichage, la couche métier.

  • muqaddarmuqaddar Administrateur
    septembre 2013 modifié #12

    Ah bein voilà  !


    C'est de ça que je voulais parler. Je me doutais que les pros avaient "des techniques" particulières, comme ce pattern decorator.


     


    Là , tu as vraiment compris mon problème. :)


     


    Cette nouvelle classe te permet de garder ton modèle propre, de garder ton controller compréhensible et d'isoler à  un seul endroit le code qui utilise des conversions basées sur des conventions que tu auras oubliées dans 6 mois ("multiples" == -1 pour un NSNumber, vide == 1er janvier 1970 pour une date, ou je ne sais quoi...).  

     


    Voilà , c'est ça. Là , j'ai un algo qui marche, mais un peu crado, dans mon modèle.


    multiple == -1, et multiple pour les dates = 1er janvier 1970...etc


     


    Je vais essayer de migrer vers une classe intermédiaire.




  • Je me doutais que les pros avaient "des techniques" particulières, comme ce pattern decorator.


     




     


    Quoique tu penses être, techniquement, tu es un professionnel aussi puisque c'est ton gagne pain (ou presque).

Connectez-vous ou Inscrivez-vous pour répondre.