source: extensions/AMetaData/admin/amd_metadata_personnal.tpl @ 16007

Revision 16007, 22.5 KB checked in by grum, 7 years ago (diff)

feature:2637- compatibility with Piwigo 2.4

Line 
1{combine_script id="jquery.ui" require='jquery' path="themes/default/js/ui/jquery.ui.core.js"}
2{combine_script id="jquery.ui.widget" require='jquery.ui' path="themes/default/js/ui/jquery.ui.widget.js"}
3{combine_script id="jquery.ui.mouse" require='jquery.ui.widget' path="themes/default/js/ui/jquery.ui.mouse.js"}
4{combine_script id="jquery.ui.position" require='jquery.ui.widget' path="themes/default/js/ui/jquery.ui.position.js"}
5{combine_script id="jquery.ui.sortable" require='jquery.ui.widget' path="themes/default/js/ui/jquery.ui.sortable.js"}
6{combine_script id="jquery.ui.dialog" require='jquery.ui.widget' src="themes/default/js/ui/jquery.ui.dialog.js"}
7
8{combine_script id="gpc.external.interface" path="plugins/GrumPluginClasses/js/external/interface/interface.js" require="jquery.ui"}
9{combine_script id="gpc.external.inestedsortable" path="plugins/GrumPluginClasses/js/external/inestedsortable.pack.js" require="gpc.external.interface"}
10{combine_script id="tagListSelector" path="plugins/AMetaData/js/tagListSelector.js" require="jquery.ui"}
11
12
13{literal}
14<script type="text/javascript">
15  var udm, tls;
16
17
18  function userDefManage ()
19  {
20    var options = {
21      numId:'',
22      newRuleId:1,
23      optimalHeight:0,
24    }
25
26    /**
27     * initialize the page
28     */
29    this.init = function ()
30    {
31      computedHeight=$(window).height()-100;
32      $('#iDialogEdit')
33        .dialog(
34          {
35            autoOpen:false,
36            width:900,
37            height:computedHeight,
38            modal: true,
39            dialogClass: 'gcBgTabSheet gcBorder',
40            title: '{/literal}{"g003_personnal_metadata"|@translate}{literal}',
41            buttons:
42              {
43                '{/literal}{"g003_ok"|@translate}{literal}':
44                  function()
45                  {
46                    if(checkValidity()) doUpdate();
47                  },
48                '{/literal}{"g003_cancel"|@translate}{literal}':
49                  function()
50                  {
51                    $('#iDialogEdit').dialog("close");
52                  }
53              }
54          }
55        );
56
57      $('#iBDTagId').bind('keyup focusout', function (event)
58        {
59          if(!checkTagIdValidity($(this).val()))
60          {
61            $(this).addClass('error');
62          }
63          else
64          {
65            $(this).removeClass('error');
66          }
67        }
68      );
69
70
71      loadList();
72    }
73
74    /**
75     * open the dialog box to edit the metadata properties
76     *
77     * @param String id : if set to '' => open dialogbox in 'add' mode
78     *                    otherwise edit the given metadata
79     */
80    this.editMetadata = function (id)
81    {
82      options.numId=id;
83      updateDialog('');
84
85      $('#iDialogEdit')
86        .bind('dialogopen', function ()
87          {
88            if(options.numId!='')
89            {
90              displayProcessing(true);
91
92              $.ajax(
93                {
94                  type: "POST",
95                  url: "{/literal}{$datas.urlRequest}{literal}",
96                  async: true,
97                  data: { ajaxfct:"admin.userDefined.getTag", token:'{/literal}{$token}{literal}', id:options.numId },
98                  success:
99                    function(msg)
100                    {
101                      updateDialog(msg);
102                      displayProcessing(false);
103                    }
104                }
105              );
106            }
107
108            options.optimalHeight=$('#iDialogEdit').height()-$('#mdRulesArea').position().top;
109            $('#mdRulesArea').css('height', options.optimalHeight+'px' );
110          }
111        )
112        .dialog("open");
113    }
114
115    /**
116     * delete a metadata
117     *
118     * @param String id : id of the metadata to delete
119     */
120    this.deleteMetadata = function (id)
121    {
122      $('#iDialogDelete')
123        .html('<br>{/literal}{"g003_pleaseConfirmMetadataDelete"|@translate}{literal}')
124        .dialog(
125          {
126            autoOpen:true,
127            modal: true,
128            dialogClass: 'gcBgTabSheet gcBorder',
129            title: '{/literal}{"g003_deleteMetadata"|@translate}{literal}',
130            buttons:
131              {
132                '{/literal}{"g003_delete"|@translate}{literal}':
133                  function()
134                  {
135                    $(this).html("<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");
136                    $.ajax(
137                      {
138                        type: "POST",
139                        url: "{/literal}{$datas.urlRequest}{literal}",
140                        async: true,
141                        data: { ajaxfct:"admin.userDefined.deleteTag", token:'{/literal}{$token}{literal}', id:id },
142                        success:
143                          function(msg)
144                          {
145                            $('#iDialogDelete').dialog("destroy");
146                            loadList();
147                          }
148                      }
149                    );
150                  },
151                '{/literal}{"g003_cancel"|@translate}{literal}':
152                  function()
153                  {
154                    $('#iDialogDelete').dialog("destroy");
155                  }
156              }
157          }
158        );
159    }
160
161    /**
162     * update values of the dialog box
163     *
164     * @param String items : json string ; if empty assume to reset all fields
165     *                       with blank
166     */
167    var updateDialog = function (items)
168    {
169      if(items=='')
170      {
171        options.newRuleId=1;
172        $('#iBDNumId').val('');
173        $('#iBDTagId').val('');
174        $('#iBDLabel').val('');
175        $('#iBDRules').html('');
176      }
177      else
178      {
179        tmp=$.parseJSON(items);
180
181        options.newRuleId=tmp.lastDefId+1;
182        $('#iBDNumId').val(tmp.numId);
183        $('#iBDTagId').val(tmp.tagId);
184        $('#iBDLabel').val(tmp.label);
185        $('#iBDRules').html('');
186        for(i=0;i<tmp.rules.length;i++)
187        {
188          addRule(tmp.rules[i]);
189        }
190      }
191    }
192
193    /**
194     * reload the user defined metadata list
195     */
196    var loadList = function ()
197    {
198      $('#iListTags').html("<br>{/literal}{'g003_loading'|@translate}{literal}<br><img src='./plugins/GrumPluginClasses/icons/processing.gif'>");
199
200      $.ajax(
201        {
202          type: "POST",
203          url: "{/literal}{$datas.urlRequest}{literal}",
204          async: true,
205          data: { ajaxfct:"admin.userDefined.getList", token:'{/literal}{$token}{literal}' },
206          success:
207            function(msg)
208            {
209              $("#iListTags").html(msg);
210            }
211        }
212      );
213    }
214
215    /**
216     * check the validity of a given tagId
217     *  a valid tagId only contains chars : A-Z0-9.
218     *  a valid tagId can't start or finish with a dot, and a dot can't repeat
219     *  "machin.truc.much" => ok
220     *  ".machin.truc"     => ko
221     *  "machin.truc."     => ko
222     *  "machin..truc"     => ko
223     *
224     * @param String tagId : the tagId
225     * @return Boolean : true if ok, otherwise false
226     */
227    var checkTagIdValidity = function (tagId)
228    {
229      re=/^(?:[a-z0-9]+\.)*[a-z0-9]+$/i;
230      if(re.exec(tagId)==null) return(false);
231      return(true);
232    }
233
234    /**
235     * this function make the groups&items ready to be sorted & grouped
236     */
237    var applyNested = function ()
238    {
239      $('#iBDRules').NestedSortableDestroy();
240      $('#iBDRules').NestedSortable(
241        {
242          accept: 'rmSortable',
243          noNestingClass: 'rmItem',
244          opacity: 0.8,
245          helperclass: 'helper',
246          serializeRegExp:/.*/i,
247          autoScroll: true,
248          handle: '.rmSortHandle',
249          ghosting:false,
250          nestingPxSpace:5,
251
252          onChange: function(serialized)
253            {
254              $('#mdRulesArea li.rmSortable').each(
255                function ()
256                {
257                  checkSubRules(this.id);
258                }
259              );
260              checkDialogHeight();
261            },
262          onHover: function (draggedItem)
263            {
264              $('#mdRulesArea').scrollTop($('#sortHelper').position().top);
265            }
266        }
267      );
268    }
269
270    /**
271     * create a rule item and add it to the rulesArea
272     *
273     * the given object properties have the structure of a user_tags_def record
274     *  - itemId
275     *  - parentId
276     *  - numId
277     *  - type
278     *  - value
279     *  - ifType
280     *  - ifValue
281     *  - elseId
282     *  - order
283     *
284     * @param Object properties : an object with rules properties
285     */
286    this.addRule = function (properties)
287    {
288      addRule(properties);
289    }
290    var addRule = function (properties)
291    {
292      if(properties.defId==null)
293      {
294        properties={
295          defId:options.newRuleId++,
296          parentId:0,
297          numId:options.numId,
298          type:'T',
299          value:'',
300          conditionType:'E',
301          conditionValue:'',
302          order:-1
303        }
304      }
305
306      if(properties.parentId==0)
307      {
308        $('#iBDRules').append($('#iBDModel').html().split('ZZZZZ').join(properties.defId));
309      }
310      else
311      {
312        $('#iBDSubRulesNum'+properties.parentId).append($('#iBDModel').html().split('ZZZZZ').join(properties.defId));
313      }
314
315      $('#iBDRuleType'+properties.defId).val(properties.type).change();
316      switch(properties.type)
317      {
318        case 'T':
319          $('#iBDRuleTypeT'+properties.defId).val(properties.value);
320          break;
321        case 'M':
322          $('#iBDRuleTypeM'+properties.defId).attr('value', properties.value);
323          $('#iBDRuleTypeM'+properties.defId+' span.ruleContent').html($('#iTagListItem'+properties.value).html());
324          break;
325        case 'C':
326          $('#iBDRuleTypeCM'+properties.defId).attr('value', properties.value);
327          $('#iBDRuleTypeCM'+properties.defId+' span.ruleContent').html($('#iTagListItem'+properties.value).html());
328          $('#iBDRuleTypeCIf'+properties.defId).val(properties.conditionType).change();
329          $('#iBDRuleTypeCIfValue'+properties.defId).val(properties.conditionValue);
330          break;
331      }
332      applyNested();
333      checkDialogHeight();
334    }
335
336    /**
337     *
338     */
339    this.deleteRule = function (id)
340    {
341      $('#iBDRuleNum'+id).remove();
342      $('#mdRulesArea li.rmSortable').each(
343        function ()
344        {
345          checkSubRules(this.id);
346        }
347      );
348      checkDialogHeight();
349    }
350
351    /**
352     *
353     */
354    this.changeRuleType = function (id)
355    {
356      if($('#iBDRuleType'+id).val()=='T')
357      {
358        $('#iBDRuleNum'+id).addClass('rmItem');
359        $('#iBDRuleTypeT'+id).css('display', 'inline');
360        $('#iBDRuleTypeM'+id).css('display', 'none');
361        $('#iBDRuleTypeC'+id).css('display', 'none');
362      }
363      else if($('#iBDRuleType'+id).val()=='M')
364      {
365        $('#iBDRuleNum'+id).addClass('rmItem');
366        $('#iBDRuleTypeT'+id).css('display', 'none');
367        $('#iBDRuleTypeM'+id).css('display', 'inline-block');
368        $('#iBDRuleTypeC'+id).css('display', 'none');
369      }
370      else if($('#iBDRuleType'+id).val()=='C')
371      {
372        $('#iBDRuleNum'+id).removeClass('rmItem');
373        $('#iBDRuleTypeT'+id).css('display', 'none');
374        $('#iBDRuleTypeM'+id).css('display', 'none');
375        $('#iBDRuleTypeC'+id).css('display', 'inline-block');
376      }
377      checkDialogHeight();
378    }
379
380    /**
381     * display/hide the 'ifValue' property
382     */
383    this.changeRuleTypeCIf = function (id)
384    {
385      value=$('#iBDRuleTypeCIf'+id).val();
386      if(value=='E' || value =='!E')
387      {
388        $('#iBDRuleTypeCIfValue'+id).css('display', 'none');
389      }
390      else
391      {
392        $('#iBDRuleTypeCIfValue'+id).css('display', 'inline');
393      }
394      checkDialogHeight();
395    }
396
397    /**
398     * check if there is subrules affected to the item (conditionned by the 'condition' type)
399     * if subrules are present, disable the selector
400     */
401    var checkSubRules = function (parentId)
402    {
403      value=$('#'+parentId).attr('value');
404
405      if($('#iBDRuleType'+value).val()=='C' && $('#iBDSubRulesNum'+value+' li').length>0)
406      {
407        $('#iBDRuleType'+value).get(0).disabled=true;
408      }
409      else
410      {
411        $('#iBDRuleType'+value).get(0).disabled=false;
412      }
413    }
414
415    /**
416     * check if it necessary to calculate the height of the dialogbox
417     */
418    var checkDialogHeight = function()
419    {
420      if($('#iBDRules').height() < options.optimalHeight &&
421         $('#mdRulesArea').get(0).scrollHeight > options.optimalHeight)
422      {
423        $('#iDialogEdit').height(options.optimalHeight+$('#mdRulesArea').get(0).offsetTop);
424        $('#mdRulesArea').height(options.optimalHeight);
425      }
426      else if($('#mdRulesArea').get(0).scrollHeight > options.optimalHeight)
427      {
428        $('#iDialogEdit').height($('#mdRulesArea').get(0).scrollHeight+$('#mdRulesArea').get(0).offsetTop);
429        $('#mdRulesArea').height($('#mdRulesArea').get(0).scrollHeight);
430      }
431    }
432
433    /**
434     * check for the validity of the metadata settings
435     */
436    var checkValidity = function ()
437    {
438      $('.error').removeClass('error');
439
440      ok=true;
441
442      if(checkTagIdValidity($('#iBDTagId').val())==false)
443      {
444        $('#iBDTagId').addClass('error');
445        alert('{/literal}{"g003_invalidId"|@translate}{literal}');
446        ok=false;
447      }
448
449      if($('#iBDRules li').length==0)
450      {
451        $('#iBDRules').addClass('error');
452        alert('{/literal}{"g003_oneRuleIsNeeded"|@translate}{literal}');
453        ok=false;
454      }
455      else
456      {
457        $('#iBDRules li').each(
458          function ()
459          {
460            value=$(this).attr('value');
461            switch($('#iBDRuleType'+value).val())
462            {
463              case 'T':
464                if($('#iBDRuleTypeT'+value).val()=='')
465                {
466                  $('#iBDRuleTypeT'+value).addClass('error');
467                  alert('{/literal}{"g003_textRuleInvalid"|@translate}{literal}');
468                  ok=false;
469                }
470                break;
471              case 'M':
472                if($('#iBDRuleTypeM'+value).attr('value')=='-')
473                {
474                  $('#iBDRuleTypeM'+value).addClass('error');
475                  alert('{/literal}{"g003_metadataRuleInvalid"|@translate}{literal}');
476                  ok=false;
477                }
478                break;
479              case 'C':
480                if($('#iBDRuleTypeCM'+value).attr('value')=='-')
481                {
482                  $('#iBDRuleTypeCM'+value).addClass('error');
483                  alert('{/literal}{"g003_conditionMdRuleInvalid"|@translate}{literal}');
484                  ok=false;
485                }
486
487                if($('#iBDSubRulesNum'+value+' li').length==0)
488                {
489                  $('#iBDSubRulesNum'+value).addClass('error');
490                  alert('{/literal}{"g003_conditionRulesRuleInvalid"|@translate}{literal}');
491                  ok=false;
492                }
493                break;
494            }
495          }
496        );
497      }
498      return(ok);
499    }
500
501    /**
502     * send metadata update to the server, and close the dialog box if everything
503     * is ok
504     */
505    var doUpdate = function ()
506    {
507      displayProcessing(true);
508
509      // build datas
510      properties = {
511        tagId:$('#iBDTagId').val(),
512        name:$('#iBDLabel').val(),
513        rules: [ ]
514      }
515
516      order=1;
517      $('#iBDRules li').each(
518        function ()
519        {
520          defId=$(this).attr('value');
521          type=$('#iBDRuleType'+defId).val();
522          switch(type)
523          {
524            case 'T':
525              value=$('#iBDRuleTypeT'+defId).val();
526              conditionType='';
527              conditionValue='';
528              break;
529            case 'M':
530              value=$('#iBDRuleTypeM'+defId).attr('value');
531              conditionType='';
532              conditionValue='';
533              break;
534            case 'C':
535              value=$('#iBDRuleTypeCM'+defId).attr('value');
536              conditionType=$('#iBDRuleTypeCIf'+defId).val();
537              conditionValue=$('#iBDRuleTypeCIfValue'+defId).val();
538              break;
539          }
540
541          properties.rules.push(
542            {
543              defId:defId,
544              parentId:$(this).parent().parent().attr('value'),
545              type:type,
546              value:value,
547              conditionType:conditionType,
548              conditionValue:conditionValue,
549              order:order
550            }
551          );
552
553          order++;
554        }
555      );
556
557      $.ajax(
558        {
559          type: "POST",
560          url: "{/literal}{$datas.urlRequest}{literal}",
561          async: true,
562          data: { ajaxfct:"admin.userDefined.setTag", token:'{/literal}{$token}{literal}', id:options.numId, properties:properties },
563          success:
564            function(msg)
565            {
566              displayProcessing(false);
567
568              re=/^\d+,\d+$/;
569              if(re.exec(msg)!=null)
570              {
571                // result Ok ! => close the dialog box and reload the list
572                $('#iDialogEdit').dialog("close");
573                loadList();
574              }
575              else
576              {
577                returned=msg.split('!');
578                $('#'+returned[0]).addClass('error');
579                alert(returned[1]);
580              }
581            }
582        }
583      );
584    }
585
586    /**
587     * display or hide the processing flower
588     */
589    var displayProcessing = function (visible)
590    {
591      if(visible)
592      {
593        $('#iBDProcessing').css("display", "block");
594      }
595      else
596      {
597        $('#iBDProcessing').css("display", "none");
598      }
599    }
600
601    this.init();
602  }
603
604
605
606  $(window).load(
607    function ()
608    {
609      udm=new userDefManage();
610      tls=new tagListSelector({itemId:'iTagList'});
611    }
612  );
613
614
615</script>
616{/literal}
617
618
619<h2>{'g003_personnal_metadata'|@translate}</h2>
620
621<div class='helps'>
622  <p>{'g003_personnal_page_help'|@translate}</p>
623</div>
624
625<div class='addMetadata'>
626  <a onclick="udm.editMetadata('');">{'g003_add_a_new_md'|@translate}</a>
627</div>
628
629<table id='iHeaderListTags' class="littlefont">
630  <tr>
631    <th style="width:35%;min-width:340px;">{'g003_TagId'|@translate}</th>
632    <th>{'g003_TagLabel'|@translate}</th>
633    <th style="width:15%;">{'g003_num_of_rules'|@translate}</th>
634    <th width="40px">&nbsp;</th>
635  </tr>
636</table>
637<div id='iListTags' class="{$themeconf.name}">
638</div>
639<div id="iListTagsNb"></div>
640
641<div id="iDialogDelete">
642</div>
643
644<div id="iDialogEdit">
645  <div id='iBDProcessing' style="display:none;position:absolute;width:100%;height:100%;background:#000000;opacity:0.75">
646      <img src="plugins/GrumPluginClasses/icons/processing.gif" style="margin-top:100px;">
647  </div>
648
649  <form>
650    <table class='formtable'>
651      <tr>
652        <td>{'g003_metadatId'|@translate}</td>
653        <td>
654          <input type='text' id='iBDTagId' maxlength=200 size=60 value=''>
655          <input type='hidden' id='iBDNumId' value=''>
656        </td>
657      </tr>
658      <tr>
659        <td>{'g003_TagLabel'|@translate}</td>
660        <td>
661          <input type='text' id='iBDLabel' maxlength=200 size=60 value=''>
662          <!--<select id='iBDLang' disabled>
663            <option value='fr_FR'>Français</option>
664          </select>-->
665        </td>
666      </tr>
667      <tr>
668        <td>{'g003_rules'|@translate}</td>
669        <td>
670          <a onclick='udm.addRule({ldelim}{rdelim});'>{'g003_add_a_rule'|@translate}</a>
671        </td>
672      </tr>
673    </table>
674
675    <div id='mdRulesArea' value='0'>
676      <ul id='iBDRules'>
677      </ul>
678    </div>
679
680  </form>
681</div>
682
683
684<ul style='display:none' id='iBDModel'>
685  <li id='iBDRuleNumZZZZZ' class='groupItems gcBgPage rmSortable rmItem' value='ZZZZZ'>
686    <span onclick='udm.deleteRule("ZZZZZ");' class='buttonDelete button' title='{"g003_delete"|@translate}' /></span>
687    <div class='rmContent'>
688
689      <div class='ruleSelector'>
690        <span class='buttonMove rmSortHandle drag_button' title='{"Drag to re-order"|@translate}'/></span>
691
692        <select id='iBDRuleTypeZZZZZ' onchange='udm.changeRuleType("ZZZZZ");'>
693          <option value='T'>{'g003_typeText'|@translate}</option>
694          <option value='M'>{'g003_typeMetadata'|@translate}</option>
695          <option value='C'>{'g003_typeCondition'|@translate}</option>
696        </select>
697      </div>
698
699      <div class='ruleProperties'>
700        <input type='text' id='iBDRuleTypeTZZZZZ' value='' maxlength=200 size=60>
701
702        <div id='iBDRuleTypeMZZZZZ'
703             style='display:none;'
704             value='-'
705             class='ruleTypeM gcTextInput gcBgInput gcBorderInput pointer'
706             onclick='tls.display("iBDRuleTypeMZZZZZ");'>
707          <span class='ruleContent'><span class='tagName'>&nbsp;</span></span>
708          <span style='float:right' class='gcText3'>&dArr;</span>
709        </div>
710
711        <div id='iBDRuleTypeCZZZZZ' style='display:none;'>
712          <table>
713            <tr>
714              <td style='vertical-align:top;'>{'g003_conditionIf'|@translate}</td>
715              <td>
716                <div id='iBDRuleTypeCMZZZZZ'
717                     value='-'
718                     style='display:inline-block'
719                     class='ruleTypeM2 gcTextInput gcBgInput gcBorderInput pointer'
720                     onclick='tls.display("iBDRuleTypeCMZZZZZ");'>
721                  <span class='ruleContent'>
722                    <span class='tagName'>&nbsp;</span>
723                  </span>
724                  <span style='float:right' class='gcText3'>&dArr;</span>
725                </div>
726                <br>
727                <div style='display:inline-block;margin-top:2px;'>
728                  <select id='iBDRuleTypeCIfZZZZZ' onchange='udm.changeRuleTypeCIf("ZZZZZ");'>
729                    <option value='E'>{'g003_typeCIfExist'|@translate}</option>
730                    <option value='!E'>{'g003_typeCIfNotExist'|@translate}</option>
731                    <option value='='>{'g003_typeCIfEqual'|@translate}</option>
732                    <option value='!='>{'g003_typeCIfNotEqual'|@translate}</option>
733                    <option value='%'>{'g003_typeCIfLike'|@translate}</option>
734                    <option value='!%'>{'g003_typeCIfNotLike'|@translate}</option>
735                    <option value='^%'>{'g003_typeCIfBeginWith'|@translate}</option>
736                    <option value='!^%'>{'g003_typeCIfNotBeginWith'|@translate}</option>
737                    <option value='$%'>{'g003_typeCIfEndWith'|@translate}</option>
738                    <option value='!$%'>{'g003_typeCIfNotEndWith'|@translate}</option>                  </select>
739                  <input type='text' id='iBDRuleTypeCIfValueZZZZZ' value='' maxlength=200 size=26 style='display:none;'>
740                </div>
741              </td>
742            </tr>
743          </table>
744        </div>
745
746      </div>
747    </div>
748
749    <ul class='subRules' id='iBDSubRulesNumZZZZZ'></ul>
750  </li>
751</ul>
752
753<ul style='display:none' id='iTagList' class="{$themeconf.name}">
754  {foreach from=$datas.tagList item=tag}
755    <li id='iTagListItem{$tag.numId}' value='{$tag.numId}'><span class='tagName'>{$tag.tagId}</span><span>{$tag.name}</span></li>
756  {/foreach}
757</ul>
Note: See TracBrowser for help on using the repository browser.