recrutement merge
[auf_rh_dae.git] / src / qbe / django_qbe / static / django_qbe / js / qbe.core.js
1 if (!window.qbe) {
2 var qbe = {};
3 }
4 qbe.CurrentModels = [];
5 qbe.CurrentRelations = [];
6 qbe.Core = function() {};
7
8 (function($) {
9 $(document).ready(function() {
10 /**
11 * Handle the loading initial data blocking process
12 */
13 var _loadingData = false;
14
15 /**
16 * Load initial data to edit query
17 */
18 qbe.Core.loadData = function(data) {
19 var initialForms, maxForms, totalForms;
20 _loadingData = true;
21 initialForms = parseInt(data["form-INITIAL_FORMS"]);
22 maxForms = parseInt(data["form-MAX_NUM_FORMS"]);
23 totalForms = parseInt(data["form-TOTAL_FORMS"]);
24 for(var i=initialForms; i<totalForms; i++) {
25 var appModel, splits, show, model, field, sorted;
26 appModel = data["form-"+ i +"-model"];
27 if (!(appModel in qbe.CurrentModels)) {
28 splits = appModel.split(".");
29 app = splits[0];
30 model = splits[1];
31 qbe.Core.addModule(app, model);
32 }
33 qbe.Core.updateModels();
34 $("#id_form-"+ i +"-model").val(appModel);
35 $("#id_form-"+ i +"-model").change();
36 field = data["form-"+ i +"-field"];
37 $("#id_form-"+ i +"-field").val(field);
38 $("#id_form-"+ i +"-field").change();
39 sorted = data["form-"+ i +"-sort"];
40 $("#id_form-"+ i +"-sort").val(sorted);
41 $("#id_form-"+ i +"-show").remove("checked");
42 if (data["form-"+ i +"-show"]) {
43 show = data["form-"+ i +"-show"];
44 if (show && show == "on") {
45 $("#id_form-"+ i +"-show").attr("checked", "checked");
46 }
47 }
48 c = 0;
49 criteria = data["form-"+ i +"-criteria_"+ c];
50 while(criteria) {
51 $("#id_form-"+ i +"-criteria_"+ c).val(criteria);
52 criteria = data["form-"+ i +"-criteria_"+ ++c];
53 }
54 }
55 $("#id_form_limit").val(data["limit"]);
56 var positions, positionSplits, splits, appModel, appName, modelName;
57 positions = data["positions"].split("|");
58 for(var i=0; i<positions.length; i++) {
59 splits = positions[i].split("@");
60 appModel = splits[0].split(".");
61 appName = appModel[0];
62 modelName = appModel[1];
63 positionSplits = splits[1].split(";");
64 if (!(appModel in qbe.CurrentModels)) {
65 $("#qbeModelItem_"+ modelName).toggleClass("selected");
66 qbe.Core.addModule(appName, modelName);
67 }
68 $("#qbeBox_"+ modelName).css({
69 left: positionSplits[0],
70 top: positionSplits[1]
71 });
72 }
73 $("#id_positions").val(data["positions"]);
74 _loadingData = false;
75 };
76
77 /**
78 * Toggle visibility of models
79 */
80 qbe.Core.toggleModel = function () {
81 var id, appName, modelName, idSplits, splits, $this;
82 $this = $(this);
83 idSplits = $this.attr("id").split("qbeModelAnchor_");
84 splits = idSplits[1].split(".");
85 appName = splits[0];
86 modelName = splits[1];
87 $("#qbeModelItem_"+ modelName).toggleClass("selected");
88 if ($("#qbeModelItem_"+ modelName).hasClass("selected")) {
89 qbe.Core.addModule(appName, modelName);
90 } else {
91 qbe.Core.removeModule(appName, modelName);
92 }
93 qbe.Core.updateModels();
94 return false;
95 }
96
97 /**
98 * Invokes the update of the each row
99 */
100 qbe.Core.updateModels = function() {
101 $(this).each(qbe.Core.updateRow);
102 };
103
104 /**
105 * Update the rows with the new models added
106 */
107 qbe.Core.updateRow = function(row) {
108 var options = ['<option value="">----</option>'];
109 for(i=0; i<qbe.CurrentModels.length; i++) {
110 var appModel = qbe.CurrentModels[i];
111 var key = appModel;
112 var value = appModel.replace(".", ": ");
113 options.push('<option value="'+ key +'">'+ value +'</option>');
114 }
115 $(".qbeFillModels").each(function() {
116 var val = $(this).val();
117 $(this).html(options.join(""));
118 $(this).val(val);
119 });
120 qbe.Core.alternatingRows();
121 };
122
123 /**
124 * Set a CSS class for alterned rows
125 */
126 qbe.Core.alternatingRows = function() {
127 var rows = "#qbeConditionsTable tbody tr";
128 $(rows).not(".add-row").removeClass("row1 row2");
129 $(rows +":even").not(".add-row").addClass("row1");
130 $(rows +":odd").not(".add-row").addClass("row2");
131 $(rows +":last").addClass("add-row");
132 };
133
134 /**
135 * Add rows per new relation with the models list hyphen separated
136 */
137 qbe.Core.addRelationsFrom = function(through) {
138 var appModels
139 appModels = through.split("-");
140 for(var i=0; i<appModels.length; i++) {
141 var appModel = appModels[i];
142 var splits = appModel.split(".");
143 qbe.Core.addModule(splits[0], splits[1]);
144 $("#qbeModelItem_"+ splits[1]).addClass("selected");
145 $("#qbeForm .add-row").click();
146 $(".qbeFillModels:last").val(splits[0] +"."+ splits[1]);
147 $(".qbeFillModels:last").change();
148 $(".qbeFillFields:last").val(splits[2]);
149 $(".qbeFillFields:last").change();
150 }
151 };
152
153 /**
154 * Event triggered when the SELECT tag for fill models is changed
155 */
156 qbe.Core.fillModelsEvent = function() {
157 var appModel, key, fields, splits, appModelSplits, allowed_fields, prefix, css, cssSplit, domTo, option, optFields, optPrimaries, optForeigns, optManies, style, value;
158 appModel = $(this).val();
159 if (appModel) {
160 appModelSplits = appModel.split(".");
161 fields = qbe.Models[appModelSplits[0]][appModelSplits[1]].fields;
162 allowed_fields = null;
163 if (qbe.AllowedFields !== null) {
164 try {
165 allowed_fields = qbe.AllowedFields[appModelSplits[0]][appModelSplits[1]];
166 } catch(e) {}
167 }
168 splits = $(this).attr("id").split("-");
169 prefix = splits.splice(0, splits.length-1).join("-");
170 css = $(this).attr("class");
171 cssSplit = css.split("to:")
172 domTo = prefix +"-"+ cssSplit[cssSplit.length-1];
173 optFields = [];
174 optPrimaries = [];
175 optForeigns = [];
176 optManies = [];
177 for(key_num in fields) {
178 // We can't jump fields with no target 'cause they are
179 // ManyToManyField and ForeignKey fields!
180 key = fields[key_num][0];
181 value = fields[key_num][1].label;
182 if (fields[key_num][1].type == "ForeignKey") {
183 style = "foreign";
184 option = '<option class="'+ style +'" value="'+ key +'">'+ value +'</option>'
185 optForeigns.push(option);
186 } else if (fields[key_num][1].type == "ManyToManyField") {
187 style = "many";
188 option = '<option class="'+ style +'" value="'+ key +'">'+ value +'</option>'
189 optManies.push(option);
190 } else if (fields[key_num][1].primary) {
191 style = "primary";
192 option = '<option class="'+ style +'" value="'+ key +'">'+ value +'</option>'
193 optPrimaries.push(option);
194 } else {
195 if (allowed_fields && allowed_fields.indexOf(key) < 0)
196 continue;
197 style = "";
198 option = '<option class="'+ style +'" value="'+ key +'">'+ value +'</option>'
199 optFields.push(option);
200 }
201 }
202 optEtat = '<option value="status">État</option>'
203 $("#"+ domTo).html('<option value="">*</option>' + optPrimaries.join("") + optForeigns.join("") + optManies.join("") + optFields.join("") + optEtat);
204 // We need to raise change event
205 $("#"+ domTo).change();
206 }
207 };
208
209 /**
210 * Event triggered when the SELECT tag for fill fields is changed
211 */
212 qbe.Core.fillFieldsEvent = function() {
213 var field, splits, prefix, css, cssSplit, inputs, input, domTo, appModel, appModelSplits, fields, primary, target, targetRel, targetModel, targetStrings, targetString, relations;
214 field = $(this).val();
215 splits = $(this).attr("id").split("-");
216 prefix = splits.splice(0, splits.length-1).join("-");
217 css = $(this).attr("class");
218 cssSplit = css.split("enable:")
219 inputs = cssSplit[cssSplit.length-1].split(",");
220 if (field == 'status') {
221 $("#"+ prefix + "-sort").attr("disabled", "disabled");
222 $("#"+ prefix + "-sort").val("");
223 $("#"+ prefix + "-criteria").attr("disabled", "disabled");
224 $("#"+ prefix + "-criteria").val("");
225 $("#"+ prefix + "-criteria").addClass("hidden");
226 $("#"+ prefix + "-criteria_0").attr("disabled", "disabled");
227 $("#"+ prefix + "-criteria_0").val("");
228 $("#"+ prefix + "-criteria_0").addClass("hidden");
229 $("#"+ prefix + "-criteria_1").attr("disabled", "disabled");
230 $("#"+ prefix + "-criteria_1").val("");
231 $("#"+ prefix + "-criteria_1").addClass("hidden");
232 $("#"+ prefix + "-status").removeClass("hidden");
233 $("#"+ prefix + "-status").removeAttr("disabled");
234
235 }
236 else {
237 $("#"+ prefix + "-status").val("");
238 $("#"+ prefix + "-status").addClass("hidden");
239
240 for(var i=0; i<inputs.length; i++) {
241 input = inputs[i];
242 domTo = prefix +"-"+ input;
243 if (field) {
244 $("#"+ domTo).removeAttr("disabled");
245 $("#"+ domTo).removeClass("hidden");
246 } else {
247 $("#"+ domTo).attr("disabled", "disabled");
248 $("#"+ domTo).val("");
249 }
250 if ($("#"+ domTo).is('input[type="text"]')) {
251 appModel = $("#"+ prefix +"-model").val();
252 appModelSplits = appModel.split(".");
253 fields = qbe.Models[appModelSplits[0]][appModelSplits[1]].fields;
254 var found = false;
255 for (key_num in fields) {
256 key = fields[key_num][0];
257 if (field == key && fields[key_num][1].target) {
258 target = fields[key_num][1].target;
259 found = true;
260 break;
261 }
262
263 }
264 if (found && !_loadingData) {
265 if (target.through) {
266 $(this).parent().parent().children("td:last").children("a").click();
267 targetModel = qbe.Models[target.through.name][target.through.model];
268 targetsString = [];
269 relations = targetModel.relations;
270 for(var r=0; r<targetModel.relations.length; r++) {
271 targetRel = targetModel.relations[r];
272 targetString = target.through.name +"."+ target.through.model +"."+ targetRel.source;
273 targetsString.push(targetString);
274 }
275 qbe.Core.addRelationsFrom(targetsString.join("-"));
276 } else {
277 targetString = target.name +"."+ target.model +"."+ target.field;
278 $("#"+ domTo).val(targetString);
279 $("#"+ domTo).prev().val("join");
280 qbe.Core.addRelationsFrom(targetString);
281 }
282 } else {
283 $("#"+ domTo).val("");
284 }
285 }
286 }
287 }
288 };
289
290 /**
291 * Adds a model to the layer
292 */
293 qbe.Core.addModule = function (appName, modelName) {
294 var appModel, model, target1, target2;
295 model = qbe.Models[appName][modelName];
296 appModel = appName +"."+ modelName;
297 if (qbe.CurrentModels.indexOf(appModel) < 0) {
298 qbe.CurrentModels.push(appModel);
299 if (model.is_auto) {
300 target1 = model.relations[0].target;
301 target2 = model.relations[1].target;
302 qbe.Core.addModule(target1.name, target1.model);
303 qbe.Core.addModule(target2.name, target2.model);
304 } else {
305 qbe.Diagram.addBox(appName, modelName);
306 }
307 qbe.Core.updateRelations();
308 }
309 };
310
311 /*
312 * Removes a model from the layer
313 */
314 qbe.Core.removeModule = function(appName, modelName) {
315 var appModel = appName +"."+ modelName;
316 var pos = qbe.CurrentModels.indexOf(appModel);
317 if (pos >= 0) {
318 qbe.CurrentModels.splice(pos, 1);
319 var model = qbe.Models[appName][modelName];
320 qbe.Diagram.removeBox(appName, modelName)
321 qbe.Diagram.removeRelations(appName, modelName);
322 }
323 };
324
325 /*
326 * Update relations among models
327 */
328 qbe.Core.updateRelations = function () {
329 var label, labelStyle, paintStyle, backgroundPaintStyle, makeOverlay;
330 var relations, relation, mediumHeight, connections;
331 var sourceAppModel, sourceModelName, sourceAppName, sourceModel, sourceFieldName, sourceId, sourceField, sourceSplits, divSource;
332 var targetModel, targetAppName, targetModelName, targetFieldName, targetId, targetField, divTarget;
333 for(var i=0; i<qbe.CurrentModels.length; i++) {
334 sourceAppModel = qbe.CurrentModels[i];
335 sourceSplits = sourceAppModel.split(".");
336 sourceAppName = sourceSplits[0];
337 sourceModelName = sourceSplits[1];
338 sourceModel = qbe.Models[sourceAppName][sourceModelName];
339 relations = sourceModel.relations;
340 for(var j=0; j<relations.length; j++) {
341 relation = relations[j];
342 sourceFieldName = relation.source;
343 label = qbe.Diagram.Defaults["foreign"].label;
344 labelStyle = qbe.Diagram.Defaults["foreign"].labelStyle;
345 paintStyle = qbe.Diagram.Defaults["foreign"].paintStyle;
346 makeOverlays = qbe.Diagram.Defaults["foreign"].makeOverlays;
347 backgroundPaintStyle = qbe.Diagram.Defaults["foreign"].backgroundPaintStyle;
348 if (relation.target.through) {
349 if (qbe.Models[relation.target.through.name][relation.target.through.model].is_auto) {
350 targetModel = relation.target;
351 label = relation.target.through.model;
352 labelStyle = qbe.Diagram.Defaults["many"].labelStyle;
353 paintStyle = qbe.Diagram.Defaults["many"].paintStyle;
354 makeOverlays = qbe.Diagram.Defaults["many"].makeOverlays;
355 backgroundPaintStyle = qbe.Diagram.Defaults["many"].backgroundPaintStyle;
356 } else {
357 targetModel = relation.target.through;
358 }
359 } else {
360 targetModel = relation.target;
361 }
362 targetAppName = targetModel.name;
363 targetModelName = targetModel.model;
364 targetFieldName = targetModel.field;
365 sourceField = $("#qbeBoxField_"+ sourceAppName +"\\."+ sourceModelName +"\\."+ sourceFieldName);
366 targetField = $("#qbeBoxField_"+ targetAppName +"\\."+ targetModelName +"\\."+ targetFieldName);
367 if (sourceField.length && targetField.length
368 && !qbe.Diagram.hasConnection(sourceField, targetField)) {
369 sourceId = "qbeBox_"+ sourceModelName;
370 targetId = "qbeBox_"+ targetModelName;
371 divSource = document.getElementById(sourceId);
372 divTarget = document.getElementById(targetId);
373 if (divSource && divTarget) {
374 qbe.Diagram.addRelation(sourceId, sourceField, targetId, targetField, label, labelStyle, paintStyle, backgroundPaintStyle, makeOverlays());
375 }
376 }
377 }
378 }
379 }
380
381 });
382 })(jQuery.noConflict());