Putting 4.2.0 on top of 4.0.17
[usit-rt.git] / share / static / js / util.js
1 /* Visibility */
2
3 function show(id) { delClass( id, 'hidden' ) }
4 function hide(id) { addClass( id, 'hidden' ) }
5
6 function hideshow(id) { return toggleVisibility( id ) }
7 function toggleVisibility(id) {
8     var e = jQuery('#' + id);
9
10     if ( e.hasClass('hidden') ) {
11         e.removeClass('hidden');
12     }
13     else {
14         e.addClass('hidden');
15     }
16
17     return false;
18 }
19
20 function setVisibility(id, visibility) {
21     if ( visibility ) show(id);
22     else hide(id);
23 }
24
25 function switchVisibility(id1, id2) {
26     // Show both and then hide the one we want
27     show(id1);
28     show(id2);
29     hide(id2);
30     return false;
31 }
32
33 function toggle_upgrade_history(widget, selector) {
34     jQuery(selector).toggle();
35     jQuery(widget).toggleClass("rolled-up");
36 }
37
38 /* Classes */
39 function jQueryWrap( id ) {
40     return typeof id == 'object' ? jQuery(id) : jQuery('#'+id);
41 }
42
43 function addClass(id, value) {
44     jQueryWrap(id).addClass(value);
45 }
46
47 function delClass(id, value) {
48     jQueryWrap(id).removeClass(value);
49 }
50
51 /* Rollups */
52
53 function rollup(id) {
54     var e = jQueryWrap(id);
55     var e2  = e.parent();
56     
57     if (e.hasClass('hidden')) {
58         set_rollup_state(e,e2,'shown');
59         createCookie(id,1,365);
60     }
61     else {
62         set_rollup_state(e,e2,'hidden');
63         createCookie(id,0,365);
64     }
65     return false;
66 }
67
68 function set_rollup_state(e,e2,state) {
69     if (e && e2) {
70         if (state == 'shown') {
71             show(e);
72             delClass( e2, 'rolled-up' );
73         }
74         else if (state == 'hidden') {
75             hide(e);
76             addClass( e2, 'rolled-up' );
77         }
78     }
79 }
80
81 /* other utils */
82
83 function setCheckbox(input, name, val) {
84     if (val == null) val = input.checked;
85
86     // Find inputs within the current form or collection list, whichever is closest.
87     var container = jQuery(input).closest("form, table.collection-as-table").get(0);
88     var myfield   = container.getElementsByTagName('input');
89     for ( var i = 0; i < myfield.length; i++ ) {
90         if ( myfield[i].type != 'checkbox' ) continue;
91         if ( name ) {
92             if ( name instanceof RegExp ) {
93                 if ( ! myfield[i].name.match( name ) ) continue;
94             }
95             else {
96                 if ( myfield[i].name != name ) continue;
97             }
98
99         }
100
101         myfield[i].checked = val;
102     }
103 }
104
105 /* apply callback to nodes or elements */
106
107 function walkChildNodes(parent, callback)
108 {
109     if( !parent || !parent.childNodes ) return;
110     var list = parent.childNodes;
111     for( var i = 0; i < list.length; i++ ) {
112         callback( list[i] );
113     }
114 }
115
116 function walkChildElements(parent, callback)
117 {
118     walkChildNodes( parent, function(node) {
119         if( node.nodeType != 1 ) return;
120         return callback( node );
121     } );
122 }
123
124 /* shredder things */
125
126 function showShredderPluginTab( plugin )
127 {
128     var plugin_tab_id = 'shredder-plugin-'+ plugin +'-tab';
129     var root = jQuery('#shredder-plugin-tabs');
130     
131     root.children(':not(.hidden)').addClass('hidden');
132     root.children('#' + plugin_tab_id).removeClass('hidden');
133
134     if( plugin ) {
135         show('shredder-submit-button');
136     } else {
137         hide('shredder-submit-button');
138     }
139 }
140
141 function checkAllObjects()
142 {
143     var check = jQuery('#shredder-select-all-objects-checkbox').attr('checked');
144     var elements = jQuery('#shredder-search-form :checkbox[name=WipeoutObject]');
145
146     if( check ) {
147         elements.attr('checked', true);
148     } else {
149         elements.attr('checked', false);
150     }
151 }
152
153 function checkboxToInput(target,checkbox,val){    
154     var tar = jQuery('#' + escapeCssSelector(target));
155     var box = jQuery('#' + escapeCssSelector(checkbox));
156     if(box.attr('checked')){
157         if (tar.val()==''){
158             tar.val(val);
159         }
160         else{
161             tar.val( val+', '+ tar.val() );        
162         }
163     }
164     else{
165         tar.val(tar.val().replace(val+', ',''));
166         tar.val(tar.val().replace(val,''));
167     }
168     jQuery('#UpdateIgnoreAddressCheckboxes').val(true);
169 }
170
171 // ahah for back compatibility as plugins may still use it
172 function ahah( url, id ) {
173     jQuery('#'+id).load(url);
174 }
175
176 // only for back compatibility, please JQuery() instead
177 function doOnLoad( js ) {
178     jQuery(js);
179 }
180
181 jQuery(function() {
182     var opts = {
183         dateFormat: 'yy-mm-dd',
184         constrainInput: false,
185         showButtonPanel: true,
186         changeMonth: true,
187         changeYear: true,
188         showOtherMonths: true,
189         selectOtherMonths: true
190     };
191     jQuery(".datepicker:not(.withtime)").datepicker(opts);
192     jQuery(".datepicker.withtime").datetimepicker( jQuery.extend({}, opts, {
193         stepHour: 1,
194         // We fake this by snapping below for the minute slider
195         //stepMinute: 5,
196         hourGrid: 6,
197         minuteGrid: 15,
198         showSecond: false,
199         timeFormat: 'HH:mm:ss'
200     }) ).each(function(index, el) {
201         var tp = jQuery.datepicker._get( jQuery.datepicker._getInst(el), 'timepicker');
202         if (!tp) return;
203
204         // Hook after _injectTimePicker so we can modify the minute_slider
205         // right after it's first created
206         tp._base_injectTimePicker = tp._injectTimePicker;
207         tp._injectTimePicker = function() {
208             this._base_injectTimePicker.apply(this, arguments);
209
210             // Now that we have minute_slider, modify it to be stepped for mouse movements
211             var slider = jQuery.data(this.minute_slider[0], "ui-slider");
212             slider._base_normValueFromMouse = slider._normValueFromMouse;
213             slider._normValueFromMouse = function() {
214                 var value           = this._base_normValueFromMouse.apply(this, arguments);
215                 var old_step        = this.options.step;
216                 this.options.step   = 5;
217                 var aligned         = this._trimAlignValue( value );
218                 this.options.step   = old_step;
219                 return aligned;
220             };
221         };
222     });
223 });
224
225 function textToHTML(value) {
226     return value.replace(/&/g,    "&amp;")
227                 .replace(/</g,    "&lt;")
228                 .replace(/>/g,    "&gt;")
229                 .replace(/-- \n/g,"--&nbsp;\n")
230                 .replace(/\n/g,   "\n<br />");
231 };
232
233 function ReplaceAllTextareas(encoded) {
234     var sAgent = navigator.userAgent.toLowerCase();
235     if (!CKEDITOR.env.isCompatible ||
236         sAgent.indexOf('iphone') != -1 ||
237         sAgent.indexOf('ipad') != -1 ||
238         sAgent.indexOf('android') != -1 )
239         return false;
240
241     // replace all content and signature message boxes
242     var allTextAreas = document.getElementsByTagName("textarea");
243
244     for (var i=0; i < allTextAreas.length; i++) {
245         var textArea = allTextAreas[i];
246         if (jQuery(textArea).hasClass("messagebox")) {
247             // Turn the original plain text content into HTML
248             if (encoded == 0) {
249                 textArea.value = textToHTML(textArea.value);
250             }
251             // For this javascript
252             var CKeditorEncoded = document.createElement('input');
253             CKeditorEncoded.setAttribute('type', 'hidden');
254             CKeditorEncoded.setAttribute('name', 'CKeditorEncoded');
255             CKeditorEncoded.setAttribute('value', '1');
256             textArea.parentNode.appendChild(CKeditorEncoded);
257
258             // For fckeditor
259             var typeField = document.createElement('input');
260             typeField.setAttribute('type', 'hidden');
261             typeField.setAttribute('name', textArea.name + 'Type');
262             typeField.setAttribute('value', 'text/html');
263             textArea.parentNode.appendChild(typeField);
264
265
266             CKEDITOR.replace(textArea.name,{ width: '100%', height: RT.Config.MessageBoxRichTextHeight });
267             CKEDITOR.basePath = RT.Config.WebPath + "/static/RichText/";
268
269             jQuery("#" + textArea.name + "___Frame").addClass("richtext-editor");
270         }
271     }
272 };
273
274 function toggle_addprincipal_validity(input, good, title) {
275     if (good) {
276         jQuery(input).nextAll(".warning").hide();
277         jQuery("#acl-AddPrincipal input[type=checkbox]").removeAttr("disabled");
278     } else {
279         jQuery(input).nextAll(".warning").css("display", "block");
280         jQuery("#acl-AddPrincipal input[type=checkbox]").attr("disabled", "disabled");
281     }
282
283     if (title == null)
284         title = jQuery(input).val();
285
286     update_addprincipal_title( title );
287 }
288
289 function update_addprincipal_title(title) {
290     var h3 = jQuery("#acl-AddPrincipal h3");
291     h3.html( h3.text().replace(/: .*$/,'') + ": " + title );
292 }
293
294 // when a value is selected from the autocompleter
295 function addprincipal_onselect(ev, ui) {
296
297     // if principal link exists, we shall go there instead
298     var principal_link = jQuery(ev.target).closest('form').find('ul.ui-tabs-nav a[href="#acl-' + ui.item.id + '"]:first');
299     if (principal_link.size()) {
300         jQuery(this).val('').blur();
301         update_addprincipal_title( '' ); // reset title to blank for #acl-AddPrincipal
302         principal_link.click();
303         return false;
304     }
305
306     // pass the item's value along as the title since the input's value
307     // isn't actually updated yet
308     toggle_addprincipal_validity(this, true, ui.item.value);
309 }
310
311 // when the input is actually changed, through typing or autocomplete
312 function addprincipal_onchange(ev, ui) {
313     // if we have a ui.item, then they selected from autocomplete and it's good
314     if (!ui.item) {
315         var input = jQuery(this);
316         // Check using the same autocomplete source if the value typed would
317         // have been autocompleted and is therefore valid
318         jQuery.ajax({
319             url: input.autocomplete("option", "source"),
320             data: {
321                 op: "=",
322                 term: input.val()
323             },
324             dataType: "json",
325             success: function(data) {
326                 if (data)
327                     toggle_addprincipal_validity(input, data.length ? true : false );
328                 else
329                     toggle_addprincipal_validity(input, true);
330             }
331         });
332     } else {
333         toggle_addprincipal_validity(this, true);
334     }
335 }
336
337
338 function escapeCssSelector(str) {
339     return str.replace(/([^A-Za-z0-9_-])/g,'\\$1');
340 }
341
342
343 jQuery(function() {
344     jQuery(".user-accordion").each(function(){
345         jQuery(this).accordion({
346             active: (jQuery(this).find("h3").length == 1 ? 0 : false),
347             collapsible: true,
348             heightStyle: "content",
349             header: "h3"
350         }).find("h3 a.user-summary").click(function(ev){
351             ev.stopPropagation();
352             return true;
353         });
354     });
355 });