Initialization needed for custom fieldType

Initialization needed for custom fieldType

klinkklink Posts: 3Questions: 0Answers: 0
edited August 2013 in Editor
Hello,

I am new with Editor and Datatables, but already worked with it for some days so now I think it is OK to ask a question here.

I created a new fieldType for Editor, it basically adds a "+" and "-" button besides a text inputfield to increment/decrement numeric values.

It is very basic and works fine, but only after I hit the "New" button in Datatables.
If I reload the page and edit a Row in Editor, the "set" Function of my new dataType is not called (I debugged with console.log) and therefore the value is not set in the inputfield. If I hit the "New" Button, then close the Editor and edit a row anything works fine and the setter is called.

Seems like there is some initialization needed. Can anyone help?

Here is my fieldType:
[code]
$.fn.DataTable.Editor.fieldTypes.plusminus = $.extend( true, {}, $.fn.DataTable.Editor.models.fieldType, {
"create": function ( conf ) {
var that = this;

conf._enabled = true;

conf._input = $(
''+
'-'+
'' +
'+'+
'')[0];

$('button.inputButton', conf._input).click( function () {

var value = new Number(0);
if ($.isNumeric($('#' + conf.id).val())) {
var value = new Number($('#' + conf.id).val());
}
if ($.isNumeric($(this).attr('value'))) {
var change = new Number($(this).attr('value'));
value = value + change;
$('#' + conf.id).val(value);
}
return false;
} );

return conf._input;
},

"get": function ( conf ) {
return $('#' + conf.id).val(val);
},

"set": function ( conf, val ) {
if ( ! conf._enabled ) {
return;
}
if ($.isNumeric(val)) {
$('#' + conf.id).val(val);
}
else {
$('#' + conf.id).val(0);
}
},

"enable": function ( conf ) {
conf._enabled = true;
},

"disable": function ( conf ) {
conf._enabled = false;
}
} );
[/code]

Replies

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    The problem is with this:

    > $('#' + conf.id)

    That is querying the document (since there is no context specified), but your element (and more generally the Editor field) doesn't get added to the document until a later time.

    So what to do, is just give jQuery the specific context:

    [code]
    $('#' + conf.id, conf._input)
    [/code]

    That will then work before and after it has been attached to the document.

    Regards,
    Allan
  • klinkklink Posts: 3Questions: 0Answers: 0
    Oh, that is excellent, thanks a lot. It works like a charm. I will add some more functionality and then post the snippet here, just in case it could be useful for somebody else.

    Have a nice day!

    Lukas
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin
    Sounds great! I look forward to seeing the finished plug-in!

    Allan
  • klinkklink Posts: 3Questions: 0Answers: 0
    edited August 2013
    OK, here is the working version. I know it is not very nice JavaScript but it works very nice. Don't know if it is against some Datatables Guidelines to extend thie fields definition?

    The Function
    [code]
    $.fn.DataTable.Editor.fieldTypes.plusminus = $.extend( true, {}, $.fn.DataTable.Editor.models.fieldType, {
    "create": function ( conf ) {
    var that = this;

    conf._change = 1;
    conf._min = false;
    conf._max = false;
    conf._buttonClass = 'inputButton';
    conf._inputClass = '';
    if (typeof conf.min != 'undefined') {
    if ($.isNumeric(conf.min)) {
    conf._min = new Number(conf.min);
    }
    }
    if (typeof conf.max != 'undefined') {
    if ($.isNumeric(conf.max)) {
    conf._max = new Number(conf.max);
    }
    }
    if (typeof conf.change != 'undefined') {
    if ($.isNumeric(conf.change)) {
    conf._change = new Number(conf.change);
    }
    }
    if (typeof conf.buttonClass != 'undefined') {
    conf._buttonClass = conf.buttonClass;
    }
    if (typeof conf.inputClass != 'undefined') {
    conf._inputClass = conf.inputClass;
    }

    conf._enabled = true;

    conf._input = $(
    ''+
    '' +
    '-'+
    '' +
    '+'+
    '')[0];

    $('button.' + conf._buttonClass, conf._input).click( function () {
    var value = new Number(0);
    if ($.isNumeric($('#' + conf.id).val())) {
    var value = new Number($('#' + conf.id, conf._input).val());
    }

    if ($(this).attr('value') == '-') {
    newvalue = value - conf._change;
    }
    else {
    newvalue = value + conf._change;
    }
    if (conf._min !== false) {
    if (newvalue < conf._min) {
    newvalue = value;
    }
    }
    if (conf._max !== false) {
    if (newvalue > conf._max) {
    newvalue = value;
    }
    }
    $('#' + conf.id, conf._input).val(newvalue);
    $('#' + conf.id + 'Display', conf._input).val(newvalue);
    return false;
    } );

    return conf._input;
    },

    "get": function ( conf ) {
    return $('#' + conf.id, conf._input).val();
    },

    "set": function ( conf, val ) {
    if ( ! conf._enabled ) {
    return;
    }
    if ($.isNumeric(val)) {
    $('#' + conf.id, conf._input).val(val);
    $('#' + conf.id + 'Display', conf._input).val(val);
    }
    else {
    $('#' + conf.id, conf._input).val(0);
    $('#' + conf.id + 'Display', conf._input).val(0);
    }
    },

    "enable": function ( conf ) {
    conf._enabled = true;
    },

    "disable": function ( conf ) {
    conf._enabled = false;
    }
    } );
    [/code]


    It is implemented in field definition like this
    [code]
    {
    "label": "Anzahl:",
    "type": "plusminus",
    "change": "2",
    "min": "0",
    "max": "10",
    "buttonClass": "inputButtonPlusminus",
    "inputClass": "inputPlusminus"
    }
    [/code]

    With this CSS it looks very nice:
    [code]
    .inputPlusminus { float: left; text-align: center; width:50px; color: black; margin-right:2px; margin-top:5px; }
    .inputButtonPlusminus {
    float: left;
    text-align: center;
    display: block;
    margin-top: 0;
    margin-right:2px;
    padding: 5px 15px;

    cursor: pointer;
    *cursor: hand;

    font-size: 14px;
    text-shadow: 0 1px 0 white;
    border: 1px solid #999;

    -webkit-border-radius: 4px;
    -moz-border-radius: 4px;
    -ms-border-radius: 4px;
    -o-border-radius: 4px;
    border-radius: 4px;

    -webkit-box-shadow: 1px 1px 3px #ccc;
    -moz-box-shadow: 1px 1px 3px #ccc;
    -ms-box-shadow: 1px 1px 3px #ccc;
    -o-box-shadow: 1px 1px 3px #ccc;
    box-shadow: 1px 1px 3px #ccc;

    /* Generated by http://www.colorzilla.com/gradient-editor/ */
    background: #ffffff; /* Old browsers */
    background: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Chrome10+,Safari5.1+ */
    background: -moz-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* FF3.6+ */
    background: -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* IE10+ */
    background: -o-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Opera 11.10+ */
    background: linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f9f9f9',GradientType=0 ); /* IE6-9 */
    }
    [/code]

    Lukas
This discussion has been closed.