how to add dynamic field to ui-grid header-name field - javascript

Grid which has one field name Users and requirement is it should display Users(count of Users) in ui-grid header-name. How can I get that.
This is my JS file code:
var userCount= response.usercount;
columnDefs: [{
name: 'Users', // Along with Users i want count also
width: '25%',
cellTemplate: 'beacon-template'
},
How can I get that?

You can always change the header text. Sounds like you can put a watch to the count value and do something similar like the following:
$scope.$watch('yourCountValue', function(newVal){
$scope.gridOptions.columnDefs[0].displayName = 'Users(' + newVal + ')';
$scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
})
the code may vary in your case. For example, you may watch the $scope.data change instead and use $scope.data.length to concat the displayName. You may have select header and index will be 1 instead of 0, etc.
Updated Answer: did you forget to inject ui.grid and uiGridConstants?
var app = angular.module('myApp', ['ui.grid']);
app.controller('appCtrl', ['$scope', 'uiGridConstants', function($scope, uiGridConstants) {
$scope.gridOptions = {
columnDefs: [
{field: 'field1', displayName: 'User 1'},
{field: 'field2', displayName: 'User 2'},
],
data: [
{ field1: "user 1", field2: "bar"},
{ field1: "user 2", field2: "bar"},
{ field1: "user 3", field2: "bar"}
],
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
}
};
//put the watch here
/...
}]);

Related

using a backbone model to fill options of a select field

