I want to add glyphicon to a column based on row value in ng-table component .For example if row.firstProperty==row.secondProperty then the glyph be added to column.I know how to do this in angular Grid UI but although I review documentations and examples but I did not find any way in ng-Table.Can anyone suggest a solution to my issue?
Edit:My scenario is that I have a custom directive that it is used to produce many pages with same style and functionality by getting page data and in part of it ng-table is used by defining template for my directive.
ng-table.html
<table ng-table="to.tableParams" class="table" show-filter="{{::to.showFilter}}">
<tr ng-show="to.showHeaders">
<th class="th-select" ng-repeat="column in to.columns">{{column.title}}</th>
</tr>
<tr ng-repeat="row in $data">
<td ng-repeat="column in to.columns" ng-show="column.visible" sortable="column.field" ng-click="save(row)">
{{row[column.field][column.subfield] || row[column.field]}}
<span compile="column.getValue()" ></span>
</td>
</tr>
ngTable Columns is defined in Controllers and one of the columns is html values like glyphicons and buttons that is maked base on object named actionList which is defined in each controller like below:
vm.actionList = [
{
name: 'edit',
body: function (row) {
$state.go("editrule", {ruleId: row.id});
},
glyph: 'glyphicon-pencil',
permission: $scope.permission.edit,
showCondition:"true"
},
{
name: 'view',
body: function (row) {
$state.go("showrule", {ruleId: row.id});
},
glyph: "glyphicon-eye-open",
permission: $scope.permission.watch,
showCondition:"row.modifiedDate==row.createDate"
},
{
name: 'history',
body: function (row) {
$state.go("rulehistory", {ruleId: row.id});
},
glyph: "glyphicon-info-sign",
showCondition: "row.modifiedDate!=row.createDate",
permission: $scope.permission.history
}
];
.I put the logic for creating html column to my directive to prevent repeated code from controllers and delivering it to controllers and the controller part for defining columns is as below :
vm.columns = [
{
title: $translate.instant('URL'),
translate: "URL",
field: 'url',
visible: true,
alignment: 'text-align-lg-left'
},
{
title: $translate.instant('MATCH_TYPE'),
translate: "MATCH_TYPE",
field: 'matchType',
visible: true,
alignment: 'text-align-lg-center',
filter: [{lowercase: []}]
},
{title: $translate.instant('PRIORITY'), translate: "PRIORITY", field: 'priority', visible: true,alignment: 'text-align-lg-center'},
{title: $translate.instant('SOURCE'), tanslate: "SOURCE", field: 'source', visible: true,alignment: 'text-align-lg-center'},
{title: $translate.instant('CATEGORY'), translate: "CATEGORY", field: 'category', visible: true,alignment: 'text-align-lg-center'},
{
title: $translate.instant('CREATE_DATE'),
translate: "CREATE_DATE",
field: 'createdDate',
visible: true,
alignment: 'text-align-lg-center'
},
{
title: $translate.instant('LAST_CHANGE'),
translate: "LAST_CHANGE",
field: 'modifiedDate',
visible: true,
alignment: 'text-align-lg-center'
},
{title: $translate.instant('ACTION') ,translate: "ACTION", field: 'action', visible: true,alignment: 'text-align-lg-center'},
{title: '', visible: true, getValue: htmlValue, id: "actionList"}/*actions*/
];
function htmlValue() {
return $sce.trustAsHtml(actions);
}
The action value comes from directive that contains htmls.The Directive part is as below :
scope.html = function htmlValue() {
var html = "";
/*intentionaly angular ng-repeat not used*/
for (var i = 0; i < scope.actionList.length; i++) {
scope.entry = scope.actionList[i];
scope.permission = scope.entry.permission;
scope.myglyph = scope.entry.glyph;
if (typeof scope.entry.permission == 'undefined' || scope.entry.permission == true) {
debugger
html = '<button ng-show="{{entry.condition}}" type="button" class="btn btn-list" ng-click=' + $interpolate("{{entry.name}}(row)")(scope) + '> ' +
'<span class=\"glyphicon ' + $interpolate("{{entry.glyph}}")(scope) + '\"></span>' +
'</button>' + html;
console.log("this is test");
console.log(scope.test);
}
}
}
scope.$watch('refreshDataFilter', function (newValue, oldValue) {
/*EXTRACT ACTIONS*/
for (var i = 0; i < scope.actionList.length; i++) {
var entry = scope.actionList[i];
Object.defineProperty(scope, entry.name, {value: entry.body});
Object.defineProperty(scope, entry.showCondition, {value: "aaa"});
}
/*define table data filler*/
if (newValue == true) {
renderTable();
scope.refreshDataFilter = false;
}
});
The main problem is here that if I interpolate the values of entry.showCondition I always get the value of of last item in actionList. Is there any solution that I can make html part of table base on conditions?
Related
I am trying to use custom editors for an editable kendo ui grid in my angular app.
For some reason( which I am not able to trace) the custom editor is not triggered.
I am expecting the following to be triggered but it does not work.
console.log("Editor Launched", options);
Here is the plunker for the same:
http://plnkr.co/edit/WioRbXA3LHVVRQD95nXA?p=preview
app.controller('MainCtrl', function($scope) {
$scope.model = {};
$scope.model.dataSource = new kendo.data.DataSource({
data: createRandomData(10),
schema: {
model: {
fields: {
City: { type: "string" },
Title: { type: "string" },
BirthDate: { type: "date" },
Age: { type: "number" }
}
}
},
pageSize: 16,
editable:true
});
$scope.addWWNumEditor= function (container, options) {
console.log("Editor Launched", options);
$('<input kendo-numeric-text-box k-min="10" k-max="20" style="width: 100%;" data-bind="value:' + options.field + '"/>')
.appendTo(container);
}
$scope.controlIsDisabled=function(model){
//console.log("model",(model.Age>=50));
var toReturn = (model.Age>50)?"columnDisabled" : "columnActive";
//console.log('to Return',toReturn);
return toReturn;
}
$scope.model.columns = [
{ field: 'City', title: 'City' },
{
field: 'Title',
title: 'Title',
template:'<span style="color:red;">EDITABLE</span><span ng-
class="controlIsDisabled(dataItem)">#=Title#</span>'
},
{
field: 'Age',
title: 'Age',
template:'<span ng-class="controlIsDisabled(dataItem)">#=Age#</span>'
,
editor:$scope.addWWNumEditor
}
];
});
Assuming your Plunkr mirrors your actual code, the primary problem I'm seeing is in your binding of k-columns on the grid element.
You currently have k-columns="{{model.columns}}", but the {{}} are unnecessary here. Changing to k-columns="model.columns" causes your editor function to execute as expected.
I have a requirement to toggle between the view in kendo UI scheduler, my view will be week but on checkbox click i want to change week view type between week and workWeek; how to do this?
Here is html
<label><input type="checkbox" ng-model="hideWeekend" ng-change="hideWeekends(hideWeekend);" value="true" />Hide Weekend</label>
<div id="team-schedule">
<div kendo-tooltip k-content="tooltipContent" k-filter="'.k-event'" class="k-group">
<div id="target"></div>
<div kendo-scheduler="weeklyScheduler" k-options="weeklySchedulerOptions" id="scheduler"></div>
</div>
</div>
JS code
$scope.schedulerDS = new kendo.data.SchedulerDataSource({
batch: true,
filter: {
logic: "or",
filters: [
{ field: "ownerId", operator: "eq", value: 1 },
{ field: "ownerId", operator: "eq", value: 2 }
]
}
});
var weekOrWorkWeek = 'workWeek';
$scope.loadWeeklySchedule = function (value) {
$scope.weeklySchedulerOptions = {
autoBind: false,
date: new Date(),
height: 600,
views: [{ type: value, selected: true, majorTick: 15, footer: false, allDaySlot: false }],
timezone: "Etc/UTC",
dataSource: $scope.schedulerDS,
resources: [
{
field: "ownerId",
title: "Owner",
dataSource: [
{ text: "Alex", value: 1, color: "#f8a398" },
{ text: "Bob", value: 2, color: "#51a0ed" },
{ text: "Charlie", value: 3, color: "#56ca85" }
]
}
]
};
};
$scope.hideWeekends = function (value) {
if (value == true) {
weekOrWorkWeek = 'workWeek';
$scope.loadWeeklySchedule(weekOrWorkWeek);
$scope.weeklySchedulerOptions.dataSource.read();
} else {
weekOrWorkWeek = 'week';
$scope.loadWeeklySchedule(weekOrWorkWeek);
$scope.weeklySchedulerOptions.dataSource.read();
}
};
$scope.loadWeeklySchedule(weekOrWorkWeek);
You can enable this view by adding the view type "workWeek" to the views array of the scheduler options object from the get go.
This will also show a view selection on the scheduler top toolbar but you can remove it by adding a CSS rule:
.k-scheduler-views {
display: none;
}
Switching between views can be done using the scheduler's view method:
$("#scheduler").data("kendoScheduler").view("ViewName")
Here's a Plunker with a demo.
I'm using a Kendo UI Grid with AngularJS. The grid has a 'popup' mode editable kendo template. The grid invokes the create, destroy & delete functions; however the update function won't get called. Strangely when I change the edit mode to 'inline', the update function is called. Below are the code snippets from my application :
Main UI Grid:
<div class="container-fluid">
<kendo-grid style="margin-top: 2em" k-options="ctrl.fundGridOptions" k-scope-field="kgrid" id="myGrid"></kendo-grid>
</div>
Edit Template:
<script id="edit-template" type="text/x-kendo-template">
<div class="container">
<div class="well">
Fund :
<select kendo-drop-down-list k-options="ctrl.fundOptions" style="width: 130px;" ng-model="dataItem.GenevaId"></select>
<!--<select kendo-drop-down-list k-data-source="ctrl.funds" style="width: 130px;" ng-model="dataItem.GenevaId"></select>-->
NAV Change Threshold
<input kendo-numeric-text-box k-min="0" k-max="100" k-ng-model="value" style="width: 60px;" ng-model="dataItem.NAVThreshold" />
NAV Source
<select k-data-source="ctrl.navSources" kendo-drop-down-list k-option-label="'-Select-'" style="width: 130px;" ng-model="dataItem.NAVSource"></select>
Frequency
<select k-data-source="ctrl.frequencyList" kendo-drop-down-list k-option-label="'-Select-'" style="width: 130px;" ng-model="dataItem.Frequency"></select>
Type
<select k-data-source="ctrl.typeList" kendo-drop-down-list k-option-label="'-Select-'" style="width: 130px;" ng-model="dataItem.Type"></select>
</div>
<div kendo-grid="ctrl.currencyKendoGrid" style="margin-top: 2em" k-options="ctrl.currencyGridOptions"></div>
</div>
</script>
Grid Options:
ctrl.fundGridOptions = {
dataSource: {
transport: {
update: function (options) {
DataSvc.updateFund(e.data).then(function (response) {
e.success(e.data);
});
},
},
schema: {
model: {
id: "FundId",
fields: {
FundId: { type: "number", editable: false, nullable: true },
GenevaId: { type: "string", editable: true },
NAVThreshold: { type: "number", editable: true },
NAVSource: { type: "string", editable: true },
Frequency: { type: "string", editable: true },
Type: { type: "string", editable: true },
}
}
},
},
sortable: true,
columns: [
{ field: "GenevaId", title: "Fund Name" },
{ field: "NAVThreshold*100", title: "NAV Threshold", template: '#=kendo.format("{0:p}", NAVThreshold)#' },
{ field: "NAVSource", title: "NAV Source" },
{ field: "Frequency", title: "Frequency" },
{ field: "Type", title: "Type" },
{ command: ["edit", "destroy"], title: " " }
],
detailTemplate: kendo.template($("#detail-template").html()),
detailInit: function (e) {
kendo.bind(e.detailRow, e.data);
},
dataBound: function (e) {
var grid = e.sender;
if (grid.dataSource.total() == 0) {
var colCount = grid.columns.length;
$(e.sender.wrapper)
.find('tbody')
.append('<tr class="kendo-data-row"><td colspan="' + colCount + '" class="no-data">Sorry, no data :(</td></tr>');
}
},
editable: {
mode: "popup",
template: kendo.template($("#edit-template").html()),
window: {
title: "Edit Fund Details",
animation: false,
height: "600",
width: "1200"
}
},
edit: function (e) {
if (e.model.Currencies)
ctrl.currencyKendoGrid.dataSource.data(e.model.Currencies);
},
toolbar: [
{
name: 'create',
text: 'Add Fund',
}],
};
Could anyone help me understand the reason why the 'update' function won't be called in 'popup' mode, but gets called in 'inline' mode ? Appreciate any responses in advance.
I know this is question old, but I came across it searching for an answer. I think the issue might be that your (and my) edit template uses ng-model binding to edit the dataItem ie we're using angularjs. This doesn't actually seem to change the dirty property on the dataItem. I solved the issue by using ng-change on each control. It's a pain, but seems to work.
<input id="Title" type="text" class="k-textbox" ng-model="dataItem.Title" ng-change="dataItem.dirty=true"/>
I am using Kendo UI Grid with row filters. i am facing filters options issue. I am using Filterbale.cell.template for filters to display kendo autoComplete.
Issue is as displayed in image autocomplete options are not updating on selecting of one of the filters.
Below is my html
<div ng-controller="VehiclesController" class="my-grid" >
<kendo-grid options="vehiclesGridOption">
</kendo-grid>
</div>
Below is my Controller
$scope.vehiclesGridOption = {
dataSource: {
schema: {
id: "_id",
model: {
fields: {
make: {type: "string"},
model: {type: "string"},
year: {type: "number"}
}
}
},
transport: {
read: function (e) {
vehicleService.vehicles().then(function (response) {
e.success(response);
console.log(response.length);
}).then(function () {
console.log("error happened");
})
}
},
pageSize: 12,
pageSizes: false,
},
sortable: {
mode: "multiple",
allowUnsort: true
},
filterable: {
mode: "row"
},
pageable: {
buttonCount: 5
},
columns: [
{
title: "",
template: '',
width: "3%" // ACTS AS SPACER
},
{
field: "make",
title: "Make",
filterable: {
cell: {
operator: "contains",
template: function (args) {
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "make",
dataValueField: "make",
valuePrimitive: true,
placeholder: "Make",
});
}
}
},
width: "29%",
}, {
field: "model",
filterable: {
cell: {
operator: "contains",
template: function (args) {
console.log(args);
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "model",
dataValueField: "model",
valuePrimitive: true,
placeholder: "Model",
});
}
}
},
title: "Model",
width: "29%",
}, {
field: "year",
title: "Year",
filterable: {
cell: {
template: function (args) {
args.element.kendoAutoComplete({
dataSource: args.dataSource,
dataTextField: "year",
dataValueField: "year",
placeholder: "Year",
suggest: true,
ignoreCase: true,
filter: "gte"
});
}
}
},
width: "29%",
},
{
field: "",
title: "Edit",
template: '<a class=\"k-link text-center grid-edit-btn vehicle-grid-edit-btn\" ui-sref="vehicleDetails({\'id\': \'#=_id #\' })"><span class=\"icon-editpencil icon-grid\"></span></a>',
width: "10%",
}],
};
Below is the Issue if user selects the Make in the first column filter then Model filter should display only selected make models like Honda (make)-> Accord , Civic ..etc but its displaying all unique values irrespective of model filter..
Kendo filter row uses the same dataSource from the grid component, just providing unique values. Since the autocomplete components are initialized when the grid dataSource is empty, they always show all the values.
You can manually filter based on current filter row values.
Firstly, add ids for your coresponding autocomplete components i.e. inside template functions:
args.element.attr('id', 'make');
//<...>
args.element.attr('id', 'model');
//<...>
args.element.attr('id', 'year');
Then add a data bound event to the grid (since autocomplete components do not fire change events when filters are cleared).
$scope.vehiclesGridOption = {
//...
dataBound : function(e) {
setTimeout(function() { //timeout is to make sure value() is already updated
var make = $('#make').data('kendoAutoComplete').value();
if (make) {
$('#model').data('kendoAutoComplete').dataSource.filter({field: 'make', operator: 'eq', value: make });
} else {
$('#model').data('kendoAutoComplete').dataSource.filter({});
}
});
}
}
Or if you also want to filter by "Year" column, it could go like this:
$scope.vehiclesGridOption = {
//...
dataBound: function(e) {
setTimeout(function() { //timeout is to make sure value() is already updated
var make = $('#make').data('kendoAutoComplete').value();
var model = $('#model').data('kendoAutoComplete').value();
if (make) {
$('#model').data('kendoAutoComplete').dataSource.filter({field: 'make', operator: 'eq', value: make });
} else {
$('#model').data('kendoAutoComplete').dataSource.filter({});
}
var yearFilter = {filters: [], logic: 'and'};
if (make) {
yearFilter.filters.push({field: 'make', operator: 'eq', value: make });
}
if (model) {
yearFilter.filters.push({field: 'model', operator: 'eq', value: model });
}
$('#year').data('kendoAutoComplete').dataSource.filter(yearFilter.filters.length ? yearFilter : null);
});
}
}
My problem is I'm using the kendo-grid as follows
in index.html
<table kendo-grid k-options="gridOptions" k-ng-delay="gridOptions" id="grid">
<thead>
<tr>
<th data-field="type">Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="asset in assets">
<td>{{asset.type}}</td>
</tr>
</tbody>
</table>
and using a factory for restangular
angular.module('myApp')
.factory('assetFactory', function (Restangular) {
return Restangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('my/service/url');
});
});
then in assetCtrl
assetFactory.all('cases').getList().then(function(assets) {
$scope.assets = assets;
});
.......
.......
$timeout(function(){
$scope.gridOptions = {
sortable: true,
selectable: true,
scrollable: true,
groupable: true,
height:790,
pageable: {
pageSize: 25,
input: true
}
};
}, 500);
now it is working but I'm not able to add more attributes for columns or updating because everything is generated in the index.html so I feel like I have no control on it.
So I want to make it something like this
in index.html just
<kendo-grid k-options="gridOptions" k-ng-delay="gridOptions">
</kendo-grid>
and keeping the factory as it is (using Restangular)
then in assetCtrl
var myData = new kendo.data.dataSource{
data: **// assign the assets here**
}
$timeout(function(){
$scope.gridOptions = {
dataSource: myData,
columns: [
**//fields with attributes like filtering for each col**
]
sortable: true,
selectable: true,
scrollable: true,
groupable: true,
height:790,
pageable: {
pageSize: 25,
input: true
}
};
}, 500);
Also can anyone tell me how should my service return look like ?? json array or .... ?
Any help ?
Thanks in advance
I know this question is a few months old, but I had to figure out how to make Restangular and Kendo UI Grid play nice today. I eventually came across the kendo.data.DataSource api as a reference: http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.read
Note: There's some solutions out there recommending using Datasource.push or DataSource.add and essentially transferring your json array via a for-loop. That's a bad idea since .add and .push both trigger an update.
Anyway, the solution using DataSource.transport.read:
Angular HTML Template:
<kendo-grid k-options="mainGridOptions"></kendo-grid>
Pertinent Controller Code:
// Set the columns of the grid. 'title' is the Label, 'field' is the corresponding json field name.
var kGridColumns = [
{title: "Asset Type", field: "asset"},
{title: "Asset Case Name", field: "name"},
{title: "Asset Case ID", field: "id"},
];
// Create a new Kendo DataSource and set the transport.read to a function.
var kDataSource = new kendo.data.DataSource({
pageSize: 10,
transport:{
read:function(e){
var assetListPromise= assetFactory.all('cases').getList();
assetListPromise.then(function(resp){
// Use .plain() to strip out all the excess Restangular features from the response
var plain = resp.plain();
// Pass your data back to the datasource/grid
e.success(plain);
});
assetListPromise.catch(function(resp){
var msg = "Issue loading asset cases:"+JSON.stringify(resp);
e.error(msg)
});
}
}
});
// Set the scope object with our columns and datasource config
$scope.mainGridOptions = {
dataSource: kDataSource,
sortable: true,
pageable: true,
columns: kGridColumns
};