|
1 /* |
|
2 * :organization: Logilab |
|
3 * :copyright: 2003-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
|
4 * :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
|
5 */ |
|
6 |
|
7 CubicWeb.require('htmlhelpers.js'); |
|
8 CubicWeb.require('ajax.js'); |
|
9 |
|
10 //============= filter form functions ========================================// |
|
11 function copyParam(origparams, newparams, param) { |
|
12 var index = findValue(origparams[0], param); |
|
13 if (index > -1) { |
|
14 newparams[param] = origparams[1][index]; |
|
15 } |
|
16 } |
|
17 |
|
18 function facetFormContent(form) { |
|
19 var names = []; |
|
20 var values = []; |
|
21 jQuery(form).find('.facet').each(function () { |
|
22 var facetName = jQuery(this).find('.facetTitle').attr('cubicweb:facetName'); |
|
23 var facetValues = jQuery(this).find('.facetValueSelected').each(function(x) { |
|
24 names.push(facetName); |
|
25 values.push(this.getAttribute('cubicweb:value')); |
|
26 }); |
|
27 }); |
|
28 jQuery(form).find('input').each(function () { |
|
29 names.push(this.name); |
|
30 values.push(this.value); |
|
31 }); |
|
32 jQuery(form).find('select option[selected]').each(function () { |
|
33 names.push(this.parentNode.name); |
|
34 values.push(this.value); |
|
35 }); |
|
36 return [names, values]; |
|
37 } |
|
38 |
|
39 function buildRQL(divid, vid, paginate, vidargs) { |
|
40 jQuery(CubicWeb).trigger('facets-content-loading', [divid, vid, paginate, vidargs]); |
|
41 var form = getNode(divid+'Form'); |
|
42 var zipped = facetFormContent(form); |
|
43 zipped[0].push('facetargs'); |
|
44 zipped[1].push(vidargs); |
|
45 var d = asyncRemoteExec('filter_build_rql', zipped[0], zipped[1]); |
|
46 d.addCallback(function(result) { |
|
47 var rql = result[0]; |
|
48 var $bkLink = jQuery('#facetBkLink'); |
|
49 if ($bkLink.length) { |
|
50 var bkUrl = $bkLink.attr('cubicweb:target') + '&path=view?rql=' + rql; |
|
51 if (vid) { |
|
52 bkUrl += '&vid=' + vid; |
|
53 } |
|
54 $bkLink.attr('href', bkUrl); |
|
55 } |
|
56 var toupdate = result[1]; |
|
57 var extraparams = vidargs; |
|
58 var displayactions = jQuery('#' + divid).attr('cubicweb:displayactions'); |
|
59 if (displayactions) { extraparams['displayactions'] = displayactions; } |
|
60 if (paginate) { extraparams['paginate'] = '1'; } |
|
61 // copy some parameters |
|
62 // XXX cleanup vid/divid mess |
|
63 // if vid argument is specified , the one specified in form params will |
|
64 // be overriden by replacePageChunk |
|
65 copyParam(zipped, extraparams, 'vid'); |
|
66 extraparams['divid'] = divid; |
|
67 copyParam(zipped, extraparams, 'divid'); |
|
68 copyParam(zipped, extraparams, 'subvid'); |
|
69 // paginate used to know if the filter box is acting, in which case we |
|
70 // want to reload action box to match current selection |
|
71 replacePageChunk(divid, rql, vid, extraparams, true, function() { |
|
72 jQuery(CubicWeb).trigger('facets-content-loaded', [divid, rql, vid, extraparams]); |
|
73 }); |
|
74 if (paginate) { |
|
75 // FIXME the edit box might not be displayed in which case we don't |
|
76 // know where to put the potential new one, just skip this case |
|
77 // for now |
|
78 if (jQuery('#edit_box').length) { |
|
79 reloadComponent('edit_box', rql, 'boxes', 'edit_box'); |
|
80 } |
|
81 } |
|
82 var d = asyncRemoteExec('filter_select_content', toupdate, rql); |
|
83 d.addCallback(function(updateMap) { |
|
84 for (facetId in updateMap) { |
|
85 var values = updateMap[facetId]; |
|
86 jqNode(facetId).find('.facetCheckBox').each(function () { |
|
87 var value = this.getAttribute('cubicweb:value'); |
|
88 if (!values.contains(value)) { |
|
89 if (!jQuery(this).hasClass('facetValueDisabled')) { |
|
90 jQuery(this).addClass('facetValueDisabled'); |
|
91 } |
|
92 } else { |
|
93 if (jQuery(this).hasClass('facetValueDisabled')) { |
|
94 jQuery(this).removeClass('facetValueDisabled'); |
|
95 } |
|
96 } |
|
97 }); |
|
98 } |
|
99 }); |
|
100 }); |
|
101 } |
|
102 |
|
103 |
|
104 var SELECTED_IMG = baseuri()+"data/black-check.png"; |
|
105 var UNSELECTED_IMG = baseuri()+"data/no-check-no-border.png"; |
|
106 var UNSELECTED_BORDER_IMG = baseuri()+"data/black-uncheck.png"; |
|
107 |
|
108 function initFacetBoxEvents(root) { |
|
109 // facetargs : (divid, vid, paginate, extraargs) |
|
110 root = root || document; |
|
111 jQuery(root).find('form').each(function () { |
|
112 var form = jQuery(this); |
|
113 // NOTE: don't evaluate facetargs here but in callbacks since its value |
|
114 // may changes and we must send its value when the callback is |
|
115 // called, not when the page is initialized |
|
116 var facetargs = form.attr('cubicweb:facetargs'); |
|
117 if (facetargs !== undefined) { |
|
118 form.submit(function() { |
|
119 buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs'))); |
|
120 return false; |
|
121 }); |
|
122 form.find('div.facet').each(function() { |
|
123 var facet = jQuery(this); |
|
124 facet.find('div.facetCheckBox').each(function (i) { |
|
125 this.setAttribute('cubicweb:idx', i); |
|
126 }); |
|
127 facet.find('div.facetCheckBox').click(function () { |
|
128 var $this = jQuery(this); |
|
129 if ($this.hasClass('facetValueDisabled')){ |
|
130 return |
|
131 } |
|
132 if ($this.hasClass('facetValueSelected')) { |
|
133 $this.removeClass('facetValueSelected'); |
|
134 $this.find('img').each(function (i){ |
|
135 if (this.getAttribute('cubicweb:unselimg')){ |
|
136 this.setAttribute('src', UNSELECTED_BORDER_IMG); |
|
137 this.setAttribute('alt', (_('not selected'))); |
|
138 } |
|
139 else{ |
|
140 this.setAttribute('src', UNSELECTED_IMG); |
|
141 this.setAttribute('alt', (_('not selected'))); |
|
142 } |
|
143 }); |
|
144 var index = parseInt($this.attr('cubicweb:idx')); |
|
145 // we dont need to move the element when cubicweb:idx == 0 |
|
146 if (index > 0){ |
|
147 var shift = jQuery.grep(facet.find('.facetValueSelected'), function (n) { |
|
148 var nindex = parseInt(n.getAttribute('cubicweb:idx')); |
|
149 return nindex > index; |
|
150 }).length; |
|
151 index += shift; |
|
152 var parent = this.parentNode; |
|
153 var $insertAfter = jQuery(parent).find('.facetCheckBox:nth('+index+')'); |
|
154 if ( ! ($insertAfter.length == 1 && shift == 0) ) { |
|
155 // only rearrange element if necessary |
|
156 $insertAfter.after(this); |
|
157 } |
|
158 } |
|
159 } else { |
|
160 var lastSelected = facet.find('.facetValueSelected:last'); |
|
161 if (lastSelected.length) { |
|
162 lastSelected.after(this); |
|
163 } else { |
|
164 var parent = this.parentNode; |
|
165 jQuery(parent).prepend(this); |
|
166 } |
|
167 jQuery(this).addClass('facetValueSelected'); |
|
168 var $img = jQuery(this).find('img'); |
|
169 $img.attr('src', SELECTED_IMG).attr('alt', (_('selected'))); |
|
170 } |
|
171 buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs'))); |
|
172 facet.find('.facetBody').animate({scrollTop: 0}, ''); |
|
173 }); |
|
174 facet.find('select.facetOperator').change(function() { |
|
175 var nbselected = facet.find('div.facetValueSelected').length; |
|
176 if (nbselected >= 2) { |
|
177 buildRQL.apply(null, evalJSON(form.attr('cubicweb:facetargs'))); |
|
178 } |
|
179 }); |
|
180 facet.find('div.facetTitle').click(function() { |
|
181 facet.find('div.facetBody').toggleClass('hidden').toggleClass('opened'); |
|
182 jQuery(this).toggleClass('opened'); |
|
183 }); |
|
184 |
|
185 }); |
|
186 } |
|
187 }); |
|
188 } |
|
189 |
|
190 // trigger this function on document ready event if you provide some kind of |
|
191 // persistent search (eg crih) |
|
192 function reorderFacetsItems(root){ |
|
193 root = root || document; |
|
194 jQuery(root).find('form').each(function () { |
|
195 var form = jQuery(this); |
|
196 if (form.attr('cubicweb:facetargs')) { |
|
197 form.find('div.facet').each(function() { |
|
198 var facet = jQuery(this); |
|
199 var lastSelected = null; |
|
200 facet.find('div.facetCheckBox').each(function (i) { |
|
201 var $this = jQuery(this); |
|
202 if ($this.hasClass('facetValueSelected')) { |
|
203 if (lastSelected) { |
|
204 lastSelected.after(this); |
|
205 } else { |
|
206 var parent = this.parentNode; |
|
207 jQuery(parent).prepend(this); |
|
208 } |
|
209 lastSelected = $this; |
|
210 } |
|
211 }); |
|
212 }); |
|
213 } |
|
214 }); |
|
215 } |
|
216 |
|
217 // we need to differenciate cases where initFacetBoxEvents is called |
|
218 // with one argument or without any argument. If we use `initFacetBoxEvents` |
|
219 // as the direct callback on the jQuery.ready event, jQuery will pass some argument |
|
220 // of his, so we use this small anonymous function instead. |
|
221 jQuery(document).ready(function() {initFacetBoxEvents();}); |
|
222 |
|
223 CubicWeb.provide('facets.js'); |