Просмотр исходного кода

Merge branch 'feature/vx/jsoptimize' into feature/v0.9.3/design

Bastien Sevajol 12 лет назад
Родитель
Сommit
747e272117

+ 42 - 36
src/Muzich/CoreBundle/Resources/views/Tag/tagsPrompt.html.twig Просмотреть файл

@@ -1,46 +1,52 @@
1 1
 
2 2
 
3 3
 <div class="tags_prompt" id="tags_prompt_{{ form_name }}">
4
-    
5
-   <input class="tags_prompt_list" name="tags" value="" /> 
6
-   <input id="tags_selected_tag_{{ form_name }}" type="hidden" value="" />
4
+
5
+  <input
6
+    class="tag_prompt"
7
+    value=""
8
+    placeholder="{{ 'tags.inputtext.help'|trans({}, 'userui') }}"
9
+  />
10
+  <img id="tag_prompt_loader_{{ form_name }}" class="tag_loader" style="display: none;"
11
+    src="{{ asset('/bundles/muzichcore/img/ajax-loader.gif') }}" alt="loading"/>
7 12
    
8
-   <div id="search_tag_{{ form_name }}" class="search_tag_list" style="display: none;">
9
-     <span class="info"></span>
10
-     <div class="tag_loader_div">
11
-       <img id="tag_loader_{{ form_name }}" class="tag_loader" style="display: none;" src="{{ asset('/bundles/muzichcore/img/ajax-loader.gif') }}" alt="loading"/>
12
-     </div>
13
-     <ul class="search_tag_list"></ul>
14
-     <a class="more button" href="#" style="display: none;">
15
-       {{ 'tags.search.display_more'|trans({}, 'userui') }}
16
-     </a>
17
-   </div>
13
+  <div id="search_tag_{{ form_name }}" class="search_tag_list" style="display: none;">
14
+    <span class="info"></span>
15
+    <div class="tag_loader_div">
16
+      <img id="tag_loader_{{ form_name }}" class="tag_loader" style="display: none;"
17
+        src="{{ asset('/bundles/muzichcore/img/ajax-loader.gif') }}" alt="loading"/>
18
+    </div>
19
+    <ul class="search_tag_list"></ul>
20
+    <a class="more button" href="#" style="display: none;">
21
+      {{ 'tags.search.display_more'|trans({}, 'userui') }}
22
+    </a>
23
+  </div>
24
+  
25
+  <ul class="tagbox"></ul>
26
+  
18 27
 </div>
19 28
 
20 29
 <script language="javascript" type="text/javascript">
21
-  
22
-  var taginit = new Array();
23
-  {% if search_tags is defined %}
24
-    {% for tid, tname in search_tags %}
25
-      taginit[{{ loop.index0 }}] = {"id":"{{ tid }}", "name":"{{ tname }}"};
26
-    {% endfor %}
27
-  {% endif %}
28
-  
29
-  var options = new Array();
30
-  options.form_name  = "{{ form_name }}";
31
-  options.tag_init   = taginit;
32
-  
33
-  // tags_prompt_list_
34
-  $("div#tags_prompt_{{ form_name }} input.tags_prompt_list").tagBox(options);
35
-  
36
-  // text help en cas de rafraichissement de la page (nav. comme firefox 
37
-  // garde la valeur de l'input)
38 30
   $(document).ready(function(){
39
-    $('div#tags_prompt_{{ form_name }} ul.tagbox li.input input[type="text"]')
40
-      .attr('placeholder', "{{ 'tags.inputtext.help'|trans({}, 'userui') }}");
41
-  });
42
-  
43
-  // On détruit la variable taginit
44
-  delete taginit;
45 31
     
32
+    $('form[name="{{ form_name }}"] input.tag_prompt').val('');
33
+    
34
+    window.{{ form_name }}_tag_prompt_connector = new TagPromptConnector(
35
+      $('form[name="{{ form_name }}"] input.tag_prompt'),
36
+      $('form[name="{{ form_name }}"] input.tagBox_tags_ids'),
37
+      $('form[name="{{ form_name }}"] div.search_tag_list'),
38
+      $('form[name="{{ form_name }}"] ul.tagbox'),
39
+      $('#tag_prompt_loader_{{ form_name }}')
40
+    );
41
+    
42
+    var {{ form_name }}_taginit = new Array();
43
+    {% if search_tags is defined %}
44
+      {% for tid, tname in search_tags %}
45
+        {{ form_name }}_taginit[{{ loop.index0 }}] = {"id":"{{ tid }}", "name":"{{ tname }}"};
46
+      {% endfor %}
47
+    {% endif %}
48
+    
49
+    window.{{ form_name }}_tag_prompt_connector.initializeTags({{ form_name }}_taginit);
50
+  
51
+  });
46 52
 </script>

+ 2 - 1
src/Muzich/CoreBundle/Resources/views/layout.html.twig Просмотреть файл

@@ -13,7 +13,7 @@
13 13
     <link href="{{ asset('bundles/muzichcore/css/base.css') }}" rel="stylesheet" media="screen" type="text/css" />
14 14
     <link href="{{ asset('bundles/muzichcore/css/old.css') }}" rel="stylesheet" media="screen" type="text/css" />
15 15
     <link href="{{ asset('css/main.css') }}" rel="stylesheet" media="screen" type="text/css" />
16
-    
16
+
17 17
     <!--[if gte IE 9]>
18 18
       <style type="text/css">
