Editor Field Plugin

Editor Field Plugin

mguinnessmguinness Posts: 61Questions: 10Answers: 1

There are already several Field type plug-ins for Editor. I came across International Telephone Input control which seems like it could be a nice addition.

Maybe this could be added as a field type plugin for Editor? I don't have the requisite skills to create a custom plug-in, but maybe someone else can.

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 54,528Questions: 1Answers: 8,526 Site admin

    You can actually do this one without the need for a plug-in, since it works by just giving it an input element to work with. You can get that for a field using the field().input() method - here is an example: http://live.datatables.net/nuvihosi/92/edit .

    Nice input library that - thanks for introducing me to it.

    Allan

  • mguinnessmguinness Posts: 61Questions: 10Answers: 1

    Thanks Allan. Although on the surface that appears to work, it doesn't when using it in conjunction with libphonenumber and storing numbers in the database as E.164 standard.

    The reason is that when using that library you need to use Public Methods getNumber() and setNumber() for the country selection and formatting to work. See crude example below:

    http://live.datatables.net/yomenika/1/edit?js,console,output

    If developed using plug-in interface I see that the getNumber() and setNumber() functions would map nicely with the get() and set() functions of the plugin.

    There is a hiddenInput Initialisation Option though that would add complexity, but I'm open to suggestions on getting this working.

  • allanallan Posts: 54,528Questions: 1Answers: 8,526 Site admin

    Ah - yes, if you need to use methods such as getNumber and setNumber, then a field type plug-in would be the way to do it.

    I've made a little attempt at it: http://live.datatables.net/qicamepe/1/edit .

    But the getNumber() method is always giving me an empty string. Have you used this input elsewhere? Perhaps you can see something daft I've done?

    Allan

  • mguinnessmguinness Posts: 61Questions: 10Answers: 1
    edited April 22

    Thanks so much for looking into this further. From a quick look I think you missed adding the Utilities Script. I just added the following to the HTML and it appears to work now.

    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/js/utils.min.js"></script>

    BTW, you can also format the phone number in the grid with formatNumber function.

    {
      "data": "tel", "render": function (data, type, row, meta) {
        return intlTelInputUtils.formatNumber(data, null, intlTelInputUtils.numberFormat.NATIONAL);
      }
    }
    
  • mguinnessmguinness Posts: 61Questions: 10Answers: 1

    I changed the field definition to also pass initialization options to the control.

    fields: [
        {
            label: "Telephone number:",
            name: "tel",
            type: 'telephone',
            opts: {
                preferredCountries: [],
                onlyCountries: ['au', 'ca', 'nz', 'gb', 'us'],
                initialCountry: 'us'
            }
        }
    ]
    

    I also added the close event since the initial country wasn't getting reset when the editor closed - it would stay on the last selected country.

    DataTable.ext.editorFields.telephone = {
        create: function (conf) {
            conf._input = $('<input>');
    
            this.one('open', function () {
                var options = $.extend({
                    dropdownContainer: document.body
                }, conf.opts);
    
                conf._tel = intlTelInput(conf._input[0], options);
    
                if (conf._initSet) {
                    conf._tel.setNumber(conf._initSet);
                }
            });
    
            this.on('close', function () {
                conf._tel.setCountry(conf.opts.initialCountry || '');
            });
    
            return conf._input[0];
        },
    
        get: function (conf) {
            return conf._tel.getNumber();
        },
    
        set: function (conf, val) {
            if (!conf._tel) {
                conf._initSet = val;
            }
            else {
                conf._tel.setNumber(val);
            }
        }
    };
    

    This seems to be working well, hopefully others will find it useful. I think this would be a good field type plug-in addition as it's such a common use case.

  • allanallan Posts: 54,528Questions: 1Answers: 8,526 Site admin
    Answer ✓

    That's very cool - many thanks! I'll get it added into the list :).

    Allan

  • mguinnessmguinness Posts: 61Questions: 10Answers: 1

    Below is my attempt to cobble together a plugin:

    /**
     * Use the [International Telephone Input](https://intl-tel-input.com/) telephone input control in Editor.
     */
    
    (function( factory ){
        if ( typeof define === 'function' && define.amd ) {
            // AMD
            define( ['jquery', 'datatables', 'datatables-editor'], factory );
        }
        else if ( typeof exports === 'object' ) {
            // Node / CommonJS
            module.exports = function ($, dt) {
                if ( ! $ ) { $ = require('jquery'); }
                factory( $, dt || $.fn.dataTable || require('datatables') );
            };
        }
        else if ( jQuery ) {
            // Browser standard
            factory( jQuery, jQuery.fn.dataTable );
        }
    }(function( $, DataTable ) {
    'use strict';
    
    
    if ( ! DataTable.ext.editorFields ) {
        DataTable.ext.editorFields = {};
    }
    
    var _fieldTypes = DataTable.Editor ?
        DataTable.Editor.fieldTypes :
        DataTable.ext.editorFields;
    
    
    _fieldTypes.telephone = {
        create: function (conf) {
            conf._input = $('<input>');
    
            this.one('open', function () {
                var options = $.extend({
                    dropdownContainer: document.body
                }, conf.opts);
    
                conf._tel = conf._input.intlTelInput(options);
    
                if (conf._initSet) {
                    conf._tel.intlTelInput('setNumber', conf._initSet);
                }
            });
    
            return conf._input[0];
        },
    
        get: function (conf) {
            return conf._tel.intlTelInput('getNumber', intlTelInputUtils.numberFormat.INTERNATIONAL);
        },
    
        set: function (conf, val) {
            if (!conf._tel) {
                conf._initSet = val;
            }
            else {
                conf._tel.intlTelInput('setCountry', conf.opts.initialCountry || '');
                conf._tel.intlTelInput('setNumber', val);
            }
        },
    
        enable: function ( conf ) {},
    
        disable: function ( conf ) {},
    
        destroy: function (conf) {
            this.off( 'open' );
        }
    };
    
    
    }));
    

    You need to include the following into your HTML:

    <link href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/css/intlTelInput.min.css" type="text/css" />
    
    <style>
        .iti.iti--allow-dropdown {
            width: 100%;
        }
    </style>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/js/intlTelInput-jquery.min.js" type="text/javascript"></script>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.12/js/utils.min.js" type="text/javascript"></script>
    

    Below is an example field configuration:

    {
        label: "Telephone number:",
        name: "tel",
        type: "telephone",
        opts: {
            initialCountry: 'us'
        }
    }
    
  • allanallan Posts: 54,528Questions: 1Answers: 8,526 Site admin

    Nice one - thanks for sharing that with us!

    Allan

Sign In or Register to comment.