[Update] This Plunker does what I want, but :
it uses ui-grid, rather than ag-grid.
it injects the grid into the module, rather than just the single controller which uses it.
I presume that these changes would be straightforward & will try to work them into my code when I get home in about 14 hours time.
If anyone wants to fork that Plunk and make those changes, I will award a bounty, as this is a good basic start point demo for others wanting to do the same, so that a Plunker would be of general help.
I am tantalizingly close, but
Cannot read property 'setRowData' of undefined (caused by "<ui-view class="ng-scope ng-binding">")"TypeError: Cannot read property 'setRowData' of undefined
I am using "controller as" syntax, hence the Self; (Self = this;). That is working fine, my problem is when I try to set the rowData for an ag-grid in the templateURL of a ui-router state.
It's much to big to post, but here's the relevant stuff:
<div id="currentCandidatesGridDiv"
ag-grid="Search_result_controller.currentCandidatesGrid"
class="ag-theme-balham red_border"
style="height: 30%; width:90%">
</div>
// lookup the container we want the Grid to use
const currentCandidatesGridDiv = document.querySelector('#currentCandidatesGridDiv');
// create the grid passing in the div to use together with the columns & data we want to use
new agGrid.Grid(currentCandidatesGridDiv, Self.currentCandidatesGrid);
Self.currentCandidatesGrid =
{
columnDefs: [
{ headerName: "Candidate", field: "candidate_name", sortable: true },
{ headerName: "Skills", field: "skills", sortable: true },
{ headerName: "Start date", field: "start_date", sortable: true }
],
rowData: [],
pagination: true,
paginationAutoPageSize: true,
};
Was I correct to rowData: [], or ought I to have rowData: <someVariable>?
Then I calculate the row data into an array, Self.currentCandidatesGridRowData.
When I try to Self.currentCandidatesGrid.api.setRowData(Self.currentCandidatesGridRowData); I get error showing above.
I searched, but cannot find a working Plunker using the controller as syntax.
[Dupers] 1) the "dupe" question does not have an answer, so is of no use to me
2) my question is specifically about using Self.xxxGrid.api.setRowData(Self.xxxGridRowData); with the `controller as syntax. Pleas ere-open. Thnaks
DEMO of ag-Grid with AngularJS using "controller As" syntax
When the ag-Grid script loads, it does not register with AngularJS 1.x. This is because AngularJS 1.x is an optional part of ag-Grid and you need to tell ag-Grid you want to use it:
agGrid.initialiseAgGridWithAngular1(angular);
angular.module("example", ["agGrid"])
For more information, see
Ag-Grid Documentation - Basic AngularJS 1.x Example
The DEMO on PLNKR
agGrid.initialiseAgGridWithAngular1(angular);
angular.module("example", ["agGrid"])
.controller("exampleCtrl", function() {
var columnDefs = [
{headerName: "Make", field: "make"},
{headerName: "Model", field: "model"},
{headerName: "Price", field: "price"}
];
var rowData = [
{make: "Toyota", model: "Celica", price: 35000},
{make: "Ford", model: "Mondeo", price: 32000},
{make: "Porsche", model: "Boxter", price: 72000}
];
this.gridOptions = {
columnDefs: columnDefs,
rowData: rowData
};
})
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
<script src="//unpkg.com/angular/angular.js"></script>
<script src='//unpkg.com/#ag-grid-community/all-modules/dist/ag-grid-community.min.js'>
</script>
<body ng-app="example" ng-controller="exampleCtrl as $ctrl"
style="height: 100%">
<div ag-grid="$ctrl.gridOptions" class="ag-theme-balham"
style="height: 100%;">
</div>
</body>
Was I correct to rowData: [], or ought I to have rowData: <someVariable>?
You can even ignore this property in gridOptions, but the difference is that:
if you will define rowData as an empty array - grid will render handle it as 'No rows to show', but if you will not define it, grid will show 'Loading...' - which is more correct, with a delayed request case.
Besides, you can handle overlay logic by yourself for more details check here.
Now, as I said in comments
Cannot read property 'setRowData' of undefined
this issue could be caused by using the wrong reference.
First, take a look and check this answer with ag-grid developer comment also.
Secondly, about an issue itself:
.controller('yourController', [function() {
var Self = this; // here's your controller reference
// then you will have columns and rowData (probably)
// but the most important part is here
Self.currentCandidatesGrid = {
... // anything that you need
onGridReady: gridReady // major point for future api reference
}
function gridReady(params){
Self.gridApi = params.api;
Self.columnsApi = params.columnsApi;
}
}]);
And after gridReady you would be able to use grid API methods via Self.gridApi
Demo
Related
I had a working app, including a few ag-grids. I decided to add ui-router, with the grids in the templateUrl of a state.
The code is mcuh to large to post, but I have two problems:
document.addEventListener("DOMContentLoaded" is not called when I put it in the controller of the templateUrl
I guess that I can get round that by moving the enclosed logic into $transitions.onSuccess({ entering: 'search_result' }, function (transition), BUT, when I
const currentCandidatesGridDiv = document.querySelector('#currentCandidatesGrid');
new agGrid.Grid(currentCandidatesGridDiv, Self.currentCandidatesGrid);
I find that currentCandidatesGridDiv is null, despite having
<div ag-grid="SearchResultController.currentCandidatesGrid"></div>
in the HTML of the templateUrl.
Again, not much help to you without full code, which is very, very large.
I guess that what I am looking for is a working code sample, Plunk, etc to show how to put a simple ag-grid into a ui-router state's templateUrl.
It looks like your actual problem is that you are using a querySelector on the id
#currentCandidatesGrid
# is a selector for an element id
This would only match your element if it had that specified id, which in your example does not exist.
<div ag-grid="SearchResultController.currentCandidatesGrid"></div>
Would need to be
<div id="currentCandidatesGrid" ag-grid="SearchResultController.currentCandidatesGrid"></div>
if you want to get that element via
document.querySelector('#currentCandidatesGrid');
This answer has three parts:
Why DOMContentLoaded event listeners fail in controllers
Use custom directives to inject code that manipulates DOM
DEMO of ag-Grid with AngularJS
Why DOMContentLoaded event listeners fail in controllers
JavaScript libraries that manipulate the DOM need to coordinate with DOM manipulations done by the AngularJS framework.
AngularJS modifies the normal JavaScript flow by providing its own event processing loop. This splits the JavaScript into classical and AngularJS execution context. Only operations which are applied in the AngularJS execution context will benefit from AngularJS data-binding, exception handling, property watching, etc.
document.addEventListener("DOMContentLoaded" is not called when I put it in the controller of the templateUrl
The AngularJS framework initializes itself after the DOMContentLoaded event. So naturally any DOMContentLoaded event listener added afterwards by a controller will miss that event.
One should use caution when mixing AngularJS with third-party libraries that manipulate the DOM.
Use custom directives to inject code that manipulates DOM
When one sees code such as document.querySelector("#myid'), replace that with a custom directive:
app.directive("myDirective", function() {
return {
link: postLink
};
function postLink(scope, elem, attrs) {
//DOM initialization here
//e.g. initialize(elem);
scope.$on('$destroy', function() {
//DOM teardown code here
});
}
})
Usage:
<div id="myid" my-directive></div>
AngularJS directives are markers on a DOM element that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element.
When the AngularJS framework adds templates to the DOM, it parses the markup and injects code for the AngularJS directives. When it destroys DOM, it broadcasts a $destroy event on the scope associated with the element.
For more information, see
AngularJS Developer Guide - Creating Custom Directives
DEMO of ag-Grid with AngularJS
When the ag-Grid script loads, it does not register with AngularJS 1.x. This is because AngularJS 1.x is an optional part of ag-Grid and you need to tell ag-Grid you want to use it:
agGrid.initialiseAgGridWithAngular1(angular);
angular.module("example", ["agGrid"])
For more information, see
Ag-Grid Documentation - Basic AngularJS 1.x Example
The DEMO
agGrid.initialiseAgGridWithAngular1(angular);
angular.module("example", ["agGrid"])
.controller("exampleCtrl", function($scope) {
var columnDefs = [
{headerName: "Make", field: "make"},
{headerName: "Model", field: "model"},
{headerName: "Price", field: "price"}
];
var rowData = [
{make: "Toyota", model: "Celica", price: 35000},
{make: "Ford", model: "Mondeo", price: 32000},
{make: "Porsche", model: "Boxter", price: 72000}
];
$scope.gridOptions = {
columnDefs: columnDefs,
rowData: rowData
};
})
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
<script src="//unpkg.com/angular/angular.js"></script>
<script src='//unpkg.com/#ag-grid-community/all-modules/dist/ag-grid-community.min.js'>
</script>
<body ng-app="example" ng-controller="exampleCtrl" style="height: 100%">
<div ag-grid="gridOptions" class="ag-theme-balham" style="height: 100%;">
</div>
</body>
I'm using Angular ui calendar in my app.
Everything is working fine. The calendar is showing, but events are not appearing in the calendar.
Here is my code: -
$timeout(function() {
$scope.events = [
{
title: 'Long Event',
start: '2019-01-10'
}
];
$scope.eventSources = [$scope.events];
return $scope.uiConfig = {
calendar: {
height: 450,
editable: true,
header: {
left: 'title',
center: '',
right: 'today prev,next'
}
}
};
},5000);
Here I'm using timeout because I want some delay for calendar to be loaded.
This is my HTML code: -
<div ui-calendar="uiConfig.calendar" class="span8 calendar" ng-model="events" calendar="myCalendar" style="height:700px;"></div>
The docs suggest you should give an array named eventSources. I have given it, but nothing works.
Please suggest what I'm doing wrong.
Here is the screenshot: -
You are initializing scope variables after sometime 5 seconds, your calendar is getting the undefined variables and hence if you check your console there are errors., what you need to do is to load the calendar only when this variables comes defined.
So, you need
ng-if="uiConfig!==undefined"
if this variables defined then only your calendar will comes into picture.
Your div should look like this
<div class="span8" ng-if="uiConfig!==undefined">
<div class="calendar" ng-model="eventSources" calendar="myCalendar1" ui-calendar="uiConfig.calendar"></div>
</div>
this will make sure to initialize when this variables has some values.
Demo
I hope this will help others too as there isn't a lot of documentation about this exactly.
I want to use a RTE (rich text editor) within a macro I've created to handle page sections.
I have successfully rendered the RTE within the macro. I can select my macroRte from the macro parameters panel. It even renders where I edit the values of my page section. I have attributed the alias of "macroRte" to the parameter.
However, it is not storing the values. Each time I press submit it is wiping the content.
I'm no Angular expert but i think that's the problem. Code below. Thank you.
View
<div ng-controller="CustomSectionEditController" class="umb-editor umb-rte">
<umb-editor model="macroRte">
<div ng-model="model.value">{{model.value}}</div>
</umb-editor>
Controller
angular.module("umbraco").controller("CustomSectionEditController", function ($scope) {
$scope.macroRte = {
label: 'bodyText',
description: 'Load some stuff here',
view: 'rte',
config: {
editor: {
toolbar: ["code", "undo", "redo", "cut", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "table", "umbembeddialog"],
stylesheets: ["rte"],
dimensions: { height: 400 },
valueType:"STRING"
}
}
};
});
Render
#inherits Umbraco.Web.Macros.PartialViewMacroPage
<div class="lh-text">
#Model.MacroParameters["macroRte"];
</div>
Any ideas? :)
using this, https://github.com/engern/Umbraco-custom-macro-parameters/tree/master/App_Plugins/MacroRichText - I was able to solve my problem.
The view needs to be changed to the following
<div ng-controller="CustomSectionEditController">
<ng-form>
<umb-editor model="macroRte"></umb-editor>
</ng-form>
</div>
The controller needed the following code (add under view
value: $scope.model.value,
and an additional scope control
$scope.$watch("macroRte.value", function (newValue, oldValue) {
$scope.model.value = newValue;
});
The controller now looks like this
angular.module("umbraco").controller("CustomSectionEditController", function ($scope) {
$scope.macroRte = {
label: 'bodyText',
description: 'Load some stuff here',
view: 'rte',
value: $scope.model.value,
config: {
editor: {
toolbar: ["code", "undo", "redo", "cut", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "table", "umbembeddialog"],
stylesheets: ["rte"],
dimensions: { height: 400 },
valueType:"STRING"
}
}
},
$scope.$watch("macroRte.value", function (newValue, oldValue) {
$scope.model.value = newValue;
});
});
I hope this help others.
I'm using UIGrid.
How can I get the row-column object of a selected cell's DOM element in the grid?
$(".ui-grid-cell-focus") this gives you the HTML DOM of the currently focused/selected cell. I'm trying to get the uiGrid row-col object using this HTML DOM value. I dont know how to!
Please try as shown below.
js
var editCellTemplate = '<div class="ngCellText"><button class="btn btn-icon-only
green height-28" ng-click="grid.appScope.editProperty(row.entity.id)"><i
class="fa fa-edit"></i></button></div>';
vm.yourGridOptions = {
appScopeProvider: vm,
flatEntityAccess: false,
fastWatch: true,
showHeader: false,
columnDefs: [
{
name: 'id',
field: 'id',
width: 240,
},
{
name: 'Edit',
cellTemplate: editCellTemplate,
width: 40,
}
],
data: []
};
//edit property
vm.editProperty = function (id) {
// your logic here
};
You could try in your gridOptions declaration:
onRegisterApi: function(gridApi){
gridApi.cellNav.on.navigate($scope,function(newRowcol, oldRowCol){
console.log(newRowcol);
});
}
Just be sure to inject ui.grid.cellNav into your angular module and ui-grid-cellNav in your grid directive view. newRowcol is your row-col object
I am using ag-grid . But I am not able to paint the data from json using $scope.gridOptions.api.setRowData method.. Only headers are displayed.Data is not painted in UI.
Find the code below
myApp.controller("getProfitabilityDetailsController", function($scope, $http) {
var columnDefs = [
{headerName: 'quantity',field: 'quantity', width: 150},
{headerName: 'finyear',field: 'finyear', width: 150}
];
$scope.gridOptions = {
columnDefs: columnDefs
};
$http.get("partials/profitability/mock/profitability_details.json")
.then(function(result){
$scope.gridOptions.api.setRowData(result.data.response);
});
});
A classic error to check when using ag-grid :
Does the div containing the ag-grid directive has a raw height specified (raw = in px) or any parent dom element. If not add a style="height:500px" for instance.
Otherwise i need to see the html you're using and the format of your json file.
try this instead:
$http.get("partials/profitability/mock/profitability_details.json")
.then(function(result){
$scope.gridOptions.api.setRowData(result.data);
});
Looks like you had an extra property name on return