source: trunk/admin/themes/default/template/user_list.tpl @ 25928

Last change on this file since 25928 was 25928, checked in by plg, 7 years ago

feature 1668: hide "delete" link for protected users, hide "change username" and "email address" for guest

  • Property svn:eol-style set to LF
File size: 38.5 KB
Line 
1{combine_script id='common' load='footer' path='admin/themes/default/js/common.js'}
2
3{combine_script id='jquery.dataTables' load='footer' path='themes/default/js/plugins/jquery.dataTables.js'}
4{combine_css path="themes/default/js/plugins/datatables/css/jquery.dataTables.css"}
5
6{combine_script id='jquery.chosen' load='footer' path='themes/default/js/plugins/chosen.jquery.min.js'}
7{combine_css path="themes/default/js/plugins/chosen.css"}
8
9{combine_script id='jquery.ui.slider' require='jquery.ui' load='footer' path='themes/default/js/ui/minified/jquery.ui.slider.min.js'}
10{combine_css path="themes/default/js/ui/theme/jquery.ui.slider.css"}
11
12{footer_script}
13var selectedMessage_pattern = "{'%d of %d users selected'|translate|escape:javascript}";
14var selectedMessage_none = "{'No user selected of %d users'|translate|escape:javascript}";
15var selectedMessage_all = "{'All %d users are selected'|translate|escape:javascript}";
16var applyOnDetails_pattern = "{'on the %d selected users'|translate|escape:javascript}";
17var newUser_pattern = "✔ {'User %s added'|translate|escape:javascript}";
18var registeredOn_pattern = "{'Registered on %s, %s.'|translate|escape:javascript}";
19var lastVisit_pattern = "{'Last visit on %s, %s.'|translate|escape:javascript}";
20var missingConfirm = "{'You need to confirm deletion'|translate|escape:javascript}";
21var missingUsername = "{'Please, enter a login'|translate|escape:javascript}";
22
23var allUsers = [{$all_users}];
24var selection = [{$selection}];
25var pwg_token = "{$PWG_TOKEN}";
26
27var protectedUsers = [{$protected_users}];
28var guestUser = {$guest_user};
29
30var truefalse = {
31  true:"{'Yes'|translate}",
32  false:"{'No'|translate}",
33};
34{/footer_script}
35
36{footer_script}{literal}
37jQuery(document).ready(function() {
38  /**
39   * Add user
40   */
41  jQuery("#addUser").click(function() {
42    jQuery("#addUserForm").toggle();
43    jQuery("#showAddUser .infos").hide();
44    jQuery("input[name=username]").focus();
45    return false;
46  });
47
48  jQuery("#addUserClose").click(function() {
49    jQuery("#addUserForm").hide();
50    return false;
51  });
52
53  jQuery("#addUserForm").submit(function() {
54    jQuery.ajax({
55      url: "ws.php?format=json&method=pwg.users.add",
56      type:"POST",
57      data: jQuery(this).serialize(),
58      beforeSend: function() {
59        jQuery("#addUserForm .errors").hide();
60
61        if (jQuery("input[name=username]").val() == "") {
62          jQuery("#addUserForm .errors").html('✘ '+missingUsername).show();
63          return false;
64        }
65
66        jQuery("#addUserForm .loading").show();
67      },
68      success:function(data) {
69        oTable.fnDraw();
70        jQuery("#addUserForm .loading").hide();
71
72        var data = jQuery.parseJSON(data);
73        if (data.stat == 'ok') {
74          jQuery("#addUserForm input[type=text], #addUserForm input[type=password]").val("");
75
76          var new_user = data.result.users[0];
77          allUsers.push(parseInt(new_user.id));
78          jQuery("#showAddUser .infos").html(sprintf(newUser_pattern, new_user.username)).show();
79          checkSelection();
80
81          jQuery("#addUserForm").hide();
82        }
83        else {
84          jQuery("#addUserForm .errors").html('✘ '+data.message).show();
85        }
86      },
87      error:function(XMLHttpRequest, textStatus, errorThrows) {
88        jQuery("#addUserForm .loading").hide();
89      }
90    });
91
92    return false;
93  });
94
95  /**
96   * Table with users
97   */
98  /**
99   * find the key from a value in the startStopValues array
100   */
101  function getSliderKeyFromValue(value, values) {
102    for (var key in values) {
103      if (values[key] >= value) {
104        return key;
105      }
106    }
107    return 0;
108  }
109
110  var recent_period_values = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,25,30,40,50,60,80,99];
111
112  function getRecentPeriodInfoFromIdx(idx) {
113    return sprintf(
114      "{/literal}{'%d days'|@translate}{literal}",
115      recent_period_values[idx]
116    );
117  }
118
119  var nb_image_page_values = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,35,40,45,50,60,70,80,90,100,200,300,500,999];
120
121  function getNbImagePageInfoFromIdx(idx) {
122    return sprintf(
123      "{/literal}{'%d photos per page'|@translate}{literal}",
124      nb_image_page_values[idx]
125    );
126  }
127
128  /* Formating function for row details */
129  function fnFormatDetails(oTable, nTr) {
130    var userId = oTable.fnGetData(nTr)[0];
131    console.log("userId = "+userId);
132    var sOut = null;
133
134    jQuery.ajax({
135      url: "ws.php?format=json&method=pwg.users.getList",
136      type:"POST",
137      data: {
138        user_id: userId,
139        display: "all",
140      },
141      success:function(data) {
142        jQuery("#user"+userId+" .loading").hide();
143
144        var data = jQuery.parseJSON(data);
145        if (data.stat == 'ok') {
146          var user = data.result.users[0];
147
148          var userDetails = '<form>';
149          userDetails += '<div class="userActions">';
150
151          if (parseInt(userId) != guestUser) {
152            userDetails += '<span class="changePasswordDone infos" style="display:none">&#x2714; {/literal}{'Password updated'|translate|escape:javascript}{literal}</span>';
153            userDetails += '<span class="changePassword" style="display:none">{/literal}{'New password'|translate}{literal} <input type="text"> <a href="#" class="buttonLike updatePassword"><img src="themes/default/images/ajax-loader-small.gif" style="margin-bottom:-1px;margin-left:1px;display:none;"><span class="text">{/literal}{'Submit'|translate|escape:javascript}{literal}</span></a> <a href="#" class="cancel">{/literal}{'Cancel'|translate|escape:javascript}{literal}</a></span>';
154            userDetails += '<a class="icon-key changePasswordOpen" href="#">{/literal}{'Change password'|translate|escape:javascript}{literal}</a>';
155            userDetails += '<br>';
156          }
157
158          userDetails += '<a target="_blank" href="admin.php?page=user_perm&amp;user_id='+userId+'" class="icon-lock">{/literal}{'Permissions'|translate|escape:javascript}{literal}</a>';
159
160          if (protectedUsers.indexOf(parseInt(userId)) == -1) {
161            userDetails += '<br><span class="userDelete"><img class="loading" src="themes/default/images/ajax-loader-small.gif" style="display:none;"><a href="#" class="icon-trash" data-user_id="'+userId+'">{/literal}{'Delete'|translate|escape:javascript}{literal}</a></span>';
162          }
163
164          userDetails += '</div>';
165
166          userDetails += '<span class="changeUsernameOpen"><strong class="username">'+user.username+'</strong>';
167
168          if (parseInt(userId) != guestUser) {
169            userDetails += ' <a href="#" class="icon-pencil">{/literal}{'Change username'|translate|escape:javascript}{literal}</a></span>';
170            userDetails += '<span class="changeUsername" style="display:none">';
171            userDetails += '<input type="text"> <a href="#" class="buttonLike updateUsername"><img src="themes/default/images/ajax-loader-small.gif" style="margin-bottom:-1px;margin-left:1px;display:none;"><span class="text">{/literal}{'Submit'|translate}{literal}</span></a> <a href="#" class="cancel">{/literal}{'Cancel'|translate|escape:javascript}{literal}</a>';
172          }
173
174          userDetails += '</span>';
175
176          userDetails += '<div class="userStats">';
177          userDetails += sprintf(registeredOn_pattern, user.registration_date_string, user.registration_date_since);
178
179          if (typeof user.last_visit != 'undefined') {
180            userDetails += '<br>'+sprintf(lastVisit_pattern, user.last_visit_string, user.last_visit_since);
181          }
182
183          userDetails += '</div>';
184          userDetails += '<div class="userPropertiesContainer">';
185          userDetails += '<input type="hidden" name="user_id" value="'+user.id+'">';
186          userDetails += '<div class="userPropertiesSet">';
187          userDetails += '<div class="userPropertiesSetTitle">{/literal}{'Properties'|translate}{literal}</div>';
188
189          userDetails += '<div class="userProperty"><strong>{/literal}{'Email address'|translate}{literal}</strong>';
190          userDetails += '<br>';
191          if (parseInt(userId) != guestUser) {
192            userDetails += '<input name="email" type="text" value="'+ (user.email||'') +'">';
193          }
194          else {
195            userDetails += '{/literal}{'N/A'|translate}{literal}';
196          }
197          userDetails += '</div>';
198
199          userDetails += '<div class="userProperty"><strong>{/literal}{'Status'|translate}{literal}</strong>';
200          userDetails += '<br><select name="status">';
201          jQuery("#action select[name=status] option").each(function() {
202            var selected = '';
203            if (user.status == jQuery(this).val()) {
204              selected = ' selected="selected"';
205            }
206            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
207          });
208          userDetails += '</select></div>';
209
210          userDetails += '<div class="userProperty"><strong>{/literal}{'Privacy level'|translate}{literal}</strong>';
211          userDetails += '<br><select name="level">';
212          jQuery("#action select[name=level] option").each(function() {
213            var selected = '';
214            if (user.level == jQuery(this).val()) {
215              selected = ' selected="selected"';
216            }
217            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
218          });
219          userDetails += '</select></div>';
220
221          var checked = '';
222          if (user.enabled_high == 'true') {
223            checked = ' checked="checked"';
224          }
225          userDetails += '<div class="userProperty"><label><input type="checkbox" name="enabled_high"'+checked+'> <strong>{/literal}{'High definition enabled'|translate}{literal}</strong></label>';
226          userDetails += '</div>';
227
228          userDetails += '<div class="userProperty"><strong>{/literal}{'Groups'|translate}{literal}</strong>';
229          userDetails += '<br><select multiple class="chzn-select" style="width:340px;" name="group_id[]">';
230          jQuery("#action select[name=associate] option").each(function() {
231            var selected = '';
232            if (user.groups.indexOf( parseInt(jQuery(this).val()) ) != -1) {
233              selected = ' selected="selected"';
234            }
235            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
236          });
237          userDetails += '</select></div>';
238          // userDetails += '<br>'+user.groups.join(",")+'</div>';
239
240          userDetails += '</div><div class="userPropertiesSet userPrefs">';
241          userDetails += '<div class="userPropertiesSetTitle">{/literal}{'Preferences'|translate}{literal}</div>';
242
243          userDetails += '<div class="userProperty"><strong class="nb_image_page_infos"></strong>';
244          userDetails += '<div class="nb_image_page"></div>';
245          userDetails += '<input type="hidden" name="nb_image_page" value="'+user.nb_image_page+'">';
246          userDetails += '</div>';
247
248          userDetails += '<div class="userProperty"><strong>{/literal}{'Theme'|translate|escape:javascript}{literal}</strong>';
249          userDetails += '<br><select name="theme">';
250          jQuery("#action select[name=theme] option").each(function() {
251            var selected = '';
252            if (user.theme == jQuery(this).val()) {
253              selected = ' selected="selected"';
254            }
255            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
256          });
257          userDetails += '</select></div>';
258
259          userDetails += '<div class="userProperty"><strong>{/literal}{'Language'|translate}{literal}</strong>';
260          userDetails += '<br><select name="language">';
261          jQuery("#action select[name=language] option").each(function() {
262            var selected = '';
263            if (user.language == jQuery(this).val()) {
264              selected = ' selected="selected"';
265            }
266            userDetails += '<option value="'+jQuery(this).val()+'"'+selected+'>'+jQuery(this).html()+'</option>';
267          });
268          userDetails += '</select></div>';
269
270          userDetails += '<div class="userProperty"><strong>{/literal}{'Recent period'|translate}{literal}</strong> <span class="recent_period_infos"></span>';
271          userDetails += '<div class="recent_period"></div>';
272          userDetails += '<input type="hidden" name="recent_period" value="'+user.recent_period+'">';
273          userDetails += '</div>';
274
275          var checked = '';
276          if (user.expand == 'true') {
277            checked = ' checked="checked"';
278          }
279          userDetails += '<div class="userProperty"><label><input type="checkbox" name="expand"'+checked+'> <strong>{/literal}{'Expand all albums'|translate}{literal}</strong></label>';
280          userDetails += '</div>';
281
282          var checked = '';
283          if (user.show_nb_comments == 'true') {
284            checked = ' checked="checked"';
285          }
286          userDetails += '<div class="userProperty"><label><input type="checkbox" name="show_nb_comments"'+checked+'> <strong>{/literal}{'Show number of comments'|translate}{literal}</strong></label>';
287          userDetails += '</div>';
288
289          var checked = '';
290          if (user.show_nb_hits == 'true') {
291            checked = ' checked="checked"';
292          }
293          userDetails += '<div class="userProperty"><label><input type="checkbox" name="show_nb_hits"'+checked+'> <strong>{/literal}{'Show number of hits'|translate}{literal}</strong></label>';
294          userDetails += '</div>';
295          userDetails += '</div>';
296          userDetails += '<div style="clear:both"></div></div>';
297
298          userDetails += '<span class="infos propertiesUpdateDone" style="display:none">&#x2714; ';
299          userDetails += sprintf("{/literal}{'User %s updated'|translate|escape:javascript}{literal}", user.username);
300          userDetails += '</span>';
301          userDetails += '<input type="submit" value="{/literal}{'Update user'|translate|escape:javascript}{literal}" style="display:none;" data-user_id="'+userId+'">';
302          userDetails += '<img class="submitWait" src="themes/default/images/ajax-loader-small.gif" style="display:none">'
303          userDetails += '</form>';
304
305          jQuery("#user"+userId).append(userDetails);
306          jQuery(".chzn-select").chosen();
307
308          /* nb_image_page slider */
309          var nb_image_page_init = getSliderKeyFromValue(jQuery('input[name=nb_image_page]').val(), nb_image_page_values);
310         
311          jQuery('#user'+userId+' .nb_image_page_infos').html(getNbImagePageInfoFromIdx(nb_image_page_init));
312         
313          jQuery('#user'+userId+' .nb_image_page').slider({
314            range: "min",
315            min: 0,
316            max: nb_image_page_values.length - 1,
317            value: nb_image_page_init,
318            slide: function( event, ui ) {
319              jQuery('#user'+userId+' .nb_image_page_infos').html(getNbImagePageInfoFromIdx(ui.value));
320            },
321            stop: function( event, ui ) {
322              jQuery('#user'+userId+' input[name=nb_image_page]').val(nb_image_page_values[ui.value]).trigger('change');
323            }
324          });
325
326          /* recent_period slider */
327          var recent_period_init = getSliderKeyFromValue(jQuery('input[name=recent_period]').val(), recent_period_values);
328          jQuery('#user'+userId+' .recent_period_infos').html(getRecentPeriodInfoFromIdx(recent_period_init));
329         
330          jQuery('#user'+userId+' .recent_period').slider({
331            range: "min",
332            min: 0,
333            max: recent_period_values.length - 1,
334            value: recent_period_init,
335            slide: function( event, ui ) {
336              jQuery('#user'+userId+' .recent_period_infos').html(getRecentPeriodInfoFromIdx(ui.value));
337            },
338            stop: function( event, ui ) {
339              jQuery('#user'+userId+' input[name=recent_period]').val(recent_period_values[ui.value]).trigger('change');
340            }
341          });
342        }
343        else {
344          console.log('error loading user details');
345        }
346      },
347      error:function(XMLHttpRequest, textStatus, errorThrows) {
348        console.log('technical error loading user details');
349      }
350    });
351 
352    return '<div id="user'+userId+'" class="userProperties"><img class="loading" src="themes/default/images/ajax-loader-small.gif"></div>';
353  }
354
355  /* change password */
356  jQuery(document).on('click', '.changePasswordOpen',  function() {
357    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
358
359    jQuery(this).hide();
360    jQuery('#user'+userId+' .changePasswordDone').hide();
361    jQuery('#user'+userId+' .changePassword').show();
362    jQuery('#user'+userId+' .changePassword input[type=text]').focus();
363
364    return false;
365  });
366
367  jQuery(document).on('click', '.changePassword a.updatePassword',  function() {
368    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
369
370    jQuery('#user'+userId+' .changePassword a .text').hide();
371    jQuery('#user'+userId+' .changePassword a img').show();
372
373    jQuery.ajax({
374      url: "ws.php?format=json&method=pwg.users.setInfo",
375      type:"POST",
376      data: {
377        user_id:userId,
378        password: jQuery('#user'+userId+' .changePassword input[type=text]').val()
379      },
380      beforeSend: function() {
381        jQuery('#user'+userId+' .changePassword input[type=text]').val("");
382      },
383      success:function(data) {
384        jQuery('#user'+userId+' .changePassword a .text').show();
385        jQuery('#user'+userId+' .changePassword a img').hide();
386        jQuery('#user'+userId+' .changePassword').hide();
387        jQuery('#user'+userId+' .changePasswordOpen').show();
388        jQuery('#user'+userId+' .changePasswordDone').show();
389      },
390      error:function(XMLHttpRequest, textStatus, errorThrows) {
391      }
392    });
393
394    return false;
395  });
396
397  jQuery(document).on('click', '.changePassword a.cancel',  function() {
398    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
399
400    jQuery('#user'+userId+' .changePassword').hide();
401    jQuery('#user'+userId+' .changePasswordOpen').show();
402
403    return false;
404  });
405
406  /* change username */
407  jQuery(document).on('click', '.changeUsernameOpen a',  function() {
408    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
409    var username = jQuery('#user'+userId+' .username').html();
410
411    jQuery('#user'+userId+' .changeUsernameOpen').hide();
412    jQuery('#user'+userId+' .changeUsername').show();
413    jQuery('#user'+userId+' .changeUsername input[type=text]').val(username).focus();
414
415    return false;
416  });
417
418  jQuery(document).on('click', 'a.updateUsername',  function() {
419    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
420
421    jQuery('#user'+userId+' .changeUsername a .text').hide();
422    jQuery('#user'+userId+' .changeUsername a img').show();
423
424    jQuery.ajax({
425      url: "ws.php?format=json&method=pwg.users.setInfo",
426      type:"POST",
427      data: {
428        user_id:userId,
429        username: jQuery('#user'+userId+' .changeUsername input[type=text]').val()
430      },
431      success:function(data) {
432        jQuery('#user'+userId+' .changeUsername a .text').show();
433        jQuery('#user'+userId+' .changeUsername a img').hide();
434        jQuery('#user'+userId+' .changeUsername').hide();
435        jQuery('#user'+userId+' .changeUsernameOpen').show();
436
437        var data = jQuery.parseJSON(data);
438        jQuery('#user'+userId+' .username').html(data.result.users[0].username);
439      },
440      error:function(XMLHttpRequest, textStatus, errorThrows) {
441      }
442    });
443
444    return false;
445  });
446
447  jQuery(document).on('click', '.changeUsername a.cancel',  function() {
448    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
449
450    jQuery('#user'+userId+' .changeUsername').hide();
451    jQuery('#user'+userId+' .changeUsernameOpen').show();
452
453    return false;
454  });
455
456  /* display the "save" button when a field changes */
457  jQuery(document).on('change', '.userProperties input, .userProperties select',  function() {
458    var userId = jQuery(this).parentsUntil('form').parent().find('input[name=user_id]').val();
459
460    jQuery('#user'+userId+' input[type=submit]').show();
461    jQuery('#user'+userId+' .propertiesUpdateDone').hide();
462  });
463
464  /* delete user */
465  jQuery(document).on('click', '.userDelete a',  function() {
466    if (!confirm("{/literal}{'Are you sure?'|translate|escape:javascript}{literal}")) {
467      return false;
468    }
469
470    var userId = jQuery(this).data('user_id');
471    var username = jQuery('#user'+userId+' .username').html();
472
473    jQuery.ajax({
474      url: "ws.php?format=json&method=pwg.users.delete",
475      type:"POST",
476      data: {
477        user_id:userId,
478        pwg_token:pwg_token
479      },
480      beforeSend: function() {
481        jQuery('#user'+userId+' .userDelete .loading').show();
482      },
483      success:function(data) {
484        oTable.fnDraw();
485        jQuery('#showAddUser .infos').html('&#x2714; User '+username+' deleted').show();
486      },
487      error:function(XMLHttpRequest, textStatus, errorThrows) {
488        jQuery('#user'+userId+' .userDelete .loading').hide();
489      }
490    });
491
492    return false;
493  });
494
495  jQuery(document).on('click', '.userProperties input[type=submit]',  function() {
496    var userId = jQuery(this).data('user_id');
497
498    var formData = jQuery('#user'+userId+' form').serialize();
499
500    if (jQuery('#user'+userId+' form select[name="group_id[]"] option:selected').length == 0) {
501      formData += '&group_id=-1';
502    }
503
504    if (!jQuery('#user'+userId+' form input[name=enabled_high]').is(':checked')) {
505      formData += '&enabled_high=false';
506    }
507
508    if (!jQuery('#user'+userId+' form input[name=expand]').is(':checked')) {
509      formData += '&expand=false';
510    }
511
512    if (!jQuery('#user'+userId+' form input[name=show_nb_hits]').is(':checked')) {
513      formData += '&show_nb_hits=false';
514    }
515
516    if (!jQuery('#user'+userId+' form input[name=show_nb_comments]').is(':checked')) {
517      formData += '&show_nb_comments=false';
518    }
519
520    jQuery.ajax({
521      url: "ws.php?format=json&method=pwg.users.setInfo",
522      type:"POST",
523      data: formData,
524      beforeSend: function() {
525        jQuery('#user'+userId+' .submitWait').show();
526      },
527      success:function(data) {
528        jQuery('#user'+userId+' .submitWait').hide();
529        jQuery('#user'+userId+' input[type=submit]').hide();
530        jQuery('#user'+userId+' .propertiesUpdateDone').show();
531      },
532      error:function(XMLHttpRequest, textStatus, errorThrows) {
533        jQuery('#user'+userId+' .submitWait').hide();
534      }
535    });
536
537    return false;
538  });
539
540  /* Add event listener for opening and closing details
541   * Note that the indicator for showing which row is open is not controlled by DataTables,
542   * rather it is done here
543   */
544  jQuery(document).on('click', '#userList tbody td .openUserDetails',  function() {
545    var nTr = this.parentNode.parentNode;
546    if (jQuery(this).hasClass('icon-angle-circled-up')) {
547      /* This row is already open - close it */
548      jQuery(this).removeClass('icon-angle-circled-up').addClass('icon-angle-circled-down').attr('title', 'Open user details');
549      oTable.fnClose( nTr );
550    }
551    else {
552      /* Open this row */
553      jQuery(this).removeClass('icon-angle-circled-down').addClass('icon-angle-circled-up').attr('title', 'Close user details');
554      oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
555    }
556  });
557
558
559  /* first column must be prefixed with the open/close icon */
560  var aoColumns = [
561    {
562      'bVisible':false
563    },
564    {
565      "mRender": function(data, type, full) {
566        return '<span title="Open user details" class="icon-angle-circled-down openUserDetails"></span> <label><input type="checkbox" data-user_id="'+full[0]+'"> '+data+'</label>';
567      }
568    }
569  ];
570
571  for (i=2; i<jQuery("#userList thead tr th").length; i++) {
572    aoColumns.push(null);
573  }
574
575  var oTable = jQuery('#userList').dataTable({
576    "iDisplayLength": 10,
577    "bDeferRender": true,
578    "bProcessing": true,
579    "bServerSide": true,
580                "sServerMethod": "POST",
581    "sAjaxSource": "admin/user_list_backend.php",
582    "oLanguage": {
583      "sProcessing": "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}",
584      "sLengthMenu": sprintf("{/literal}{'Show %s users'|translate|escape:'javascript'}{literal}", '_MENU_'),
585      "sZeroRecords": "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}",
586      "sInfo": sprintf("{/literal}{'Showing %s to %s of %s users'|translate|escape:'javascript'}{literal}", '_START_', '_END_', '_TOTAL_'),
587      "sInfoEmpty": "{/literal}{'No matching user found'|translate|escape:'javascript'}{literal}",
588      "sInfoFiltered": sprintf("{/literal}{'(filtered from %s total users)'|translate|escape:'javascript'}{literal}", '_MAX_'),
589      "sSearch": '<span class="icon-search"></span>'+"{/literal}{'Search'|translate|escape:'javascript'}{literal}",
590      "sLoadingRecords": "{/literal}{'Loading...'|translate|escape:'javascript'}{literal}",
591      "oPaginate": {
592          "sFirst":    "{/literal}{'First'|translate|escape:'javascript'}{literal}",
593          "sPrevious": '← '+"{/literal}{'Previous'|translate|escape:'javascript'}{literal}",
594          "sNext":     "{/literal}{'Next'|translate|escape:'javascript'}{literal}"+' →',
595          "sLast":     "{/literal}{'Last'|translate|escape:'javascript'}{literal}",
596      }
597    },
598    "fnDrawCallback": function( oSettings ) {
599      jQuery("#userList input[type=checkbox]").each(function() {
600        var user_id = jQuery(this).data("user_id");
601        jQuery(this).prop('checked', (selection.indexOf(user_id) != -1));
602      });
603    },
604    "aoColumns": aoColumns
605  });
606
607  /**
608   * Selection management
609   */
610  function checkSelection() {
611    if (selection.length > 0) {
612      jQuery("#forbidAction").hide();
613      jQuery("#permitAction").show();
614
615      jQuery("#applyOnDetails").text(
616        sprintf(
617          applyOnDetails_pattern,
618          selection.length
619        )
620      );
621
622      if (selection.length == allUsers.length) {
623        jQuery("#selectedMessage").text(
624          sprintf(
625            selectedMessage_all,
626            allUsers.length
627          )
628        );
629      }
630      else {
631        jQuery("#selectedMessage").text(
632          sprintf(
633            selectedMessage_pattern,
634            selection.length,
635            allUsers.length
636          )
637        );
638      }
639    }
640    else {
641      jQuery("#forbidAction").show();
642      jQuery("#permitAction").hide();
643
644      jQuery("#selectedMessage").text(
645        sprintf(
646          selectedMessage_none,
647          allUsers.length
648        )
649      );
650    }
651
652    jQuery("#applyActionBlock .infos").hide();
653  }
654
655  jQuery(document).on('change', '#userList input[type=checkbox]',  function() {
656    var user_id = jQuery(this).data("user_id");
657
658    array_delete(selection, user_id);
659
660    if (jQuery(this).is(":checked")) {
661      selection.push(user_id);
662    }
663
664    checkSelection();
665  });
666
667  jQuery("#selectAll").click(function () {
668    selection = allUsers;
669    jQuery("#userList input[type=checkbox]").prop('checked', true);
670    checkSelection();
671    return false;
672  });
673
674  jQuery("#selectNone").click(function () {
675    selection = [];
676    jQuery("#userList input[type=checkbox]").prop('checked', false);
677    checkSelection();
678    return false;
679  });
680
681  jQuery("#selectInvert").click(function () {
682    var newSelection = [];
683    for(var i in allUsers)
684    {
685      if (selection.indexOf(allUsers[i]) == -1) {
686        newSelection.push(allUsers[i]);
687      }
688    }
689    selection = newSelection;
690
691    jQuery("#userList input[type=checkbox]").each(function() {
692      var user_id = jQuery(this).data("user_id");
693      jQuery(this).prop('checked', (selection.indexOf(user_id) != -1));
694    });
695
696    checkSelection();
697    return false;
698  });
699
700  /**
701   * Action management
702   */
703  jQuery("[id^=action_]").hide();
704 
705  jQuery("select[name=selectAction]").change(function () {
706    jQuery("#applyActionBlock .infos").hide();
707
708    jQuery("[id^=action_]").hide();
709
710    jQuery("#action_"+$(this).prop("value")).show();
711 
712    if (jQuery(this).val() != -1) {
713      jQuery("#applyActionBlock").show();
714    }
715    else {
716      jQuery("#applyActionBlock").hide();
717    }
718  });
719
720  jQuery("#permitAction input, #permitAction select").click(function() {
721    jQuery("#applyActionBlock .infos").hide();
722  });
723
724  jQuery("#applyAction").click(function() {
725    var action = jQuery("select[name=selectAction]").prop("value");
726    var method = 'pwg.users.setInfo';
727    var data = {
728      user_id: selection
729    };
730
731    switch (action) {
732      case 'delete':
733        if (!jQuery("input[name=confirm_deletion]").is(':checked')) {
734          alert(missingConfirm);
735          return false;
736        }
737        method = 'pwg.users.delete';
738        data.pwg_token = pwg_token;
739        break;
740      case 'group_associate':
741        method = 'pwg.groups.addUser';
742        data.group_id = jQuery("select[name=associate]").prop("value");
743        break;
744      case 'group_dissociate':
745        method = 'pwg.groups.deleteUser';
746        data.group_id = jQuery("select[name=dissociate]").prop("value");
747        break;
748      case 'status':
749        data.status = jQuery("select[name=status]").prop("value");
750        break;
751      case 'enabled_high':
752        data.enabled_high = jQuery("input[name=enabled_high]:checked").val();
753        break;
754      case 'level':
755        data.level = jQuery("select[name=level]").val();
756        break;
757      case 'nb_image_page':
758        data.nb_image_page = jQuery("input[name=nb_image_page]").val();
759        break;
760      case 'theme':
761        data.theme = jQuery("select[name=theme]").val();
762        break;
763      case 'language':
764        data.language = jQuery("select[name=language]").val();
765        break;
766      case 'recent_period':
767        data.recent_period = jQuery("input[name=recent_period]").val();
768        break;
769      case 'expand':
770        data.expand = jQuery("input[name=expand]:checked").val();
771        break;
772      case 'show_nb_comments':
773        data.show_nb_comments = jQuery("input[name=show_nb_comments]:checked").val();
774        break;
775      case 'show_nb_hits':
776        data.show_nb_hits = jQuery("input[name=show_nb_hits]:checked").val();
777        break;
778      default:
779        alert("Unexpected action");
780        return false;
781    }
782
783    jQuery.ajax({
784      url: "ws.php?format=json&method="+method,
785      type:"POST",
786      data: data,
787      beforeSend: function() {
788        jQuery("#applyActionLoading").show();
789      },
790      success:function(data) {
791        oTable.fnDraw();
792        jQuery("#applyActionLoading").hide();
793        jQuery("#applyActionBlock .infos").show();
794
795        if (action == 'delete') {
796          var allUsers_new = [];
797          for(var i in allUsers)
798          {
799            if (selection.indexOf(allUsers[i]) == -1) {
800              allUsers_new.push(allUsers[i]);
801            }
802          }
803          allUsers = allUsers_new;
804          console.log('allUsers_new.length = '+allUsers_new.length);
805          selection = [];
806          checkSelection();
807        }
808      },
809      error:function(XMLHttpRequest, textStatus, errorThrows) {
810        jQuery("#applyActionLoading").hide();
811      }
812    });
813
814    return false;
815  });
816
817});
818{/literal}{/footer_script}
819
820{literal}
821<style>
822.dataTables_wrapper, .dataTables_info {clear:none;}
823table.dataTable {clear:right;padding-top:10px;}
824.dataTable td img {margin-bottom: -6px;margin-left: -6px;}
825.paginate_enabled_previous, .paginate_enabled_previous:hover, .paginate_disabled_previous, .paginate_enabled_next, .paginate_enabled_next:hover, .paginate_disabled_next {background:none;}
826.paginate_enabled_previous, .paginate_enabled_next {color:#005E89 !important;}
827.paginate_enabled_previous:hover, .paginate_enabled_next:hover {color:#D54E21 !important; text-decoration:underline !important;}
828
829.paginate_disabled_next, .paginate_enabled_next {padding-right:3px;}
830.bulkAction {margin-top:10px;}
831#addUserForm p {margin-left:0;}
832#applyActionBlock .actionButtons {margin-left:0;}
833span.infos, span.errors {background-image:none; padding:2px 5px; margin:0;border-radius:5px;}
834
835.userStats {margin-top:10px;}
836.recent_period_infos {margin-left:10px;}
837.nb_image_page, .recent_period {width:340px;margin-top:5px;}
838</style>
839{/literal}
840
841<div class="titrePage">
842  <h2>{'User list'|@translate}</h2>
843</div>
844
845<p class="showCreateAlbum" id="showAddUser">
846  <a href="#" id="addUser" class="icon-plus-circled">{'Add a user'|translate}</a>
847  <span class="infos" style="display:none"></span>
848</p>
849
850<form id="addUserForm" style="display:none" method="post" name="add_user" action="{$F_ADD_ACTION}">
851  <fieldset>
852    <legend>{'Add a user'|@translate}</legend>
853
854    <p>
855      <strong>{'Username'|translate}</strong><br>
856      <input type="text" name="username" maxlength="50" size="20">
857    </p>
858
859    <p>
860      <strong>{'Password'|translate}</strong><br>
861      <input type="{if $Double_Password}password{else}text{/if}" name="password">
862    </p>
863   
864{if $Double_Password}
865    <p>
866      <strong>{'Confirm Password'|@translate}</strong><br>
867      <input type="password" name="password_confirm">
868    </p>
869{/if}
870
871    <p>
872      <strong>{'Email address'|@translate}</strong><br>
873      <input type="text" name="email">
874    </p>
875
876    <p>
877      <label><input type="checkbox" name="send_password_by_mail"> <strong>{'Send connection settings by email'|@translate}</strong></label>
878    </p>
879
880    <p class="actionButtons">
881      <input class="submit" name="submit_add" type="submit" value="{'Submit'|@translate}">
882      <a href="#" id="addUserClose">{'Cancel'|@translate}</a>
883      <span class="loading" style="display:none"><img src="themes/default/images/ajax-loader-small.gif"></span>
884      <span class="errors" style="display:none"></span>
885    </p>
886  </fieldset>
887</form>
888
889<form method="post" name="preferences" action="">
890
891<table id="userList">
892  <thead>
893    <tr>
894      <th>id</th>
895      <th>{'Username'|@translate}</th>
896      <th>{'Status'|@translate}</th>
897      <th>{'Email address'|@translate}</th>
898      <th>{'registration date'|@translate}</th>
899    </tr>
900  </thead>
901</table>
902
903<div style="clear:right"></div>
904
905<p class="checkActions">
906  {'Select:'|@translate}
907  <a href="#" id="selectAll">{'All'|@translate}</a>,
908  <a href="#" id="selectNone">{'None'|@translate}</a>,
909  <a href="#" id="selectInvert">{'Invert'|@translate}</a>
910
911  <span id="selectedMessage"></span>
912</p>
913
914<fieldset id="action">
915  <legend>{'Action'|@translate}</legend>
916
917  <div id="forbidAction"{if count($selection) != 0} style="display:none"{/if}>{'No user selected, no action possible.'|@translate}</div>
918  <div id="permitAction"{if count($selection) == 0} style="display:none"{/if}>
919
920    <select name="selectAction">
921      <option value="-1">{'Choose an action'|@translate}</option>
922      <option disabled="disabled">------------------</option>
923      <option value="delete" class="icon-trash">{'Delete selected users'|@translate}</option>
924      <option value="status">{'Status'|@translate}</option>
925      <option value="group_associate">{'associate to group'|translate}</option>
926      <option value="group_dissociate">{'dissociate from group'|@translate}</option>
927      <option value="enabled_high">{'High definition enabled'|@translate}</option>
928      <option value="level">{'Privacy level'|@translate}</option>
929      <option value="nb_image_page">{'Number of photos per page'|@translate}</option>
930      <option value="theme">{'Theme'|@translate}</option>
931      <option value="language">{'Language'|@translate}</option>
932      <option value="recent_period">{'Recent period'|@translate}</option>
933      <option value="expand">{'Expand all albums'|@translate}</option>
934{if $ACTIVATE_COMMENTS}
935      <option value="show_nb_comments">{'Show number of comments'|@translate}</option>
936{/if}
937      <option value="show_nb_hits">{'Show number of hits'|@translate}</option>
938    </select>
939
940    {* delete *}
941    <div id="action_delete" class="bulkAction">
942      <p><label><input type="checkbox" name="confirm_deletion" value="1"> {'Are you sure?'|@translate}</label></p>
943    </div>
944
945    {* status *}
946    <div id="action_status" class="bulkAction">
947      <select name="status">
948        {html_options options=$pref_status_options selected=$pref_status_selected}
949      </select>
950    </div>
951
952    {* group_associate *}
953    <div id="action_group_associate" class="bulkAction">
954      {html_options name=associate options=$association_options selected=$associate_selected}
955    </div>
956
957    {* group_dissociate *}
958    <div id="action_group_dissociate" class="bulkAction">
959      {html_options name=dissociate options=$association_options selected=$dissociate_selected}
960    </div>
961
962    {* enabled_high *}
963    <div id="action_enabled_high" class="bulkAction">
964      <label><input type="radio" name="enabled_high" value="true">{'Yes'|@translate}</label>
965      <label><input type="radio" name="enabled_high" value="false" checked="checked">{'No'|@translate}</label>
966    </div>
967
968    {* level *}
969    <div id="action_level" class="bulkAction">
970      <select name="level" size="1">
971        {html_options options=$level_options selected=$level_selected}
972      </select>
973    </div>
974
975    {* nb_image_page *}
976    <div id="action_nb_image_page" class="bulkAction">
977      <input size="4" maxlength="3" type="text" name="nb_image_page" value="{$NB_IMAGE_PAGE}">
978    </div>
979
980    {* theme *}
981    <div id="action_theme" class="bulkAction">
982      <select name="theme" size="1">
983        {html_options options=$theme_options selected=$theme_selected}
984      </select>
985    </div>
986
987    {* language *}
988    <div id="action_language" class="bulkAction">
989      <select name="language" size="1">
990        {html_options options=$language_options selected=$language_selected}
991      </select>
992    </div>
993
994    {* recent_period *}
995    <div id="action_recent_period" class="bulkAction">
996      <input type="text" size="3" maxlength="2" name="recent_period" value="{$RECENT_PERIOD}">
997    </div>
998
999    {* expand *}
1000    <div id="action_expand" class="bulkAction">
1001      <label><input type="radio" name="expand" value="true">{'Yes'|@translate}</label>
1002      <label><input type="radio" name="expand" value="false" checked="checked">{'No'|@translate}</label>
1003    </div>
1004
1005    {* show_nb_comments *}
1006    <div id="action_show_nb_comments" class="bulkAction">
1007      <label><input type="radio" name="show_nb_comments" value="true">{'Yes'|@translate}</label>
1008      <label><input type="radio" name="show_nb_comments" value="false" checked="checked">{'No'|@translate}</label>
1009    </div>
1010
1011    {* show_nb_hits *}
1012    <div id="action_show_nb_hits" class="bulkAction">
1013      <label><input type="radio" name="show_nb_hits" value="true">{'Yes'|@translate}</label>
1014      <label><input type="radio" name="show_nb_hits" value="false" checked="checked">{'No'|@translate}</label>
1015    </div>
1016
1017    <p id="applyActionBlock" style="display:none" class="actionButtons">
1018      <input id="applyAction" class="submit" type="submit" value="{'Apply action'|@translate}" name="submit"> <span id="applyOnDetails"></span>
1019      <span id="applyActionLoading" style="display:none"><img src="themes/default/images/ajax-loader-small.gif"></span>
1020      <span class="infos" style="display:none">&#x2714; {'Users modified'|translate}</span>
1021    </p>
1022
1023  </div> {* #permitAction *}
1024</fieldset>
1025
1026</form>
Note: See TracBrowser for help on using the repository browser.