From dc2490940932195c2420ade981728b9d6a2e1234 Mon Sep 17 00:00:00 2001 From: aliounedia Date: Mon, 13 Jan 2014 22:42:16 +0100 Subject: [PATCH 1/6] [#384,sclickgrid][s] add field validator bind to field.format --- src/view.slickgrid.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index f7512f8d..2dfdf1c5 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -99,6 +99,19 @@ my.SlickGrid = Backbone.View.extend({ return value; } }; + + // we need to be sure that user is entering a valid input , for exemple if + // field is date type and field.format ='YY-MM-DD', we sould be sure that + // user enter a correct value + var validator = function(field){ + return function(value){ + if(field.type == "date" && isNaN(Date.parse(value))){ + return {valid: false, msg: "This format is required" + field.type}; + }else { + return {valid: true, msg :null } + } + } + }; _.each(this.model.fields.toJSON(),function(field){ var column = { id: field.id, @@ -106,7 +119,8 @@ my.SlickGrid = Backbone.View.extend({ field: field.id, sortable: true, minWidth: 80, - formatter: formatter + formatter: formatter, + validator:validator }; var widthInfo = _.find(self.state.get('columnsWidth'),function(c){return c.column === field.id;}); From 7fbab3d8d800be620657391b081221d98ae05480 Mon Sep 17 00:00:00 2001 From: aliounedia Date: Wed, 15 Jan 2014 11:40:07 +0100 Subject: [PATCH 2/6] [#384,slickgrid][s]add validator function to validate input --- src/view.slickgrid.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index 2dfdf1c5..2d24cb52 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -101,12 +101,12 @@ my.SlickGrid = Backbone.View.extend({ }; // we need to be sure that user is entering a valid input , for exemple if - // field is date type and field.format ='YY-MM-DD', we sould be sure that + // field is date type and field.format ='YY-MM-DD', we should be sure that // user enter a correct value var validator = function(field){ return function(value){ if(field.type == "date" && isNaN(Date.parse(value))){ - return {valid: false, msg: "This format is required" + field.type}; + return {valid: false, msg: "A date is required , check field field-date-format"}; }else { return {valid: true, msg :null } } @@ -120,7 +120,7 @@ my.SlickGrid = Backbone.View.extend({ sortable: true, minWidth: 80, formatter: formatter, - validator:validator + validator:validator(field) }; var widthInfo = _.find(self.state.get('columnsWidth'),function(c){return c.column === field.id;}); From ba8a84f7481e87641c1840ccb6f6812114f3a975 Mon Sep 17 00:00:00 2001 From: aliounedia Date: Thu, 16 Jan 2014 00:27:04 +0100 Subject: [PATCH 3/6] [#384, slickgrid][s]: slickgrid add support for row-delete --- src/view.slickgrid.js | 64 +++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index 2d24cb52..1ce1c725 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -55,13 +55,8 @@ my.SlickGrid = Backbone.View.extend({ ); this.state = new recline.Model.ObjectState(state); - this._slickHandler = new Slick.EventHandler(); }, - - events: { - }, - onRecordChanged: function(record) { // Ignore if the grid is not yet drawn if (!this.grid) { @@ -74,10 +69,8 @@ my.SlickGrid = Backbone.View.extend({ this.grid.getData().updateItem(record, row_index); this.grid.render(); }, - - render: function() { + render: function() { var self = this; - var options = _.extend({ enableCellNavigation: true, enableColumnReorder: true, @@ -87,19 +80,27 @@ my.SlickGrid = Backbone.View.extend({ }, self.state.get('gridOptions')); // We need all columns, even the hidden ones, to show on the column picker - var columns = []; + var columns = []; + // custom formatter as default one escapes html // plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...) // row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values var formatter = function(row, cell, value, columnDef, dataContext) { - var field = self.model.fields.get(columnDef.id); + // If row delete field format , change here if for example insteed + // of link we can have bouton or image depending of what you need + // RUFFUS! Do you think we should have a variable to set if + // ie template_del = 'X' + if (columnDef.id == "del"){ + return 'X' + } + var field = self.model.fields.get(columnDef.id); if (field.renderer) { - return field.renderer(value, field, dataContext); - } else { - return value; + return field.renderer(value, field, dataContext); + }else { + return value } }; - + // we need to be sure that user is entering a valid input , for exemple if // field is date type and field.format ='YY-MM-DD', we should be sure that // user enter a correct value @@ -111,7 +112,17 @@ my.SlickGrid = Backbone.View.extend({ return {valid: true, msg :null } } } - }; + }; + //Add row delete support + columns.push({ + id: 'del', + name: 'del', + field: 'del', + sortable: true, + width: 10, + formatter: formatter, + validator:validator + }) _.each(this.model.fields.toJSON(),function(field){ var column = { id: field.id, @@ -151,8 +162,8 @@ my.SlickGrid = Backbone.View.extend({ } } columns.push(column); - }); - + }); + // Restrict the visible columns var visibleColumns = _.filter(columns, function(column) { return _.indexOf(self.state.get('hiddenColumns'), column.id) === -1; @@ -205,6 +216,7 @@ my.SlickGrid = Backbone.View.extend({ rows[i] = toRow(m); models[i] = m; }; + } var data = new RowSet(); @@ -247,19 +259,25 @@ my.SlickGrid = Backbone.View.extend({ }); self.state.set({columnsWidth:columnsWidth}); }); - + this._slickHandler.subscribe(this.grid.onCellChange, function (e, args) { // We need to change the model associated value - // var grid = args.grid; - var model = data.getModel(args.row); + var model = data.getModel(args.row); var field = grid.getColumns()[args.cell].id; var v = {}; v[field] = args.item[field]; model.set(v); - }); - - var columnpicker = new Slick.Controls.ColumnPicker(columns, this.grid, + }); + this._slickHandler.subscribe(this.grid.onClick,function(e, args){ + if (args.cell == 0){ + // We need to delete the associated model + var model = data.getModel(args.row); + model.destroy() + } + }) ; + + var columnpicker = new Slick.Controls.ColumnPicker(columns, this.grid, _.extend(options,{state:this.state})); if (self.visible){ From 4e41afca90c74bed9a1989a8578b65c7dcc237ef Mon Sep 17 00:00:00 2001 From: aliounedia Date: Fri, 17 Jan 2014 00:09:18 +0100 Subject: [PATCH 4/6] [#384, slickgrid][s]: slickgrid add support for row-add --- src/view.slickgrid.js | 66 +++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index 1ce1c725..d4c08b07 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -5,6 +5,38 @@ this.recline.View = this.recline.View || {}; (function($, my) { "use strict"; + + // Add new grid Control to display a new row add menu bouton + // It display a simple side-bar menu ,for user to add new + // row to grid + + my.GridControl= Backbone.View.extend({ + className: "recline-row-add", + // Template for row edit menu , change it if you don't love + template: '

Add row

', + + initialize: function(options){ + var self = this; + _.bindAll(this, 'render'); + this.state = new recline.Model.ObjectState(); + this.render(); + }, + + render: function() { + var self = this; + this.$el.html(this.template) + }, + + events : { + "click .recline-row-add" : "addNewRow" + }, + + addNewRow : function(e){ + e.preventDefault() + this.state.set({"newrow" : "pending"}) + } + } + ); // ## SlickGrid Dataset View // // Provides a tabular view on a Dataset, based on SlickGrid. @@ -39,10 +71,25 @@ my.SlickGrid = Backbone.View.extend({ initialize: function(modelEtc) { var self = this; this.$el.addClass('recline-slickgrid'); + + // Template for row delete menu , change it if you don't love + this.templates = { + "deleterow" : 'X' + } + + //add menu for new row + this.editor = new my.GridControl() + this.elSidebar = this.editor.$el + + _.bindAll(this, 'render', 'onRecordChanged'); this.listenTo(this.model.records, 'add remove reset', this.render); this.listenTo(this.model.records, 'change', this.onRecordChanged); - + this.listenTo(this.editor.state, 'change', function(){ + this.model.records.add({}) + this.editor.state.set({"newrow" : "done"}) + }); + var state = _.extend({ hiddenColumns: [], columnsOrder: [], @@ -62,7 +109,6 @@ my.SlickGrid = Backbone.View.extend({ if (!this.grid) { return; } - // Let's find the row corresponding to the index var row_index = this.grid.getData().getModelRow( record ); this.grid.invalidateRow(row_index); @@ -81,17 +127,12 @@ my.SlickGrid = Backbone.View.extend({ // We need all columns, even the hidden ones, to show on the column picker var columns = []; - // custom formatter as default one escapes html // plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...) // row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values var formatter = function(row, cell, value, columnDef, dataContext) { - // If row delete field format , change here if for example insteed - // of link we can have bouton or image depending of what you need - // RUFFUS! Do you think we should have a variable to set if - // ie template_del = 'X' - if (columnDef.id == "del"){ - return 'X' + if(columnDef.id == "del"){ + return self.templates.deleterow } var field = self.model.fields.get(columnDef.id); if (field.renderer) { @@ -100,7 +141,6 @@ my.SlickGrid = Backbone.View.extend({ return value } }; - // we need to be sure that user is entering a valid input , for exemple if // field is date type and field.format ='YY-MM-DD', we should be sure that // user enter a correct value @@ -133,12 +173,10 @@ my.SlickGrid = Backbone.View.extend({ formatter: formatter, validator:validator(field) }; - var widthInfo = _.find(self.state.get('columnsWidth'),function(c){return c.column === field.id;}); if (widthInfo){ column.width = widthInfo.width; } - var editInfo = _.find(self.state.get('columnsEditor'),function(c){return c.column === field.id;}); if (editInfo){ column.editor = editInfo.editor; @@ -163,12 +201,10 @@ my.SlickGrid = Backbone.View.extend({ } columns.push(column); }); - // Restrict the visible columns var visibleColumns = _.filter(columns, function(column) { return _.indexOf(self.state.get('hiddenColumns'), column.id) === -1; }); - // Order them if there is ordering info on the state if (this.state.get('columnsOrder') && this.state.get('columnsOrder').length > 0) { visibleColumns = visibleColumns.sort(function(a,b){ @@ -226,7 +262,6 @@ my.SlickGrid = Backbone.View.extend({ }); this.grid = new Slick.Grid(this.el, data, visibleColumns, options); - // Column sorting var sortInfo = this.model.queryState.get('sort'); if (sortInfo){ @@ -434,3 +469,4 @@ my.SlickGrid = Backbone.View.extend({ // Slick.Controls.ColumnPicker $.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}}); })(jQuery); + From 66daf6f36f75113d314d6cca5ff4d12bc14a91b0 Mon Sep 17 00:00:00 2001 From: aliounedia Date: Mon, 20 Jan 2014 23:28:37 +0100 Subject: [PATCH 5/6] [#384, slickgrid][s]: slickgrid add support for row-add and row-delete --- src/view.slickgrid.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index d4c08b07..331ebef8 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -1,3 +1,4 @@ + /*jshint multistr:true */ this.recline = this.recline || {}; @@ -6,6 +7,8 @@ this.recline.View = this.recline.View || {}; (function($, my) { "use strict"; + + // Add new grid Control to display a new row add menu bouton // It display a simple side-bar menu ,for user to add new // row to grid @@ -33,7 +36,7 @@ this.recline.View = this.recline.View || {}; addNewRow : function(e){ e.preventDefault() - this.state.set({"newrow" : "pending"}) + this.state.trigger("change") } } ); @@ -76,20 +79,9 @@ my.SlickGrid = Backbone.View.extend({ this.templates = { "deleterow" : 'X' } - - //add menu for new row - this.editor = new my.GridControl() - this.elSidebar = this.editor.$el - - _.bindAll(this, 'render', 'onRecordChanged'); this.listenTo(this.model.records, 'add remove reset', this.render); this.listenTo(this.model.records, 'change', this.onRecordChanged); - this.listenTo(this.editor.state, 'change', function(){ - this.model.records.add({}) - this.editor.state.set({"newrow" : "done"}) - }); - var state = _.extend({ hiddenColumns: [], columnsOrder: [], @@ -103,6 +95,18 @@ my.SlickGrid = Backbone.View.extend({ ); this.state = new recline.Model.ObjectState(state); this._slickHandler = new Slick.EventHandler(); + + //add menu for new row , check if enableAddRow is set to true or not set + if(this.state.get("gridOptions") + && this.state.get("gridOptions").enabledAddRow != undefined + && this.state.get("gridOptions").enabledAddRow == true ){ + this.editor = new my.GridControl() + this.elSidebar = this.editor.$el + this.listenTo(this.editor.state, 'change', function(){ + this.model.records.add({}) + }); + } + }, onRecordChanged: function(record) { // Ignore if the grid is not yet drawn @@ -153,16 +157,19 @@ my.SlickGrid = Backbone.View.extend({ } } }; - //Add row delete support + //Add row delete support , check if enableDelRow is set to true or not set + if(this.state.get("gridOptions") + && this.state.get("gridOptions").enabledDelRow != undefined + && this.state.get("gridOptions").enabledDelRow == true ){ columns.push({ id: 'del', name: 'del', field: 'del', sortable: true, - width: 10, + width: 80, formatter: formatter, validator:validator - }) + })} _.each(this.model.fields.toJSON(),function(field){ var column = { id: field.id, @@ -470,3 +477,4 @@ my.SlickGrid = Backbone.View.extend({ $.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}}); })(jQuery); +/*jshint multistr:true */ From a046861c4a41ba0a3dab7af8656f30b13faedb94 Mon Sep 17 00:00:00 2001 From: aliounedia Date: Mon, 20 Jan 2014 23:33:34 +0100 Subject: [PATCH 6/6] [#384, slickgrid][s]: slickgrid add support for row-add and row-delete --- src/view.slickgrid.js | 2 -- test/view.slickgrid.test.js | 71 +++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index 331ebef8..07faa048 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -1,4 +1,3 @@ - /*jshint multistr:true */ this.recline = this.recline || {}; @@ -477,4 +476,3 @@ my.SlickGrid = Backbone.View.extend({ $.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}}); })(jQuery); -/*jshint multistr:true */ diff --git a/test/view.slickgrid.test.js b/test/view.slickgrid.test.js index 597461cd..80c895c6 100644 --- a/test/view.slickgrid.test.js +++ b/test/view.slickgrid.test.js @@ -103,6 +103,77 @@ test('editable', function () { view.remove(); }); +test('delete-row' , function(){ + var dataset = Fixture.getDataset(); + var view = new recline.View.SlickGrid({ + model: dataset, + state: { + hiddenColumns:['x','lat','title'], + columnsOrder:['lon','id','z','date', 'y', 'country'], + columnsWidth:[ + {column:'id',width: 250} + ], + gridOptions: {editable: true , "enabledDelRow":true}, + columnsEditor: [{column: 'country', editor: Slick.Editors.Text}] + } + }); + + $('.fixtures .test-datatable').append(view.el); + view.render(); + view.show(); + old_length = dataset.records.length + dataset.records.on('remove', function(record){ + equal(dataset.records.length, old_length -1 ); + }); + + // Be sure a cell change triggers a change of the model + e = new Slick.EventData(); + view.grid.onClick.notify({ + row: 1, + cell: 0, + grid: view.grid + }, e, view.grid); + + view.remove(); + + +}); + +test('add-row' , function(){ +//To test adding row on slickgrid , we add some menu GridControl +//I am based on the FlotControl in flot wiewer , to add a similary +//to the sclickgrid , The GridControl add a bouton menu +//one the .side-bar place , which will allow to add a row to +//the grid on-click + +var dataset = Fixture.getDataset(); + var view = new recline.View.SlickGrid({ + model: dataset, + state: { + hiddenColumns:['x','lat','title'], + columnsOrder:['lon','id','z','date', 'y', 'country'], + columnsWidth:[ + {column:'id',width: 250} + ], + gridOptions: {editable: true , "enabledAddRow":true}, + columnsEditor: [{column: 'country', editor: Slick.Editors.Text}] + } + }); + +// view will auto render ... +assertPresent('.recline-row-add', view.elSidebar); +// see recline.SlickGrid.GridControl widget +//view.render() +old_length = dataset.records.length +dataset.records.on('add',function(record){ + equal(dataset.records.length ,old_length + 1 ) +}); + +view.elSidebar.find('.recline-row-add').click(); + +}); + + test('update', function() { var dataset = Fixture.getDataset(); var view = new recline.View.SlickGrid({