Backbone et event doubleclick

Backbone et event doubleclick - HTML/CSS - Programmation

Marsh Posté le 13-05-2014 à 10:18:27    

Bonjour à tous !
 
Je développe (en tout cas j'essaie) une application de téléphonie qui utilise une API qui marche avec Slim et backbone.js.
 
Là où j'en suis j'aimerais pouvoir faire un double clique sur une ligne de mon tableau, et qu'à la réaction de se double click, le champ devienne un input text.  
Mon problème est le suivant, lorsque je clique, ce n'est pas seulement mon champ où j'ai cliqué qui se transforme en input text mais l'ensemble du tableau.
Le problème vient du fait que mon (this.$el) de ma fonction event est égal a l'ensemble du <div id ="contentComplement" ...> alors que j'aimerais que le addClass ne s'applique qu'au <td> concerné mais je ne sais pas comment faire.
 
Bref voici le code de app.js :

Code :
  1. app_router.on('route:getInfoContact', function (UserId) {
  2.             var PhoneUserContact = Backbone.Model.extend();
  3.             var PhoneUserContactsCollection = Backbone.Collection.extend({   
  4.                 url: 'http://localhost/keyyo_app/trunk/api/application/index/phone_user/'+UserId+'/contact',
  5.                 model: PhoneUserContact,
  6.                 parse: function(ajaxdata) {
  7.                     return ajaxdata.data;
  8.                 }
  9.             });
  10.             var myPhoneUserContacts = new PhoneUserContactsCollection();
  11.             var PhoneUserContactsView = Backbone.View.extend({
  12.                 el: '#contentComplement',
  13.                 initialize:function(){
  14.                     this.render();
  15.                     myPhoneUserContacts.bind('sync', this.render, this);
  16.                     myPhoneUserContacts.bind('reset', this.render, this);
  17.                     myPhoneUserContacts.fetch();
  18.                 },
  19.                 render: function () {
  20.                     var template = _.template($('#phoneUser-contacts-template').html(), {myPhoneUserContacts: myPhoneUserContacts.models});
  21.                     this.$el.html(template);
  22.                     this.input = this.$('.edit');
  23.                     return this;
  24.                 },
  25.                
  26.                
  27.                 events: {
  28.                     "dblclick .info"  : "edit",
  29.                 },
  30.                        
  31.              
  32.                 edit: function() {
  33.                   console.log(this.$el);
  34.                   this.$el.addClass("editing" );
  35.                   this.input.focus;
  36.                   console.log("Double Click" );
  37.                 },
  38.             });
  39.             var phoneUserContactsView = new PhoneUserContactsView();
  40.             phoneUserContactsView.render();
  41.         });


 
Et voici le code du .html qui m'affiche mon tableau
 

Code :
  1. <div id="contentComplement"></div>
  2.     <script type="text/template" id="phoneUser-contacts-template">
  3.         <table>
  4.                 <thead>
  5.                     <tr>
  6.                         <th>Contacts</th>
  7.                     </tr>
  8.                 </thead>
  9.             <tbody>
  10.            
  11.                 <% _.each(myPhoneUserContacts, function(myPhoneUserContacts) { %>
  12.                     <% _.each(myPhoneUserContacts.get('MAIL'), function(myPhoneUserMail) { %>
  13.                         <tr id="list">
  14.                             <td>
  15.                                 <div class ="info"><%= myPhoneUserMail.UsercValue%></div>
  16.                                 <input class="edit" type="text" value="<%= myPhoneUserMail.UsercValue%>">
  17.                             </td>
  18.                         </tr>
  19.                     <% }); %>
  20.                     <% _.each(myPhoneUserContacts.get('TEL'), function(myPhoneUserTel) { %>
  21.                         <tr id="list">
  22.                             <td>
  23.                                 <div class ="info"><%= myPhoneUserTel.UsercValue%></div>
  24.                                 <input class="edit" type="text" value="<%= myPhoneUserTel.UsercValue%>">
  25.                             </td>
  26.                         </tr>
  27.                     <% }); %>
  28.                 <% }); %>
  29.             </tbody>
  30.         </table>
  31.     </script>


 
Voila, l'erreur est peut etre simple, ou pas, mon code est peut etre horrible je sais pas trop étant donné que je débute avec backbone ..
Toujours est il que je suis bloqué sur ce point la !  
 
Merci a ceux qui prendront le temps de lire et de m'aider ! :)

Reply

Marsh Posté le 13-05-2014 à 10:18:27   

Reply

Marsh Posté le 13-05-2014 à 10:53:11    

Pourquoi $.el ?

Reply

Marsh Posté le 13-05-2014 à 10:56:45    

Pour récupérer l'élément de ma page. Mais comme c'est pas celui que je voulais j'ai tenter de mettre en "dur" à base de table > td etc. mais ça ne marchait plus, alors j'ai remis $.el pour fournir un code qui fonctionne (pas comme je voudrais mais au moins il fonctionne ^^)

Reply

Marsh Posté le 13-05-2014 à 11:04:23    

le plus simple dans backbone est de faire une vue globale PhoneUserContactsView qui contiendra une vue par ligne

 
Code :
  1. var LineView = Backbone.View.extend({
  2.     events:{
  3.           "dblclick .info"  : "edit",
  4.      }
  5.     render:function(){
  6.          //just the template of one line
  7.      }  
  8.            
  9.      edit: function() {
  10.           console.log(this.$el);
  11.           this.$el.addClass("editing" );
  12.           this.input.focus;
  13.           console.log("Double Click" );
  14.      },
  15. })
  16.  
  17. var PhoneUserContactsView = Backbone.View.extend({
  18.                el: '#contentComplement',
  19.                initialize:function(){
  20.                    this.subviews={};
  21.                    this.render();
  22.                    myPhoneUserContacts.bind('sync', this.render, this);
  23.                    myPhoneUserContacts.bind('reset', this.render, this);
  24.                    myPhoneUserContacts.fetch();
  25.                },
  26.                render: function () {
  27.                    var template = _.template($('#phoneUser-contacts-template').html(), {myPhoneUserContacts: myPhoneUserContacts.models});
  28.                    this.$el.html(template);
  29.                     var tbody =this.$('tbody');
  30.                     this.collection.each(function(contact){
  31.                              this.subviews[contact.id] = new LineView ({model:contact});
  32.                              this.subviews[contact.id].render();
  33.                              tbody.append(this.subviews[contact.id].$el);
  34.                      });
  35.                    this.$('body').
  36.                    this.input = this.$('.edit');
  37.                    return this;
  38.                },
  39.              
  40.              
  41.            });


il faut faire attention a purger dtes sous vues lorsque tu détruit ta vue principale pour éviter les fuites de mémoire


Message édité par flo850 le 13-05-2014 à 11:04:55

---------------

Reply

Marsh Posté le 13-05-2014 à 11:25:39    

Ok merci pour le conseil, j'en prend note !
Pour info (je sais pas si ça change quelque chose a ce conseil mais bon),
cette vue vient s'ajouter a deux autres déjà existante sur la page html.
 
Donc le code que tu m'as fourni je l'ai compris a peu près, et je l'ai récupérer, mais je ne vois pas ce que tu veux dire dans "//just the template of one line", concrètement je dois faire quoi a cet endroit ?
Et aussi, "this.subviews[contact.id]" est undefined (enfin this.subviews plus précisément) et comme je vois pas trop a quoi c'est censé correspondre je sais pas par quoi le remplacé ?
 
(j'ai remplacer this.collection.each par myPhoneUsersContacts parce que pareil, il était undefined sinon :) )

Reply

Marsh Posté le 13-05-2014 à 11:40:32    

1/ la il faut juste que tu fasse le rendu d'une ligne ( donc tu extrait la template d'une ligne et tu lui files ton model)

 

2/
typo de ma part, à remplacer par

Code :
  1. var self = this;
  2. this.collection.each(function(contact){
  3.                              self.subviews[contact.id] = new LineView ({model:contact});
  4.                              self.subviews[contact.id].render();
  5.                              tbody.append(self.subviews[contact.id].$el);
  6.                      });

 


Message édité par flo850 le 13-05-2014 à 11:41:24

---------------

Reply

Marsh Posté le 13-05-2014 à 12:03:50    

C'est modifier mais je n'arrive pas a modifier le html en conséquence, comme tu as pu le voir mon html gérait le boucle each et maintenant je ne vois pas comment l'adapter.
J'ai essayé avec des trucs comme <%- contact %> et pas mal d'autres chose mais rien trouver qui fonctionne malheureusement :( .
Et les deux templates doivent bien être l'un en dessous de l'autre, pas le deuxième dans le global ?

Reply

Marsh Posté le 13-05-2014 à 13:22:51    

Un truc comme ça : (approximatif, je préfère utiliser mustache en moteur de template)

Code :
  1. <script type="text/template" id="phoneUser-contacts-template">
  2.         <table>
  3.                 <thead>
  4.                     <tr>
  5.                         <th>Contacts</th>
  6.                     </tr>
  7.                 </thead>
  8.             <tbody>
  9.             </tbody>
  10.         </table>
  11.     </script>
  12. <script type="text/template" id="phoneUser-contacts-template-line">
  13.        
  14.                     <% _.each(myPhoneUserContacts.get('MAIL'), function(myPhoneUserMail) { %>
  15.                         <tr id="list">
  16.                             <td>
  17.                                 <div class ="info"><%= myPhoneUserMail.UsercValue%></div>
  18.                                 <input class="edit" type="text" value="<%= myPhoneUserMail.UsercValue%>">
  19.                             </td>
  20.                         </tr>
  21.                     <% }); %>
  22.                     <% _.each(myPhoneUserContacts.get('TEL'), function(myPhoneUserTel) { %>
  23.                         <tr id="list">
  24.                             <td>
  25.                                 <div class ="info"><%= myPhoneUserTel.UsercValue%></div>
  26.                                 <input class="edit" type="text" value="<%= myPhoneUserTel.UsercValue%>">
  27.                             </td>
  28.                         </tr>
  29.                     <% }); %>
  30. </script>
 
Code :
  1. //dans line
  2. render: function () {
  3.                    var template = _.template($('#phoneUser-contacts-template-line').html(), {myPhoneUserContacts: this.model});
  4.                    this.input = this.$('.edit');
  5.                    return this;
  6.                },


Message édité par flo850 le 13-05-2014 à 13:23:47

---------------

Reply

Marsh Posté le 13-05-2014 à 14:21:00    

Merci beaucoup de ton aide !  
J'ai adapté le code ( il manquait "this.$el.html(template);" dans le render inline ^^')
Par contre le problème de départ est toujours la, lorsque je double clique, tout mes td deviennent des text input :/
 
EDIT:  
 
Je pense que le problème est que le "this" contient un objet avec l'ensemble des input, alors que chaque input devrait être isolé ?


Message édité par scribou le 13-05-2014 à 14:31:48
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed