1 %# BEGIN BPS TAGGED BLOCK {{{
5 %# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
6 %# <sales@bestpractical.com>
8 %# (Except where explicitly superseded by other copyright notices)
13 %# This work is made available to you under the terms of Version 2 of
14 %# the GNU General Public License. A copy of that license should have
15 %# been provided with this software, but in any event can be snarfed
18 %# This work is distributed in the hope that it will be useful, but
19 %# WITHOUT ANY WARRANTY; without even the implied warranty of
20 %# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 %# General Public License for more details.
23 %# You should have received a copy of the GNU General Public License
24 %# along with this program; if not, write to the Free Software
25 %# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 %# 02110-1301 or visit their web page on the internet at
27 %# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
30 %# CONTRIBUTION SUBMISSION POLICY:
32 %# (The following paragraph is not intended to limit the rights granted
33 %# to you to modify and distribute this software under the terms of
34 %# the GNU General Public License and is only of importance to you if
35 %# you choose to contribute your changes and enhancements to the
36 %# community by submitting them to Best Practical Solutions, LLC.)
38 %# By intentionally submitting any modifications, corrections or
39 %# derivatives to this work, or any other work intended for use with
40 %# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41 %# you are the copyright holder for those contributions and you grant
42 %# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43 %# royalty-free, perpetual, license to use, copy, create derivative
44 %# works based on those contributions, and sublicense and distribute
45 %# those contributions and any derivatives thereof.
47 %# END BPS TAGGED BLOCK }}}
50 function show(id) { delClass( id, 'hidden' ) }
51 function hide(id) { addClass( id, 'hidden' ) }
53 function hideshow(id) { return toggleVisibility( id ) }
54 function toggleVisibility(id) {
55 var e = jQuery('#' + id);
57 if ( e.hasClass('hidden') ) {
58 e.removeClass('hidden');
67 function setVisibility(id, visibility) {
68 if ( visibility ) show(id);
72 function switchVisibility(id1, id2) {
73 // Show both and then hide the one we want
81 function jQueryWrap( id ) {
82 return typeof id == 'object' ? jQuery(id) : jQuery('#'+id);
85 function addClass(id, value) {
86 jQueryWrap(id).addClass(value);
89 function delClass(id, value) {
90 jQueryWrap(id).removeClass(value);
96 var e = jQueryWrap(id);
99 if (e.hasClass('hidden')) {
100 set_rollup_state(e,e2,'shown');
101 createCookie(id,1,365);
104 set_rollup_state(e,e2,'hidden');
105 createCookie(id,0,365);
110 function set_rollup_state(e,e2,state) {
112 if (state == 'shown') {
114 delClass( e2, 'rolled-up' );
116 else if (state == 'hidden') {
118 addClass( e2, 'rolled-up' );
125 function focusElementById(id) {
126 var e = jQuery('#'+id);
130 function setCheckbox(form, name, val) {
131 var myfield = form.getElementsByTagName('input');
132 for ( var i = 0; i < myfield.length; i++ ) {
133 if ( myfield[i].type != 'checkbox' ) continue;
135 if ( name instanceof RegExp ) {
136 if ( ! myfield[i].name.match( name ) ) continue;
139 if ( myfield[i].name != name ) continue;
144 myfield[i].checked = val;
148 /* apply callback to nodes or elements */
150 function walkChildNodes(parent, callback)
152 if( !parent || !parent.childNodes ) return;
153 var list = parent.childNodes;
154 for( var i = 0; i < list.length; i++ ) {
159 function walkChildElements(parent, callback)
161 walkChildNodes( parent, function(node) {
162 if( node.nodeType != 1 ) return;
163 return callback( node );
167 /* shredder things */
169 function showShredderPluginTab( plugin )
171 var plugin_tab_id = 'shredder-plugin-'+ plugin +'-tab';
172 var root = jQuery('#shredder-plugin-tabs');
174 root.children(':not(.hidden)').addClass('hidden');
175 root.children('#' + plugin_tab_id).removeClass('hidden');
178 show('shredder-submit-button');
180 hide('shredder-submit-button');
184 function checkAllObjects()
186 var check = jQuery('#shredder-select-all-objects-checkbox').attr('checked');
187 var elements = jQuery('#shredder-search-form :checkbox[name=WipeoutObject]');
190 elements.attr('checked', true);
192 elements.attr('checked', false);
196 function checkboxToInput(target,checkbox,val){
197 var tar = jQuery('#' + escapeCssSelector(target));
198 var box = jQuery('#' + escapeCssSelector(checkbox));
199 if(box.attr('checked')){
204 tar.val( val+', '+ tar.val() );
208 tar.val(tar.val().replace(val+', ',''));
209 tar.val(tar.val().replace(val,''));
211 jQuery('#UpdateIgnoreAddressCheckboxes').val(true);
214 // ahah for back compatibility as plugins may still use it
215 function ahah( url, id ) {
216 jQuery('#'+id).load(url);
219 // only for back compatibility, please JQuery() instead
220 function doOnLoad( js ) {
226 dateFormat: 'yy-mm-dd',
227 constrainInput: false,
228 showButtonPanel: true,
231 showOtherMonths: true,
232 selectOtherMonths: true
234 jQuery(".ui-datepicker:not(.withtime)").datepicker(opts);
235 jQuery(".ui-datepicker.withtime").datetimepicker( jQuery.extend({}, opts, {
237 // We fake this by snapping below for the minute slider
242 timeFormat: 'hh:mm:ss'
243 }) ).each(function(index, el) {
244 var tp = jQuery.datepicker._get( jQuery.datepicker._getInst(el), 'timepicker');
247 // Hook after _injectTimePicker so we can modify the minute_slider
248 // right after it's first created
249 tp._base_injectTimePicker = tp._injectTimePicker;
250 tp._injectTimePicker = function() {
251 this._base_injectTimePicker.apply(this, arguments);
253 // Now that we have minute_slider, modify it to be stepped for mouse movements
254 var slider = jQuery.data(this.minute_slider[0], "slider");
255 slider._base_normValueFromMouse = slider._normValueFromMouse;
256 slider._normValueFromMouse = function() {
257 var value = this._base_normValueFromMouse.apply(this, arguments);
258 var old_step = this.options.step;
259 this.options.step = 5;
260 var aligned = this._trimAlignValue( value );
261 this.options.step = old_step;
268 function textToHTML(value) {
269 return value.replace(/&/g, "&")
270 .replace(/</g, "<")
271 .replace(/>/g, ">")
272 .replace(/-- \n/g,"-- \n")
273 .replace(/\n/g, "\n<br />");
276 function ReplaceAllTextareas(encoded) {
277 var sAgent = navigator.userAgent.toLowerCase();
278 if (!CKEDITOR.env.isCompatible ||
279 sAgent.indexOf('iphone') != -1 ||
280 sAgent.indexOf('ipad') != -1 ||
281 sAgent.indexOf('android') != -1 )
284 // replace all content and signature message boxes
285 var allTextAreas = document.getElementsByTagName("textarea");
287 for (var i=0; i < allTextAreas.length; i++) {
288 var textArea = allTextAreas[i];
289 if (jQuery(textArea).hasClass("messagebox")) {
290 // Turn the original plain text content into HTML
292 textArea.value = textToHTML(textArea.value);
294 // For this javascript
295 var CKeditorEncoded = document.createElement('input');
296 CKeditorEncoded.setAttribute('type', 'hidden');
297 CKeditorEncoded.setAttribute('name', 'CKeditorEncoded');
298 CKeditorEncoded.setAttribute('value', '1');
299 textArea.parentNode.appendChild(CKeditorEncoded);
302 var typeField = document.createElement('input');
303 typeField.setAttribute('type', 'hidden');
304 typeField.setAttribute('name', textArea.name + 'Type');
305 typeField.setAttribute('value', 'text/html');
306 textArea.parentNode.appendChild(typeField);
309 CKEDITOR.replace(textArea.name,{width:'100%',height:<% RT->Config->Get('MessageBoxRichTextHeight') |n,j%>});
310 CKEDITOR.basePath = <%RT->Config->Get('WebPath')|n,j%>+"/NoAuth/RichText/";
312 jQuery("#" + textArea.name + "___Frame").addClass("richtext-editor");
317 function toggle_addprincipal_validity(input, good, title) {
319 jQuery(input).nextAll(".warning").hide();
320 jQuery("#acl-AddPrincipal input[type=checkbox]").removeAttr("disabled");
322 jQuery(input).nextAll(".warning").css("display", "block");
323 jQuery("#acl-AddPrincipal input[type=checkbox]").attr("disabled", "disabled");
327 title = jQuery(input).val();
329 update_addprincipal_title( title );
332 function update_addprincipal_title(title) {
333 var h3 = jQuery("#acl-AddPrincipal h3");
334 h3.html( h3.text().replace(/: .*$/,'') + ": " + title );
337 // when a value is selected from the autocompleter
338 function addprincipal_onselect(ev, ui) {
339 // pass the item's value along as the title since the input's value
340 // isn't actually updated yet
341 toggle_addprincipal_validity(this, true, ui.item.value);
344 // when the input is actually changed, through typing or autocomplete
345 function addprincipal_onchange(ev, ui) {
346 // if we have a ui.item, then they selected from autocomplete and it's good
348 var input = jQuery(this);
349 // Check using the same autocomplete source if the value typed would
350 // have been autocompleted and is therefore valid
352 url: input.autocomplete("option", "source"),
358 success: function(data) {
360 toggle_addprincipal_validity(input, data.length ? true : false );
362 toggle_addprincipal_validity(input, true);
366 toggle_addprincipal_validity(this, true);
371 function escapeCssSelector(str) {
372 return str.replace(/([^A-Za-z0-9_-])/g,'\\$1');