Bind the event to the body, but not the current element, then unbind it inside the callback
I want to convert tr
to input
on doubleclick
, let the user edit it, and then when they go out of bounds, I call a function to update the db and restore the table row and unbind the event. of course it doesn't work as expected.
var edit_event;
$('.editable-column').on('dblclick',function(e){
//make editable
var type = $(this).data('type'),
val = $(this).text(),
id= $(this).parents('tr').data('id'),
column = $(this).data('column'),
model = $(this).parents('table').data('model');
if(type == 'textarea'){
$(this).html('<textarea data-id="'+id+'" data-model="'+model+'" data-column="'+column+'" class="editing" style="min-height: 80px;">'+val+'</textarea>');
}
if(type == 'input'){
$(this).html('<input data-id="'+id+'" data-model="'+model+'" data-column="'+column+'" class="editing" type="text" value="'+val+'" />');
}
edit_event = $('body').not(this)[0].addEventListener('click',function(e){
//save model
var $el = $('.editing');
var id= $el.data('id'),
column = $el.data('column'),
model = $el.data('model'),
val = $el.val();
$el.parent('td').html( val );
updateModel(model,id,column,val);
$('body')[0].removeEventListener('click',edit_event);
edit_event = null;
});
});
Adding some html to clean up the image
<table data-model="video">
<tbody>
{% for item in pending_videos %}
<tr data-id="{{item.id}}" data-type="{{item.type}}" data-file="{{item.video_file}}">
<td style="text-align:center">
<button type="button" class="preview-vid btn btn-md btn-default" data-toggle="modal" data-target="#preview-window" >
<i class="fa fa-play"></i>
</button>
<button type="button" class="approve-vid btn btn-md btn-success">
<i class="fa fa-check"></i>
</button>
<button type="button" class="delete-vid btn btn-md btn-danger">
<i class="fa fa-times"></i>
</button>
</td>
<td class="editable-column" data-type="input">{{item.title}}</td>
<td class="editable-column" data-type="textarea">{{item.description}}</td>
<td>{{item.upload_date|date('m/d/Y')}}</td>
<td>
<select class="cat-opts select-onload video-category" data-selected="{{item.videocategory_id}}" autocomplete="off">
{{category_options|raw}}
</select>
</td>
</tr>
{% endfor %}
</tbody>
</table>
+3
source to share
1 answer
So after discussing it with a friend, I was able to see a much simpler solution.
Instead of trying to listen to the second event in the body, I just focus the input and bind it to the event blur
.
$('.editable-column').on('dblclick',function(e){
//make editable
var type = $(this).data('type'),
val = $(this).text(),
id= $(this).parents('tr').data('id'),
column = $(this).data('column'),
model = $(this).parents('table').data('model');
if(type == 'textarea'){
$(this).html('<textarea data-id="'+id+'" data-model="'+model+'" data-column="'+column+'" class="editing" style="min-height: 80px;">'+val+'</textarea>');
}
if(type == 'input'){
$(this).html('<input data-id="'+id+'" data-model="'+model+'" data-column="'+column+'" class="editing" type="text" value="'+val+'" />');
}
//focus input then listen for blur
$(this).children(':input').focus().blur(function(){
//save model
var $el = $('.editing');
var id= $el.data('id'),
column = $el.data('column'),
model = $el.data('model'),
val = $el.val();
$el.parent('td').html( val );
updateModel(model,id,column,val);
});
});
0
source to share