I'm making a formatter for slickgrid that will display a url as an img tag.
Due to the complexity and performance issues involved slickgrid doesnt support dynamic row heights but it does allow setting the global row height via the options.
var gridOptions = { rowHeight: 64 };
To make the images fit in a reasonable way I want to set the img tag to be the same as, or slightly smaller than the row height.
Neither the columnDef nor dataContext parameters that are passed to the formatter appear to have a reference to the parent grid so I'm not sure how to get the row height set on the grid options.
I'd like to avoid having to hack up the slickgrid scripts to pass through what I need as this makes updating a big PITA!
I could declare the formatter inline I guess and pull in the info via a closure but this isn't as reusable as a standalone formatter implimented in a similar mannor to the default formatters. But this is probably what I'll do for now until a better option presents itself.
Can anyone give me any hints or suggestions?
EDIT:
This does what I want but in a non-reusable mannor. It's not masses of code but it would still be nice to only have to write it once.
var gridOptions = { rowHeight: 64 };
var gridImageFormatter = function ImageFormatter(row, cell, value, columnDef, dataContext) {
return "<img src='" + value + "' style='width:auto;height=" + gridOptions.rowHeight + "' />";
};
var gridColumns = [
{id: "Id", name: "Id", field: "id", width: 250 },
{id: "Name", name: "Name", field: "name", width: 100 },
{id: "Image", name: "Image", field: "image", width: 64, formatter: gridImageFormatter },
{id: "Url", name: "Url", field: "url", width: 250 }
];
EDIT 2:
Using the power of the internet I found a nice little trick for making images autosize if they are bigger that the availible space.
This doesn't work to make smaller images strech to the given space but I can live with that!
How do I auto-resize an image to fit a div container
And this gives us something which works for most cases and is reusable:
function ImageFormatter(row, cell, value, columnDef, dataContext) {
return "<img src='" + value + "' style='max-width:100%;max-height:100%' />";
}
Related
I have to display cell content like
Policy
Part
Cert
Separated with next line character
In slickgrid table and so on.
How can I do this?
I searched but nothing worked for me.
What should I do with this is there any way to fit contents by height.
I Have this code written for breaking cells
columnname: <p>+policy+</p><br/>+part......and so on.
Any lead will be highly appreciated.
Better register a new formatter for your column.
Example
function myformatter(row, cell, value, columnDef, dataContext) {
return "<style='text-decoration: underline;color: #669900;height:120px;'>" + value +";
}
And call myformatter into column definition
var columns = [];
columns[0] = { id: "id", name: "columnname", field: "id", sortable: true, width: 5, formatter: myformatter };
this follows in from another post to do with setting a grid's selected fields when we have a data source field (and combo fields) with a json object (as opposed to a simple string).
So if we look at the change event handler for the following combox...
function createCombo(container, options, data) {
var input = $('<input name="' + options.field + '" />')
input.appendTo(container)
input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "display",
dataValueField: "rego",
dataSource: data,
change: function () {
var dataItem = this.dataItem();
var dataField = options.field.split('.');
var fieldName = dataField[0];
options.model.set(fieldName + '.rego', dataItem.rego);
options.model.set(fieldName + '.display', dataItem.display);
}
});
}
I am setting my 2 fields as follows...
options.model.set(fieldName + '.rego', dataItem.rego);
options.model.set(fieldName + '.display', dataItem.display);
(each item in the combo, and the grid data source has a json object with a 'rego' and 'display' field, see full example here.
This seemed to work exactly as I wanted, but I had just had someone point out to me that when you scroll the combobox with the up/down arrow keys, it just seems to toggle between 2 values in the list, as opposed to iterating through all the items. If I remove the 2 'options.model.set' statements, the combo then behaves.
I am really hoping there is a work around this, but everything I Have tried makes no different.
If there were any suggestion to finish this off, it would be greatly appreciated!
Thanks in advance for any help
Since you're modifying the model manually, you should to remove the name=... attribute from the input (otherwise the grid will also modify the model; you could also use name="car.rego" - it has to be the value field - and then not set the combobox value in the config) and also only call set for the last change you make on the model (otherwise, the grid's save event will get triggered twice, once with invalid data).
So you editor would look like this:
function createCombo(container, options, data) {
var dataField = options.field.split('.');
var fieldName = dataField[0];
var input = $('<input/>')
input.appendTo(container)
input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "display",
dataValueField: "rego",
dataSource: data,
value: options.model[fieldName].rego,
change: function (e) {
var dataItem = this.dataItem();
options.model[fieldName]['rego'] = dataItem.rego;
options.model.set(fieldName + '.display', dataItem.display);
}
});
}
Also, your data should be consistent (in one DS, you use "C1" as rego, in the other "CAR1").
(demo)
I've looked all over for help on this, which should be extremely easy, but I can't find exactly what I need. Here is my jsFiddle, which contains a super basic Kendo grid. I just want to get all data for the row that is currently selected (using a column of radio buttons) when the button is clicked.
http://jsfiddle.net/HTXua/412/
I know that when a row is selected, it is altering a property in the css class. Therefore, the row that I am trying to retrieve is going to have the property:
.detailGridRowSelector:checked
I have managed to implement the first row using checkboxes (instead of radio buttons) and count how many are checked, but I can't access the data for some reason!
var dataSource = {
data: [
{
"first": "Adam",
"last": "Paul"},
{
"first": "Shannon",
"last": "Harris"},
{
"first": "Frank",
"last": "Rolinson"},
]
};
var columns = [
{
template:'<input type="radio" class="detailGridRowSelector" title="Select Lines" name="radioLineSelector" />', width: 20
},
{
field: "first",
title: "First Name",
width: "90px"},
{
field: "last",
title: "Last Name",
width: "90px"},
];
$("#grid1").kendoGrid({
dataSource: dataSource,
columns: columns,
});
$("#getInfoButton").bind("click", function () {
var lineData ="line data would be set here";
//I know the selected row has the property: .detailGridRowSelector:checked
alert(lineData);
});
You should do:
// Get a reference to the grid
var grid = $("#grid1").data("kendoGrid");
// Get checked row by getting the input and then the row containing the input
var row = $("input:checked", grid.tbody).closest("tr");
// Get the item
var item = grid.dataItem(row);
// Format and display item
alert (JSON.stringify(item));
Your JSFiddle modified here: http://jsfiddle.net/OnaBai/HTXua/414/
SOLVED
Turns out I was making this way too hard on myself. I just learned that Kendo has a feature built in that handles this for you, so instead of using a column of radio buttons, I deleted it and implemented the
selectable: 'row'
feature. Then I just got it using
var grid = $("#grid1").data("kendoGrid");
var row = grid.select();
var data = grid.dataItem(row);
alert(data.first);
I've got a grid that's width is 100%. The columns size equals out among all columns when the grid first loads.
The user can then re-size columns to fit their need.
Now I need a way to reset all the columns back to defaults without reloading the page.
I tried refreshing the grid but that didn't work after the grid has already been bound:
.data().kendoGrid.refresh()
You might try a little trick (this is not perfect and might fail depending on your custom grid formatting). The trick is setting the widths to the same amount (ex. 100px). Something like:
Grid definition:
var grid = $("#grid").kendoGrid({
dataSource: ds,
resizable : true,
pageable : true,
columns :
[
{ field: "FirstName", title: "First Name" },
{ field: "LastName", title: "Last Name" },
{ field: "City" }
]
}).data("kendoGrid");
Code for resizing:
$("col", grid.element).css("width", "100px");
In addition, you might be interested on doing:
$("table", grid.element).css("width", "100%");
This resizes the "table" columns to use all the original space otherwise (just doing the col resizing) you might end-up with equally spaced cols but not using all the original width of the table).
You can see how it works here: http://jsfiddle.net/OnaBai/a9QSr/
I added the resizeStop event to my grid and it gets called, but I need to save the new column widths in the session and then use the new values to maintain the user preferences for column widths. Currently paging in the grid or reloading resets the column widths.
Here is what I have so far.
resizeStop: function(newwidth, index) {
alert(index + " : " + newwidth);
}
OK, I got it. I store all column widths in a HashMap in a bean I use to save session info. When the resizeStop event is fired I submit the new column size to a controller (I'm using Java and Spring) which updates the values in the HashMap.
Here are the code snippets:
resizeStop: function(newwidth, index) {
var colModel = $("#list").jqGrid('getGridParam','colModel');
$.post("/sessionState/columnWidth/update",
{
column: colModel[index].name,
width: newwidth
}
)
}
and in the colModel:
{name:'Title', index:'title', width: ${uiState.columnWidthMap["Title"]}, jsonmap: 'title', sorttype: "text"}