I have a KendoUI Grid bound using Angular and I'd like to implement a custom action dropdown command or template column on each row. I need to track the dropdown change event for any of the rows when the grid is in display mode, not edit mode. The dropdown is effectively just a list of all of the name properties of the grid rows that I want to user to be able to select to move the row after another existing row.
For instance, say I have this data:
Id Name Position
A Red 1
B Blue 2
C White 3
I'd like each row to display a dropdown column while in display mode (so it acts like a row command). The dropdown would contain the names Red,Blue,White with corresponding values. When a user picks one of those colors, I will change the position of that row to the row position after the color selected. It's basically a row reorder dropdown instead of using drag and drop.
My other option is to show a couple of template columns with a move up/move down metaphor to do the switch but that gets a little cumbersome when you want to move a row more than a couple of positions.
Any ideas?
Ok, I did some more searching and found out a way to do this although it's not 100% of the way there yet. I also found a way to bind the dropdown to the data that populates the grid
The other thing I found when doing it this way is it is painfully slow in rendering the grid now.
<div id="mainGrid" kendo-grid="mainGrid" k-options="mainGridOptions"></div>
//grid columns
$scope.mainGridOptions = {
dataSource: {
transport: {
read: function (e) {
gridcolumnService.getGridColumns().success(function (data) {
e.success(data);
});
},
},
},
columns: [
{ field: "Name" },
{ field: "ColumnSettings.Type", title: "Type" },
{ field: "ColumnSettings.PrimaryKey", title: "Primary Key", template: '<input type="checkbox" #= ColumnSettings.PrimaryKey ? "checked=checked" : "" # disabled="disabled" ></input>' },
{ field: "ColumnSettings.Title", title: "Title" },
{ field: "ColumnSettings.Editable", title: "Editable", template: '<input type="checkbox" #= ColumnSettings.Editable ? "checked=checked" : "" # disabled="disabled" ></input>' },
{ field: "ColumnSettings.Visible", title: "Visible", template: '<input type="checkbox" #= ColumnSettings.Visible ? "checked=checked" : "" # disabled="disabled" ></input>' },
{ field: "LookupDataCommandId", title: "Lookup", template: '#= LookupDataCommandId ? "Yes" : "" #' },
{ template: '<select id="reorder-dropdown" kendo-drop-down-list k-on-change="exchangeRows(dataItem, kendoEvent)" k-data-source="reorderData()" k-data-text-field="\'Name\'" k-data-value-field="\'GridColumnId\'"></select>' },
{ template: '<a kendo-button k-icon="\'pencil\'" ng-click="editGridColumn(dataItem.GridColumnId)">Edit</a>', width: 100 }
]
};
$scope.reorderData = function() {
return $scope.mainGrid.dataSource.data();
};
$scope.exchangeRows = function (fromRow, e) {
$log.log(fromRow.GridColumnId, e.sender.dataItem().GridColumnId);
};
Related
When I export my grid to excel,headers are like: Product Name,{{'unitsOrder'| translate}} in excel. My grid supports 2 languages and I am showing it with angularjs translate way. Any offer?
<script>
$("#grid").kendoGrid({
toolbar: ["excel"],
excel: {
fileName: "Kendo UI Grid Export.xlsx"
},
dataSource: {
type: "odata",
transport: {
read: "http://demos.telerik.com/kendo-ui/service/Northwind.svc/Products"
},
pageSize: 7
},
sortable: true,
pageable: true,
columns: [
{ width: 300, field: "ProductName", title: "<b>Product Name</b>" },
{ field: "UnitsOnOrder", title: "{{'unitsOrder'| translate}}" },
{ field: "UnitsInStock", title: "Units In Stock" }
]
});
</script>
I had a similar problem but I use i18next translation instead of angular but maybe it helps you find a solution to your case:
I use the 'excelExport' event to manually update the generated worksheet. Within the worksheet object I search for the header cells and manually trigger the translation for the text it contains:
excelExport: function(e) {
// First I loop through all rows in the worksheet
e.workbook.sheets[0].rows.forEach(function(row){
// Ignore 'data' rows (only use 'header' and 'footer')
if(row.type != 'data'){
// Loop through all cells of the row
row.cells.forEach(function(cell){
// Here I overwrite the cell value with its translation
// You have to implement translate() so it works with angular
cell.value = translate(cell.value)
});
}
});
},
You now have to write your own translate function which can handle your angular translation. As I use i18next for translations my solution won't help here (I use jquery to generate a jquery html object on which I can trigger the translation)
I need to change the value in a particular row wise column value in ui grid i.e., from Inactive to active status
I have a table in ui grid like
ID Name Status
1 India Active
2 Germany Inactive
3 France Active
4 Italy Active
5 Canada Inactive
My grid code
$scope.gridOptions = {
columnDefs: [
{
field : 'name',
displayName : 'Name',
width : '25%',
enableColumnMenu : false,
sort : {
direction : uiGridConstants.ASC
},
cellTemplate : '<div class="ngCellText" ng-class="col.colIndex()" ng-controller="NameController"><a ng-click="editPop({{row.entity}})">{{COL_FIELD}}</a></div>'
}, {
field : 'status',
displayName : 'Status',
width : '25%',
enableColumnMenu : false,
cellTemplate: '<div ng-controller="StatusController" ng-if=\"row.entity.status == \'Active\'\" ><img src=\'assets/img/on.png\' /><a ng-click="checkStatusDepend(row.entity.id,row.entity.name,row.entity.status)">Active</a></div>'+
'<div ng-controller="StatusController" ng-if=\"row.entity.status == \'Inactive\'\" ><img src=\'assets/img/off.png\' /><a ng-click="checkStatusDepend(row.entity.id,row.entity.name,row.entity.status)">Inactive</a></div>'
}
],
data: 'myData'
};
For calling this grid
getPage();
var getPage = function(obj) {
object.charge({}, function(list){
$scope.myData = list.data;
});
};
I am getting the list in myData so it is displayed in ui grid table.
I am updating the status in status controller
$rootScope.$emit("statusUpdateCall",id);
and for changing the value in another controller
$rootScope.$on('statusUpdateCall', function(events, args){
getPage();
});
I want to change for ID no 2 status Inactive to Active, in backend using rest spring i am updating in database but in frontend i need to change it to Active.
Currently i load the data from beginning.
I have gone through the angularjs ui grid tutorial using splice it removes particular row and add a new row with new changed data.
But without splice is there any other options are there to update particular column value?
Is there any possibility of showing more than one label in the category axis?
I need to show two fields from my data source in my category axis(And,yes there is no multi category axis. I need to show multiple fields on the same category axis. Please help if I'm missing out searching for any related topic.
Thanks in advance.
You can use label templates on the categoryAxis labels:
categoryAxis: {
field: 'submitTime',
majorGridLines: {
visible: false
},
labels: {
visible: true,
template: ' #= FormatLabel(dataItem) # '
}
},
In this example the template is passing the dataItem to a function which builds the desired string:
function FormatLabel(dataItem){
var tg = dataItem.TargetGroup;
var st = dataItem.submitTime.replace(" ", "\n");
return tg + "\n" + st;
}
DEMO
In your series, you can define the template on the label to display pretty much anything you want from the item it is bound to.
series: [
{
field: 'totalVisits',
name: 'Total Visits',
labels: {
visible: true,
template: ' #= dataItem.month # \n Total Visits : #= dataItem.totalVisits # \n Unique Visitors : #= dataItem.uniqueVisitors # '
}
}
],
See working sample at Kendo Dojo
If you need a bit more functionality, you can set that template to a function, and return whatever you want from it.
series: [
{
field: 'totalVisits',
name: 'Total Visits',
labels: {
visible: true,
template: chartSeriesTemplate
}
}
],
function chartSeriesTemplate(e) {
return kendo.format("{0} \n Total Visits:{1}\n Unique Visitors:{2} \n Ratio :{3}", e.dataItem.month, e.dataItem.totalVisits, e.dataItem.uniqueVisitors, (parseInt(e.dataItem.uniqueVisitors) / parseInt(e.dataItem.totalVisits)).toFixed(2));
}
See working sample at Kendo Dojo
Documentation for series template at Kendo Docs
I try to setup custom dropdown in Kendo UI.
I have a reference to my issue.
http://dojo.telerik.com/aFIZa/13
My issue is that I do not know how I can setup the selected text in the template attribute? I want to show the text field but save the id as a value. And I do not want to use external datasource. I would like it as inline in the json.
The code is below:
$scope.mainGridOptions = {
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{ field: "Category", title: "Category", width: "180px",
editor: function(container, options) {
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'cat\'" k-data-value-field="\'id\'" k-data-source="{data:[{id: 1, cat: \'test\'}, {id: 2, cat: \'test2\'}]}" data-bind="value:Category"/>')
.appendTo(container);
$compile(editor)($scope);
editor.css("visibility", "visible");
}
, template:"selected text in the combo "
}
], editable: true
}
Ok, this was a tough one, but I think I could achieve what you want, or at least I got closer:
$scope.mainGridOptions =
{
dataSource: $scope.dataSource,
pageable: true,
height: 550,
toolbar: ["create"],
columns: [
{
field: "Category", title: "Category", width: "180px",
editor: function(container, options)
{
// #1
var editor = $('<input kendo-drop-down-list required k-data-text-field="\'cat\'" k-data-value-field="\'id\'" k-data-source="{data:[{id: 1, cat: \'test\'}, {id: 2, cat: \'test2\'}]}" data-bind="value:Category,events:{ change: onChange }"/>')
.appendTo(container);
$compile(editor)($scope);
editor.css("visibility", "visible");
},
// #2
template:kendo.template($("#column-template").html())
}],
editable: true,
// #3
edit: function(e)
{
var ko = kendo.observable(
{
onChange: function(e)
{
var el = $(e.sender.element);
var ddl = el.data("kendoDropDownList");
var ds = $scope.dataSource.getByUid(el.closest("tr").data("uid"));
ds.OptionText = ddl.text();
},
});
var widget = $(e.container).find("input");
kendo.bind(widget, ko);
}
}});
Demo.
In the code you can notice 3 changes:
data-bind="value:Category,events:{ change: onChange }" Look that I have added an events object in the bind, which I declare onChange as the change event handler. We'll talk about this in the 3rd item below;
For a complex template(with javascript code and logic) I created a script content and rendered it at the template property. The template is this:
<script id="column-template" type="text/x-kendo-template">
# if (data.hasOwnProperty('OptionText')) { #
#: OptionText #
# } else { #
#: "selected text in the combo" #
# } #
</script>
In the template I simply check for the property OptionText in the model(dataSource's current item) and: if it exists, use it; else, use the default text. We'll talk about OptionText in the 3rd item, below;
Now, here I have added an edit event to the grid. In that event I created an observable object, where I define the onChange function handler. In that function I seek for the current dataSource(ds) and I add text of the selected item in the dropdownlist in it, as the property OptionText, which I use in the template above explained.
I hope this explains how it works(in fact I hate working with those binders and observables, but sometimes they are needed).
Good luck.
I have an ext js grid like below:
var grid = new Ext.grid.GridPanel({
columns: [
{header: 'Account Id',dataIndex:'accountId' },
{header: 'Account NUmber',dataIndex:'accountNumber' }
]
})
Now I need to show Account Id column as a column of radio buttons. So from the grid user can select one Account Id and submit. When the user reloads the page, that account id should be preselected.
I need some help on how to proceed on this. Do I need to write a renderer on Account Id column? Or is there an easier way.
EDIT: I did like this:
{header: 'Account Id',dataIndex:'accountId',renderer: function(value) {
return "<input type='radio' name = 'primaryRadio' " + (value ? "checked='checked'" : "") + ">";
}},
What is the syntax to add an onclick event or onchange event to the radio group?
Building off the previous answer, yes, I think using a renderer for your column is the correct solution. I think you should go about the click event differently than J. Bruni suggested though. I'd recommend a click listener on your grid panel that checks if you clicked a radio button, and delegates to a method in your GridPanel.
Something like this:
MyRadioGrid = Ext.extend(Ext.grid.GridPanel, {
columns: [
{header: 'Account Id',dataIndex:'accountId', renderer: function(value) {
return "<input type='radio' name = 'primaryRadio' " + (value ? "checked='checked'" : "") + ">";
}},
{header: 'Account NUmber',dataIndex:'accountNumber' }
],
afterRender: function() {
MyRadioGrid.superclass.afterRender.apply(this, arguments);
this.el.on('click', this.checkRadioClick, this);
},
checkRadioClick: function(event) {
if (event.getTarget('input[type="radio"]')) {
//radio clicked... do something
}
}
});
You did well on showing Account Id column as a column of radio buttons, by using a renderer function.
Regarding the onclick event for these, you may simply add the onclick attribute in the HTML tag:
return "<input onclick='my_function()' type='radio' name = 'primaryRadio' " + (value ? "checked='checked'" : "") + ">";