Bonjour,

Présentation du code :

Le code suivant tente d'utiliser plusieurs instances de JStree (http://www.jstree.com/) afin d'offrir une multi-sélection arborescente.
Chaque liste déroulante est dissimulée puis remplacée visuellement par un simple bouton.
Ce bouton permet d'ouvrir une boîte de dialogue (jqueryUI) qui contient l'arbre JStree.
Chaque JStree est/doit-être indépendant afin que chaque sélection le soit.
La liste d'option des listes déroulantes dépend de la valeur d'un select, et est mise à jour lors d'un changement de cette valeur via AJAX (toutes les sélections ont les même options).
Une fois la sélection effectuée, la validation via UIdialog affecte la valeur au select correspondant dissimulé et change le texte du bouton.

Problème :

Peu importe le bouton sélectionné, ce sera toujours le dernier qui sera affecté (et son select associé).

Tentatives de résolutions :

J'ai essayé d'affecter bouton et arbre dans les data des select.
J'ai essayé de créer un tableau déclaré hors fonction ( select[] ) afin d'y accéder par l'index ( select[i] )

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
$( function(){
 
	first_id = $("*[name*=product_id]").val();
 
	$("select[name*=product_data_id]").each( function(i,serie){
 
		$(serie).data("treeParams", {
			"plugins" : [ "themes", "xml_data", "ui", "checkbox" ],
			"themes" : {
				"theme" : "default",
				"dots" : true
			},
			"core" : {
				"animation": 1
			},
			"xml_data" : {
				"data" : ""
			},
			"ui": {
				"select_multiple_modifier" : "ctrl",
				"disable_selecting_children" : false
			},
			"checkbox": {
				"two_state": true,
				"override_ui": true
			}
		});
 
		button = $('<input type="button" id="b'+i+'" />');
		$(serie).data("button",button);
		val = $(serie).val();
		text = $(serie).find("option:selected").text();
 
		$(serie).hide();
		button.insertAfter($(serie));
 
		if(val == null){
			button.val("Codes produit");
		} else {
 
			if(val.length == 1) {
 
				button.val(text);
				$(serie).data("treeParams").ui.initially_select = val;
 
			} else {
 
				button.val(val.length + " codes sélectionnés");
				$(serie).data("treeParams").ui.initially_select = val;
			}
		}
 
		dialog_tree = $('<div class="dialogTree"/>');
		$('body').append(dialog_tree);
 
		dialog_tree.dialog({
			resizable: true,
			width: 400,
			modal: true,
			autoOpen: false,
			buttons: {
				"Déselectionner tout": function(){
					tree.deselect_all();
					tree.uncheck_all();
					$(serie).val('');
					button.val("Codes produit");
				},
				"Sélectionner": function() {
					if(tree.get_checked().length > 0){
 
						var values = [];
						tree.get_checked().each(function(key,row){
							values.push($(row).attr('id'));
						});
						$(serie).val(values);
 
						if(tree.get_checked(null,true).length == 1){
							button.val($.trim(tree.get_checked().text()));
						} else {
							button.val(tree.get_checked(null,true).length + " codes sélectionnés");
						}
 
						$(this).dialog("close");
					}
				},
				"Fermer": function() {
					$(this).dialog("close");
				}
			},
			open: function(){
 
				if(!$(serie).data("loaded")){
 
					dialog_tree.bind("loaded.jstree", function (event, data) {
						tree = data.inst;
						tree.open_all();
						$(serie).data("loaded",true);
 
					    dialog_tree.find("ul a").dblclick(function(){
 
							toggleState = function(nodes,checked){
								tree.change_state(nodes,checked);
								nodes.each( function(key, row){
									toggleState(tree._get_children(row),checked);
								});
							};
 
							node = tree._get_node(this);
							checked = tree.is_checked(node);
							toggleState(node,checked);
							return false;
						});
				    });
 
					dialog_tree.jstree($(serie).data("treeParams"));
				}
			}
		});
 
		button.click( function(){
			dialog_tree.dialog("open");
		});
 
 
	});
 
 
	$("*[name*=product_id]").change( function(){
 
		$.ajax({
			async: false,
			url : "<?php echo $this->url(array('controller'=>'product_data','action'=>'tree'),null,true,null,true) ?>",
			data : {
				product_id : $(this).val()
			},
			success : function(json){
				$("select[name*=product_data_id]").each( function(){
					tmp = $(this).data("treeParams");
					tmp.xml_data.data = json.xml;
					$(this).data("treeParams",tmp);
				});
			},
			dataType : "json"
		});
 
		$("select[name*=product_data_id]").each( function(){
 
			if(!$(this).data("treeParams").ui.initially_select){
				$(this).data("button").val("Codes produit");
				$(this).val(0);
			} else {
 
				if($(this).val() != first_id){
					tmp = $(this).data("treeParams");
					delete tmp.ui.initially_select;
					$(this).data("treeParams",tmp);
					$(this).data("button").val("Codes produit");
					$(this).val(0);
				}
			}
 
			$("div.dialogTree").jstree("destroy");
			$(this).data("loaded",false);
 
		});
 
	}).change();
 
});
Le code HTML de base étant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
<select name="serie[1][product_data_id][]" multiple="multiple">
	<option value="1">Foo</option>
	<option value="2">Bar</option>
</select>
<select name="serie[2][product_data_id][]" multiple="multiple">
	<option value="1">Foo</option>
	<option value="2">Bar</option>
</select>

Je ne comprends pas pourquoi mon code ne fonctionne pas, et j'imagine que c'est une histoire de portée des variables déclarées, comme si chaque bouton & select variabilisé (on se comprend ?) avait pour référence le dernier.