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

Line feed in a string field #92

Closed curriouscat closed 7 years ago

curriouscat commented 9 years ago

I really do like this app. It has saved me a huge amount of development time. How do I have a set of line feeds in a string field so that the contents of the filed can be displayed one under the other Did this yesterday Do this now Do this tomorrow Do this next week What happens now is that the linefeeds are stripped. So, it all ends up in one long wrapped line.

webismymind commented 9 years ago

In order to edit multi-line texts, you should create a custom cell editor. If you're interested, I can give you the source code of an editor we commonly use for editing texts through a textarea presented in a jQuery UI dialog. Note that this could be added in the core library (as well as the new column type "text"), but we lack time!

curriouscat commented 9 years ago

THank you for your reply. Yes, I am very interested in the source code and a few lines to describe how to implement it.

Have fun and do neat stuff

Regards,

Geoff Bell, INTP phone: 02 9484 4983 email: g.bell@bigpond.net.au mailto:g.bell@bigpond.net.au mobile: 0418 998 020 www.bellsite.id.au http://www.bellsite.id.au/ The Competitive Enterprise

P Please consider the environment before printing this e-mail

On 23 Apr 2015, at 12:09 am, Webismymind notifications@github.com wrote:

In order to edit multi-line texts, you should create a custom cell editor. If you're interested, I can give you the source code of an editor we commonly use for editing texts through a textarea presented in a jQuery UI dialog. Note that this could be added in the core library (as well as the new column type "text"), but we lack time!

— Reply to this email directly or view it on GitHub https://github.com/webismymind/editablegrid/issues/92#issuecomment-95192829.

curriouscat commented 9 years ago

Hello, It looks to me as though it would be extremely good to be able to incorporate something like ckeditor with editable grid. So that an extensive textarea could be displayed, edited, stored, retrieved, displayed, ... Yes, I am interested in your source code.

Have fun and do neat stuff

Regards,

Geoff Bell, INTP phone: 02 9484 4983 email: g.bell@bigpond.net.au mailto:g.bell@bigpond.net.au mobile: 0418 998 020 www.bellsite.id.au http://www.bellsite.id.au/ The Competitive Enterprise

P Please consider the environment before printing this e-mail

On 23 Apr 2015, at 12:09 am, Webismymind notifications@github.com wrote:

In order to edit multi-line texts, you should create a custom cell editor. If you're interested, I can give you the source code of an editor we commonly use for editing texts through a textarea presented in a jQuery UI dialog. Note that this could be added in the core library (as well as the new column type "text"), but we lack time!

— Reply to this email directly or view it on GitHub https://github.com/webismymind/editablegrid/issues/92#issuecomment-95192829.

curriouscat commented 7 years ago

Why have you closed this? It has NOT been resolved. Where is the code that allows linefeeds in a string?

louisantoinem commented 7 years ago

I realize I never sent you the code I promised. So here it is!

Definition of TextAreaCellEditor, which inherits the more generic DialogCellEditor.:


/**
 * 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;
    this.autoOpen = true;

    // erase defaults with given options
    CellEditor.prototype.init.call(this, config);
};

// abstract functions (only getValue should always be redefined, others are optional)
DialogCellEditor.prototype.getValue = function() { return null; };
DialogCellEditor.prototype.create = function() {};
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"),
        maxHeight: window_height() - 200,
        modal: true,
        autoOpen: this.autoOpen,

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

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

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

        beforeClose: function(event, ui) {
            if (cell && 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() {
                if (self.applyEditing(cell, self.getValue()))
                    $(this).dialog("close");
            }
        }],

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

    return null;
};

/**
 * TextAreaCellEditor
 * @param config
 * @returns {TextAreaCellEditor}
 */

// inherits CellEditor functionalities
function TextAreaCellEditor(config) { this.init(config); }
TextAreaCellEditor.prototype = new DialogCellEditor();
TextAreaCellEditor.prototype.init = function(config)
{
    // defaults specific to TextAreaCellEditor
    this.useTinyMce = false;
    this.placeHolder = null;
    this.tinyMceHeight = 300;

    // defaults overriden from DialogCellEditor
    if (!config) config = {};
    if (!config.width) config.width = config && config.useTinyMce ? 700 : 600;

    // erase defaults with given options
    DialogCellEditor.prototype.init.call(this, config);

    // tinymmce must be initialized if set to true
    if (typeof tinymce == 'undefined') this.useTinyMce = false;

    // build dialog
    this.dialog = $('<div>').css({ 'text-align': 'left', 'display' : 'none' });
    var innerDiv = $('<div>').css({ 'padding': '0px', 'margin-top' : '7px' });
    this.textArea = $('<textarea>').css({ padding: '0px', width: '100%', height: this.tinyMceHeight + 'px' }).addClass('dialog').attr('id', 'TextAreaCellEditor_textarea'); // id needed for tinymce
    if (this.placeHolder) this.textArea.attr('placeholder', this.placeHolder);
    this.dialog.append(innerDiv.append(this.textArea));
};

