Completed
Push — master ( e8947e...dc23b0 )
by Andreas
15:04
created

$.fn.create_tablesorter   B

Complexity

Conditions 5
Paths 16

Size

Total Lines 137

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 16
nop 1
dl 0
loc 137
rs 8.1463
c 0
b 0
f 0

3 Functions

Rating   Name   Duplication   Size   Complexity  
A 0 5 1
A 0 4 1
A 0 5 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
var COLUMN_TITLE = 'Please enter the column name';
2
3
var change_label = function()
4
{
5
    var field_name = prompt(COLUMN_TITLE, $(this).parent().find('input.field_name').val());
6
    $(this).html(field_name);
7
    $(this).parent().find('input.field_name').val(field_name);
8
};
9
10
$.fn.toggleClick = function(){
11
    var functions = arguments;
12
    return this.click(function(){
13
            var iteration = $(this).data('iteration') || 0;
14
            functions[iteration].apply(this, arguments);
15
            iteration = (iteration + 1) % functions.length ;
16
            $(this).data('iteration', iteration);
17
    });
18
};
19
20
$.fn.create_tablesorter = function(options)
21
{
22
    $(this).addClass('jquery-enabled');
23
    $(this).find('th.index').text('');
24
    $(this).find('td.midcom_helper_datamanager2_helper_sortable input').css({display: 'none'});
25
26
    $(this).create_tablesorter_rows(options);
27
    $(this).create_tablesorter_columns(options);
28
    $(this).rearrange_scores();
29
    $(this).check_column_positions(options);
30
31
    // Column adding and sorting
32
    if ($(options.sortable_columns))
33
    {
34
        $(this).initialize_column_creation(options);
35
    }
36
37
    // Convert add/remove buttons
38
    $(this).find('button').each(function()
39
    {
40
        $(this).find('img').appendTo($(this).parent());
41
    });
42
43
    // Create the sortable rows
44
    $(this).create_tablesorter_rows(options);
45
46
    if (options.sortable_rows)
47
    {
48
        $('tbody td.midcom_helper_datamanager2_helper_sortable').css({display: 'table-cell'});
49
    }
50
51
    $(this).find('th.index').css({display: 'table-cell'});
52
53
    // IE6 compliant hovering
54
    $(this).find('tbody tr')
55
        .mouseover(function()
56
        {
57
            // Fix IE6 hover
58
            $(this).addClass('hover');
59
        })
60
        .mouseout(function()
61
        {
62
            // Fix IE6 hover
63
            $(this).removeClass('hover');
64
        });
65
66
    $(this).find('tbody td.midcom_helper_datamanager2_helper_sortable').each(function()
67
    {
68
        if ($(this).find('img.down').size() == 0)
69
        {
70
            $('<img />')
71
                .addClass('down')
72
                .addClass('enabled')
73
                .attr({
74
                    src: MIDCOM_STATIC_URL + '/stock-icons/16x16/down.png',
75
                    alt: 'Down'
76
                })
77
                .click(function()
78
                {
79
                    $(this).move_row('down');
80
                })
81
                .prependTo($(this));
82
        }
83
84
        if ($(this).find('img.up').size() == 0)
85
        {
86
            $('<img />')
87
                .addClass('up')
88
                .addClass('enabled')
89
                .attr({
90
                    src: MIDCOM_STATIC_URL + '/stock-icons/16x16/up.png',
91
                    alt: 'Up'
92
                })
93
                .click(function()
94
                {
95
                    $(this).move_row('up');
96
                })
97
                .prependTo($(this));
98
        }
99
    });
100
101
    $(this).find('tbody tr').find('td:first').each(function()
102
    {
103
        if (   $(this).find('img.delete').size() > 0
104
            || options.allow_delete == false)
105
        {
106
            return;
107
        }
108
109
        $('<img />')
110
            .addClass('delete')
111
            .attr({
112
                    src: MIDCOM_STATIC_URL + '/stock-icons/16x16/trash.png',
113
                    alt: 'Delete'
114
            })
115
            .toggleClick(
116
                function()
117
                {
118
                    $(this).parents('tr')
119
                        .addClass('deleted')
120
                        .find('input, select, textarea').each(function(i)
0 ignored issues
show
Unused Code introduced by
The parameter i is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
121
                        {
122
                            var name = $(this).attr('name');
123
                            name = '___' + name;
124
                            $(this).attr('name', name);
125
                            $(this).prop('disabled', true);
126
                        });
127
                },
128
                function()
129
                {
130
                    $(this).parents('tr')
131
                        .removeClass('deleted')
132
                        .find('input, select, textarea').each(function()
133
                        {
134
                            var name = $(this).attr('name');
135
                            name = name.replace(/^___/, '');
136
                            $(this).attr('name', name);
137
                            $(this).prop("disabled", false);
138
                        });
139
140
                }
141
            )
142
            .prependTo($(this))
143
            .show();
144
    });
145
146
    // Check the amount of rows presented
147
    var row_count = $(this).find('tbody tr').size();
148
149
    if (   options.max_row_count != 0
150
        && row_count >= options.max_row_count)
151
    {
152
        $(this)
153
            .find('tfoot td.new_row').fadeTo(500, 0.5)
154
            .unbind('click');
155
    }
156
};
157
158
$.fn.create_tablesorter_rows = function(options)
159
{
160
    $(this).find('tfoot td.new_row')
161
        .unbind('click')
162
        .click(function()
163
        {
164
            var new_row = $(this).parent().clone(true),
165
                date = new Date(),
166
                timestamp = date.getTime();
167
168
            $(new_row).find('img.add-row').remove();
169
170
            // Insert the rows
171
            $(new_row)
172
                .addClass('new_row')
173
                .attr(
174
                {
175
                    id: 'row_' + timestamp
176
                })
177
                .appendTo($(this).parents('table.jquery-enabled').find('tbody'));
178
179
            $(new_row).find('input, select, textarea').each(function()
180
            {
181
                var name = $(this).attr('name');
182
183
                $(this).parent().removeClass('new_row');
184
185
                if (name)
186
                {
187
                    name = name.replace(/index/, timestamp);
188
                    $(this).attr('name', name);
189
                }
190
191
                var id = $(this).attr('id');
192
193
                if (id)
194
                {
195
                    id = id.replace(/index/, 'row_' + timestamp);
196
                    $(this).attr('id', id);
197
                }
198
199
                var value = $(this).val();
200
201
                if (value)
202
                {
203
                    value = value.replace(/index/, timestamp);
204
                    $(this).val(value);
205
                }
206
            });
207
208
            $(new_row).find('td')
209
                .unbind('click')
210
                .removeClass('new_row');
211
212
            $(this).parents('table.jquery-enabled').create_tablesorter(options);
213
            $(this).rearrange_scores();
214
215
            // Check the amount of rows presented
216
            var row_count = $(this).parents('table.jquery-enabled').find('tbody tr').size();
217
218
            if (   options.max_row_count != 0
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if options.max_row_count !=...= options.max_row_count is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
219
                && row_count >= options.max_row_count)
220
            {
221
                $(this)
222
                    .fadeTo(500, 0.5)
223
                    .unbind('click');
224
                return false;
225
            }
226
        });
227
228
    // Less than two, no point in initializing the sortable
229
    if (!options.sortable_rows
230
        || $(this).find('tbody td.midcom_helper_datamanager2_helper_sortable').size() < 2)
231
    {
232
        $('tbody td.midcom_helper_datamanager2_helper_sortable').css({display: 'none'});
233
        $(this).find('th.index').css({display: 'none'});
234
    }
235
};
236
237
$.fn.move_row = function(direction)
238
{
239
    if (!$(this).hasClass('enabled'))
240
    {
241
        return false;
242
    }
243
244
    var parent = $(this).parents('tr');
245
246
    $(parent).removeClass('hover');
247
248
    switch (direction)
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
249
    {
250
        case 'up':
251
            $(parent).insertBefore($(parent).prev('tr'));
252
            $(this).parents('table.jquery-enabled').rearrange_scores();
253
            break;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
254
        case 'down':
255
            $(parent).insertAfter($(parent).next('tr'));
256
            $(this).parents('table.jquery-enabled').rearrange_scores();
257
            break;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
258
    }
0 ignored issues
show
Comprehensibility introduced by
There is no default case in this switch, so nothing gets returned when all cases fail. You might want to consider adding a default or return undefined explicitly.
Loading history...
259
};
260
261
$.fn.rearrange_scores = function()
262
{
263
    var size = $(this).find('tbody td.midcom_helper_datamanager2_helper_sortable').size();
264
265
    $(this).find('tbody td.midcom_helper_datamanager2_helper_sortable').each(function(i)
266
    {
267
        var last_index = size - 1;
268
269
        switch (i)
270
        {
271
            case 0:
272
                $(this).find('.up')
273
                    .fadeTo(500, 0.3)
274
                    .removeClass('enabled');
275
276
                if (!$(this).find('.down').hasClass('enabled'))
277
                {
278
                    $(this).find('.down')
279
                        .addClass('enabled')
280
                        .fadeTo(500, 1);
281
                }
282
283
                break;
284
285
            case last_index:
286
                $(this).find('.down')
287
                    .fadeTo(500, 0.3)
288
                    .removeClass('enabled');
289
290
                if (!$(this).find('.up').hasClass('enabled'))
291
                {
292
                    $(this).find('.up')
293
                        .addClass('enabled')
294
                        .fadeTo(500, 1);
295
                }
296
297
                break;
298
299
            default:
300
                // Stays somewhere in between the first and the last
301
                $(this).find('.up, .down').each(function()
302
                {
303
                    // This was already enabled, no need to make any changes
304
                    if ($(this).hasClass('enabled'))
305
                    {
306
                        return;
307
                    }
308
309
                    $(this)
310
                        .addClass('enabled')
311
                        .fadeTo(500, 1);
312
                });
313
        }
314
315
        $(this).find('input.image_sortable, input.downloads_sortable').val(i + 1);
316
    });
317
318
    $(this).find('tbody tr:odd')
319
        .addClass('odd')
320
        .removeClass('even');
321
322
    $(this).find('tbody tr:even')
323
        .addClass('even')
324
        .removeClass('odd');
325
};
326
327
$.fn.create_tablesorter_columns = function(options)
328
{
329
    if (!options.sortable_columns)
330
    {
331
        return;
332
    }
333
334
    $(this).find('thead th').each(function()
335
    {
336
        if (   $(this).hasClass('index')
337
            || $(this).hasClass('new_column')
338
            || $(this).hasClass('add_column')
339
            || $(this).find('img').size() >= 1)
340
        {
341
            return;
342
        }
343
344
        $('<img />')
345
            .css({
346
347
            })
348
            .addClass('column_sort move_left enabled')
349
            .attr({
350
                alt: 'move left',
351
                src: MIDCOM_STATIC_URL + '/stock-icons/16x16/stock_left.png'
352
            })
353
            .click(function()
354
            {
355
                if (!$(this).hasClass('enabled'))
356
                {
357
                    return;
358
                }
359
                $(this).parent().move_column('left', options);
360
            })
361
            .prependTo($(this));
362
363
        $('<img />')
364
            .css({
365
366
            })
367
            .addClass('column_sort move_right enabled')
368
            .attr({
369
                alt: 'move left',
370
                src: MIDCOM_STATIC_URL + '/stock-icons/16x16/stock_right.png'
371
            })
372
            .click(function()
373
            {
374
                if (!$(this).hasClass('enabled'))
375
                {
376
                    return;
377
                }
378
                $(this).parent().move_column('right', options);
379
            })
380
            .appendTo($(this));
381
382
        if ($(this).hasClass('deletable'))
383
        {
384
            $('<img />')
385
                .css({
386
387
                })
388
                .addClass('enabled delete')
389
                .attr({
390
                    alt: 'delete',
391
                    src: MIDCOM_STATIC_URL + '/stock-icons/16x16/trash.png'
392
                })
393
                .click(function()
394
                {
395
                    var class_name = $(this).parent().attr('class');
396
397
                    if (!class_name)
398
                    {
399
                        return;
400
                    }
401
402
                    class_name = class_name.replace(/tabledata_header /, '');
403
                    class_name = class_name.replace(/ deletable/, '');
404
                    class_name = class_name.replace(/ deleted/, '');
405
406
                    $(this).parent().delete_column(class_name, options);
407
                })
408
                .prependTo($(this));
409
        }
410
411
        $(this).hover(
412
            function()
413
            {
414
                $(this).find('img').addClass('hover');
415
            },
416
            function()
417
            {
418
                $(this).find('img').removeClass('hover');
419
            }
420
        );
421
    });
422
423
    // Disable the moving outside table borders
424
    $(options.table_id).find('thead th:first').next().find('img.move_left')
425
        .removeClass('enabled')
426
        .fadeTo(500, 0.5);
427
428
    $(options.table_id).find('thead th:first').next().next().find('img.move_left')
429
        .addClass('enabled')
430
        .fadeTo(500, 1.0);
431
432
    // Disable the moving outside table borders
433
    $(options.table_id).find('thead th:last').prev().find('img.move_right')
434
        .removeClass('enabled')
435
        .fadeTo(500, 0.5);
436
437
    $(options.table_id).find('thead th:last').prev().prev().find('img.move_right')
438
        .addClass('enabled')
439
        .fadeTo(500, 1.0);
440
};
441
442
$.fn.move_column = function(direction, options)
443
{
444
    var class_name = $(this).attr('class');
445
    class_name = class_name.replace(/tabledata_header /, '');
446
    class_name = class_name.replace(/ deletable/, '');
447
    class_name = class_name.replace(/ deleted/, '');
448
449
    $(options.table_id).find('td.' + class_name + ', th.' + class_name).each(function()
450
    {
451
        if (direction == 'left')
452
        {
453
            $(this).insertBefore($(this).prev());
454
        }
455
        else
456
        {
457
            $(this).insertAfter($(this).next());
458
        }
459
460
        $(this).find('img.column_sort').removeClass('hover');
461
    });
462
463
    $(options.table_id).create_tablesorter_columns(options);
464
};
465
466
$.fn.check_column_positions = function(options)
0 ignored issues
show
Unused Code introduced by
The parameter options is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
467
{
468
469
};
470
471
$.fn.delete_column = function(column_id, options)
472
{
473
    if ($(options.table_id).find('.' + column_id).hasClass('deleted'))
474
    {
475
        $(options.table_id).find('.' + column_id)
476
            .removeClass('deleted')
477
            .find('input, select, textarea').prop('disabled', false);
478
    }
479
    else
480
    {
481
        $(options.table_id).find('.' + column_id)
482
            .addClass('deleted')
483
            .find('input, select, textarea').prop('disabled', true);
484
    }
485
486
    if ($(this).hasClass('deleted'))
487
    {
488
        $('<input type="hidden" name="midcom_helper_datamanager2_tabledata_widget_delete[' + options.field_name + '][]"/>')
489
            .addClass('delete_input')
490
            .val(column_id)
491
            .appendTo($(this));
492
    }
493
    else
494
    {
495
        $(this).find('input.delete_input').remove();
496
    }
497
};
498
499
$.fn.initialize_column_creation = function(options)
500
{
501
    if ($(this).find('img.add_new_column').size() > 0)
502
    {
503
        return;
504
    }
505
506
    if ($(this).find('img.add_new_column').size() > 0)
507
    {
508
        return;
509
    }
510
511
    $('<img />')
512
        .addClass('enabled add_new_column')
513
        .attr({
514
            src: MIDCOM_STATIC_URL + '/stock-icons/16x16/list-add.png',
515
            alt: 'Add column'
516
        })
517
        .click(function()
518
        {
519
            // Prompt for the field name from the user
520
            var field_name = prompt(COLUMN_TITLE, '');
521
522
            var date = new Date();
523
            var timestamp = date.getTime();
524
525
            if (!field_name)
526
            {
527
                return;
528
            }
529
530
            // Create a new table head cell
531
            $('<th></th>')
532
                .attr('id', 'new_column_' + timestamp)
533
                .addClass('deletable')
534
                .insertBefore($(this).parent());
535
536
            $('<span></span>')
537
                .addClass('field_name')
538
                .dblclick(change_label)
539
                .html(field_name)
540
                .appendTo('#new_column_' + timestamp);
541
542
            // Input for changing the column name
543
            $('<input type="hidden" id="new_column_' + timestamp + '_input" name="midcom_helper_datamanager2_sortable_column[' + options.field_name + '][new_' + timestamp + ']" />')
544
                .addClass('field_name')
545
                .val(field_name)
546
                .appendTo($('#new_column_' + timestamp));
547
548
            // Insert a new column for each row
549
            $(this).parents(options.table_id).find('tbody tr, tfoot tr').each(function(i)
550
            {
551
                var row = $(this).attr('id');
552
553
                if (row)
554
                {
555
                    row = row.replace(/^row_/, '');
556
                }
557
                else
558
                {
559
                    row = '';
560
                }
561
562
                $('<td></td>')
563
                    .addClass('new_column_' + timestamp)
564
                    .appendTo($(this));
565
566
                $('<input type="text" />')
567
                    .addClass('column_field tabledata_widget_text')
568
                    .attr({
569
                        name: 'midcom_helper_datamanager2_type_tabledata[' + options.field_name + '][' + row + '][new_' + timestamp + ']',
570
                        id: 'midcom_helper_datamanager2_type_tabledata_' + options.field_name + '_new_' + timestamp + '_' + i
571
                    })
572
                    .appendTo($(this).find('td.new_column_' + timestamp));
573
            });
574
575
            // Recreate the sortable columns
576
            $(this).create_tablesorter_columns(options);
577
        })
578
        .appendTo($(this).find('thead th.add_column'));
579
};
580
581
$(document).ready(function()
582
{
583
    $('table.midcom_helper_datamanager2_tabledata_widget th span.allow_rename')
584
        .dblclick(change_label);
585
});
586