How can you get Tabulator to use Select2 header filter? - javascript

Following the example here, we've been trying for over a week to get Tabulator working with a Select2 header filter. There is a JS Fiddle here with all the pieces. It seems like the Tabulator filter (which are really just editors) onRendered() function is not even getting called because the console log we have inside it never gets logged.
The select element itself shows up in the header filter, but never gets the Select2 object applied (probably because the onRendered seems to not even be called). If we put the Select2 object outside the onRendered function, it get applied, but then the filter does not get applied after selection is made. There are no console or other errors and we've followed the Tabulator 'example' to the letter, so we are not sure what to try next.
Does anyone know how to get a basic Select2 header filter functioning with Tabulator?
var tableData = [{
id: "1",
topic: "1.1"
},
{
id: "2",
topic: "2.2"
},
];
var select2Editor = function(cell, onRendered, success, cancel, editorParams) {
var editor = document.createElement("select");
var selData = [{
id: '1.1',
text: "One"
}, {
id: "2.2",
text: "Two"
}, {
id: "3.3",
text: "Three"
}, ];
onRendered(function() {
// TODO: map tracks to id and text
console.log('rendered');
$(editor).select2({
data: selData,
minimumResultsForSearch: Infinity,
width: '100%',
minimumInputLength: 0,
//allowClear: true,
});
$(editor).on('change', function(e) {
success($(editor).val());
});
$(editor).on('blur', function(e) {
cancel();
});
});
return editor
};
var columns = [{
title: "ID",
field: "id"
}, {
title: "Topic",
field: "topic",
headerFilter: select2Editor,
}, ];
var table = new Tabulator("#table", {
placeholder: "No Data Found.",
layout: "fitData",
data: tableData,
columns: columns,
});

I'm new to both Tabulator and select2 and I think this is possibly a bad way to do it but it seems like it miiight work.
If you want to use select2 with text input elements, it looks like you need to use the full package.
https://jsfiddle.net/dku41pjy/
var tableData = [{
id: "1",
topic: "1.1"
},
{
id: "2",
topic: "2.2"
},
];
var columns = [{
title: "ID",
field: "id"
}, {
title: "Topic",
field: "topic",
headerFilter: 'select2Editor'
}, ];
var awaiting_render = [];
function do_render({ editor, cell, success, cancel, editorParams }) {
console.log('possibly dodgy onrender');
var selData = [{
id: '',
text: "-- All Topics --"
}, {
id: '1.1',
text: "One"
}, {
id: "2.2",
text: "Two"
}, {
id: "3.3",
text: "Three"
}, ];
$(editor).select2({
data: selData,
//allowClear: true,
});
$(editor).on('change', function(e) {
console.log('chaaaange')
success($(editor).val());
});
$(editor).on('blur', function(e) {
cancel();
});
}
function render_awaiting() {
var to_render = awaiting_render.shift();
do_render(to_render);
if(awaiting_render.length > 0)
render_awaiting();
}
Tabulator.prototype.extendModule("edit", "editors", {
select2Editor:function(cell, onRendered, success, cancel, editorParams) {
console.log(cell);
var editor = document.createElement("input");
editor.type = 'text';
awaiting_render.push({ editor, cell, success, cancel, editorParams });
return editor
},
});
var table = new Tabulator("#table", {
placeholder: "No Data Found.",
layout: "fitData",
data: tableData,
columns: columns,
tableBuilt:function(){
render_awaiting();
},
});
Edit: my suspicion is that onRendered only gets fired when these edit elements are used in cells to sope with the transition between showing just data and showing an editable field.

Related

DGrid Editor - Changing the Displayed Value when Trying to Edit a Text Cell