// redefine asbtract functions
TextAreaCellEditor.prototype.open = function(cell, value) {
    this.textArea.val(value).focus();
    if (this.useTinyMce) tinymce.execCommand('mceAddEditor', false, 'TextAreaCellEditor_textarea');
};

TextAreaCellEditor.prototype.close = function() {
    if (this.useTinyMce) tinymce.execCommand('mceRemoveEditor', false, 'TextAreaCellEditor_textarea');
};

TextAreaCellEditor.prototype.resize = function(event, ui) {
    // resize text area
    if (!this.useTinyMce) $(this.textArea).height(ui.size.height - differenceBetweenDialogAndTextArea);
};

TextAreaCellEditor.prototype.resizeStart = function(event, ui) {
    // remember height delta 
    if (!this.useTinyMce && typeof differenceBetweenDialogAndTextArea == 'undefined') differenceBetweenDialogAndTextArea = ui.size.height - $(this.textArea).height();
};

TextAreaCellEditor.prototype.getValue = function() {
    return this.useTinyMce ? tinymce.get('TextAreaCellEditor_textarea').getContent() : this.textArea.val();
};

This editor allows editing a multi-line text through a text area, and optionally attaching a TinyMCE HTML editor to it.

Dependencies:

In our projects, we use the "text" and "html" data types in column definitions and we do this (a pretty ugly but functional hack) to create the right editor for these columns:

MyEditableGrid.prototype._createCellEditor = function(column)
{
    // hack to use text area cell editor when type is text or html
    EditableGrid.prototype._createCellEditor.call(this, column);

    if (column.datatype == "text") column.cellEditor = new TextAreaCellEditor();
    else if (column.datatype == "html" && column.editable) column.cellEditor = new TextAreaCellEditor({ useTinyMce: true });

    // give access to the column from the cell editor
    if (column.cellEditor) {
        column.cellEditor.editablegrid = this;
        column.cellEditor.column = column;
    }
};

(Yes, this could/should be integrated in the core library).

So it has been useful to close this issue after all ;)

curriouscat commented 7 years ago

Why have you closed this? It has NOT been resolved. Where is the code that allows linefeeds in a string?

curriouscat commented 7 years ago

Thank you for the code. I'm still a bit confused. It does not work, so I assume I've done something wrong. I pasted all the code above (less the uncommented comments) into the end of js/editablegrid_editors.js Is that where it goes?

I also made the column type 'text' in the php code that loads the grid $grid->addColumn('Extract', 'Extract', 'text');

louisantoinem commented 7 years ago

Well, it "does not work" is a bit vague. Do you have Javascript errors ?

You declared the two cell editors and made your column of type "text". But you still have to associate the TextAreaCellEditor with your text column. You can do it in the normal way:

myColumn.setCellEditor("my_text_column", new TextAreaCellEditor({ useTinyMce: true }));

Or you can setup the automatic use of TextAreaCellEditor when a column is of type "text" or "html", by overriding internal function _createCellEditor on your grid. To achieve this, you have to create your own class (here "MyEditableGrid").


MyEditableGrid(name, config) { if (name) this.init(name, config); }
MyEditableGrid.prototype = new EditableGrid(); 

MyEditableGrid.prototype._createCellEditor = function(column)
{
    // hack to use text area cell editor when type is text or html
    EditableGrid.prototype._createCellEditor.call(this, column);

    if (column.datatype == "text") column.cellEditor = new TextAreaCellEditor();
    else if (column.datatype == "html" && column.editable) column.cellEditor = new TextAreaCellEditor({ useTinyMce: true });

    // give access to the column from the cell editor
    if (column.cellEditor) {
        column.cellEditor.editablegrid = this;
        column.cellEditor.column = column;
    }
};

// when creating a "MyEditableGrid", text and html columns are handled automatically:
myGrid = new MyEditableGrid(...);