19 19
         .gradient, .button {
@@ -30,6 +30,7 @@
30 30
     {% endif %}
31 31
     <script src="{{ asset('js/jquery-ui-1.8.7.min.js') }}" type="text/javascript"></script>
32 32
     <script src="{{ asset('bundles/muzichcore/js/muzich.js') }}" type="text/javascript"></script>
33
+    <script src="{{ asset('js/lib/TagPrompt.js') }}" type="text/javascript"></script>
33 34
 
34 35
     <script type="text/javascript" src="{{ asset('js/swfobject.js') }}"></script> 
35 36
     {# TODO: On peux piquer les js ?  #}

+ 0 - 1
src/Muzich/HomeBundle/Resources/views/Show/showGroup.html.twig Просмотреть файл

@@ -75,7 +75,6 @@
75 75
 
76 76
         {% include "MuzichCoreBundle:Element:form.add.html.twig" with { 'form': add_form, 'form_name': add_form_name } %}
77 77
 
78
-        <input type="submit" class="button" >
79 78
       </form>
80 79
       
81 80
     </div>

+ 409 - 403
web/bundles/muzichcore/js/muzich.js Просмотреть файл

@@ -230,12 +230,31 @@ function explode (delimiter, string, limit) {
230 230
 function remove_tags(form_name)
231 231
 {
232 232
   //tagsAddeds[form_name] = new Array();
233
-  $('form[name="'+form_name+'"] ul.tagbox li.tag').remove();
234
-  $('form[name="'+form_name+'"] input.tagBox_tags_ids').val('');
233
+  //$('form[name="'+form_name+'"] ul.tagbox li.tag').remove();
234
+  //$('form[name="'+form_name+'"] input.tagBox_tags_ids').val('');
235 235
   
236 236
 }
237 237
 
238
-$(document).ready(function(){
238
+function JQueryJson(url, data, callback_success)
239
+{
240
+  $.ajax({
241
+    type: 'POST',
242
+    url: url,
243
+    dataType: 'json',
244
+    data: data,
245
+    success: function(response)
246
+    {
247
+      if (response.status == 'mustbeconnected')
248
+      {
249
+        $(location).attr('href', url_index);
250
+      }
251
+      
252
+      callback_success(response);
253
+    }
254
+  });
255
+}
256
+
257
+$(document).ready(function(){  
239 258
     
240 259
   // Controle du focus sur la page
241 260
   function onBlur() {
@@ -261,9 +280,11 @@ $(document).ready(function(){
261 280
     $('img.elements_more_loader').show();
262 281
     $('ul.elements').html('');
263 282
     // On initialise la liste de tags déjà ajouté
264
-    tagsAddeds['search'] = new Array;
283
+    window.search_tag_prompt_connector.initializeTags([]);
284
+    $('div.no_elements').hide();
285
+    //tagsAddeds['search'] = new Array;
265 286
     var form = $('form[name="search"]');
266
-    remove_tags(form.attr('name'));
287
+    //remove_tags(form.attr('name'));
267 288
     form.submit();
268 289
   });
269 290
   
@@ -272,8 +293,6 @@ $(document).ready(function(){
272 293
     
273 294
     $('img.elements_more_loader').show();
274 295
     $('ul.elements').html('');
275
-    // On initialise la liste de tags déjà ajouté
276
-    tagsAddeds['search'] = new Array;
277 296
     
278 297
     var form = $('form[name="search"]');
279 298
     
@@ -283,22 +302,15 @@ $(document).ready(function(){
283 302
         $(location).attr('href', url_index);
284 303
       }
285 304
       
286
-      remove_tags(form.attr('name'));
287
-//      if (tags.length)
288
-//      {
289
-        var inputTag = $("div#tags_prompt_"+form.attr('name')+" input.form-default-value-processed");
305
+        var tags = [];
290 306
         for (i in response.tags)
291 307
         {
292
-          $('input#tags_selected_tag_'+form.attr('name')).val(i);
293
-          inputTag.val(response.tags[i]);
294
-                                        
295
-          // Et on execute l'évènement selectTag de l'input
296
-          inputTag.trigger("selectTag");
308
+          var tag = new Tag(i, response.tags[i]);
309
+          tags.push(tag);
297 310
         }
298 311
         
312
+        window.search_tag_prompt_connector.initializeTags(tags);
299 313
         form.submit();
300
-      //}
301
-      
302 314
     });
303 315
   });
304 316
   
@@ -307,9 +319,6 @@ $(document).ready(function(){
307 319
     // Si il y a une liste de tags (comme sur la page favoris, profil)
308 320
     var id;
309 321
     
310
-    // On initialise la liste de tags déjà ajouté
311
-    tagsAddeds['search'] = new Array;
312
-    
313 322
     if ($('ul#favorite_tags').length)
314 323
     {
315 324
       id = str_replace('element_tag_', '', $(this).attr('id'));
@@ -321,13 +330,13 @@ $(document).ready(function(){
321 330
     {
322 331
       $('img.elements_more_loader').show();
323 332
       $('ul.elements').html('');
333
+      
324 334
       var form = $('form[name="search"]');
325 335
       id = str_replace('element_tag_', '', $(this).attr('id'));
326
-      remove_tags('search');
327
-      var inputTag = $("div#tags_prompt_search input.form-default-value-processed");
328
-      $('input#tags_selected_tag_search').val(id);
329
-      inputTag.val($(this).html());
330
-      inputTag.trigger("selectTag");
336
+      var tag = new Tag(id, $(this).text());
337
+      
338
+      window.search_tag_prompt_connector.initializeTags([tag]);
339
+      
331 340
       form.submit();
332 341
     }
333 342
   });
@@ -705,378 +714,378 @@ $(document).ready(function(){
705 714
   });
706 715
  
707 716
   ////////////////// TAG PROMPT ///////////////
708
- 
709
-  var ajax_query_timestamp = null;
710
- 
711
-  // Les deux clicks ci-dessous permettent de faire disparaitre
712
-  // la div de tags lorsque l'on clique ailleurs
713
-  $('html').click(function() {
714
-    if ($("div.search_tag_list").is(':visible'))
715
-    {
716
-      $("div.search_tag_list").hide();
717
-    }
718
-  });
719
-
720
-  $("div.search_tag_list, div.search_tag_list a.more").live('click', function(event){
721
-    event.stopPropagation();
722
-    $("div.search_tag_list").show();
723
-  });
724
-
725
-  function autocomplete_tag(input, form_name)
726
-  {
727
-    // Il doit y avoir au moin un caractère
728
-    if (input.val().length > 0) 
729
-    {
730
-
731
-      // on met en variable l'input
732
-      var inputTag = input;
733
-      
734
-      // On récupére la div de tags
735
-      var divtags = $("#search_tag_"+form_name);
736
-
737
-      // Si la fenêtre de tags est caché
738
-      if (!divtags.is(':visible'))
739
-      {
740
-        // On la replace
741
-        var position = input.position();
742
-        divtags.css('left', Math.round(position.left) + 5);
743
-        divtags.css('top', Math.round(position.top) + 28);
744
-        // Et on l'affiche
745
-        divtags.show();
746
-      }
747
-      // On affiche le loader
748
-      $('#tag_loader_'+form_name).show();
749
-      // On cache la liste de tags
750
-      var search_tag_list = divtags.find('ul.search_tag_list');
751
-      // On supprime les anciens li
752
-      search_tag_list.find('li').remove();
753
-      search_tag_list.hide();
754
-      // Et on affiche une info
755
-      var span_info = divtags.find('span.info');
756
-      span_info.show();
757
-      // TODO: multilingue !
758
-      span_info.text(str_replace('%string_search%', input.val(), string_search_tag_title));
759
-
760
-      // C'est en fonction du nb de resultats qu'il sera affiché
761
-      divtags.find('a.more').hide();
762
-
763
-      // On récupère le timestamp pour reconnaitre la dernière requête effectué
764
-      ajax_query_timestamp = new Date().getTime();
765
-      
766
-      // Récupération des tags correspondants
767
-      $.ajax({
768
-        type: 'POST',
769
-        url: url_search_tag+'/'+ajax_query_timestamp,
770
-        dataType: 'json',
771
-        data: {'string_search':input.val()},
772
-        success: function(data) {
773
-        if (data.status == 'mustbeconnected')
774
-        {
775
-          $(location).attr('href', url_index);
776
-        }
777
-        
778
-        // Ce contrôle permet de ne pas continuer si une requete
779
-        // ajax a été faite depuis.
780
-        if (data.timestamp == ajax_query_timestamp)
781
-        {
782
-          var status = data.status;
783
-          var tags   = data.data;
784
-
785
-          // Si on spécifie une erreur
786
-          if (status == 'error')
787
-          {
788
-            // On l'affiche a l'utilisateur
789
-            span_info.text(data.error);
790
-          }
791
-          // Si c'est un succés
792
-          else if (status == 'success')
793
-          {
794
-            if (tags.length > 0)
795
-            {
796
-              var more = false;
797
-              // Pour chaque tags retournés
798
-              for (i in tags)
799
-              {
800
-                var tag_name = tags[i]['name'];
801
-                var tag_id = tags[i]['id'];
802
-                var t_string = tag_name
803
-                // On construit un li
804
-                
805
-                var r_string = $.trim(input.val());
806
-                var re = new RegExp(r_string, "i");
807
-                t_string = t_string.replace(re,"<strong>" + r_string + "</strong>");
808
-                
809
-                                
810
-                var li_tag = 
811
-                  $('<li>').append(
812
-                    $('<a>').attr('id','searched_tag_'+tag_id)
813
-                      .attr('href', '#')
814
-                    // qui réagit quand on clique dessus
815
-                    .click(function(e){
816
-                      
817
-                      var id = str_replace('searched_tag_', '', $(this).attr('id'));
818
-                      var name = $('span#tag_prompt_tag_'+id+'_name').html();
819
-                                            
820
-                      $('input#tags_selected_tag_'+form_name).val(id);
821
-                      inputTag.val(name);
822
-                      // Et on execute l'évènement selectTag de l'input
823
-                      inputTag.trigger("selectTag");
824
-                      // On cache la liste puisque le choix vient d'être fait
825
-                      divtags.hide();
826
-                      // On vide le champs de saisie du tag
827
-                      $('input.form-default-value-processed').val('');
828
-                      return false;
829
-                    })
830
-                    .append(t_string)
831
-                ).append($('<span style="display: none;" id="tag_prompt_tag_'+tag_id+'_name">'+tag_name+'</span>'));
832
-
833
-                // Si on depasse les 30 tags
834
-                if (i > 30)
835
-                {
836
-                  more = true;
837
-                  // On le cache
838
-                  li_tag.hide();
839
-                }
840
-
841
-                // On ajout ce li a la liste
842
-                search_tag_list.append(li_tag);
843
-              } 
844
-
845
-              if (more)
846
-              {
847
-                divtags.find('a.more').show();
848
-              }
849
-              
850
-              span_info.show();
851
-              span_info.text(data.message);
852
-              // Et on affiche la liste
853
-              search_tag_list.show();
854
-            }
855
-            else
856
-            {
857
-              span_info.show();
858
-              span_info.text(data.message);
859
-              search_tag_list.show();
860
-              
861
-              // Dans ce cas ou aucun tag n'a été trouvé, la proposition 
862
-              // d'ajout s'affichecf en dessous
863
-              
864
-              //span_info.text("Aucun tag de trouvé pour \""+inputTag.val()+"\"");
865
-            }
866
-            
867
-            // Si le tag ne semble pas connu en base
868
-            if (!data.same_found)
869
-            {
870
-              li_tag = 
871
-                $('<li>').addClass('new').append(
872
-                  $('<a>').attr('href','#new#'+$.trim(input.val()))
873
-                  // qui réagit quand on clique dessus
874
-                  .click({
875
-                    inputTag: inputTag,
876
-                    form_name: form_name,
877
-                    divtags: divtags
878
-                  }, event_click_new_tag_proposition)
879
-                  .append($.trim(input.val()))
880
-              );
881
-              search_tag_list.append(li_tag);
882
-            }
883
-            
884
-          }
885
-
886
-          // On cache le loader
887
-          $('#tag_loader_'+form_name).hide();
888
-        }
889
-      }
890
-      });
891
-      
892
-      
893
-      //$.getJSON(url_search_tag+'/'+input.val()+'/'+ajax_query_timestamp, );
894
-      
895
-    }
896
-  }
897
-  
898
-  function event_click_new_tag_proposition(event)
899
-  {
900
-    form_add_open_dialog_for_new_tag($(event.target), event.data.inputTag, event.data.form_name, event.data.divtags);
901
-  }
902
- 
903
-  function form_add_open_dialog_for_new_tag(link_add_tag, inputTag, form_name, divtags)
904
-  {       
905
-    
906
-    
907
-    // Effet fade-in du fond opaque
908
-    $('body').append($('<div>').attr('id', 'fade')); 
909
-    //Apparition du fond - .css({'filter' : 'alpha(opacity=80)'}) pour corriger les bogues de IE
910
-    $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
911
-    
912
-    // En premier lieux on fait apparaître la fenêtre de confirmation
913
-    var popup = $('<div>')
914
-    .attr('id', 'add_tag')
915
-    .addClass('popin_block')
916
-    .css('width', '400px')
917
-      //.append($('<h2>').append(string_tag_add_title))
918
-    .append($('<form>')
919
-      .attr('action', url_add_tag)
920
-      .attr('method', 'post')
921
-      .attr('name', 'add_tag')
922
-      .ajaxForm(function(response) {
923
-        /*
924
-        *
925
-        */
926
-
927
-        if (response.status == 'mustbeconnected')
928
-        {
929
-          $(location).attr('href', url_index);
930
-        }
931
-
932
-        if (response.status == 'success')
933
-        {
934
-          var tag_id   = response.tag_id;
935
-          var tag_name = response.tag_name;
936
-
937
-          $('input#tags_selected_tag_'+form_name).val(tag_id);
938
-          inputTag.val(tag_name);
939
-          // Et on execute l'évènement selectTag de l'input
940
-          inputTag.trigger("selectTag");
941
-          // On cache la liste puisque le choix vient d'être fait
942
-          divtags.hide();
943
-
944
-          link_add_tag.parents('div.search_tag_list').find('img.tag_loader').hide();
945
-
946
-          $('#fade').fadeOut(400, function(){$('#fade').remove();});
947
-          $('#add_tag').remove();
948
-        }
949
-
950
-        if (response.status == 'error')
951
-        {
952
-          $('form[name="add_tag"]').find('ul.error_list').remove();
953
-          var ul_errors = $('<ul>').addClass('error_list');
954
-
955
-          for (i in response.errors)
956
-          {
957
-            ul_errors.append($('<li>').append(response.errors[i]));
958
-          }
959
-
960
-          $('form[name="add_tag"]').prepend(ul_errors);
961
-        }
962
-
963
-        return false;
964
-      })
965
-
966
-      .append($('<div>').addClass('tag')
967
-        .append($('<ul>')
968
-          .append($('<li>').addClass('button')
969
-            .append(link_add_tag.text()))))
970
-      .append($('<p>').append(string_tag_add_text))
971
-      .append($('<p>').append(string_tag_add_argument))
972
-      .append($('<textarea>').attr('name', 'argument'))
973
-      .append($('<div>').addClass('inputs')
974
-        .append($('<input>')
975
-          .attr('type', 'button')
976
-          .attr('value', string_tag_add_inputs_cancel)
977
-          .addClass('button')
978
-          .click(function(){
979
-            $('#fade').fadeOut(1000, function(){$('#fade').remove();});
980
-            $('#add_tag').remove();
981
-
982
-            return false;
983
-          })
984
-        )
985
-        .append($('<input>')
986
-          .attr('type', 'submit')
987
-          .attr('value', string_tag_add_inputs_submit)
988
-          .addClass('button')
989
-          .click(function(){
990
-
991
-            link_add_tag.parents('div.search_tag_list').find('img.tag_loader').show();
992
-
993
-          })
994
-        )
995
-        .append($('<input>').attr('type', 'hidden').attr('name', 'tag_name').val(link_add_tag.text()))
996
-      ))
997
-    ;
998
-
999
-    // Il faut ajouter le popup au dom avant de le positionner en css
1000
-    // Sinon la valeur height n'est pas encore calculable
1001
-    $('body').prepend(popup);
1002
-
1003
-    //Récupération du margin, qui permettra de centrer la fenêtre - on ajuste de 80px en conformité avec le CSS
1004
-    var popMargTop = (popup.height() + 50) / 2;
1005
-    var popMargLeft = (popup.width() + 50) / 2;
1006
-
1007
-    //On affecte le margin
1008
-    $(popup).css({
1009
-      'margin-top' : -popMargTop,
1010
-      'margin-left' : -popMargLeft
1011
-    });
1012
-
1013
-    return false;
1014
-  }
1015
- 
1016
-  var last_keypress = 0;
1017
-  
1018
-  function check_timelaps_and_search(input, form_name, time_id, timed, info)
1019
-  {
1020
-    if (!timed)
1021
-    {
1022
-      // C'est une nouvelle touche (pas redirigé) on lui donne un id
1023
-      // et on met a jour l'id de la dernière pressé
1024
-      last_keypress = new Date().getTime(); 
1025
-      var this_time_id = last_keypress;
1026
-    }
1027
-    else
1028
-    {
1029
-      // Si elle a été redirigé, on met son id dans cette variable
1030
-      var this_time_id = time_id;
1031
-    }
1032
-    
1033
-    // C'est une touche redirigé dans le temps qui a été suivit d'une autre touche
1034
-    if (time_id != last_keypress && timed)
1035
-    {
1036
-      // elle disparait
1037
-    }
1038
-    else
1039
-    {
1040
-      //
1041
-      if ((new Date().getTime() - last_keypress) < 600 || timed == false)
1042
-      {
1043
-        // Si elle vient d'être tapé (timed == false) elle doit attendre (au cas ou une autre touche soit tapé)
1044
-        // Si c'est une redirigé qui n'a pas été remplacé par une nouvelle lettre
1045
-        // elle doit attendre au cas ou soit pressé.
1046
-        setTimeout(function(){check_timelaps_and_search(input, form_name, this_time_id, true, info)}, 700);
1047
-      }
1048
-      else
1049
-      {
1050
-        // il n'y a plus a attendre, on envoie la demande de tag.
1051
-        autocomplete_tag(input, form_name);
1052
-      }
1053
-    }
1054
-  }
1055
-  
1056
-  // Autocompletion de tags
1057
-  $("div.tags_prompt ul.tagbox li.input input").live('keypress', function(e){
1058
-    
1059
-    var form_name = $(this).parents('form').attr('name');
1060
-    var code = (e.keyCode ? e.keyCode : e.which);
1061
-
1062
-    if ((e.which !== 0 && e.charCode !== 0) || (code == 8 || code == 46))
1063
-    {
1064
-      check_timelaps_and_search($(this), form_name, new Date().getTime(), false, $(this).val());
1065
-    }
1066
-     
1067
-  });
1068
-  
1069
-  // Un click sur ce lien affiche tout les tags cachés de la liste
1070
-  $('div.search_tag_list a.more').live('click', function(){
1071
-    jQuery.each( $(this).parent('div').find('ul.search_tag_list li') , function(){
1072
-      $(this).show();
1073
-    });
1074
-    $(this).hide();
1075
-    return false;
1076
-  });
1077
-  
1078
-  $('ul.tagbox li.input input[type="text"]').formDefaults();
1079
- 
717
+  //
718
+  //var ajax_query_timestamp = null;
719
+  //
720
+  //// Les deux clicks ci-dessous permettent de faire disparaitre
721
+  //// la div de tags lorsque l'on clique ailleurs
722
+  //$('html').click(function() {
723
+  //  if ($("div.search_tag_list").is(':visible'))
724
+  //  {
725
+  //    $("div.search_tag_list").hide();
726
+  //  }
727
+  //});
728
+  //
729
+  //$("div.search_tag_list, div.search_tag_list a.more").live('click', function(event){
730
+  //  event.stopPropagation();
731
+  //  $("div.search_tag_list").show();
732
+  //});
733
+  //
734
+  //function autocomplete_tag(input, form_name)
735
+  //{
736
+  //  // Il doit y avoir au moin un caractère
737
+  //  if (input.val().length > 0) 
738
+  //  {
739
+  //
740
+  //    // on met en variable l'input
741
+  //    var inputTag = input;
742
+  //    
743
+  //    // On récupére la div de tags
744
+  //    var divtags = $("#search_tag_"+form_name);
745
+  //
746
+  //    // Si la fenêtre de tags est caché
747
+  //    if (!divtags.is(':visible'))
748
+  //    {
749
+  //      // On la replace
750
+  //      var position = input.position();
751
+  //      divtags.css('left', Math.round(position.left) + 5);
752
+  //      divtags.css('top', Math.round(position.top) + 28);
753
+  //      // Et on l'affiche
754
+  //      divtags.show();
755
+  //    }
756
+  //    // On affiche le loader
757
+  //    $('#tag_loader_'+form_name).show();
758
+  //    // On cache la liste de tags
759
+  //    var search_tag_list = divtags.find('ul.search_tag_list');
760
+  //    // On supprime les anciens li
761
+  //    search_tag_list.find('li').remove();
762
+  //    search_tag_list.hide();
763
+  //    // Et on affiche une info
764
+  //    var span_info = divtags.find('span.info');
765
+  //    span_info.show();
766
+  //    // TODO: multilingue !
767
+  //    span_info.text(str_replace('%string_search%', input.val(), string_search_tag_title));
768
+  //
769
+  //    // C'est en fonction du nb de resultats qu'il sera affiché
770
+  //    divtags.find('a.more').hide();
771
+  //
772
+  //    // On récupère le timestamp pour reconnaitre la dernière requête effectué
773
+  //    ajax_query_timestamp = new Date().getTime();
774
+  //    
775
+  //    // Récupération des tags correspondants
776
+  //    $.ajax({
777
+  //      type: 'POST',
778
+  //      url: url_search_tag+'/'+ajax_query_timestamp,
779
+  //      dataType: 'json',
780
+  //      data: {'string_search':input.val()},
781
+  //      success: function(data) {
782
+  //      if (data.status == 'mustbeconnected')
783
+  //      {
784
+  //        $(location).attr('href', url_index);
785
+  //      }
786
+  //      
787
+  //      // Ce contrôle permet de ne pas continuer si une requete
788
+  //      // ajax a été faite depuis.
789
+  //      if (data.timestamp == ajax_query_timestamp)
790
+  //      {
791
+  //        var status = data.status;
792
+  //        var tags   = data.data;
793
+  //
794
+  //        // Si on spécifie une erreur
795
+  //        if (status == 'error')
796
+  //        {
797
+  //          // On l'affiche a l'utilisateur
798
+  //          span_info.text(data.error);
799
+  //        }
800
+  //        // Si c'est un succés
801
+  //        else if (status == 'success')
802
+  //        {
803
+  //          if (tags.length > 0)
804
+  //          {
805
+  //            var more = false;
806
+  //            // Pour chaque tags retournés
807
+  //            for (i in tags)
808
+  //            {
809
+  //              var tag_name = tags[i]['name'];
810
+  //              var tag_id = tags[i]['id'];
811
+  //              var t_string = tag_name
812
+  //              // On construit un li
813
+  //              
814
+  //              var r_string = $.trim(input.val());
815
+  //              var re = new RegExp(r_string, "i");
816
+  //              t_string = t_string.replace(re,"<strong>" + r_string + "</strong>");
817
+  //              
818
+  //                              
819
+  //              var li_tag = 
820
+  //                $('<li>').append(
821
+  //                  $('<a>').attr('id','searched_tag_'+tag_id)
822
+  //                    .attr('href', '#')
823
+  //                  // qui réagit quand on clique dessus
824
+  //                  .click(function(e){
825
+  //                    
826
+  //                    var id = str_replace('searched_tag_', '', $(this).attr('id'));
827
+  //                    var name = $('span#tag_prompt_tag_'+id+'_name').html();
828
+  //                                          
829
+  //                    $('input#tags_selected_tag_'+form_name).val(id);
830
+  //                    inputTag.val(name);
831
+  //                    // Et on execute l'évènement selectTag de l'input
832
+  //                    inputTag.trigger("selectTag");
833
+  //                    // On cache la liste puisque le choix vient d'être fait
834
+  //                    divtags.hide();
835
+  //                    // On vide le champs de saisie du tag
836
+  //                    $('input.form-default-value-processed').val('');
837
+  //                    return false;
838
+  //                  })
839
+  //                  .append(t_string)
840
+  //              ).append($('<span style="display: none;" id="tag_prompt_tag_'+tag_id+'_name">'+tag_name+'</span>'));
841
+  //
842
+  //              // Si on depasse les 30 tags
843
+  //              if (i > 30)
844
+  //              {
845
+  //                more = true;
846
+  //                // On le cache
847
+  //                li_tag.hide();
848
+  //              }
849
+  //
850
+  //              // On ajout ce li a la liste
851
+  //              search_tag_list.append(li_tag);
852
+  //            } 
853
+  //
854
+  //            if (more)
855
+  //            {
856
+  //              divtags.find('a.more').show();
857
+  //            }
858
+  //            
859
+  //            span_info.show();
860
+  //            span_info.text(data.message);
861
+  //            // Et on affiche la liste
862
+  //            search_tag_list.show();
863
+  //          }
864
+  //          else
865
+  //          {
866
+  //            span_info.show();
867
+  //            span_info.text(data.message);
868
+  //            search_tag_list.show();
869
+  //            
870
+  //            // Dans ce cas ou aucun tag n'a été trouvé, la proposition 
871
+  //            // d'ajout s'affichecf en dessous
872
+  //            
873
+  //            //span_info.text("Aucun tag de trouvé pour \""+inputTag.val()+"\"");
874
+  //          }
875
+  //          
876
+  //          // Si le tag ne semble pas connu en base
877
+  //          if (!data.same_found)
878
+  //          {
879
+  //            li_tag = 
880
+  //              $('<li>').addClass('new').append(
881
+  //                $('<a>').attr('href','#new#'+$.trim(input.val()))
882
+  //                // qui réagit quand on clique dessus
883
+  //                .click({
884
+  //                  inputTag: inputTag,
885
+  //                  form_name: form_name,
886
+  //                  divtags: divtags
887
+  //                }, event_click_new_tag_proposition)
888
+  //                .append($.trim(input.val()))
889
+  //            );
890
+  //            search_tag_list.append(li_tag);
891
+  //          }
892
+  //          
893
+  //        }
894
+  //
895
+  //        // On cache le loader
896
+  //        $('#tag_loader_'+form_name).hide();
897
+  //      }
898
+  //    }
899
+  //    });
900
+  //    
901
+  //    
902
+  //    //$.getJSON(url_search_tag+'/'+input.val()+'/'+ajax_query_timestamp, );
903
+  //    
904
+  //  }
905
+  //}
906
+  //
907
+  //function event_click_new_tag_proposition(event)
908
+  //{
909
+  //  form_add_open_dialog_for_new_tag($(event.target), event.data.inputTag, event.data.form_name, event.data.divtags);
910
+  //}
911
+  //
912
+  //function form_add_open_dialog_for_new_tag(link_add_tag, inputTag, form_name, divtags)
913
+  //{       
914
+  //  
915
+  //  
916
+  //  // Effet fade-in du fond opaque
917
+  //  $('body').append($('<div>').attr('id', 'fade')); 
918
+  //  //Apparition du fond - .css({'filter' : 'alpha(opacity=80)'}) pour corriger les bogues de IE
919
+  //  $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
920
+  //  
921
+  //  // En premier lieux on fait apparaître la fenêtre de confirmation
922
+  //  var popup = $('<div>')
923
+  //  .attr('id', 'add_tag')
924
+  //  .addClass('popin_block')
925
+  //  .css('width', '400px')
926
+  //    //.append($('<h2>').append(string_tag_add_title))
927
+  //  .append($('<form>')
928
+  //    .attr('action', url_add_tag)
929
+  //    .attr('method', 'post')
930
+  //    .attr('name', 'add_tag')
931
+  //    .ajaxForm(function(response) {
932
+  //      /*
933
+  //      *
934
+  //      */
935
+  //
936
+  //      if (response.status == 'mustbeconnected')
937
+  //      {
938
+  //        $(location).attr('href', url_index);
939
+  //      }
940
+  //
941
+  //      if (response.status == 'success')
942
+  //      {
943
+  //        var tag_id   = response.tag_id;
944
+  //        var tag_name = response.tag_name;
945
+  //
946
+  //        $('input#tags_selected_tag_'+form_name).val(tag_id);
947
+  //        inputTag.val(tag_name);
948
+  //        // Et on execute l'évènement selectTag de l'input
949
+  //        inputTag.trigger("selectTag");
950
+  //        // On cache la liste puisque le choix vient d'être fait
951
+  //        divtags.hide();
952
+  //
953
+  //        link_add_tag.parents('div.search_tag_list').find('img.tag_loader').hide();
954
+  //
955
+  //        $('#fade').fadeOut(400, function(){$('#fade').remove();});
956
+  //        $('#add_tag').remove();
957
+  //      }
958
+  //
959
+  //      if (response.status == 'error')
960
+  //      {
961
+  //        $('form[name="add_tag"]').find('ul.error_list').remove();
962
+  //        var ul_errors = $('<ul>').addClass('error_list');
963
+  //
964
+  //        for (i in response.errors)
965
+  //        {
966
+  //          ul_errors.append($('<li>').append(response.errors[i]));
967
+  //        }
968
+  //
969
+  //        $('form[name="add_tag"]').prepend(ul_errors);
970
+  //      }
971
+  //
972
+  //      return false;
973
+  //    })
974
+  //
975
+  //    .append($('<div>').addClass('tag')
976
+  //      .append($('<ul>')
977
+  //        .append($('<li>').addClass('button')
978
+  //          .append(link_add_tag.text()))))
979
+  //    .append($('<p>').append(string_tag_add_text))
980
+  //    .append($('<p>').append(string_tag_add_argument))
981
+  //    .append($('<textarea>').attr('name', 'argument'))
982
+  //    .append($('<div>').addClass('inputs')
983
+  //      .append($('<input>')
984
+  //        .attr('type', 'button')
985
+  //        .attr('value', string_tag_add_inputs_cancel)
986
+  //        .addClass('button')
987
+  //        .click(function(){
988
+  //          $('#fade').fadeOut(1000, function(){$('#fade').remove();});
989
+  //          $('#add_tag').remove();
990
+  //
991
+  //          return false;
992
+  //        })
993
+  //      )
994
+  //      .append($('<input>')
995
+  //        .attr('type', 'submit')
996
+  //        .attr('value', string_tag_add_inputs_submit)
997
+  //        .addClass('button')
998
+  //        .click(function(){
999
+  //
1000
+  //          link_add_tag.parents('div.search_tag_list').find('img.tag_loader').show();
1001
+  //
1002
+  //        })
1003
+  //      )
1004
+  //      .append($('<input>').attr('type', 'hidden').attr('name', 'tag_name').val(link_add_tag.text()))
1005
+  //    ))
1006
+  //  ;
1007
+  //
1008
+  //  // Il faut ajouter le popup au dom avant de le positionner en css
1009
+  //  // Sinon la valeur height n'est pas encore calculable
1010
+  //  $('body').prepend(popup);
1011
+  //
1012
+  //  //Récupération du margin, qui permettra de centrer la fenêtre - on ajuste de 80px en conformité avec le CSS
1013
+  //  var popMargTop = (popup.height() + 50) / 2;
1014
+  //  var popMargLeft = (popup.width() + 50) / 2;
1015
+  //
1016
+  //  //On affecte le margin
1017
+  //  $(popup).css({
1018
+  //    'margin-top' : -popMargTop,
1019
+  //    'margin-left' : -popMargLeft
1020
+  //  });
1021
+  //
1022
+  //  return false;
1023
+  //}
1024
+  //
1025
+  //var last_keypress = 0;
1026
+  //
1027
+  //function check_timelaps_and_search(input, form_name, time_id, timed, info)
1028
+  //{
1029
+  //  if (!timed)
1030
+  //  {
1031
+  //    // C'est une nouvelle touche (pas redirigé) on lui donne un id
1032
+  //    // et on met a jour l'id de la dernière pressé
1033
+  //    last_keypress = new Date().getTime(); 
1034
+  //    var this_time_id = last_keypress;
1035
+  //  }
1036
+  //  else
1037
+  //  {
1038
+  //    // Si elle a été redirigé, on met son id dans cette variable
1039
+  //    var this_time_id = time_id;
1040
+  //  }
1041
+  //  
1042
+  //  // C'est une touche redirigé dans le temps qui a été suivit d'une autre touche
1043
+  //  if (time_id != last_keypress && timed)
1044
+  //  {
1045
+  //    // elle disparait
1046
+  //  }
1047
+  //  else
1048
+  //  {
1049
+  //    //
1050
+  //    if ((new Date().getTime() - last_keypress) < 600 || timed == false)
1051
+  //    {
1052
+  //      // Si elle vient d'être tapé (timed == false) elle doit attendre (au cas ou une autre touche soit tapé)
1053
+  //      // Si c'est une redirigé qui n'a pas été remplacé par une nouvelle lettre
1054
+  //      // elle doit attendre au cas ou soit pressé.
1055
+  //      setTimeout(function(){check_timelaps_and_search(input, form_name, this_time_id, true, info)}, 700);
1056
+  //    }
1057
+  //    else
1058
+  //    {
1059
+  //      // il n'y a plus a attendre, on envoie la demande de tag.
1060
+  //      autocomplete_tag(input, form_name);
1061
+  //    }
1062
+  //  }
1063
+  //}
1064
+  //
1065
+  //// Autocompletion de tags
1066
+  //$("div.tags_prompt ul.tagbox li.input input").live('keypress', function(e){
1067
+  //  
1068
+  //  var form_name = $(this).parents('form').attr('name');
1069
+  //  var code = (e.keyCode ? e.keyCode : e.which);
1070
+  //
1071
+  //  if ((e.which !== 0 && e.charCode !== 0) || (code == 8 || code == 46))
1072
+  //  {
1073
+  //    check_timelaps_and_search($(this), form_name, new Date().getTime(), false, $(this).val());
1074
+  //  }
1075
+  //   
1076
+  //});
1077
+  //
1078
+  //// Un click sur ce lien affiche tout les tags cachés de la liste
1079
+  //$('div.search_tag_list a.more').live('click', function(){
1080
+  //  jQuery.each( $(this).parent('div').find('ul.search_tag_list li') , function(){
1081
+  //    $(this).show();
1082
+  //  });
1083
+  //  $(this).hide();
1084
+  //  return false;
1085
+  //});
1086
+  //
1087
+  //$('ul.tagbox li.input input[type="text"]').formDefaults();
1088
+  //
1080 1089
   ////////////////// FIN TAG PROMPT ///////////////
1081 1090
  
1082 1091
   // Suppression d'un element
@@ -1348,15 +1357,12 @@ $(document).ready(function(){
1348 1357
     
1349 1358
     var form_name = "add";
1350 1359
     var tag_id = str_replace('#', '', $(this).attr('href'));
1351
-    var input_tag = $("div.tags_prompt ul.tagbox li.input input");
1352 1360
     
1353 1361
     // Si on connait le tag id (pas un nouveau tag donc)
1354 1362
     if (tag_id)
1355 1363
     {
1356
-      $('input#tags_selected_tag_'+form_name).val(tag_id);
1357
-      input_tag.val($(this).text());
1358
-      // Et on execute l'évènement selectTag de l'input
1359
-      input_tag.trigger("selectTag");
1364
+      var tag = new Tag(tag_id, $(this).text());
1365
+      window.add_tag_prompt_connector.addTagToTagPrompt(tag);
1360 1366
     }
1361 1367
     else
1362 1368
     {

+ 510 - 0
web/js/lib/TagPrompt.js Просмотреть файл

@@ -0,0 +1,510 @@
1
+function TagPrompt(select_tag_callback, tag_prompt_connector)
2
+{
3
+  
4
+  /* @var tags_selected array of Tag */
5
+  var tags_selected = [];
6
+  /* @var tags_proposed array of Tag */
7
+  var tags_proposed = [];
8
+  var _select_tag_callback = select_tag_callback;
9
+  var _tag_prompt_connector = tag_prompt_connector;
10
+  
11
+  this.getProposedTagsForString = function(search_string, callback_success, callback_error)
12
+  {
13
+    tags_proposed = [];
14
+    JQueryJson(url_search_tag, {'string_search': search_string}, function(response){
15
+      if (response.status == 'error')
16
+      {
17
+        callback_error(response.error);
18
+      }
19
+      else if (response.status == 'success')
20
+      {
21
+        for (i in response.data)
22
+        {
23
+          var tag = new Tag(
24
+            response.data[i].id,
25
+            response.data[i].name
26
+          );
27
+          tags_proposed.push(tag);
28
+        }
29
+        callback_success(tags_proposed, search_string, response.message, response.same_found);
30
+      }
31
+    });
32
+  }
33
+  
34
+  this.selectProposedTag = function (tag_id, tag_name)
35
+  {
36
+    if (!tag_id)
37
+    {
38
+      openTagSubmission(tag_name);
39
+    }
40
+    else
41
+    {
42
+      addTagToSelectedTags(findTagInProposedList(tag_id));
43
+      _select_tag_callback(tags_selected);
44
+    }
45
+  }
46
+  
47
+  var openTagSubmission = function (tag_name)
48
+  {
49
+    // TODO : Cette partie du code n'est pas encore refactorisé
50
+    
51
+    // Effet fade-in du fond opaque
52
+    $('body').append($('<div>').attr('id', 'fade')); 
53
+    //Apparition du fond - .css({'filter' : 'alpha(opacity=80)'}) pour corriger les bogues de IE
54
+    $('#fade').css({'filter' : 'alpha(opacity=80)'}).fadeIn();
55
+    
56
+    // En premier lieux on fait apparaître la fenêtre de confirmation
57
+    var popup = $('<div>')
58
+    .attr('id', 'add_tag')
59
+    .addClass('popin_block')
60
+    .css('width', '400px')
61
+      //.append($('<h2>').append(string_tag_add_title))
62
+    .append($('<form>')
63
+      .attr('action', url_add_tag)
64
+      .attr('method', 'post')
65
+      .attr('name', 'add_tag')
66
+      .ajaxForm(function(response) {
67
+        /*
68
+        *
69
+        */
70
+  
71
+        if (response.status == 'mustbeconnected')
72
+        {
73
+          $(location).attr('href', url_index);
74
+        }
75
+  
76
+        if (response.status == 'success')
77
+        {
78
+          var tag = new Tag(response.tag_id, response.tag_name);
79
+          addTagToProposedTags(tag);
80
+          addTagToSelectedTags(tag);
81
+          _tag_prompt_connector.updateOutput(tags_selected);
82
+  
83
+          $('#fade').fadeOut(400, function(){$('#fade').remove();});
84
+          $('#add_tag').remove();
85
+        }
86
+  
87
+        if (response.status == 'error')
88
+        {
89
+          $('form[name="add_tag"]').find('ul.error_list').remove();
90
+          var ul_errors = $('<ul>').addClass('error_list');
91
+  
92
+          for (i in response.errors)
93
+          {
94
+            ul_errors.append($('<li>').append(response.errors[i]));
95
+          }
96
+  
97
+          $('form[name="add_tag"]').prepend(ul_errors);
98
+        }
99
+  
100
+        return false;
101
+      })
102
+  
103
+      .append($('<div>').addClass('tag')
104
+        .append($('<ul>')
105
+          .append($('<li>').addClass('button')
106
+            .append(tag_name))))
107
+      .append($('<p>').append(string_tag_add_text))
108
+      .append($('<p>').append(string_tag_add_argument))
109
+      .append($('<textarea>').attr('name', 'argument'))
110
+      .append($('<div>').addClass('inputs')
111
+        .append($('<input>')
112
+          .attr('type', 'button')
113
+          .attr('value', string_tag_add_inputs_cancel)
114
+          .addClass('button')
115
+          .click(function(){
116
+            $('#fade').fadeOut(1000, function(){$('#fade').remove();});
117
+            $('#add_tag').remove();
118
+  
119
+            return false;
120
+          })
121
+        )
122
+        .append($('<input>')
123
+          .attr('type', 'submit')
124
+          .attr('value', string_tag_add_inputs_submit)
125
+          .addClass('button')
126
+          .click(function(){
127
+  
128
+            // TODO: loader gif
129
+  
130
+          })
131
+        )
132
+        .append($('<input>').attr('type', 'hidden').attr('name', 'tag_name').val(tag_name))
133
+      ))
134
+    ;
135
+  
136
+    // Il faut ajouter le popup au dom avant de le positionner en css
137
+    // Sinon la valeur height n'est pas encore calculable
138
+    $('body').prepend(popup);
139
+  
140
+    //Récupération du margin, qui permettra de centrer la fenêtre - on ajuste de 80px en conformité avec le CSS
141
+    var popMargTop = (popup.height() + 50) / 2;
142
+    var popMargLeft = (popup.width() + 50) / 2;
143
+  
144
+    //On affecte le margin
145
+    $(popup).css({
146
+      'margin-top' : -popMargTop,
147
+      'margin-left' : -popMargLeft
148
+    });
149
+  
150
+    return false;
151
+  }
152
+  
153
+  var addTagToSelectedTags = function(tag)
154
+  {
155
+    var found = false;
156
+    for (i in tags_selected)
157
+    {
158
+      if (tags_selected[i].id == tag.id)
159
+      {
160
+        found = true;
161
+      }
162
+    }
163
+    if (!found)
164
+    {
165
+      tags_selected.push(tag);
166
+    }
167
+  }
168
+  
169
+  var addTagToProposedTags = function(tag)
170
+  {
171
+    var found = false;
172
+    for (i in tags_proposed)
173
+    {
174
+      if (tags_proposed[i].id == tag.id)
175
+      {
176
+        found = true;
177
+      }
178
+    }
179
+    if (!found)
180
+    {
181
+      tags_proposed.push(tag);
182
+    }
183
+  }
184
+  
185
+  this.addTag = function(tag)
186
+  {
187
+    addTagToSelectedTags(tag);
188
+    addTagToProposedTags(tag);
189
+  }
190
+  
191
+  var findTagInProposedList = function(tag_id)
192
+  {
193
+    for (i in tags_proposed)
194
+    {
195
+      if (tags_proposed[i].id == tag_id)
196
+      {
197
+        return tags_proposed[i];
198
+      }
199
+    }
200
+    throw new Error("Unable to find the tag !")
201
+  }
202
+  
203
+  this.removeSelectedTag = function(tag_id)
204
+  {
205
+    var new_tags_selected = [];
206
+    for (i in tags_selected)
207
+    {
208
+      if (tags_selected[i].id != tag_id)
209
+      {
210
+        new_tags_selected.push(tags_selected[i]);
211
+      }
212
+    }
213
+    tags_selected = new_tags_selected;
214
+  }
215
+  
216
+  this.getSelectedTags = function()
217
+  {
218
+    return tags_selected;
219
+  }
220
+  
221
+  this.setSelectedTags = function(tags)
222
+  {
223
+    tags_selected = tags;
224
+  }
225
+  
226
+}
227
+
228
+function TagPromptConnector(input, output, proposition_list, tag_box, prompt_loader)
229
+{
230
+  var _input = input;
231
+  var _output = output;
232
+  var _tag_box_manager = new TagBoxManager(tag_box, this);
233
+  var _prompt_loader = prompt_loader;
234
+  
235
+  this.updateOutput = function(tags)
236
+  {
237
+    _output.val(array2json(tagsToArrayIds(tags)));
238
+    _tag_proposition_list.hide();
239
+    _tag_box_manager.update(tags);
240
+    cleanInput();
241
+  }
242
+  
243
+  var _tag_prompt = new TagPrompt(this.updateOutput, this);
244
+  var _tag_proposition_list = new TagPromptPropositionList(proposition_list, _tag_prompt.selectProposedTag, this);
245
+  
246
+  var cleanInput = function()
247
+  {
248
+    _input.val('');
249
+  }
250
+  
251
+  var showPromptLoader = function()
252
+  {
253
+    _prompt_loader.show();
254
+  }
255
+  
256
+  this.hidePromptLoader = function()
257
+  {
258
+    _prompt_loader.hide();
259
+  }
260
+  
261
+  var launchSearchTagsIdLastKeystroke = function(search_string)
262
+  {
263
+    if (search_string == _input.val())
264
+    {
265
+      displayTagsProposedSearchTags();
266
+    }
267
+  }
268
+  
269
+  var displayTagsProposedSearchTags = function()
270
+  {
271
+    var string_search = _input.val();
272
+    _tag_prompt.getProposedTagsForString(
273
+      string_search,
274
+      _tag_proposition_list.displayTagsPropositions,
275
+      _tag_proposition_list.displayError
276
+    );
277
+  }
278
+  
279
+  $(_input).bind('keyup', function() {
280
+    if ($(this).val().length > 0)
281
+    {
282
+      showPromptLoader();
283
+      setTimeout(launchSearchTagsIdLastKeystroke, 1000, [_input.val()]);
284
+    }
285
+  });
286
+  
287
+  var tagsToArrayIds = function(tags)
288
+  {
289
+    var tags_ids = [];
290
+    for (i in tags)
291
+    {
292
+      tags_ids.push(tags[i].id);
293
+    }
294
+    return tags_ids;
295
+  }
296
+  
297
+  this.removeSelectedTag = function(tag_id)
298
+  {
299
+    _tag_prompt.removeSelectedTag(tag_id);
300
+    this.updateOutput(_tag_prompt.getSelectedTags());
301
+  }
302
+  
303
+  this.initializeTags = function(tags)
304
+  {
305
+    _tag_prompt.setSelectedTags(tags);
306
+    this.updateOutput(_tag_prompt.getSelectedTags());
307
+  }
308
+  
309
+  this.addTagToTagPrompt = function(tag)
310
+  {
311
+    _tag_prompt.addTag(tag);
312
+    this.updateOutput(_tag_prompt.getSelectedTags());
313
+  }
314
+  
315
+}
316
+
317
+function TagBoxManager(tag_box, tag_prompt_connector)
318
+{
319
+  var _tag_prompt_connector = tag_prompt_connector;
320
+  var _tag_box = tag_box;
321
+  
322
+  this.update = function(tags)
323
+  {
324
+    _tag_box.find('li').remove();
325
+    for (i in tags)
326
+    {
327
+      _tag_box.append(getTagLine(tags[i]));
328
+    }
329
+  }
330
+  
331
+  var getTagLine = function (tag)
332
+  {
333
+    var line = $('<li>');
334
+    line.addClass('tag');
335
+    line.text(tag.name);
336
+    line.append(getCloseLink(tag));
337
+    
338
+    return line;
339
+  }
340
+  
341
+  var getCloseLink = function(tag)
342
+  {
343
+    var close_link = $('<a>');
344
+    close_link.addClass('close');
345
+    close_link.attr('href', '#');
346
+    close_link.data('tag_id', tag.id);
347
+    close_link.data('tag_name', tag.name);
348
+    close_link.text('close');
349
+    close_link.bind('click', function(){
350
+      _tag_prompt_connector.removeSelectedTag($(this).data('tag_id'));
351
+      return false;
352
+    });
353
+    
354
+    return close_link;
355
+  }
356
+  
357
+}
358
+
359
+function TagPromptPropositionList(proposition_list, click_tag_callback, tag_prompt_connector)
360
+{
361
+  var _proposition_list = proposition_list;
362
+  var _list;
363
+  var _limit_display_tags = 30;
364
+  var _click_tag_callback = click_tag_callback;
365
+  var _tag_prompt_connector = tag_prompt_connector;
366
+  
367
+  this.displayError = function(error_string)
368
+  {
369
+    initializeList();
370
+    var span_info = _proposition_list.find('span.info');
371
+    span_info.text(error_string);
372
+  }
373
+  
374
+  this.displayTagsPropositions = function(tags, search_string, message, same_found)
375
+  {
376
+    initializeList();
377
+    displayMessage(message);
378
+    for (i in tags)
379
+    {
380
+      addTagToList(tags[i], search_string);
381
+    }
382
+    if (!same_found)
383
+    {
384
+      addTagPropositionToList(new Tag(null, search_string));
385
+    }
386
+  }
387
+  
388
+  var initializeList = function()
389
+  {
390
+    _tag_prompt_connector.hidePromptLoader();
391
+    $(_proposition_list).show();
392
+    _list = _proposition_list.find('ul.search_tag_list');
393
+    _list.find('li').remove();
394
+    _proposition_list.find('a.more').hide();
395
+  }
396
+  
397
+  var displayMessage = function(message)
398
+  {
399
+    var span_info = _proposition_list.find('span.info');
400
+    span_info.text(message);
401
+  }
402
+  
403
+  var addTagToList = function(tag, search_string)
404
+  {
405
+    var line = '';
406
+    if (_list.find('li').length > _limit_display_tags)
407
+    {
408
+      line = getListLine(tag, true);
409
+      _proposition_list.find('a.more').show();
410
+    }
411
+    else
412
+    {
413
+      line = getListLine(tag, false);
414
+    }
415
+    
416
+    line = strongifySearchedLetters(line, search_string);
417
+    _list.append(line);
418
+  }
419
+  
420
+  var getListLine = function(tag, hide)
421
+  {
422
+    if (hide)
423
+    {
424
+      var line = $('<li style="display: none;">');
425
+    }
426
+    else
427
+    {
428
+      var line = $('<li>');
429
+    }
430
+    
431
+    return line.append(getTagLink(tag));
432
+  }
433
+  
434
+  var getTagLink = function(tag)
435
+  {
436
+    link = $('<a>');
437
+    link.attr('href', '#');
438
+    link.data('tag_id', tag.id);
439
+    link.data('tag_name', tag.name);
440
+    link.text(tag.name);
441
+    link.bind('click', function(){
442
+      _click_tag_callback($(this).data('tag_id'), $(this).data('tag_name'));
443
+      return false;
444
+    });
445
+    return link;
446
+  }
447
+  
448
+  var strongifySearchedLetters = function(line, search_string)
449
+  {
450
+    var name = line.find('a').text();
451
+    line.find('a').html(name.replace(new RegExp(search_string, "i"), "<strong>" + search_string + "</strong>"));
452
+    return line;
453
+  }
454
+  
455
+  var addTagPropositionToList = function(tag)
456
+  {
457
+    var line = getListLine(tag);
458
+    line.addClass('new');
459
+    _list.append(line);
460
+  }
461
+  
462
+  this.hide = function()
463
+  {
464
+    _proposition_list.hide();
465
+  }
466
+  
467
+}
468
+
469
+function Tag(id, name)
470
+{
471
+  /* @var _id int */
472
+  this.id = id;
473
+  /* @var _name string */
474
+  this.name = name;
475
+}
476
+
477
+Tag.prototype =
478
+{
479
+  isKnew: function()
480
+  {
481
+    if (this.id)
482
+    {
483
+      return true;
484
+    }
485
+    return false;
486
+  }
487
+}
488
+
489
+$(document).ready(function(){
490
+  // Ce code permet la fermeture de la propositions de tags lors d'un click sur la page
491
+  $('html').click(function() {
492
+    if ($("div.search_tag_list").is(':visible'))
493
+    {
494
+      $("div.search_tag_list").hide();
495
+    }
496
+  });
497
+  $("div.search_tag_list, div.search_tag_list a.more").live('click', function(event){
498
+    event.stopPropagation();
499
+    $("div.search_tag_list").show();
500
+  });
501
+  
502
+  $('div.search_tag_list a.more').live('click', function(){
503
+    $(this).parents('div.search_tag_list ').find('ul.search_tag_list li').show();
504
+    $(this).hide();
505
+    return false;
506
+  });
507
+  
508
+});
509
+
510
+// loaders