Je vous propose aujourd'hui un exercice sur jQuery, dans l'idée de faire progresser les membres mais aussi d'animer la section.
Avant d'entrer dans le vif du sujet, il y aura un certain nombre de règles à respecter pour que tout se passe bien dans ce topic.
Règles
Le troll et le flood ne sont pas tolérés. Inutile de balancer des "Pourquoi jQuery et pas Mootools ?", les messages non constructifs seront modérés.
Je vous fournis le code HTML, vous n'aurez pas le droit de le modifier.
Votre réponse contiendra uniquement du code jQuery avec la balise <secret> de manière à respecter ceux qui n'ont pas commencé l'exercice.
Evidemment, le code que vous posterez devra être de vous, pas la peine de recopier un code externe, cela n'a pas d'intérêt. L'utilisation de plugins n'est pas nécessaire.
Objectif du script
Description
Nous avons 2 listes déroulantes, la première (liste A) contient des fruits et la seconde (liste B) est notre panier. Il faudra donc remplir notre panier de fruits.
Pour ce faire, 2 boutons sont à notre disposition : "Ajouter" permet de prendre un fruit de la liste A et de l'insérer dans la liste B (tout en le supprimant de la liste A).
Le bouton "Supprimer" fait exactement la même chose dans le sens inverse.
Dans votre code, n'oubliez pas de prendre en considération l'état de ces 2 boutons : ils ne doivent pas être cliquables si aucun élément de leur liste respective n'est sélectionné.
Le but n'est pas de faire le code le plus court possible. Essayez en revanche de l'optimiser, par exemple : éviter la répétition du $ de jQuery au profit de variables, si un traitement doit être fait plus d'une fois, alors utilisez une fonction...
HTML
Je vous donne le code minimal fonctionnel. Ne paniquez pas, le code n'est pas valide et j'utilise un tableau pour la mise en forme, ceci n'est pas le coeur du débat.
Tout d'abord merci à vous d'avoir fait cet exercice, je trouve cela très enrichissant de voir que pour un sujet on a tous une méthode particulière.
Concernant mes remarques :
hani_1 : si je mets de côté l'utilisation massive du $, je trouve que tu t'es compliqué la tâche. En effet tes 2 fonctions font grossièrement le même traitement. Il y avait une optimisation à faire de côté-là.
Je n'ai pas compris pourquoi tu es parti sur RegExp.
ninlock : tu as été plus méthodique en lançant tes fonctions. As-tu testé ton code ? Je reste perplexe quant à la ligne 33. Parce que selectScr contient un objet jQuery, que tu concatènes avec "option:selected", cela ne doit en théorie pas fonctionner ? Me trompe-je ?
Je vous montrerai mon code plus tard car j'aimerais d'autres propositions. Mais j'ai vraiment l'impression que vous ayez fait plus compliqué que moi.
Si, c'est valide comme sélecteur, et oui je l'ai testé, d’ailleurs il te suffit de faire un copier/coller dans une page blanche et de lancer avec ton navigateur.
En fait jQuery à mis en place des fonctions qui permette de passer plusieurs type d'argument, (évidemment me dira tu c'est la force du javascript, ou sa faiblesse, cela dépend des avis).
Une fois qu'il reçoit un argument il vérifie le type de ce dernier afin de savoir quel processus il doit engager, du coup on constate parfaitement ce comportement avec par exemple $("#monElement") ou $(this) où ce dernier n'est pas une String mais bien un élément jQuery. Du coup dans mon cas je suppose que le selectScr + "..." représente en fait selectScr.toString()+"..." où selectScr.toString doit être un identifiant unique créé par jquery.
Voilà, le code est peut être un petit peu plus chargé car j'ai bien tous séparé afin d'être clair en ajoutant la gestion de la selection multiple.
J'avais simplement commencé avec un array global et des regexp pour garder les fruits classé dans le même ordre. Puis j'ai vu que ce n'était pas requis donc j'ai supprimé pas mal ligne. les regexp fonctionnait quand même donc je les ai laissé !!! D'ou les regexp.
Pour les deux fonctions je suis d'accord avec un array de param (5 clef) j'aurais pu en faire une seule.
Je constate que tu tiens vraiment a ce qu'on utilise peu le $ ?
C'est juste une lubie ou il y a une recherche de performance ?
C'est une réponse qui m'intéresse fortement ça
Personnellement je pense qu'il y a un gain de performance car en appelant $, jQuery lance un processus complexe, alors que si tu créé une variable qui stock l'objet jquery, tu créé simplement une référence de l'objet en mémoire, donc plus d'appel d'instruction complexe, afin si, une par élément.
D'ailleurs pour t'en rendre conte, utilise $ 2 fois et passe en mode débug sur le fichier jquery et avance pas a pas tu constatera la quantité d'instruction exécuté.
Ensuite tu l'utilise une fois en l'assignant a une variable et tu réutilise cette variable, dans ce cas tu constate qu'il ne passe qu'une seule fois dans le script jQuery.
Ah oui par contre pour mon code il faut peut être changer la source du script jQuery (actuellement src="javascript/jquery.js", il suffit de pointer vers un chemin ou la librairie existe), je suis en version 1.6.4
var $liste_fruits = $('#liste_fruits');
alert($($liste_fruits+' option:selected').val());
où est-il ecrit? Dans le $(document).ready?
De plus concidère plutôt les $ comme mot clé jQuery du coup test plutôt :
var liste_fruits = $('#liste_fruits');
alert($(liste_fruits+' option:selected').val());
De plus il faut le mettre dans le ready sinon l'élément du DOM n'est pas encore construit.
Et il faut savoir que $(liste_fruits+' option:selected') est null au début, d'où le if(selectElem.val()!=null&&selectElem.val().length>0){buttonModify.removeAttr("disabled");} dans la fonction bindChangeSelect
Je vient de mettre ton code dans ma page et l'alert me retourne undefined, mais c'est normal car $($liste_fruits+' option:selected') retourne un tableau d'options sélectionnées et non pas une seule option sélectionnée.
Et pour le $, je sais que cela change rien, c'était juste pour dire qu'il est plus clair de garder cette notation pour les appel jQuery, mais après cette remarque n'as que peu d'importance.
noaman00 : j'avais pas vu mais tu es invité à éditer ton message afin qu'il respecte les règles du topic stp.
ninlock : j'ai trouvé une solution toute bête, il suffit d'utiliser le préfixe .selector !
Exemple :
var test = $('#test').selector;
alert(test); // renvoie #test
J'en profite pour mettre ma version du script (version en ligne) :
$(document).ready(function() {
// variables sélécteur
var $liste_fruits = $('#liste_fruits');
var $panier = $('#panier');
var $ajouter = $('#ajouter');
var $supprimer = $('#supprimer');
// on sélectionne un fruit dans la liste
$liste_fruits.change(function() {
$ajouter.attr('disabled', false);
});
// on sélectionne un fruit dans le panier
$panier.change(function() {
$supprimer.attr('disabled', false);
});
$ajouter.click(function() {
$ajouter.attr('disabled', true); // on désactive le bouton
transfertFruit($($liste_fruits.selector +' option:selected'), $panier);
});
$supprimer.click(function() {
$supprimer.attr('disabled', true); // on désactive le bouton
transfertFruit($($panier.selector +' option:selected'), $liste_fruits);
});
});
// fonction qui va s'occuper de basculer un fruit d'une liste à l'autre
function transfertFruit($fruit, $panierArrivee) {
// on ajoute l'option au panier
$('<option>', {
value: $fruit.val(),
text: $fruit.text()
}).appendTo($panierArrivee);
$fruit.remove(); // on supprime le fruit de la liste de départ
}
Très bien comme sujet, cependant il me semblerait intéressant de conclure à certaines bonnes pratiques afin de savoir comment optimiser un code et le rendre le plus évolutif possible.
Je vais essayer de faire différents tests avec ces différents codes, et je ferait un retour si cela me semble pertinent.
Pour les bonnes pratiques on les a plus ou moins citées. Il n'y a pas vraiment de conclusion, comme j'ai dit il y a un tas de manière de résoudre cet énoncé.
Apparemment hani_1 s'est perdu sur la toile en voulant chercher les articles.
Cet article apporte des element de réponse. Mais en approfondissant un peu je me rend compte que ce qui est préconisé c'est d'utiliser le JQuery une fois qu'on lui a maché le travail avec du JS pur et dur !!!
De plus cet article date de 2008. donc je doute qu'il soit encore fiable aujourd'hui alors que le systeme de selecteur jquery a été repensé depuis!!!
@hani_1 : Je suis tombé sur un petit blog qui me parait contenir de bonne remarque concernant ce que j'avais dit précédemment pour la répétition des $. Il explique succinctement pour quoi il est toujours mieux déclaré une variable plutôt que de réutiliser le selecteur $, avec quelques autres bonne pratiques: http://blog.arnaud-k.fr/2009/10/26/5-c [...] -avec-jquery/
Bonjour, j'arrive un peu tard ...
mais ça m'intéresse tellement que je me permet de déterrer cet intéressant exercice
voici ce que j'ai fait :
function move($dest, $selected){
$dest.append('<option value="'+$selected.val()+'" >'+$selected.text()+'</option>');
$selected.remove();
}
$(document).ready(function() {
var $lst = $('#liste_fruits');
var $panier = $('#panier');
var $add = $('#ajouter');
var $delete = $('#supprimer');
$lst.change(function(){
$add.attr('disabled', false);
});
$panier.change(function(){
$delete.attr('disabled', false);
});
$add.click(function(){
move($panier, $('#liste_fruits option:selected'));
$add.attr('disabled', true);
});
$delete.click(function(){
move($lst, $('#panier option:selected'));
$delete.attr('disabled', true);
});
});
je l'ai aussi mis en ligne ici (génial ce site ! [cf signature de Desolation])
Citation : Desolation
Vous seriez OK pour un autre exercice ?
Je ne demande pas mieux, j'adore ça.
Seulement je ne suis pas souvent sur les forums js, alors je risque de ne pas les voir.
merci.
NB
une suite intéressant pour cet exercice, ce serait de permettre le choix multiple
et par exemple d'ajouter ou de supprimer quand ou double clic sur une ligne, ou encore quand on fait entrée ...
EDIT
Voici une version améliorée.
J'ai juste rajouté un attribut "multiple" sur chaque select.
On peu sélectionner plusieurs item, ils sont tous ajoutés quand on clic su le bouton, et aussi quand on fait entrée.
var $lst = $('#liste_fruits');
var $panier = $('#panier');
var $add = $('#ajouter');
var $delete = $('#supprimer');
function move($dest, $selected){
$dest.append('<option value="'+$selected.val()+'" >'+$selected.text()+'</option>');
$selected.remove();
}
function add(){
$('#liste_fruits option:selected').each(function(){
move($panier, $(this));
});
$add.attr('disabled', true);
}
function remove(){
$('#panier option:selected').each(function(){
move($lst, $(this));
});
$delete.attr('disabled', true);
}
$(document).ready(function() {
$lst.change(function(){
$add.attr('disabled', false);
});
$panier.change(function(){
$delete.attr('disabled', false);
});
$add.click(function(){
add();
});
$delete.click(function(){
remove();
});
$lst.keypress(function(event){
if(event.which==13)
add();
});
$panier.keypress(function(event){
if(event.which==13)
remove();
});
});
testable en ligne ici (j'ai testé avec chromium, c'est impec)
pas de pb, si tout le monde s'y met, ça ira.
Quelque chose qui serait pas mal, c'est le drag'n drop .. que je ne connais pas pour le moment, mais que je rêve de faire Et je sait que c'est faisable en JQuery.
D'ailleurs, je compte bien apprendre cela dès que je pourrais.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.