Search code examples
javascriptx-editable

X-editable how to show saved value if it is not in the dynamic source anymore


I am using X-editable with bootstrap in a new project.

I am using a dynamic source, which works fine. The new value is saved in the database, no problems there.

The thing is I have multiple select options, and some of them should only be selected once. That's why I am using a dynamic source.

The problem arises when I select one of the values that should only be selected once, because when the source is updated the saved value wont be in the source anymore. If I select any other value it shows the updated value correctly. And if I refresh the page the new value also shows correctly (but of course that is because $object->award->name in the html code simply displays the new value).

I tried many different things in the last few hours, but I cannot get this to work properly.

How can I solve this problem?

This is the javascript:

$(function(){
        //edit form style - popup or inline
        $.fn.editable.defaults.mode = 'popup';
        $('.pUpdate').editable({
            validate: function(value) {
                if($.trim(value) == '')
                    return 'Value is required.';
            },
            type: 'text',
            url: posturl,
            title: 'Edit Status',
            placement: 'top',
            send:'always',
            emptytext: 'Click to add a value',
            sourceCache: false,
            ajaxOptions: {
                dataType: 'json'
            },
            success: function(response, newValue) {

                // refresh total probability
                updateProbability();

                // this does not work:
                //var $that = $(this);
                //setTimeout(function() {
                //    $that.editable('option', 'source', {{ $app['url_generator']->generate('wheeloffortune-getawardsforselect', ['wheel_id' => $wheel->id]) }});
                //}, 0);

                // this does not work:
                // return {newValue: response.newValue};
            }
        })
    });

This is the html element:

<td><a class="pUpdate update_awards"
              data-pk="{{ $object->id }}"
              data-name="award_id"
              data-type="select"
              data-source="{{ $app['url_generator']->generate('myroute', ['param' => $object2->id]) }}"
              data-emptytext="Click to select a value"
              >{{ $object->award->name }}</a></td>

Solution

  • As far as I can tell, X-editable does not support this.

    So I had to resort to simply updating the text with jQuery. I made sure the json response contains the new text that I want to display, and in the success callback I am calling a function to update the text of the relevant element.

    The javascript will now look like this:

    $(function(){
        //edit form style - popup or inline
        $.fn.editable.defaults.mode = 'popup';
        $('.pUpdate').editable({
            validate: function(value) {
                if($.trim(value) == '')
                    return 'Value is required.';
            },
            type: 'text',
            url: posturl,
            title: 'Edit Status',
            placement: 'top',
            send:'always',
            emptytext: 'Click to add a value',
            sourceCache: false,
            ajaxOptions: {
                dataType: 'json'
            },
            success: function(response, newValue) {
    
                // refresh total probability
                updateProbability();
    
                // update text for award elements only
                var element = $(this);
                if(element.hasClass('update_awards')) {
                    updateText(element, response);
                }
            }
        })
    });
    
    function updateText(element, response) {
        $(document).ajaxComplete(function() {
            element.text(response.newText);
            element.removeClass('editable-empty');
        });
    }
    

    Note I also have to remove the editable-empty class.

    I might be a little lucky here, because I already have the function updateProbabilityAjax() in the success callback, which is doing an Ajax request, which is why I am ably to use .ajaxComplete(). I noticed that the success callback is fired as soon as X-editable gets a successful response from the server, but before it is finished with updating the element on the page. Without an jQuery ajax request to wait for, I would have no other option then to use setTimeout() in the function updateText. Without that, X-editable will actually update the element AFTER my function updateText updates it :)

    Hope this helps somebody!