Custom field plugin, struggling with initializing a field that needs to first exist on the DOM.

Custom field plugin, struggling with initializing a field that needs to first exist on the DOM.

washuit-iammwashuit-iamm Posts: 133Questions: 55Answers: 2

This might not be 100% a DataTables issue, but im hoping the DT API has something here that can help me.

I am trying to wrap this into a DTE Field Plugin: https://github.com/koss-lebedev/bootstrap-duration-picker

The problem is, that plugin tries to do something like this https://github.com/koss-lebedev/bootstrap-duration-picker/blob/master/src/bootstrap-duration-picker.js#L39

I found that because my input does not actually exist on the DOM it is hidden and then the new input is never added or created.

My plugin create basically looks like this:

conf._input = $('<input>');
conf._input.durationPicker();
return conf._input;

And my input ends up looking like this:

<input style="display: none;" />

How can I first attach the input to the DOM? setTimeout? Some type of callback?

Thanks

Answers

  • yokowasisyokowasis Posts: 24Questions: 7Answers: 0

    there is some kind of callback when new / edit button clicked. Also you can always init the duration picker after the new / edit button clicked.

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Would:

    conf._input = $('<input>').appendTo('body');
    conf._input.durationPicker();
    conf._input.remove();
    return conf._input;
    

    do?

    Allan

  • washuit-iammwashuit-iamm Posts: 133Questions: 55Answers: 2

    @allan Does not seem to do the trick. The setValue fails (onf._input.data('durationPicker').setValue(0)) because Duration.Plugin.js?v=MmRzVbG7EGg2X215091RfnCrhV-uE0pE7usyION9Lrk:41 Uncaught TypeError: Cannot read property 'setValue' of undefined

    Its acting like it was never initialized as a durationPicker. Im going to try the on init event for editor

  • washuit-iammwashuit-iamm Posts: 133Questions: 55Answers: 2

    More or less what I went with

        create: function (conf) {
    
            // Create and initalize a new durationPicker
            var input = $('<input type="text" class="form-control bdp-orig-input" value="0" style="display: none;">');                        
            input.durationPicker(conf.opts);
    
            // Get the newely created duration picker.
            // By default, boostrap-duration-picker places itself after the input.
            var durationPicker = input.next();
    
            // Support Bootstrap 4. `.hidden` is no more, we use `.d-none`.
            durationPicker.find(".hidden").each(function () {
                $(this)
                    .addClass('d-none');
            });
    
            // Create a wrapper to wrap the input and newly created boostrap-duration-picker
            var wrapper = $('<div>')
                .append(input)
                .append(durationPicker);
    
            conf._input = wrapper;
    
            return conf._input;
        },
    
        get: function (conf) {
            // Find the original input, and get its val()
            var origInput = $(conf._input.children('.bdp-orig-input').eq(0));
            return origInput.val();
        },
    
        set: function (conf, val) {
            // Find the original input, and pull the durationPicker instance out.
            conf._input.children('.bdp-orig-input').eq(0).data('durationPicker').setValue(val);
        }
    
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    And that is doing the job for you now? Super - thanks for sharing it!

    Allan

  • washuit-iammwashuit-iamm Posts: 133Questions: 55Answers: 2

    @allan Yes that works for me, why do you sound surprised? That makes me nervous like I did something wrong lol

    Also, for anyone else using .NET Core, I use moment and moment-duration-formatter plugin to do a quick format to a C# ViewModel TimeSpan property.

        get: function (conf) {
            // Find the orig input, and get its val()
            var origInput = $(conf._input.children('.bdp-orig-input').eq(0));
            var value = origInput.val();            
            return moment.duration(parseInt(value), 'seconds').format("DD:hh:mm:ss");
        },
    
        set: function (conf, val) {
            var duration = moment.duration(val, moment.ISO_8601);
            // Find the orig input, and pull the durationPicker instance out.
            conf._input.children('.bdp-orig-input').eq(0).data('durationPicker').setValue(duration.asSeconds());
        }
    
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Yes that works for me, why do you sound surprised?

    Haha - it was just one of those ones where I wasn't 100% sure what the cause was :).

    Allan

This discussion has been closed.