View | Details | Raw Unified | Return to bug 9034
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/lib/jquery/plugins/jquery.dataTables.columnFilter.js (+762 lines)
Line 0 Link Here
1
/*
2
* File:        jquery.dataTables.columnFilter.js
3
* Version:     1.5.0.
4
* Author:      Jovan Popovic 
5
* 
6
* Copyright 2011-2012 Jovan Popovic, all rights reserved.
7
*
8
* This source file is free software, under either the GPL v2 license or a
9
* BSD style license, as supplied with this software.
10
* 
11
* This source file is distributed in the hope that it will be useful, but 
12
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
13
* or FITNESS FOR A PARTICULAR PURPOSE. 
14
* 
15
* Parameters:"
16
* @sPlaceHolder                 String      Place where inline filtering function should be placed ("tfoot", "thead:before", "thead:after"). Default is "tfoot"
17
* @sRangeSeparator              String      Separator that will be used when range values are sent to the server-side. Default value is "~".
18
* @sRangeFormat                 string      Default format of the From ... to ... range inputs. Default is From {from} to {to}
19
* @aoColumns                    Array       Array of the filter settings that will be applied on the columns
20
*/
21
(function ($) {
22
23
24
    $.fn.columnFilter = function (options) {
25
26
        var asInitVals, i, label, th;
27
28
        //var sTableId = "table";
29
        var sRangeFormat = "From {from} to {to}";
30
        //Array of the functions that will override sSearch_ parameters
31
        var afnSearch_ = new Array();
32
        var aiCustomSearch_Indexes = new Array();
33
34
        var oFunctionTimeout = null;
35
36
        var fnOnFiltered = function () { };
37
38
        function _fnGetColumnValues(oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty) {
39
            ///<summary>
40
            ///Return values in the column
41
            ///</summary>
42
            ///<param name="oSettings" type="Object">DataTables settings</param>
43
            ///<param name="iColumn" type="int">Id of the column</param>
44
            ///<param name="bUnique" type="bool">Return only distinct values</param>
45
            ///<param name="bFiltered" type="bool">Return values only from the filtered rows</param>
46
            ///<param name="bIgnoreEmpty" type="bool">Ignore empty cells</param>
47
48
            // check that we have a column id
49
            if (typeof iColumn == "undefined") return new Array();
50
51
            // by default we only wany unique data
52
            if (typeof bUnique == "undefined") bUnique = true;
53
54
            // by default we do want to only look at filtered data
55
            if (typeof bFiltered == "undefined") bFiltered = true;
56
57
            // by default we do not wany to include empty values
58
            if (typeof bIgnoreEmpty == "undefined") bIgnoreEmpty = true;
59
60
            // list of rows which we're going to loop through
61
            var aiRows;
62
63
            // use only filtered rows
64
            if (bFiltered == true) aiRows = oSettings.aiDisplay;
65
            // use all rows
66
            else aiRows = oSettings.aiDisplayMaster; // all row numbers
67
68
            // set up data array	
69
            var asResultData = new Array();
70
71
            for (var i = 0, c = aiRows.length; i < c; i++) {
72
                var iRow = aiRows[i];
73
                var aData = oTable.fnGetData(iRow);
74
                var sValue = aData[iColumn];
75
76
                // ignore empty values?
77
                if (bIgnoreEmpty == true && sValue.length == 0) continue;
78
79
                // ignore unique values?
80
                else if (bUnique == true && jQuery.inArray(sValue, asResultData) > -1) continue;
81
82
                // else push the value onto the result data array
83
                else asResultData.push(sValue);
84
            }
85
86
            return asResultData.sort();
87
        }
88
89
        function _fnColumnIndex(iColumnIndex) {
90
            if (properties.bUseColVis)
91
                return iColumnIndex;
92
            else
93
                return oTable.fnSettings().oApi._fnVisibleToColumnIndex(oTable.fnSettings(), iColumnIndex);
94
            //return iColumnIndex;
95
            //return oTable.fnSettings().oApi._fnColumnIndexToVisible(oTable.fnSettings(), iColumnIndex);
96
        }
97
98
        function fnCreateInput(oTable, regex, smart, bIsNumber, iFilterLength, iMaxLenght) {
99
            var sCSSClass = "text_filter";
100
            if (bIsNumber)
101
                sCSSClass = "number_filter";
102
103
            label = label.replace(/(^\s*)|(\s*$)/g, "");
104
            var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
105
            var search_init = 'search_init ';
106
            var inputvalue = label;
107
            if (currentFilter != '' && currentFilter != '^') {
108
                if (bIsNumber && currentFilter.charAt(0) == '^')
109
                    inputvalue = currentFilter.substr(1); //ignore trailing ^
110
                else
111
                    inputvalue = currentFilter;
112
                search_init = '';
113
            }
114
115
            var input = $('<input type="text" class="' + search_init + sCSSClass + '" value="' + inputvalue + '"/>');
116
            if (iMaxLenght != undefined && iMaxLenght != -1) {
117
                input.attr('maxlength', iMaxLenght);
118
            }
119
            th.html(input);
120
            if (bIsNumber)
121
                th.wrapInner('<span class="filter_column filter_number" />');
122
            else
123
                th.wrapInner('<span class="filter_column filter_text" />');
124
125
            asInitVals[i] = label;
126
            var index = i;
127
128
            if (bIsNumber && !oTable.fnSettings().oFeatures.bServerSide) {
129
                input.keyup(function () {
130
                    /* Filter on the column all numbers that starts with the entered value */
131
                    oTable.fnFilter('^' + this.value, _fnColumnIndex(index), true, false); //Issue 37
132
                    fnOnFiltered();
133
                });
134
            } else {
135
                input.keyup(function () {
136
                    if (oTable.fnSettings().oFeatures.bServerSide && iFilterLength != 0) {
137
                        //If filter length is set in the server-side processing mode
138
                        //Check has the user entered at least iFilterLength new characters
139
140
                        var currentFilter = oTable.fnSettings().aoPreSearchCols[index].sSearch;
141
                        var iLastFilterLength = $(this).data("dt-iLastFilterLength");
142
                        if (typeof iLastFilterLength == "undefined")
143
                            iLastFilterLength = 0;
144
                        var iCurrentFilterLength = this.value.length;
145
                        if (Math.abs(iCurrentFilterLength - iLastFilterLength) < iFilterLength
146
                        //&& currentFilter.length == 0 //Why this?
147
					        ) {
148
                            //Cancel the filtering
149
                            return;
150
                        }
151
                        else {
152
                            //Remember the current filter length
153
                            $(this).data("dt-iLastFilterLength", iCurrentFilterLength);
154
                        }
155
                    }
156
                    /* Filter on the column (the index) of this element */
157
                    oTable.fnFilter(this.value, _fnColumnIndex(index), regex, smart); //Issue 37
158
                    fnOnFiltered();
159
                });
160
            }
161
162
            input.focus(function () {
163
                if ($(this).hasClass("search_init")) {
164
                    $(this).removeClass("search_init");
165
                    this.value = "";
166
                }
167
            });
168
            input.blur(function () {
169
                if (this.value == "") {
170
                    $(this).addClass("search_init");
171
                    this.value = asInitVals[index];
172
                }
173
            });
174
        }
175
176
        function fnCreateRangeInput(oTable) {
177
178
			//var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
179
            th.html(_fnRangeLabelPart(0));
180
            var sFromId = oTable.attr("id") + '_range_from_' + i;
181
            var from = $('<input type="text" class="number_range_filter" id="' + sFromId + '" rel="' + i + '"/>');
182
            th.append(from);
183
            th.append(_fnRangeLabelPart(1));
184
            var sToId = oTable.attr("id") + '_range_to_' + i;
185
            var to = $('<input type="text" class="number_range_filter" id="' + sToId + '" rel="' + i + '"/>');
186
            th.append(to);
187
            th.append(_fnRangeLabelPart(2));
188
            th.wrapInner('<span class="filter_column filter_number_range" />');
189
            var index = i;
190
            aiCustomSearch_Indexes.push(i);
191
192
193
194
            //------------start range filtering function
195
196
197
            /* 	Custom filtering function which will filter data in column four between two values
198
            *	Author: 	Allan Jardine, Modified by Jovan Popovic
199
            */
200
            //$.fn.dataTableExt.afnFiltering.push(
201
            oTable.dataTableExt.afnFiltering.push(
202
	        function (oSettings, aData, iDataIndex) {
203
	            if (oTable.attr("id") != oSettings.sTableId)
204
	                return true;
205
	            // Try to handle missing nodes more gracefully
206
	            if (document.getElementById(sFromId) == null)
207
	                return true;
208
	            var iMin = document.getElementById(sFromId).value * 1;
209
	            var iMax = document.getElementById(sToId).value * 1;
210
	            var iValue = aData[_fnColumnIndex(index)] == "-" ? 0 : aData[_fnColumnIndex(index)] * 1;
211
	            if (iMin == "" && iMax == "") {
212
	                return true;
213
	            }
214
	            else if (iMin == "" && iValue <= iMax) {
215
	                return true;
216
	            }
217
	            else if (iMin <= iValue && "" == iMax) {
218
	                return true;
219
	            }
220
	            else if (iMin <= iValue && iValue <= iMax) {
221
	                return true;
222
	            }
223
	            return false;
224
	        }
225
        );
226
            //------------end range filtering function
227
228
229
230
            $('#' + sFromId + ',#' + sToId, th).keyup(function () {
231
232
                var iMin = document.getElementById(sFromId).value * 1;
233
                var iMax = document.getElementById(sToId).value * 1;
234
                if (iMin != 0 && iMax != 0 && iMin > iMax)
235
                    return;
236
237
                oTable.fnDraw();
238
                fnOnFiltered();
239
            });
240
241
242
        }
243
244
245
        function fnCreateDateRangeInput(oTable) {
246
247
            var aoFragments = sRangeFormat.split(/[}{]/);
248
249
            th.html("");
250
            //th.html(_fnRangeLabelPart(0));
251
            var sFromId = oTable.attr("id") + '_range_from_' + i;
252
            var from = $('<input type="text" class="date_range_filter" id="' + sFromId + '" rel="' + i + '"/>');
253
            from.datepicker();
254
            //th.append(from);
255
            //th.append(_fnRangeLabelPart(1));
256
            var sToId = oTable.attr("id") + '_range_to_' + i;
257
            var to = $('<input type="text" class="date_range_filter" id="' + sToId + '" rel="' + i + '"/>');
258
            //th.append(to);
259
            //th.append(_fnRangeLabelPart(2));
260
261
            for (ti = 0; ti < aoFragments.length; ti++) {
262
263
                if (aoFragments[ti] == properties.sDateFromToken) {
264
                    th.append(from);
265
                } else {
266
                    if (aoFragments[ti] == properties.sDateToToken) {
267
                        th.append(to);
268
                    } else {
269
                        th.append(aoFragments[ti]);
270
                    }
271
                }
272
                
273
274
            }
275
276
277
            th.wrapInner('<span class="filter_column filter_date_range" />');
278
            to.datepicker();
279
            var index = i;
280
            aiCustomSearch_Indexes.push(i);
281
282
283
            //------------start date range filtering function
284
285
            //$.fn.dataTableExt.afnFiltering.push(
286
            oTable.dataTableExt.afnFiltering.push(
287
	        function (oSettings, aData, iDataIndex) {
288
	            if (oTable.attr("id") != oSettings.sTableId)
289
	                return true;
290
291
	            var dStartDate = from.datepicker("getDate");
292
293
	            var dEndDate = to.datepicker("getDate");
294
295
	            if (dStartDate == null && dEndDate == null) {
296
	                return true;
297
	            }
298
299
	            var dCellDate = null;
300
	            try {
301
	                if (aData[_fnColumnIndex(index)] == null || aData[_fnColumnIndex(index)] == "")
302
	                    return false;
303
	                dCellDate = $.datepicker.parseDate($.datepicker.regional[""].dateFormat, aData[_fnColumnIndex(index)]);
304
	            } catch (ex) {
305
	                return false;
306
	            }
307
	            if (dCellDate == null)
308
	                return false;
309
310
311
	            if (dStartDate == null && dCellDate <= dEndDate) {
312
	                return true;
313
	            }
314
	            else if (dStartDate <= dCellDate && dEndDate == null) {
315
	                return true;
316
	            }
317
	            else if (dStartDate <= dCellDate && dCellDate <= dEndDate) {
318
	                return true;
319
	            }
320
	            return false;
321
	        }
322
        );
323
            //------------end date range filtering function
324
325
            $('#' + sFromId + ',#' + sToId, th).change(function () {
326
                oTable.fnDraw();
327
                fnOnFiltered();
328
            });
329
330
331
        }
332
333
        function fnCreateColumnSelect(oTable, aData, iColumn, nTh, sLabel, bRegex, oSelected) {
334
            if (aData == null)
335
                aData = _fnGetColumnValues(oTable.fnSettings(), iColumn, true, false, true);
336
            var index = iColumn;
337
            var currentFilter = oTable.fnSettings().aoPreSearchCols[i].sSearch;
338
            if (currentFilter == null || currentFilter == "")//Issue 81
339
                currentFilter = oSelected;
340
341
            var r = '<select class="search_init select_filter"><option value="" class="search_init">' + sLabel + '</option>';
342
            var j = 0;
343
            var iLen = aData.length;
344
            for (j = 0; j < iLen; j++) {
345
                if (typeof (aData[j]) != 'object') {
346
                    var selected = '';
347
                    if (escape(aData[j]) == currentFilter
348
                        || escape(aData[j]) == escape(currentFilter)
349
                        )
350
                        selected = 'selected '
351
                    r += '<option ' + selected + ' value="' + escape(aData[j]) + '">' + aData[j] + '</option>';
352
                }
353
                else {
354
                    var selected = '';
355
                    if (bRegex) {
356
                        //Do not escape values if they are explicitely set to avoid escaping special characters in the regexp
357
                        if (aData[j].value == currentFilter) selected = 'selected ';
358
                        r += '<option ' + selected + 'value="' + aData[j].value + '">' + aData[j].label + '</option>';
359
                    } else {
360
                        if (escape(aData[j].value) == currentFilter) selected = 'selected ';
361
                        r += '<option ' + selected + 'value="' + escape(aData[j].value) + '">' + aData[j].label + '</option>';
362
                    }
363
                }
364
            }
365
366
            var select = $(r + '</select>');
367
            nTh.html(select);
368
            nTh.wrapInner('<span class="filter_column filter_select" />');
369
            select.change(function () {
370
                //var val = $(this).val();
371
                if ($(this).val() != "") {
372
                    $(this).removeClass("search_init");
373
                } else {
374
                    $(this).addClass("search_init");
375
                }
376
                if (bRegex)
377
                    oTable.fnFilter($(this).val(), iColumn, bRegex); //Issue 41
378
                else
379
                    oTable.fnFilter(unescape($(this).val()), iColumn); //Issue 25
380
                fnOnFiltered();
381
            });
382
            if (currentFilter != null && currentFilter != "")//Issue 81
383
                oTable.fnFilter(unescape(currentFilter), iColumn);
384
        }
385
386
        function fnCreateSelect(oTable, aData, bRegex, oSelected) {
387
            var oSettings = oTable.fnSettings();
388
            if (aData == null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) {
389
                // Add a function to the draw callback, which will check for the Ajax data having 
390
                // been loaded. Use a closure for the individual column elements that are used to 
391
                // built the column filter, since 'i' and 'th' (etc) are locally "global".
392
                oSettings.aoDrawCallback.push({
393
                    "fn": (function (iColumn, nTh, sLabel) {
394
                        return function () {
395
                            // Only rebuild the select on the second draw - i.e. when the Ajax
396
                            // data has been loaded.
397
                            if (oSettings.iDraw == 2 && oSettings.sAjaxSource != null && oSettings.sAjaxSource != "" && !oSettings.oFeatures.bServerSide) {
398
                                return fnCreateColumnSelect(oTable, null, _fnColumnIndex(iColumn), nTh, sLabel, bRegex, oSelected); //Issue 37
399
                            }
400
                        };
401
                    })(i, th, label),
402
                    "sName": "column_filter_" + i
403
                });
404
            }
405
            // Regardless of the Ajax state, build the select on first pass
406
            fnCreateColumnSelect(oTable, aData, _fnColumnIndex(i), th, label, bRegex, oSelected); //Issue 37
407
408
        }
409
410
        function fnCreateCheckbox(oTable, aData) {
411
412
            if (aData == null)
413
                aData = _fnGetColumnValues(oTable.fnSettings(), i, true, true, true);
414
            var index = i;
415
416
            var r = '', j, iLen = aData.length;
417
418
            //clean the string
419
            var localLabel = label.replace('%', 'Perc').replace("&", "AND").replace("$", "DOL").replace("£", "STERL").replace("@", "AT").replace(/\s/g, "_");
420
            localLabel = localLabel.replace(/[^a-zA-Z 0-9]+/g, '');
421
            //clean the string
422
423
            //button label override
424
            var labelBtn = label;
425
            if (properties.sFilterButtonText != null || properties.sFilterButtonText != undefined) {
426
                labelBtn = properties.sFilterButtonText;
427
            }
428
429
            var relativeDivWidthToggleSize = 10;
430
            var numRow = 12; //numero di checkbox per colonna
431
            var numCol = Math.floor(iLen / numRow);
432
            if (iLen % numRow > 0) {
433
                numCol = numCol + 1;
434
            };
435
436
            //count how many column should be generated and split the div size
437
            var divWidth = 100 / numCol - 2;
438
439
            var divWidthToggle = relativeDivWidthToggleSize * numCol;
440
441
            if (numCol == 1) {
442
                divWidth = 20;
443
            }
444
445
            var divRowDef = '<div style="float:left; min-width: ' + divWidth + '%; " >';
446
            var divClose = '</div>';
447
448
            var uniqueId = oTable.attr("id") + localLabel;
449
            var buttonId = "chkBtnOpen" + uniqueId;
450
            var checkToggleDiv = uniqueId + "-flt-toggle";
451
            r += '<button id="' + buttonId + '" class="checkbox_filter" > ' + labelBtn + '</button>'; //filter button witch open dialog
452
            r += '<div id="' + checkToggleDiv + '" '
453
            	+ 'title="' + label + '" '
454
            	+ 'class="toggle-check ui-widget-content ui-corner-all"  style="width: ' + (divWidthToggle) + '%; " >'; //dialog div
455
            //r+= '<div align="center" style="margin-top: 5px; "> <button id="'+buttonId+'Reset" class="checkbox_filter" > reset </button> </div>'; //reset button and its div
456
            r += divRowDef;
457
458
            for (j = 0; j < iLen; j++) {
459
460
                //if last check close div
461
                if (j % numRow == 0 && j != 0) {
462
                    r += divClose + divRowDef;
463
                }
464
465
                //check button
466
                r += '<input class="search_init checkbox_filter" type="checkbox" id= "' + aData[j] + '" name= "' + localLabel + '" value="' + aData[j] + '" >' + aData[j] + '<br/>';
467
468
                var checkbox = $(r);
469
                th.html(checkbox);
470
                th.wrapInner('<span class="filter_column filter_checkbox" />');
471
                //on every checkbox selection
472
                checkbox.change(function () {
473
474
                    var search = '';
475
                    var or = '|'; //var for select checks in 'or' into the regex
476
                    var resSize = $('input:checkbox[name="' + localLabel + '"]:checked').size();
477
                    $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index) {
478
479
                        //search = search + ' ' + $(this).val();
480
                        //concatenation for selected checks in or
481
                        if ((index == 0 && resSize == 1)
482
                				|| (index != 0 && index == resSize - 1)) {
483
                            or = '';
484
                        }
485
                        //trim
486
                        search = search.replace(/^\s+|\s+$/g, "");
487
                        search = search + $(this).val() + or;
488
                        or = '|';
489
490
                    });
491
492
                    for (var jj = 0; jj < iLen; jj++) {
493
                        if (search != "") {
494
                            $('#' + aData[jj]).removeClass("search_init");
495
                        } else {
496
                            $('#' + aData[jj]).addClass("search_init");
497
                        }
498
                    }
499
500
                    //execute search
501
                    oTable.fnFilter(search, index, true, false);
502
                    fnOnFiltered();
503
                });
504
            }
505
506
            //filter button
507
            $('#' + buttonId).button();
508
            //dialog
509
            $('#' + checkToggleDiv).dialog({
510
                //height: 140,
511
                autoOpen: false,
512
                //show: "blind",
513
                hide: "blind",
514
                buttons: [{
515
                    text: "Reset",
516
                    click: function () {
517
                        //$('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected
518
                        $('input:checkbox[name="' + localLabel + '"]:checked').each(function (index3) {
519
                            $(this).attr('checked', false);
520
                            $(this).addClass("search_init");
521
                        });
522
                        oTable.fnFilter('', index, true, false);
523
                        fnOnFiltered();
524
                        return false;
525
                    }
526
                },
527
							{
528
							    text: "Close",
529
							    click: function () { $(this).dialog("close"); }
530
							}
531
						]
532
            });
533
534
535
            $('#' + buttonId).click(function () {
536
537
                $('#' + checkToggleDiv).dialog('open');
538
                var target = $(this);
539
                $('#' + checkToggleDiv).dialog("widget").position({ my: 'top',
540
                    at: 'bottom',
541
                    of: target
542
                });
543
544
                return false;
545
            });
546
547
            var fnOnFilteredCurrent = fnOnFiltered;
548
549
            fnOnFiltered = function () {
550
                var target = $('#' + buttonId);
551
                $('#' + checkToggleDiv).dialog("widget").position({ my: 'top',
552
                    at: 'bottom',
553
                    of: target
554
                });
555
                fnOnFilteredCurrent();
556
            };
557
            //reset
558
            /*
559
            $('#'+buttonId+"Reset").button();
560
            $('#'+buttonId+"Reset").click(function(){
561
            $('#'+buttonId).removeClass("filter_selected"); //LM remove border if filter selected
562
            $('input:checkbox[name="'+localLabel+'"]:checked').each(function(index3) {
563
            $(this).attr('checked', false);
564
            $(this).addClass("search_init");
565
            });
566
            oTable.fnFilter('', index, true, false);
567
            return false;
568
            }); 
569
            */
570
        }
571
572
573
574
575
        function _fnRangeLabelPart(iPlace) {
576
            switch (iPlace) {
577
                case 0:
578
                    return sRangeFormat.substring(0, sRangeFormat.indexOf("{from}"));
579
                case 1:
580
                    return sRangeFormat.substring(sRangeFormat.indexOf("{from}") + 6, sRangeFormat.indexOf("{to}"));
581
                default:
582
                    return sRangeFormat.substring(sRangeFormat.indexOf("{to}") + 4);
583
            }
584
        }
585
586
587
588
589
        var oTable = this;
590
591
        var defaults = {
592
            sPlaceHolder: "foot",
593
            sRangeSeparator: "~",
594
            iFilteringDelay: 500,
595
            aoColumns: null,
596
            sRangeFormat: "From {from} to {to}",
597
            sDateFromToken: "from",
598
            sDateToToken: "to"
599
        };
600
601
        var properties = $.extend(defaults, options);
602
603
        return this.each(function () {
604
605
            if (!oTable.fnSettings().oFeatures.bFilter)
606
                return;
607
            asInitVals = new Array();
608
609
            var aoFilterCells = oTable.fnSettings().aoFooter[0];
610
611
            var oHost = oTable.fnSettings().nTFoot; //Before fix for ColVis
612
            var sFilterRow = "tr"; //Before fix for ColVis
613
614
            if (properties.sPlaceHolder == "head:after") {
615
                var tr = $("tr:first", oTable.fnSettings().nTHead).detach();
616
                //tr.appendTo($(oTable.fnSettings().nTHead));
617
                if (oTable.fnSettings().bSortCellsTop) {
618
                    tr.prependTo($(oTable.fnSettings().nTHead));
619
                    //tr.appendTo($("thead", oTable));
620
                    aoFilterCells = oTable.fnSettings().aoHeader[1];
621
                }
622
                else {
623
                    tr.appendTo($(oTable.fnSettings().nTHead));
624
                    //tr.prependTo($("thead", oTable));
625
                    aoFilterCells = oTable.fnSettings().aoHeader[0];
626
                }
627
628
                sFilterRow = "tr:last";
629
                oHost = oTable.fnSettings().nTHead;
630
631
            } else if (properties.sPlaceHolder == "head:before") {
632
633
                if (oTable.fnSettings().bSortCellsTop) {
634
                    var tr = $("tr:first", oTable.fnSettings().nTHead).detach();
635
                    tr.appendTo($(oTable.fnSettings().nTHead));
636
                    aoFilterCells = oTable.fnSettings().aoHeader[1];
637
                } else {
638
                    aoFilterCells = oTable.fnSettings().aoHeader[0];
639
                }
640
                /*else {
641
                //tr.prependTo($("thead", oTable));
642
                sFilterRow = "tr:first";
643
                }*/
644
645
                sFilterRow = "tr:first";
646
647
                oHost = oTable.fnSettings().nTHead;
648
649
                
650
            }
651
652
            //$(sFilterRow + " th", oHost).each(function (index) {//bug with ColVis
653
            $(aoFilterCells).each(function (index) {//fix for ColVis
654
                i = index;
655
                var aoColumn = { type: "text",
656
                    bRegex: false,
657
                    bSmart: true,
658
                    iMaxLenght: -1,
659
                    iFilterLength: 0
660
                };
661
                if (properties.aoColumns != null) {
662
                    if (properties.aoColumns.length < i || properties.aoColumns[i] == null)
663
                        return;
664
                    aoColumn = properties.aoColumns[i];
665
                }
666
                //label = $(this).text(); //Before fix for ColVis
667
                label = $($(this)[0].cell).text(); //Fix for ColVis
668
                if (aoColumn.sSelector == null) {
669
                    //th = $($(this)[0]);//Before fix for ColVis
670
                    th = $($(this)[0].cell); //Fix for ColVis
671
                }
672
                else {
673
                    th = $(aoColumn.sSelector);
674
                    if (th.length == 0)
675
                        th = $($(this)[0].cell);
676
                }
677
678
                if (aoColumn != null) {
679
                    if (aoColumn.sRangeFormat != null)
680
                        sRangeFormat = aoColumn.sRangeFormat;
681
                    else
682
                        sRangeFormat = properties.sRangeFormat;
683
                    switch (aoColumn.type) {
684
                        case "null":
685
                            break;
686
                        case "number":
687
                            fnCreateInput(oTable, true, false, true, aoColumn.iFilterLength, aoColumn.iMaxLenght);
688
                            break;
689
                        case "select":
690
                            if (aoColumn.bRegex != true)
691
                                aoColumn.bRegex = false;
692
                            fnCreateSelect(oTable, aoColumn.values, aoColumn.bRegex, aoColumn.selected);
693
                            break;
694
                        case "number-range":
695
                            fnCreateRangeInput(oTable);
696
                            break;
697
                        case "date-range":
698
                            fnCreateDateRangeInput(oTable);
699
                            break;
700
                        case "checkbox":
701
                            fnCreateCheckbox(oTable, aoColumn.values);
702
                            break;
703
                        case "text":
704
                        default:
705
                            bRegex = (aoColumn.bRegex == null ? false : aoColumn.bRegex);
706
                            bSmart = (aoColumn.bSmart == null ? false : aoColumn.bSmart);
707
                            fnCreateInput(oTable, bRegex, bSmart, false, aoColumn.iFilterLength, aoColumn.iMaxLenght);
708
                            break;
709
710
                    }
711
                }
712
            });
713
714
            for (j = 0; j < aiCustomSearch_Indexes.length; j++) {
715
                //var index = aiCustomSearch_Indexes[j];
716
                var fnSearch_ = function () {
717
                    var id = oTable.attr("id");
718
                    return $("#" + id + "_range_from_" + aiCustomSearch_Indexes[j]).val() + properties.sRangeSeparator + $("#" + id + "_range_to_" + aiCustomSearch_Indexes[j]).val()
719
                }
720
                afnSearch_.push(fnSearch_);
721
            }
722
723
            if (oTable.fnSettings().oFeatures.bServerSide) {
724
725
                var fnServerDataOriginal = oTable.fnSettings().fnServerData;
726
727
                oTable.fnSettings().fnServerData = function (sSource, aoData, fnCallback) {
728
729
                    for (j = 0; j < aiCustomSearch_Indexes.length; j++) {
730
                        var index = aiCustomSearch_Indexes[j];
731
732
                        for (k = 0; k < aoData.length; k++) {
733
                            if (aoData[k].name == "sSearch_" + index)
734
                                aoData[k].value = afnSearch_[j]();
735
                        }
736
                    }
737
                    aoData.push({ "name": "sRangeSeparator", "value": properties.sRangeSeparator });
738
739
                    if (fnServerDataOriginal != null) {
740
                        try {
741
                            fnServerDataOriginal(sSource, aoData, fnCallback, oTable.fnSettings()); //TODO: See Issue 18
742
                        } catch (ex) {
743
                            fnServerDataOriginal(sSource, aoData, fnCallback);
744
                        }
745
                    }
746
                    else {
747
                        $.getJSON(sSource, aoData, function (json) {
748
                            fnCallback(json)
749
                        });
750
                    }
751
                };
752
753
            }
754
755
        });
756
757
    };
