Custom field type for horizontal radio buttons

Custom field type for horizontal radio buttons

FurburgerFurburger Posts: 33Questions: 8Answers: 0

The radio field type that ships with Editor creates vertical radio buttons.

If you have a lot of radio button options, it can be useful to display them horizontally.

Here is the code for a custom radiobutton field type which will create horizontal radio buttons.

Usage example:

{
label: "Gender:",
name: "gender",
type: "radiobutton",
options: [
"Male",
"Female"
]
}

div.DTE_Field_Type_radiobutton div.controls label {
  margin-right: 1em;
  font-weight: normal;
}

div.DTE_Field_Type_radiobutton div.controls input {
  margin-right: 0.25em;
}
(function ($, DataTable) {

if ( ! DataTable.ext.editorFields ) {
    DataTable.ext.editorFields = {};
}

var Editor = DataTable.Editor;
var _fieldTypes = DataTable.ext.editorFields;


function _triggerChange ( input ) {
  setTimeout( function () {
    input.trigger( 'change', {editor: true, editorSet: true} ); // editorSet legacy
  }, 0 );
}

_fieldTypes.radiobutton =  {

  // Locally "private" function that can be reused for the create and update methods
  _addOptions: function ( conf, opts ) {
    var val, label;
    var elOpts = conf._input[0].options;
    var jqInput = conf._input.empty();

    if ( opts ) {
      Editor.pairs( opts, conf.optionsPair, function ( val, label, i ) {

        jqInput.append(
          '<label for="'+Editor.safeId( conf.id )+'_'+i+'">'+
          '<input id="'+Editor.safeId( conf.id )+'_'+i+'" type="radio" name="'+conf.name+'" />'+
          label+'</label>'
        );

        /*jqInput.append(
          '<div>'+
            '<label for="'+Editor.safeId( conf.id )+'_'+i+'">'+
            '<input id="'+Editor.safeId( conf.id )+'_'+i+'" type="radio" name="'+conf.name+'" />'+
            label+'</label>'+
          '</div>'
        );*/


        $('input:last', jqInput).attr('value', val)[0]._editor_val = val;
      } );
    }
  },


  create: function ( conf ) {
    conf._input = $('<div />');
    _fieldTypes.radiobutton._addOptions( conf, conf.options || conf.ipOpts );

    this.on('open', function () {
      conf._input.find('input').each( function () {
        if ( this._preChecked ) {
          this.checked = true;
        }
      } );
    } );

    return conf._input[0];
  },

  get: function ( conf ) {
    var el = conf._input.find('input:checked');
    return el.length ? el[0]._editor_val : undefined;
  },

  set: function ( conf, val ) {
    var that  = this;

    conf._input.find('input').each( function () {
      this._preChecked = false;

      if ( this._editor_val == val ) {
        this.checked = true;
        this._preChecked = true;
      }
      else {
        // In a detached DOM tree, there is no relationship between the
        // input elements, so we need to uncheck any element that does
        // not match the value
        this.checked = false;
        this._preChecked = false;
      }
    } );

    _triggerChange( conf._input.find('input:checked') );

  },

  enable: function ( conf ) {
    conf._input.find('input').prop('disabled', false);
  },

  disable: function ( conf ) {
    conf._input.find('input').prop('disabled', true);
  },

  update: function ( conf, options ) {
    var radio = _fieldTypes.radiobutton;
    var currVal = radio.get( conf );

    radio._addOptions( conf, options );

    // Select the current value if it exists in the new data set, otherwise
    // select the first radio input so there is always a value selected
    var inputs = conf._input.find('input');
    radio.set( conf, inputs.filter('[value="'+currVal+'"]').length ?
      currVal :
      inputs.eq(0).attr('value')
    );
  }

};


})(jQuery, jQuery.fn.dataTable);

Replies

  • allanallan Posts: 51,467Questions: 1Answers: 7,761 Site admin

    Hi,

    Thanks very much for this! I don't think it should be necessary to go as far as a custom field type plug-in though. This CSS should be all that is needed:

    div.DTE_Field_Type_radio div.DTE_Field_InputControl > div > div {
      float: left;
      width: 33%; /* change as needed */
    }
    

    This uses floats. You could use flex box if you prefer.

    Allan

  • FurburgerFurburger Posts: 33Questions: 8Answers: 0

    You could solve it with CSS, but then ALL your radio buttons would be horizontal (or vertical).

    By creating an additional field type, it allows you to choose whether you want horizontal or vertical radio buttons for each implementation of a field.

  • allanallan Posts: 51,467Questions: 1Answers: 7,761 Site admin

    Actually, Editor adds a class name based on the field's name as well as the field type, so you can target specific fields:

    div.DTE_Field_Type_radio.DTE_Field_Name_{myFieldName} div.DTE_Field_InputControl > div > div {
      float: left;
      width: 33%; /* change as needed */
    }
    

    replacing {myFieldName} witht he field name as required of course.

    Either approach is perfectly valid I think. Plug-ins are there to be used!

    Allan

This discussion has been closed.