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







All Articles