I would like to populate the options of a select field with the attributes from a "static" model. For example I have a Model and a collections of US states:
State = Backbone.Model.extend({
label:'',
value:''
}) ;
STATES = Backbone.Collection.extend({
model: State
});
states = [
{label: "Select ", value: '__' },
{label: "Alabama ", value: 'AL' },
{label: "Alaska ", value: 'AK' },
{label: "Arizona ", value: 'AZ' },
....];
localstates = new app.STATES(states); // or fetch the list of states from a RESTful site.
I then using back form have any address view and I want to pass localstates into the Form to populate the options of the state field:
UserAddress = Backform.Form.extend({
el: $("#personalInformation"),
fields: [
{name: "address1", label: "Address1", control: "input"},
{name: "address2", label: "Address2", control: "input"},
{name: "city", label: "City", control: "input"},
{name: "state", label: "State", control: "select",
options: **localstates**,
{name: "zip", label: "Zip Code", control: "input"},
{control: "button", label: "Save to server"}
],
});
I'm guessing I need to somehow pass the states collection into the User Address view and then access the attributes. But I have not been able to find a good example of how to do this.
edit1: Ok this is a bit silly in this case but:
newstate = new app.STATES(app.states);
var allstates =[];
app.newstate.forEach(function(state){
allstates.push({"label": state.get("label"), "value" : state.get("value")});
})
Gives me and array I can use at localstate. Basically I just re-created my original array in this case. In the case where it was fetch from a server it would be useful, but is there a better way?
You can do localstates.toJSON() to get a copy of the values to use in the template.
See Collection.toJSON()

Webix DataTable - expand object properties

If I have a list of (JavaScript) objects in the following form:
var results = [
{'name': 'mary', 'availability' : { 'monday': 'True', 'tuesday': 'False' ... } },
{'name': 'john', 'availability' : { 'monday': 'False', 'tuesday': 'False' ... } },
{'name': 'pete', 'availability' : { 'monday': 'True', 'tuesday': 'True' ... } }
]
how do I display this data in a Webix DataTable, having each of the days in availability as a column?
My configuration object for the DataTable looks like this:
var dtable = webix.ui({
....
view:"datatable",
id: "nameTable",
columns:[
{ id: "name", header:"Name"},
{ id: "availability.monday", header:'Mon'},
{ id: "availability.tuesday", header:'Tue'},
...
],
data:results,
...
});
I have also tried: id: "availability['mon']" which doesn't work or report any error. If I just do : id:"availability", in the browser I see that it shows [object Object] for each row.
I've also tried the autoconfig option but that doesn't render anything (no errors).
I have tried to find examples in the documentation but haven't found any so far. I'm sure this must be possible without having to restructure my incoming data!
There is no native support for complex properties in the Webix DataTable. You can use "template" property of column object to show any property of data object as value of a column, though.
columns:[
{ id: "col1", template:"#availability.monday#"},

Angular JS replace values ng grid

I am newbie in angular JS and I think that I need help.
This is my issue :
I have a ng-grid which is linked with a table. Within there are values and a ID (which is a foreignkey from a another table). I don't want to show the ID but another field in this foreign table.
CompanyFactory.getCompanies().success(function (data) { $scope.objs = data })
$scope.gridOptions = {
data: 'objs',
showGroupPanel: true,
jqueryUIDraggable: true,
columnDefs: [
{ field: 'COMP_NAME', displayName: 'comp_name'},
{ field: 'COUNTRY', displayName: 'country' },
{ field: 'LU_SECTOR_ID', displayName: 'sector', },
]
};
I want show the sector_name field instead of the sector_ID field. How can I make the relation between these two tables ?
$scope.countries = [
{ COMP_NAME: 'KOLI', COUNTRY: 'KOLI_COUNTRY', LU_SECTOR_ID: '1'},
{ COMP_NAME: 'ZOLI', COUNTRY: 'ZOLI_COUNTRY', LU_SECTOR_ID: '2'},
{ COMP_NAME: 'TULI', COUNTRY: 'TULI_COUNTRY', LU_SECTOR_ID: '3'},
];
$scope.sector= [
{ LU_SECTOR_ID: '1', LU_SECTOR_NAME: 'SECTOR_1'},
{ LU_SECTOR_ID: '2', LU_SECTOR_NAME: 'SECTOR_2'},
{ LU_SECTOR_ID: '3', LU_SECTOR_NAME: 'SECTOR_3'},
];
I would like to show in the ng-grid the SECTOR NAME instead of the SECTOR_ID.
It is difficult to answer the question without the information of the data object.
However, suppose that your data object returned by your CompanyFactory is something like:
[
{
"COMP_NAME": "Tomms",
"COUNTRY": "France",
"LU_SECTOR_ID": "9":,
"SECTOR": { "SECTOR_NAME": "IT" }
}
]
You just need to bind the correct field:
$scope.gridOptions = {
data: 'objs',
showGroupPanel: true,
jqueryUIDraggable: true,
columnDefs: [
{ field: 'COMP_NAME', displayName: 'comp_name'},
{ field: 'COUNTRY', displayName: 'country' },
// Here
{ field: 'SECTOR.SECTOR_NAME', displayName: 'sector', },
]
};
But, if you returning both objects separated you will need to link it manually. My suggestion is to perform that in the server side and return the object like I used as an example.
the problem is here
{ field: 'LU_SECTOR_ID', displayName: 'sector', }
Specifically
LU_SECTOR_ID
you need to change the name of this variable to be the name on the objs and not the id

how to set initial value to combobox in angular?

If I want to set the value of the combobox I have tried this:
controllercode:
$scope.streettypeMockData = [{
name: 'Street',
value: 'Street'
}, {
name: 'Avenue'
}, {
name: 'Crescent'
}, {
name: 'Drive'
}, {
name: 'Road'
}, {
name: 'Highway'
}];
var sel = "Street";
var selectedValue = {
name: sel
};
$scope.streetTypeSelected = selectedValue;
Can anyone tell me why this does not work? see also http://plnkr.co/edit/4ISL8A1cNGCtafsc0leX?p=preview
The code has a few issues:
The ng-options select the name, while the ng-model points to an object. Better use streetType as streetType.name for streetType in streettypeMockData to select the entire object.
In this case, the initial value will not be honoured because Angular will try to compare objects by reference; use track by.
The full <select> should be:
<select class="form-control" ng-model="streetTypeSelected"
ng-options="streetType as streetType.name for streetType in streettypeMockData track by streetType.name">
See forked plunker.
You can simple use ng-init like this
<select ng-init="streetTypeSelected = streettypeMockData[0]" class="form-control" ng-model="streetTypeSelected" ng-options="streetType.name for streetType in streettypeMockData">
</select>
Working Demo
Also you can do Like as shown below
var app = angular.module('myApp', []);
app.controller('MainCtrl', function ($scope) {
$scope.streettypeMockData = [
{name: 'Street', value: 'Street'},
{name: 'Avenue'},
{name: 'Crescent'},
{name: 'Drive'},
{name: 'Road'},
{name: 'Highway'}
];
$scope.streetTypeSelected = $scope.streettypeMockData[0];
});
Working Demo
Also take a look at this
https://docs.angularjs.org/api/ng/directive/select

Looping through deep objects in ng-repeat

I'm in angular and i have a object like this.
var items = [{
title: 'Something',
children: [
{ title: 'Hello World' },
{ title: 'Hello Overflow' },
{ title: 'John Doe', children: [
{ title: 'Amazing title' },
{ title: 'Google it' },
{ title: 'I'm a child', children: [
{ title: 'Another ' },
{ title: 'He\'s my brother' },
{ title: 'She\'s my mother.', children: [
{title: 'You never know if I'm going to have children'}
]}
]}
]}
]
}];
I wan't to loop through all of these so i have something like this.
    • Something
       • Hello World
       • Hello Overflow
       • John Doe
          • Amazing Title
          • Google it
          • I'm a child
              • Another
              • He's my brother
              • She's my mother
                  • You never know if I'm going to have children
The problem is I wouldn't know how deep this object will go or what's in it. so I wouldn't be able to do it manually. I have done a basic loop with ng-repeat in the fiddle provided at the bottom, but i can't figure out how I can automatically loop through these and create nested <ul>'s and <li>'s.
What would be the best way to accomplish this?
Demo: http://jsfiddle.net/XtgLM/
You don't need to make a custom directive, what you want is to use an inline template that calls it's self.
I forked your fiddle.
http://jsfiddle.net/MasterMorality/E99Gh/2/
basically it looks like this:
<script type='text/ng-template' id="item.html">
...
<div ng-repeat="x in x.childrens" ng-include="'item.html'"></div>
</script>
...
<div ng-repeat="x in things" ng-include="'item.html'"></div>
I should note that you are not actually overwriting x, since angular creates a new scope for each repeated item.
Here you go:
html
<div ng-app="app" ng-controller="test">
<ul>
<li nested-item ng-repeat="item in items">{{item.title}}</li>
</ul>
</div>
JavaScript
var items = [{
title: 'Something',
children: [
{ title: 'Hello World' },
{ title: 'Hello Overflow' },
{ title: 'John Doe', children: [
{ title: 'Amazing title' },
{ title: 'Google it' },
{ title: 'Im a child', children: [
{ title: 'Another ' },
{ title: 'He\'s my brother' },
{ title: 'She\'s my mother.', children: [
{title: 'You never know if im going to have children'}
]}
]}
]}
]
}];
var app = angular.module('app', []);
app.controller('test', function( $scope ) {
$scope.items = items;
});
app.directive('nestedItem', ['$compile', function($compile){
return {
restrict: 'A',
link: function(scope, element){
console.log(element);
if (scope.item.children){
var html = $compile('<ul><li nested-item ng-repeat="item in item.children">{{item.title}}</li></ul>')(scope);
element.append(html);
}
}
};
}]);
I forked your fiddle:
http://jsfiddle.net/c4Kp8/
Actually I must confess that I like Master Morality's approach but you can also go with a custom directive. The key thing to know if you go that route is that you need to intercept on the item level to manually check if the current item has children, and if so, $compile the directive for the node yourself.
UPDATE
However, there is one thing that should bother us in the above code. The duplication of html code (inlined in the directive) is a code smell. If you like, you can get really funky and fix this by introducing a generic template-code directive which doesn't do anything else but providing the code of the node where it is applied on as a template for other directives.
So then our solution would look like this:
html
<div ng-app="app" ng-controller="test">
<ul template-code>
<li nested-item ng-repeat="item in items">{{item.title}}</li>
</ul>
</div>
JavaScript
var items = [{
title: 'Something',
children: [
{ title: 'Hello World' },
{ title: 'Hello Overflow' },
{ title: 'John Doe', children: [
{ title: 'Amazing title' },
{ title: 'Google it' },
{ title: 'Im a child', children: [
{ title: 'Another ' },
{ title: 'He\'s my brother' },
{ title: 'She\'s my mother.', children: [
{title: 'You never know if im going to have children'}
]}
]}
]}
]
}];
var app = angular.module('app', []);
app.controller('test', function( $scope ) {
$scope.items = items;
});
app.directive('templateCode', function(){
return {
restrict: 'A',
controller: function(){},
compile: function(element){
element.removeAttr('template-code');
//ATTENTION: We need to trim() here. Otherwise AngularJS raises an exception
//later when we want to use the templateCode in a $compile function.
//Be aware that we assume a modern browser
//that already ships with a trim function.
//It's easy to secure that with a polyfill.
var templateCode = element.parent().html().trim();
return function(scope, iElement, iAttrs, controller){
controller.templateCode = templateCode;
}
}
}
});
app.directive('nestedItem', ['$compile', function($compile){
return {
restrict: 'A',
require: '^templateCode',
link: function(scope, element, iAttr, controller){
if (scope.item.children){
scope.items = scope.item.children;
var html = $compile(controller.templateCode)(scope);
element.append(html);
}
}
};
}]);
Plunker: http://jsfiddle.net/2rQWf/
You're probably going to need to create your own directive passing in the object to iterate over. Put a watch on the object passed in and when that fires run some recursive function that appends elements to the element that the directive is on.
You can get at the DOM element from the element parameter on the directive link function. You can obviously append DOM elements using that same element parameter.

Categories

Resources