758
759
760
761
762
})(jQuery);
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt (-2 / +25 lines)
Lines 44-49 function verify_images() { Link Here
44
     });[% END %]
44
     });[% END %]
45
//]]>
45
//]]>
46
</script>
46
</script>
47
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" />
48
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.min.js"></script>
49
<script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.dataTables.columnFilter.js"></script>
50
[% INCLUDE 'datatables-strings.inc' %]
51
<script type="text/javascript" src="[% themelang %]/js/datatables.js"></script>
52
<script type="text/javascript">
53
//<![CDATA[
54
    $(document).ready(function() {
55
        $("#itemstable").dataTable($.extend(true, {}, dataTablesDefaults, {
56
            'sDom': 't',
57
            'bPaginate': false
58
        })).columnFilter({
59
            'sPlaceHolder': 'head:after'
60
        });
61
    });
62
//]]>
63
</script>
47
</head>
64
</head>
48
65
49
<body id="catalog_detail" class="catalog">
66
<body id="catalog_detail" class="catalog">
Lines 266-272 function verify_images() { Link Here
266
<div id="holdings">
283
<div id="holdings">
267
[% IF ( count ) %]
284
[% IF ( count ) %]
268
    [% IF ( showncount ) %]
285
    [% IF ( showncount ) %]
269
        <table>
286
        <table id="itemstable">
287
            <thead>
288
            [%# duplicate the header row for columnFilter %]
289
            [% FOREACH i IN [1,2] %]
270
            <tr>
290
            <tr>
271
                [% IF ( item_level_itypes ) %]<th>Item type</th>[% END %]
291
                [% IF ( item_level_itypes ) %]<th>Item type</th>[% END %]
272
                <th>Current location</th>
292
                <th>Current location</th>
Lines 285-290 function verify_images() { Link Here
285
        [% IF ( hostrecords ) %]<th>Host records</th>[% END %]
305
        [% IF ( hostrecords ) %]<th>Host records</th>[% END %]
286
		[% IF ( analyze ) %]<th>Used in</th><th></th>[% END %]
306
		[% IF ( analyze ) %]<th>Used in</th><th></th>[% END %]
287
            </tr>
307
            </tr>
308
            [% END %]
309
            </thead>
310
            <tbody>
288
            [% FOREACH itemloo IN itemloop %]
311
            [% FOREACH itemloo IN itemloop %]
289
                <tr>
312
                <tr>
290
                    [% IF ( item_level_itypes ) %]
313
                    [% IF ( item_level_itypes ) %]
Lines 422-427 function verify_images() { Link Here
422
445
423
                </tr>
446
                </tr>
424
            [% END %]
447
            [% END %]
448
            </tbody>
425
        </table>
449
        </table>
426
        [% END %]
450
        [% END %]
427
                [% IF ( hiddencount ) %]
451
                [% IF ( hiddencount ) %]
428
- 

Return to bug 9034