webismymind / editablegrid

EditableGrid is an open source Javascript library aimed at turning HTML tables into advanced editable components. It focuses on simplicity: only a few lines of code are required to get your first table up and running.
http://www.editablegrid.net
Other
795 stars 272 forks source link

Mulitple inputs inside one cell #39

Closed pstaabp closed 10 years ago

pstaabp commented 11 years ago

I have a grid with a column of date/times. Visually, I have the date printed in standard form and then the time as a clock icon (the time is less important), which I've generated in a custom renderer. I would like to be able to click on the date to get a date picker (much like the default is) and then the clock to edit the time.

Looking a the source code, the actual target element is lost in the mouseClicked function of EditableGrid and only the row and column is captured. It seems like to get the functionality, I could override this method to capture the clicked element. Any other thoughts?

gardiner commented 10 years ago

Have you come up with a solution to this issue? I have a similar problem where I would like to get multiple input elements within a single table cell to allow editing more complex values and I would be very interested to hear what you've come up with.

Cheers, Ole.

pstaabp commented 10 years ago

Ole,

I actually decided to write my own version of the EditableGrid. I heavily use backbone and backbone.stickit which I leveraged heavily to generate such a grid. This also allowed me to reuse a lot of code that I already had, especially to do multiple inputs.

Right now, I have a version that does limited sorting and I haven't implemented the filtering, which I think is great from yours.

Peter

On Oct 30, 2013, at 12:23 PM, Ole Trenner notifications@github.com wrote:

Have you come up with a solution to this issue? I have a similar problem where I would like to get multiple input elements within a single table cell to allow editing more complex values and I would be very interested to hear what you've come up with.

Cheers, Ole.

— Reply to this email directly or view it on GitHub.

gardiner commented 10 years ago

Writing my own version was something I'd rather avoid :) I guess I'll try adding an extended edit widget in some kind of popup and then changing the cell value via the editable grid api.

webismymind commented 10 years ago

Hi,

Having multiple inputs in the same cell is not a problem if this is really what you want. Through custom CellRenderer and CellEditor, everything is possible and I already did such things (e.g. a cell containing several checkboxes). However, I tend to prefer using a dialog when the inputs become too complex, but this is only a matter a taste.

Anyway, here is a snippet showing how to implement a "DialogCellEditor" (which should be integrated soon in the "official" EditableGrid library as an extension).

    /**
     * DialogCellEditor
     * @param config
     * @returns {DialogCellEditor}
     */
    // inherits CellEditor functionalities
    function DialogCellEditor(config) { this.init(config); }
    DialogCellEditor.prototype = new CellEditor();
    DialogCellEditor.prototype.init = function(config) 
    {
        // defaults
        this.width = 480;
        this.height = null;
        this.dialog = null;

        // erase defaults with given options
        CellEditor.prototype.init.call(this, config);
    };
    // abstract functions (only getValue should always be redefined, other ones are optional)
    DialogCellEditor.prototype.getValue = function() { return null; };
    DialogCellEditor.prototype.open = function(cell, value) {};
    DialogCellEditor.prototype.close = function() {};
    DialogCellEditor.prototype.resize = function(event, ui) {};
    DialogCellEditor.prototype.resizeStart = function(event, ui) {};
    DialogCellEditor.prototype.getDialogTitle = function(cell, value) { return this.column.label; };
    // redefine getEditor
    DialogCellEditor.prototype.getEditor = function(cell, value) {
        var self = this;
        $(this.dialog).dialog({
            width: this.width,
            height: this.height ? this.height : "auto", 
            modal: true,

            open: function(event) {
                self.open(cell, value);
            },

            close: function(event) { 
                self.close();
                $(this).dialog('destroy');
            },

            beforeClose: function(event, ui) {
                if (cell.isEditing) self.cancelEditing(cell);
                return true;
            },

            resize: function(event, ui) {
                self.resize(event, ui);
            },
            resizeStart: function(event, ui) {
                self.resizeStart(event, ui);
            },

            buttons: [{ 
                text: "Save", 
                click: function() { 
                    self.applyEditing(cell, self.getValue());
                    $(this).dialog("close"); 
                }
            }],

            title: this.getDialogTitle(cell, value)
        });

        return null;
    };

This DialogCellEditor is an abstract class. You can use it to build an actual CellEditor by overriding at least "getValue" to return the value that will be received by the modelChanged event. E.g.:

function TestCellEditor() { this.init(); }
TestCellEditor.prototype = new DialogCellEditor();
TestCellEditor.prototype.init = function() {
    DialogCellEditor.prototype.init.call(this, { dialog : $('#my_dialog'), width: 350 });
};
TestCellEditor.prototype.getValue = function()
{
    return $.toJSON({
        a: this.dialog.find('[name=a]').val(),
        b: this.dialog.find('[name=b]').val()
    });
};

Peter's question was abouting knowing where the click had been done: on the date or on the time in his example. For that, overriding the mouseClicked method would indeed be necessary I think. But it could also be achieved with two cells without border between them.

Louis

gardiner commented 10 years ago

Thanks for the code, that looks great. I'll definitely give that a try.