I'm using a DGrid editor column to edit the contents of a store. Of the fields that I want to be able to edit, one is an object. When I click on the field to edit it, what I want is for the value displayed in the editor to match the value displayed by the grid when not editing. The cell formatting just shows the value of the object, but when I click on the field to edit it, instead of the object's value, I instead the field is populated with '[object Object]'. I can still edit it (though the results of doing so is that the field will display 'undefined' until I refresh the page, but I could just force a refresh after the change), but can't seem to get it to show what I want.
Here's the set up code:
// build the store
this.postStore = Observable(Memory({
data: posts
}));
var formatCategory = function(object, data, cell) {
cell.innerHTML = object.category.value;
};
var formatAuthor = function(object, data, cell) {
cell.innerHTML = object.author.value;
};
var formatDate = function(object, data, cell) {
cell.innerHTML = new Date(object.dateCreated).toISOString();
};
// the columns displayed in the grid
var columns = [
selector({
field: 'checkbox',
label: ' ',
selectorType: 'radio',
width:33
}),
{
label: "Author",
field: "author",
width: 120,
renderCell: formatAuthor
},
editor({
label: "Title",
field: "title",
editor: "text",
editOn: "click",
width: 200
}),
editor({
label: "Text",
field: "text",
editor: "text",
editOn: "click",
width:500
}, Textarea),
editor({
label: "Category",
field: "category",
editor: "text",
editOn: "click",
width: 150,
renderCell: formatCategory
}),
{
label: "Date",
field: "date",
renderCell: formatDate,
width: 120
}
];
if (this.postGrid) {
this.postGrid.set("store", this.postStore);
} else {
var SelectionGrid = new declare([OnDemandGrid, Selection, Keyboard, editor, selector, DijitRegistry, ColumnResizer]);
this.postGrid = new SelectionGrid({
store: this.postStore,
columns: columns,
selectionMode: 'none',
sort: [{attribute: "date", descending: false}]
}, this.postGridDiv);
this.postGrid.startup();
this.postGrid.on("dgrid-select, dgrid-deselect", lang.hitch(this, this._postSelected));
this.postGrid.on("dgrid-datachange", lang.hitch(this, function(evt){
var cell = this.postGrid.cell(evt);
var post = cell.row.data;
if (cell.column.field === "title") {
post.title = evt.value;
} else if (cell.column.field === "text") {
post.text = evt.value;
} else if (cell.column.field === "category") {
post.category.value = evt.value;
}
this._updatePost(post);
}));
Instead of defining a renderCell function, define a get function (which is used to transform the value before it is even sent to renderCell) and a set function (which is used to transform data back before it's sent to a store when saving edits).
Something like:
get: function (object) {
return object.category.value;
},
set: function (object) {
return { value: object.category };
}
See also the documentation.

use of onCellWidgetCreated in Dojo Gridx (to add button to cell)

I try to add a button to the last column of my Gridx, however, the button is not shown and above the other table data the grid just says "loading...".
Cell Widget is required and declared, widgetInCell is set and onCellWidgetCreated function added. When replacing the onCellWidgetCreated function with alert, an alert message for each row is shown and the "loading..." disappears. My feeling is that the onCellWidgetCreated function is wrong?
My code looks like the following and when comparing it against some examples on the Gridx website I cannot find the problem.
require([
"gridx/Grid",
"gridx/core/model/cache/Sync",
"dojo/store/Memory",
"dojo/domReady!",
"gridx/modules/CellWidget",
"dijit/form/Button"
], function(Grid, Cache, Memory,Button,CellWidget,domConstruct){
var store = new Memory({
idProperty:"CategoryID",
data: jsondata
});
var grid = new Grid({
id:"gridId",
store: store,
cacheClass: Cache,
structure: [
{
id: "0",
field: "CategoryID",
name: "Kategorie (ID)",
width: "100px"
},
{
id: "1",
field: "CategoryName",
name: "Kategoriename"
},
{
id: "2",
field: "Attributes",
name: "Attribute"
},
{
id: "3",
field: "Actions",
name: "Aktion",
widgetsInCell: true,
onCellWidgetCreated: function(cellWidget, column){
var btn = new Button({
label: "Click me!"
});
btn.placeAt(cellWidget.domNode);
}
}
],
modules: [
CellWidget
]
});
grid.placeAt("aGrid");
grid.startup();
}
);
I came across anotheer problem with VirtualVScrolling and found out that this was due to a defective gridx css file which contained a custom layout.
When using the standard css file, "onCellWidgetCreated" worked for me as well.

Display image along with text in a cell when in non-edit mode

I'm evaluating the Kendo UI Gantt chart to see if it fits our project requirements.
One particular requirement is to display a status column which would be a drop down in edit mode and has three statuses
Red 2. Green 3. Yellow, along with an image indicator something like what is shown in the image below
I am able to achieve the above effect when i edit a cell after using a custom editor for the drop down
function statusDropDownEditor(container, options) {
$('<input data-bind="value:' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
dataTextField: "Status",
dataValueField: "StatusId",
valueTemplate: '<img class="selected-value" src="#:data.Url#" alt="#:data.Status#" /><span>#:data.Status#</span>',
template: '<img class="selected-value" src="#:data.Url#" alt="#:data.Status#" /><span>#:data.Status#</span>',
dataSource: {
transport: {
read: function (e) {
// on success
e.success([{ Status: 'Not Started', StatusId: '0', Url: 'Image/red.png' }, { Status: 'Red', StatusId: '1', Url: 'Image/red.png' }, { Status: 'Green', StatusId: '2', Url: 'Image/red.png' }, { Status: 'Yellow', StatusId: '3', Url: 'Image/red.png' }]);
// on failure
//e.error("XHR response", "status code", "error message");
}
}
}
})
}
The Gantt Column for Status looks like the below snippet
{ field: "status", title: "Status", editable: true, width: 150, editor: statusDropDownEditor, template: '<img class="selected-value" src="#:data.Url#" alt="#:data.Status#" /><span>#:data.Status#</span>' }
However when done with selecting a particular item from drop down and on exiting the edit mode this is how the cell looks like
Seems like the default cell template in read only mode does not render html and the invokes the toString of the object bound to the cell, is there a way to fix this in the kendo UI Gantt
I have been trying to solve the same issue today and it looks like gantt columns do not support the template properties.
I have created a new feature suggestion on the Kendo user feedback site. If enough people vote for it maybe they will implement this.
The only work around I found was to prepend an image tag onto the field column like this. But this solution is not conditional.
<div id="gantt"></div>
<script>
$(document).ready(function() {
var gantt = $("#gantt").kendoGantt({
dataSource: [
{
id: 1,
title: "apples",
orderId: 0,
parentId: null,
start: new Date("2015/1/17"),
end: new Date("2015/10/17"),
summary:false,
expanded:false
},
{
id: 2,
orderId: 1,
parentId: null,
title: "banana",
start: new Date("2015/1/17"),
end: new Date("2015/3/17"),
summary:false,
expanded:true
}
],
views: [
{ type: "year", selected: true }
],
columns: [
{ field: "title", title: "fruit", width: 220 },
{ field: "start", title: "start", width: 80 }
],
}).data("kendoGantt");
$(".k-grid-content tbody[role='rowgroup'] tr[role='row'] td:first-child").prepend("<img href='#' alt='image here'></img>");
});
</script>
The sample page is on git.

Selecting rows from one grid & passing them to another grid

I'm trying to allow rows to be selected via checkboxes and for those selected rows and their IDs to be sent to another grid when a 'Submit' button is clicked. In other words, acting as some sort of filter.
I've contacted Telerik's support team and was advised to take the following steps in order to get it working:
Get the selected rows with the Select() method of the Grid
Loop through them & get the underlying item with the dataItem method
Save them into an array
Destroy the grid
Initialize a new grid by setting the data data
Here's a sample on JSBin that shows what I have in mind.
I'm not sure where to start honestly. I would really appreciate it if someone could point me in the right direction to any resources or guides that would be helpful. Thanks!
Assuming you are using RadGrid, make sure you have client side selection turned on, you would see something like this:
<ClientSettings>
<Selecting AllowRowSelect="True" />
<ClientEvents OnRowSelected="RowSelected" />
</ClientSettings>
On the input button, make sure to call your JS method as follows :
<input onclick="GetSelected();" .... >
Your JS code might look something like this :
function GetSelected() {
var grid = $find("<%=Your Grid's ClientID Here%>");
var MasterTable = grid.get_masterTableView();
var selectedRows = MasterTable.get_selectedItems(); // 1. Get the selected rows. The selected item can be accessed by calling the get_selectedItems() method of the GridTableView client-side object.
for (var i = 0; i < selectedRows.length; i++) {
var row = selectedRows[i];
// This is where you would have to insert it in a collection so that you can bind it to another grid... You will need to call .Rebind() once you assign the new datasource to the other grid.
}
Hopefully this will give you some idea.. I can see if I can find any examples on inserting rows into other grid if you get stuck.
check this code
html
<div id="grid1"></div>
<input type="button" value="Submit" onclick="Move()" />
<div id="grid2" ></div>
script
<script>
$(document).ready(function() {
var data1 = [
{ id: 1, rating: 3, year: 1997, title: "Rock" }
, { id: 2, rating: 5, year: 1999, title: "X-Man" }
, { id: 3, rating: 4, year: 2011, title: "World War Z" }
];
var grid1=$("#grid1").kendoGrid({
sortable: true
, silectable: true
, selectable: "multiple row"
, filterable: true
, pageable: true
, columns: [
{ template: "<input type='checkbox' class='checkbox' />", width: "40px" }
,{ field: "id", title: "Id", filterable: false }
, { field: "rating", title: "Rating", filterable: false }
, { field: "year", title: "Year", filterable: true, type: "string"}
, { field: "title", title: "Title" }
]
, dataSource: { page: 1,
pageSize: 5,
data: data1
}
}).data("kendoGrid");
grid1.table.on("click", ".checkbox", selectRow);
var data2 = [
{ id: 101, rating: 6, year: 2012, title: "The Impossible" }
, { id: 102, rating: 8, year: 2013, title: "Escape" }
, { id: 103, rating: 7, year: 2013, title: "Gravity" }
];
$("#grid2").kendoGrid({
sortable: true
, silectable: true
, selectable: "multiple row"
, filterable: true
, pageable: true
, columns: [
{ field: "id", title: "Id", filterable: false }
, { field: "rating", title: "Rating", filterable: false }
, { field: "year", title: "Year", filterable: true, type: "string"}
, { field: "title", title: "Title" }
]
, dataSource: { page: 1,
pageSize: 5,
data: data2
}
});
});
function Move() {
var grid1 = $("#grid1").data("kendoGrid");
var rows = grid1.select();
rows.each(function(index, row) {
var selectedRow = grid1.dataItem(row);
//-move to grid2
var grid2 = $("#grid2").data("kendoGrid");
var ins = { id: selectedRow.id, rating: selectedRow.rating, year: selectedRow.year, title: selectedRow.title }; //id=1,rating=9.2,year=1995,title="The Godfather"
grid2.dataSource.insert(ins);
});
rows.each(function() {
grid1.removeRow($(this).closest('tr'));
});
}
function selectRow() {
var checked = this.checked,
row = $(this).closest("tr");
if (checked) {
//-select the row
row.addClass("k-state-selected");
} else {
//-remove selection
row.removeClass("k-state-selected");
}
}
</script>
this will help you :)

Empty a slickgrid in Javascript on a button click

Hello I have a slickgrid with five row , how can I empty my grid on a button click?
Thanks.
My grid code:
var grid;
var columns = [
{id: "title", name: "Title", field: "title"},
{id: "duration", name: "Duration", field: "duration"},
{id: "%", name: "% Complete", field: "percentComplete"},
{id: "start", name: "Start", field: "start"},
{id: "finish", name: "Finish", field: "finish"},
{id: "effort-driven", name: "Effort Driven", field: "effortDriven"}
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false
};
$(function () {
var data = [];
for (var i = 0; i < 5; i++) {
data[i] = {
title: "Task " + i,
duration: "5 days",
percentComplete: Math.round(Math.random() * 100),
start: "01/01/2009",
finish: "01/05/2009",
effortDriven: (i % 5 == 0)
};
}
grid = new Slick.Grid("#myGrid", data, columns, options);
So to do what you intend to do, the following piece of code should work... Please note that I did not try it, I usually do a refresh of data instead, so try it and let me know:
// initialize the model after all the events have been hooked up
var data = null; // empty out your dataset
dataView.beginUpdate();
dataView.setItems(data);
dataView.endUpdate();
// re-render the grid
grid.updateRowCount();
grid.render();
EDIT
I just realized that you are not using a dataview object, I always use a dataview, it's easier to play with the data. So without the dataview, you could instead try doing this:
// reset the dataset
grid.setData(null, true);
// re-render the grid
grid.updateRowCount();
grid.render();
For the method documentation, see the wiki: SlickGrid grid.setData()

Categories

Resources