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

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

some file forgotten in the previous commit...

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