AngularJS ui-grid Nested Column Menu - angularjs

ui-grid allows for column menus but they are added one on top of the other. I need to have nested menu items (like this http://www.bootply.com/86684) but I also need to specify custom controls, like check boxes and radio buttons on the nested menu item.
So far, I've spent several hours going through the docs, searching online, and reading the ui-grid code but have not been able to come up with a solution. Looking for some pointers or guidance on how I may be able to achieve this.
Sample configuration of menu items for a column in ui-grid:
$scope.gridOptions.columnDefs = [
field: 'Column01',
menuItems: [
{
title: 'Outer Scope Alert',
icon: 'ui-grid-icon-info-circled',
shown: function() { return true; },
active: function() { return true; },
context: $scope,
action: function($event) {
this.context.blargh();
}
},
{
title: 'Grid ID',
action: function() {
alert('Grid ID: ' + this.grid.id);
}
}
]
];
Is there a way to completely overwrite the column menu template so that I can specify a nested array of menu items like so? Note also that I would like to specify a template for the individual menu items.
$scope.gridOptions.columnDefs = [
field: 'Column01',
menuItems: [
{
title: 'Menu A',
icon: 'ui-grid-icon-info-circled',
context: $scope,
menuItems: [
{
title: 'Menu A1',
icon: 'ui-grid-icon-info-circled',
template: '<li>' +
' <div class="checkbox">' +
' <label>' +
' <input type="checkbox"> Checkbox 01' +
' </label>' +
' </div>' +
' <div class="checkbox">' +
' <label>' +
' <input type="checkbox"> Checkbox 02' +
' </label>' +
' </div>' +
'</li>',
action: function($event) {
this.context.blarghA1();
}
},
{
title: 'Menu A2',
icon: 'ui-grid-icon-info-circled',
action: function($event) {
this.context.blarghA2();
}
},
{
title: 'Menu A3',
icon: 'ui-grid-icon-info-circled',
action: function($event) {
this.context.blarghA3();
}
}
]
},
{
title: 'Menu B',
action: function() {
alert('Grid ID: ' + this.grid.id);
}
}
]
];
Thanks!

Related

Highstock Navigator Displayed Twice

I am using highstock,5.0.10 with angularJS.
In my chart navigator got displayed twice, like below
As you can see, navigator has been rendered twice. However, if you refresh the page, everything looks fine.
Any ideas?
I have added my Highstock code here.
Highcharts.stockChart('FindComputerUsage', {
rangeSelector: {
selected: 1
},
credits: {
enabled: false
},
title: {
text: ''
},
yAxis: {
title: {
text: 'Percentage of time (%) '
}
},
tooltip: {
formatter: function() {
var date = new Date(requiredData[this.points[0].point.index][0]);
return date + '<br>' + 'Percentage:' + requiredData[this.points[0].point.index][1] + '%';
}
},
series: [{
name: 'Percentage (%)',
data: requiredData,
tooltip: {
valueDecimals: 2,
}
}],
lang :{
noData : "No data to display "
}
});
Here you can see a working example: https://plnkr.co/edit/OphM9wf8WyGm8U6HXfTy
You haven't show your HTML view, but I guess it's similar to this.
<div ng-controller="demoCtrl">
<div id="container" style="height: 400px; min-width: 310px"></div>
</div>
Concerning controller scope, I didn't change anything:
var app = angular.module('demoApp', []);
app.controller('demoCtrl', function($scope){
$scope.data = [
[1290729600000,45.00],
[1290988800000,45.27],
[1291075200000,44.45]
];
Highcharts.stockChart('container', {
rangeSelector: {
selected: 1
},
title: {
text: 'Qing Xu Example'
},
series: [{
name: 'Value',
data: $scope.data,
tooltip: {
valueDecimals: 2
}
}]
})
});

Using Custom editors in grid column with Angular Kendo UI

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.

Adding conditional value to angular ng-table

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?

Angular UI Bootstrap's Radio Button inside a directive with ng-repeat does not show default value properly

Essentially, I have a directive that is used as a 3 way filter using a radio button. Unfortunately, it needs to have a default state and that default state has to actually be shown in the UI, the problem is that although the model is updated properly, the UI is not. Here is a plunkr that demonstrates the issue:
http://plnkr.co/edit/8pljDFyRfInI4Q0qSTmL?p=preview
The directive is used the following way:
<filter model="model"/>
Where the model is defined as this.model = { value: {} } in the controller
Here is an updated code.
At first I want to say what ng-model directive works only with input elements,
and also I changed the isActive: 'Yes/No' to true/false
// Code goes here
var filters = angular.module('filters', ['ui.bootstrap']);
filters.controller('FilterCtrl', function() {
this.model = { value: {} };
});
filters.directive('filter', function () {
return {
restrict: 'E',
scope: {
model: '='
},
template: '<div class="btn-group">' +
'<label ng-repeat="choice in choices" class="btn btn-{{ choice.buttonClass }}" ng-class="{active: choice.value.isActive}"' +
'btn-radio="{{ choice.value }}"><i class="fa {{ choice.icon }}"></i> {{ choice.name }}</label>' +
'</div>',
link: function (scope, element, attrs) {
scope.choices = [
{ value: { isActive: true }, name: 'Active', buttonClass: 'default', icon: 'fa-circle' },
{ value: null, name: 'Both', buttonClass: 'primary', icon: 'fa-arrows-h' },
{ value: { isActive: false}, name: 'Inactive', buttonClass: 'danger', icon: 'fa-circle-o' },
];
scope.model.value = _.first(_.filter(scope.choices, { value: { isActive: 'Yes' } })).value;
}
}
});

Angularjs directive not redrawing

I am trying to get a recursive directive working in angular. After quite a bit of time on stackoverflow and digging through the angular documentation I have got most of it working. I'm having a hard time getting the actions working though. The object is getting updated as I would expect, but the directive doesn't seem to be redrawn accordingly.
Here is the directive:
.directive('formgenerator', ['$compile', function ($compile) {
return {
restrict: 'E',
terminal: true,
scope: { val: '=', index: '=' },
replace: true,
link: function (scope, element, attrs) {
var template = '<div data-ng-if="val">';
template += !scope.val.type ? ''
: scope.val.type === 'text' ? '<label>{{val.label}}</label><input type="text" data-ng-model="val.value"></input><button ng-click="deleteMe(index)">delete</button>'
: scope.val.type === 'select' ? '<label>{{val.label}}</label><select data-ng-model="val.value" data-ng-options="v.name for v in val.values track by v.id"></select><button ng-click="deleteMe(index)">delete</button>'
: scope.val.type === 'multiselect' ? '<label>{{val.label}}</label><select data-ng-model="val.value" multiple="multiple" data-ng-options="v.name for v in val.values track by v.id"></select><button ng-click="deleteMe(index)">delete</button>'
: '';
template += '</div>';
if (angular.isArray(scope.val.inputs)) {
template += '<ul class="indent"><li ng-repeat="input in val.inputs track by $index"><formgenerator val="input" index="$index"></formgenerator></li></ul>';
}
scope.deleteMe = function (index) {
scope.$parent.val.inputs.splice(index, 1);
//var inpts = scope.$parent.val.inputs;
//inpts.splice(index, 1);
//scope.$parent.val.inputs = inpts;
//scope.$parent.$parent.val.inputs.splice(index, 1);
//scope.$parent.$parent.$parent.val.inputs[scope.$parent.this.index].inputs.splice(scope.$parent.this.index, 1);
};
var newElement = angular.element(template);
$compile(newElement)(scope);
element.replaceWith(newElement);
}
};
}]);
Here is the object the controller is passing into the directive:
form = {
inputs:
[
{
type: 'text',
value: 'textValue',
label: 'Text value',
defaultValue: 'defaultTextValue'
},
{
inputs:
[
{
type: 'text',
value: 'textValue1',
label: 'Text value1',
defaultValue: 'defaultTextValue1'
},
{
type: 'select',
value: 'textValue2',
values: [{ name: '1st', id: 1 }, { name: '2nd', id: 2 }],
label: 'Text value2',
defaultValue: 'defaultTextValue2'
},
{
type: 'multiselect',
value: 'textValue3',
values: [{ name: '1st', id: 1 }, { name: '2nd', id: 2 }],
label: 'Text value3',
defaultValue: 'defaultTextValue3'
}
]
}
]
};
Here is the jsFiddle: http://jsfiddle.net/5YCe7/1/
Basically, if I hit the delete button next to Text value2, I would expect the single select to 'disappear' and the multiselect to 'move up'. What seems to be happening though is that the values of the multiselect move in place of the values for the select.
Any help on this would be greatly appreciated.
There are a few errors here:
When you press deleteMe, you need to again compile and replace the element with the new element. link won't automatically be called again.
I don't think your index is being assigned correctly
I would recommend looking at a few links before making recursive directives:
Is it possible to make a Tree View with Angular?
Recursion in Angular directives

Resources