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

Last change on this file since 6950 was 6950, checked in by grum, 14 years ago

Implement metadata keywords to piwigo tags convert functionnalies
Add some help text
bug:1858

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