How to copy selction into a new ui-grid - angularjs

I am using Angular ui-grid (from ui-grid.info).
I have one ui-grid showing JSON Data delivered by a webapi-controller what works perfectly.
I added a second ui-grid with the same columsDef but no data.
I want to copy the (multi-)selected rows from grid1 to grid 2 using a button.
How would I access the selection to add it into the data of the second grid?
app.js
var app = angular.module('app', ['ui.grid', 'ui.grid.grouping','ui.grid.selection']);
app.controller('MainCtrl', ['$scope', '$http', '$log', 'i18nService', '$interval', 'uiGridGroupingConstants', function ($scope, $http, $log,i18NService, $interval, uiGridGroupingConstants) {
$scope.langs = i18NService.getAllLangs();
$scope.lang = 'de';
i18NService.setCurrentLang('de');
$scope.gridOptions = {
rowSelection:true,
enableFiltering: true,
enableRowSelection: true,
enableFullRowSelection :true,
enableSelectAll: true,
selectionRowHeaderWidth: 35,
rowHeight: 75,
showGridFooter:true,
treeRowHeaderAlwaysVisible: true,
columnDefs: [
{ name: 'Trigraph',field:'ZeigeTrigraphen',width:'10%'},
{ name: 'Titel', field: 'Titel', cellTemplate: '<td style="word-wrap:break-word;padding:5px;">{{ COL_FIELD }}</td>' },
{ name: 'Ziel', field: 'Ziel', cellTemplate: '<td style="word-wrap:break-word;padding:5px;">{{ COL_FIELD }}</td>' },
],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
i18NService.setCurrentLang('de');
$http.get('/api/Alarmkalender/HoleAlle').then(function (resp) {
$scope.gridOptions.data = resp.data;
$log.info(resp);
});
html
<div class="container" ng-app="app">
#*<link rel="styleSheet" href="../../Scripts/ui-grid/ui-grid.min.css" />*#
<style>
.grid {
width: auto;
height: 350px;
}
</style>
<h2>Alarmmassnahmen</h2>
<div ng-controller="MainCtrl">
<div id="grid1" ui-grid="gridOptions" ui-grid-grouping class="grid"></div>
<button name="SpeichernButton" class="btn btn-success" id="btnSpeichern" type="submit" value="SpeichernButton"><i class="glyphicon glyphicon-save"></i> In Alarmkalender kopieren</button>
<div id="grid2" ui-grid="gridOptions2" class="grid"></div>
</div>

There are several ways to achieve your goal. I made a Plunker to demonstrate a possible solution.
You could create an ng-click on the row-template and gather all row selections. You either instantly load them into the new grid (as shown in Plunker) or load them all on external button-click.
There are basically three steps
First modify the row-Template
$templateCache.put('ui-grid/uiGridViewport',
...
"<div ng-repeat=\"(rowRenderIndex, row) in rowContainer.renderedRows track by $index\"" +
"ng-click=\"grid.appScope.addRowtoSelection(row)\"" +
...
);
Then you bind that addRowtoSelection() to your first grid and push selected rows into an array.
all.relectedRows = [];
all.gridOptions = {
...
appScopeProvider : {
addRowtoSelection : function(row) {
all.relectedRows.push(row.entity);
},
},
};
Finally you bind that array as new data to your second grid.
all.gridOptionsTwo = {
data: 'all.relectedRows',
...
};
e: If you want to use a button instead of instant addition of rows, you could use selectedRows as temporary array and reference selectedRowsData in your second grid. See updated Plunker.
HTML
<button ng-click="all.addRowsToSecondGrid();">Add Rows</button>
JavaScript
all.relectedRowsData = [];
all.addRowsToSecondGrid = addRowsToSecondGrid;
function addRowsToSecondGrid() {
all.relectedRowsData = [];
all.relectedRowsData = all.relectedRowsData.concat(all.relectedRows);
}
all.gridOptionsTwo = {
data: 'all.relectedRowsData',
...
Hopefully that helps.

Related

How can I mouse select one column in Angular UI Gird?

For example, in below very simple Angular UI Gird sample, you can NOT select a specific column. When click mouse and drag, it will select both rows and columns, is there a way to only select a column?
http://embed.plnkr.co/BjLqXGiUI8nQFwvijduh
Also, no matter what you select, if you copy and paste into excel, the data is always in one column with no proper format. Does anyone know how to fix this? Thanks!!!
JS:
var app = angular.module('app', ['ui.grid', 'ui.grid.cellNav']);
app.controller('MainCtrl', [
'$scope',
'$http',
'$log',
'$timeout',
'uiGridConstants',
function($scope, $http, $log, $timeout, uiGridConstants) {
$scope.gridOptions = {
modifierKeysToMultiSelectCells: true,
enableRowSelection: false,
enableSelectAll: true,
// selectionRowHeaderWidth: 35,
rowHeight: 35,
showGridFooter: true,
};
$scope.gridOptions.columnDefs = [
{ name: 'name' },
{ name: 'amount', displayName: 'Amount', allowCellFocus: false },
];
$scope.gridOptions.multiSelect = true;
$http.get('data.json').success(function(data) {
$scope.gridOptions.data = data;
});
$scope.info = {};
$scope.captureCopy = function(e) {
console.log('captured keyboard event.');
if ((e.keyCode === 99 || e.keyCode === 67) && e.ctrlKey) {
console.log('copying...');
}
};
$scope.gridOptions.onRegisterApi = function(gridApi) {
//set gridApi on scope
$scope.gridApi = gridApi;
};
},
]);
app
.controller('SecondCtrl', [
'$scope',
'$http',
'$interval',
'uiGridConstants',
function($scope, $http, $interval, uiGridConstants) {
$scope.gridOptions = {
enableRowSelection: true,
enableRowHeaderSelection: false,
};
$scope.gridOptions.columnDefs = [
{ name: 'id' },
{ name: 'name' },
{
name: 'age',
displayName: 'Age (not focusable)',
allowCellFocus: false,
},
{ name: 'address.city' },
];
$scope.gridOptions.multiSelect = false;
$scope.gridOptions.modifierKeysToMultiSelect = false;
$scope.gridOptions.noUnselect = true;
$scope.gridOptions.onRegisterApi = function(gridApi) {
$scope.gridApi = gridApi;
};
$scope.toggleRowSelection = function() {
$scope.gridApi.selection.clearSelectedRows();
$scope.gridOptions.enableRowSelection = !$scope.gridOptions
.enableRowSelection;
$scope.gridApi.core.notifyDataChange(
uiGridConstants.dataChange.OPTIONS
);
};
$http.get('data.json').success(function(data) {
$scope.gridOptions.data = data;
// $interval whilst we wait for the grid to digest the data we just gave it
$interval(
function() {
$scope.gridApi.selection.selectRow($scope.gridOptions.data[0]);
},
0,
1
);
});
},
])
.directive('uiGridCellSelection', function($compile) {
/*
Proof of concept, in reality we need on/off events etc.
*/
return {
require: 'uiGrid',
link: function(scope, element, attrs, uiGridCtrl) {
// Taken from cellNav
//add an element with no dimensions that can be used to set focus and capture keystrokes
var gridApi = uiGridCtrl.grid.api;
var focuser = $compile(
'<div class="ui-grid-focuser" tabindex="-1"></div>'
)(scope);
element.append(focuser);
uiGridCtrl.focus = function() {
focuser[0].focus();
};
gridApi.cellNav.on.viewPortKeyDown(scope, function(e) {
if ((e.keyCode === 99 || e.keyCode === 67) && e.ctrlKey) {
var cells = gridApi.cellNav.getCurrentSelection();
var copyString = '',
rowId = cells[0].row.uid;
angular.forEach(cells, function(cell) {
if (cell.row.uid !== rowId) {
copyString += '\n';
rowId = cell.row.uid;
}
copyString += gridApi.grid
.getCellValue(cell.row, cell.col)
.toString();
copyString += ', ';
});
// Yes, this should be build into a directive, but this is a quick and dirty example.
var textArea = document.getElementById('grid-clipboard');
textArea.value = copyString;
textArea = document.getElementById('grid-clipboard').select();
}
});
focuser.on('keyup', function(e) {});
},
};
})
.directive('uiGridClipboard', function() {
return {
template:
'<textarea id="grid-clipboard" ng-model="uiGridClipBoardContents"></textarea>',
replace: true,
link: function(scope, element, attrs) {
// Obviously this needs to be hidden better (probably a z-index, and positioned behind something opaque)
element.css('height', '1px');
element.css('width', '1px');
element.css('resize', 'none');
},
};
});
HTML:
<!doctype html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.js"></script>
<script src="//cdn.rawgit.com/angular-ui/bower-ui-grid/v3.0.6/ui-grid.min.js"></script>
<link rel="stylesheet" href="//cdn.rawgit.com/angular-ui/bower-ui-grid/v3.0.6/ui-grid.min.css" type="text/css" />
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl" >
<p>Select using ctrl-click. To select many: press ctrl+click in the cell you want to mark and paste it into MS excel. Note that you must select the cells int the right order, since the cellNav api returns them in the selection order, not the order they appear in the grid.</p>
<br/>
<div ui-grid="gridOptions" ui-grid-cell-selection ui-grid-cellNav class="grid"></div>
<div ui-grid-clipboard ng-keydown="captureCopy($event)"></div>
</div>
<script src="app.js"></script>
</body>
</html>
Can copy cells and be pasted into excel. You should be able to work out what you need from this. Otherwise I can take a quick look at it tomorrow again. Hope it helps!

How do i update the title option in an angular-nv3d piechart

I am using nvd3 piechart to show the size of the overall files in a folder.
my question is how to update the title of the chart after each data update is happening (for example to show the overall size in the title.
i tried using an object in the scope which does update with the currect size, but it does not update in the title option in the chart)
here is my code:
app.controller("chartCtrl", function($scope, foldersSrvc){
$scope.options = {
chart: {
type: "pieChart",
height: 400,
showLabels: true,
labelType: "value",
title: "Content(" + $scope.filesSize + ")",
labelSunbeamLayout: true,
x: function(d){return d.type;},
y: function(d){return d.size;},
donut: true
}
};
foldersSrvc.getFiles("server").then(function(data){
$scope.data = data;
$scope.filesSize = foldersSrvc.getFilesSize(data);
});
$scope.$on('folderClicked', function(event, args){
foldersSrvc.getFiles(args.id).then(function(data){
$scope.data = data;
$scope.filesSize = foldersSrvc.getFilesSize(data);
});
})
})
I recommend the angular wrapper for nvd3, angular-nvd3 to support data binding.
angular.module('myApp', ['nvd3'])
.controller('myCtrl', function($scope){
/* Chart options */
$scope.options = { /* JSON data */ };
/* Chart data */
$scope.data = { /* JSON data */ }
})
html
<div ng-app="myApp">
<div ng-controller="myCtrl">
<nvd3 options="options" data="data"></nvd3>
</div>
</div>

Displaying data in ng-grid by clicking on an <a> element in the sidebar

I have a view in an angularjs application with a sidebar, where I can choose my insurers. By clicking on an insurer, I want my ng-grid show me some insurer's data. Now I can select the insurer, and see the <div class="well well-sm"> changes.
Here is my angular controller:
app.controller('ReportsInsurerPaymentsCtrl', ['$scope', '$http', '$filter', 'toaster', '$state', '$modal', function ($scope, $http, $filter, toaster, $state, $modal) {
$scope.insurer_payments = [];
$scope.insurer_payments = [];
$scope.insurer_payment = {};
$scope.gridOptions = {
data: "insurer_payment",
rowTemplate: '<div ng-style="{\'cursor\': row.cursor, \'z-index\': col.zIndex() }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell {{col.cellClass}} " ng-cell></div>',
columnDefs: [
{
field: "date",
displayName: "Date",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>',
width: 100
},
{
field: "amount",
displayName: "Amount",
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>'
},
{
field: 'comment',
displayName: 'Comment',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field)}}</span></div>',
}
],
$scope.refresh = function () {
var p = {
name: $scope.filterOptions.filterText,
pageNumber: (allPages >= $scope.pagingOptions.currentPage) ? $scope.pagingOptions.currentPage : $scope.pagingOptions.currentPage = 1,
pageSize: $scope.pagingOptions.pageSize,
sortInfo: sb.join("")
};
$http({
url: "reports/insurer_payments.json",
method: "GET",
params: p
}).success(function (data, insurer_payment) {
$scope.totalServerItems = data.insurerPaymentsCount;
$scope.insurer_payments_count = data.total_insurer_payments_count;
$scope.insurer_payments = data.insurer_payments;
$scope.insurer_payment = data.insurer_payment;
if (insurer_payment) {
$scope.insurer_payment = $filter('orderBy')($scope.insurer_payments, 'name')[0];
} else {
$scope.insurer_payment = $filter('filter')($scope.insurer_payments, {name: insurer_payment.name})[0];
}
if ($scope.insurer_payments) $scope.insurer_payment.selected = true;
$scope.showContent = true;
if ($scope.gridOptions.ngGrid) {
$scope.gridOptions.ngGrid.buildColumns();
}
}).error(function () {
});
}, 100);
};
$scope.selectInsurerPayment = function(item){
angular.forEach($scope.insurer_payments, function(item) {
item.selected = false;
});
$scope.insurer_payment = item;
$scope.insurer_payment.selected = true;
};
$scope.refresh();
}]);
A part of a view:
<a ng-repeat="insurer_payment in insurer_payments | orderBy:'name'"
class="list-group-item m-l"
ng-class="{'select m-l-none': insurer_payment.selected }"
ng-click="selectInsurerPayment(insurer_payment)">
<span class="block text-ellipsis m-l-n text-md" ng-class="{'m-l-none': insurer_payment.selected }">
{{ insurer_payment.name }}
</span>
</a>
<div class="well well-sm">
<div class="row">
<div class="col-sm-4">
<strong>Commission: {{insurer_payment.commission}}</strong>
</div>
<div class="col-sm-4">
<strong>Insurer Ppayment: {{insurer_payment.insurer_payment}}</strong>
</div>
<div class="col-sm-4">
<strong>Inequality: {{insurer_payment.commission - insurer_payment.insurer_payment}}</strong>
</div>
</div>
</div>
<div class="table-responsive">
<div ng-grid="gridOptions" class="gridStyle">
</div>
</div>
And a part of a rails controller:
def index
insurer_payments = current_company.insurers.map do |insurer|
{
commission: insurer.contracts.pluck(:commission).sum.to_f,
name: insurer.name,
insurer_payment: insurer.insurer_payments.pluck(:amount).sum.to_f,
id: insurer.id
}
end
insurer_payment = current_company.insurers.map do |insurer|
{
amount: insurer.insurer_payments.pluck(:amount).map { |x| x.to_f },
comment: insurer.insurer_payments.pluck(:comment),
date: insurer.insurer_payments.pluck(:date),
id: insurer.id
}
end
total_insurer_payments_count = current_company.insurers.map do |insurer|
insurer.insurer_payments.count
end
insurer_payments_count = current_company.insurer_payments.count
respond_to do |format|
format.json { render json: { insurer_payments: insurer_payments, insurer_payment: insurer_payment,
total_insurer_payments_count: total_insurer_payments_count,
insurerPaymentsCount: insurer_payments_count } }
end
end
So, how it can be done, by selecting an insurer to see the corresponding data?
I am not sure on this, since I don't have all of your code, but you may want to try some of the changes I have below.
Because ng-repeat has it's own scope, iterating through insurer_payment in insurer_payments is conflicting with insurer_payment on scope. When you loop through the insurer_payments, you are modifying the value of insurer_payment each time.
I would change
$scope.gridOptions = {
data: "insurer_payment",
to
$scope.gridOptions = {
data: [];
Since the data is an array, not a string.
Within the success callback of $http, you need to set gridOptions.data (unless this is elsewhere, I don't see where the grid is)
.success(function (data, insurer_payment) {
$scope.gridOptions.data = data;
...
}
And the selectInsurerPayment function:
$scope.selectInsurerPayment = function(item){
angular.forEach($scope.insurer_payments, function(item) {
item.selected = false;
});
$scope.selectedInsurerPayment = item;
$scope.insurer_payment.selected = true;
};
And finally, in the well in your HTML, change references to insurer_payment to selectedInsurerPayment, ex:
<strong>Commission: {{selectedInsurerPayment.commission}}</strong>
Old Solution
In ng-repeat:
ng-click="selectInsurerPayment(insurer_payment)"
to
ng-click="selection.insurer_payment = insurer_payment"
In the well,
<div class="well well-sm">
to
<div class="well well-sm" ng-if="selection.insurer_payment">
and change the references to insurer_payment to selection.insurer_payment.{variable}, example:
<strong>Commission: {{selection.insurer_payment.commission}}</strong>

ng-click inside cell template does not trigger function in controller

I have created a plunker here: http://plnkr.co/edit/zGqouwzxguef13lx48iP?p=preview
When I click in a cell of the ui-grid in the day view then nothing happens. What I expected is that the test function is executed and an alert is shown with text 'test' but that is not the case.
What is going on wrong here?
Thats the html cell template of the ui-grid 3.0 latest release:
HTML
<div ng-click="test()" ng-switch="row.entity[row.grid.columns.indexOf(col)].isPeriod">
<div ng-switch-when="true">
<tabset>
<tab>
<tab-heading>
<i class="glyphicon glyphicon-book"></i>
</tab-heading>period id:
{{ row.entity[row.grid.columns.indexOf(col)].id}}
</tab>
<tab select="alertMe()">
<tab-heading>
<i class="glyphicon glyphicon-bell"></i>
</tab-heading>
{{row.entity[row.grid.columns.indexOf(col)].content}}
</tab>
</tabset> <!-- PeriodTemplate -->
</div>
<div ng-switch-when="false">
<div>Hello empty template</div>
</div> <!-- EmptyPeriodTemplate -->
</div>
CONTROLLER:
'use strict';
angular.module('projectplanner').controller('DateplannerDayController', function ($scope, $state) {
var columnHeaderDates = ['col1','col2','col3','col4','col5','col6','col7']
$scope.columns = createColumnHeaders(columnHeaderDates);
var data = [{isPeriod: true, id: 10, rowNumber: 1},{isPeriod: false, id: 11, rowNumber: 2}]
$scope.test = function()
{
alert('test');
};
$scope.gridOptions = {
rowHeight: 200,
data: data,
enableSorting: false,
enableColumnMenu: false,
columnDefs: $scope.columns,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
$scope.gridApi.core.addRowHeaderColumn(
{ name: 'rowHeaderCol',
displayName: '',
width: 100,
cellTemplate: '<div>row header template</div>'
});
}
};
function createColumnHeaders(columnHeaders) {
var columnDefinitions = [];
for (var i = 0; i < columnHeaders.length; i++) {
var column = {
name: columnHeaders[i],
cellTemplate: 'lessonplanner.day.celltemplate.html',
field: i + 'x'
}
columnDefinitions.push(column);
}
return columnDefinitions;
}
});
This page kept popping up in my searches and I managed to miss the solution in the comments. To summarize, you likely need to use externalScopes. See Angular ui-grid events in cell header not firing and http://ui-grid.info/docs/#/tutorial/305_appScope
If you are using Controller-As syntax then try:
ng-click= "grid.appScope.<controllerAliasName>.myFunction(row)"
It is because the ui-grid has its own controller and it doesn't know about the outside controller.
To facilitate, do the following..
1. First assign the controller to the ui-grid.
var vm = this;
this.$scope.usersGridOptions = {
appScopeProvider: vm,
....
}
Now, once you assign the controller to the grid, you can invoke the function like this..
"<a type=\"button\" href=\"\" ng-click=\"function(row.entity)\"> {{ row.entity.text}} </a>"
In ui-grid, cell-template, because of cell has its own scope,
1) do not use onclick='', instead should use ng-click=''
2) ng-click='your_function()' will not work, should use, grid.appScope.your_function()
3) when pass parameter in function(), do not use function({{xxx}}), see sample below
cellTemplate: '<div class="ui-grid-cell-contents" title="TOOLTIP">{{grid.appScope.editLink_tree_id(grid, row)}}</div>'

How to make checkbox cell edit template in ng-grid?

I am new to ng-grid. I am learning ng-grid with edit template options. i have created grid with edit checkbox options.But i don't know How to get value in that grid after edit the checkbox? Thank you.
Here JSfiddle.
var myapp = angular.module('myapp', ["ui", "ngGrid"]);
myapp.controller('myctrl', function($scope, $http) {
$scope.testInfo= "TestInfo";
$scope.data = {
persons: [],
selected:[],
load: function () {
$http.get("/echo/json/").success(function(data) {
$scope.data.persons = [
{id:1, name:"Max", number:51323.512,value:'on'},
{id:2, name:"Adam", number:7245.2,value:'on'},
{id:3, name:"Betty", number:828,value:'off'},
{id:4, name:"Sara", number:23452.45182,value:'on'}
];
$scope.data.selected[0] = $scope.data.persons[0];
});
}
};
var cellTemplate = "<div ng-class=\"'ngCellText colt' + $index\">"
+ " <span ng-cell-text>{{COL_FIELD}}</span>"
+ "</div>";
var cellEditTemplate = '<input type="checkbox" ng-checked="row.entity.value==\'on\'" ng-input="COL_FIELD" /></div>';
$scope.grid = {
options: {
data: "data.persons",
selectedItems: $scope.data.selected,
multiSelect: false,
columnDefs: [
{field:"id", displayName:"ID"},
{field:"name", displayName:"Name"},
{field:"number", displayName:"Nummer", cellFilter:"number:2"},
{field: "value",displayName:"Value",enableCellEdit : true,cellTemplate : cellTemplate,
editableCellTemplate : cellEditTemplate}
]
}
};
});
<div ng-app="myapp">
<div ng-controller="myctrl">
<a class="btn" ng-click="data.load()">Get data!</a>
<div ng-grid="grid.options" class="grid"></div>
<ul ng-repeat="item in data.selected">
<li>{{item}}</li>
</ul>
</div>
</div>
You've probably already figured this out by now, but one possible options is to use ng-grids build in checkbox selector. It's not shown in the examples on their main page, but listed as an option in the API.
showSelectionCheckbox: true

Resources