Angular ag-grid how to add a column before autogroupcolumn - ag-grid-angular

I am new to angular aggrid. the grid displays records with autogroupcolumndef set. Now i want to add a column with context menu before the grouping column. Can anyone help how to do this?
<ag-grid-angular
#agGrid
style="height:calc(100vh - 12rem)"
class="ag-theme-balham ag-grid indent"
[rowData]="data$ | async"
[treeData]="true"
[animateRows]="true"
[gridOptions]="gridOptions"
(gridReady)="onGridReady($event)"
[autoGroupColumnDef]="autoGroupColumnDef">
</ag-grid-angular>
readonly autoGroupColumnDef = {
headerName: 'Name',
minWidth: 350,
cellClass: 'indented',
cellRendererParams: {
suppressCount: true,
innerRenderer: 'UserImageInTreeComponent',
isManager: false,
showNameAsHyperlink: true
}
};
Thanks

Here's a workaround:
gridOptions.columnApi.moveColumn('yourColumn', 0);
change yourColumn with your column name and 0 with the index.

Related

Apply the styles to selected values in the multi-select dropdown in Angular

I am new to angular. As part of my baby steps , I have a ng-select(multiple)component.
this is my component.html
<label>Multiselect with custom bindings</label>
<ng-select [multiple]=true>
<ng-option *ngFor= "let city of cities" [value]="city.id"> {{city.name}}</ng-option>
</ng-select>
component.ts
cities = [
{ id: 1, name: 'Vilnius' },
{ id: 2, name: 'Kaunas' },
{ id: 3, name: 'Pavilnys' },
{ id: 4, name: 'Pabradė' },
{ id: 5, name: 'Klaipėda' },
];
I have custom component called tags which styles the selected values.
<tags [(ng-model)]="values" </tags>
My query is I need to pass these selected values to this component and display the styled selected values in the same place . Please help!. Thanks in advance.
Passing the selected values to the component:
component.ts:
selectedValues = [];
component.html:
add the following to your ng-select:
[(ngModel)]="selectedValues"
It will automatically update this array.
Then you can display the array data again where you need them.
Not sure if this answers your question. What do you mean by 'display the styled selected values in the same place'?

ngx-datatable detail row not expanding

I am attempting to create a ngx-datatable that I can reuse everywhere to keep styling and how editing, etc work.
Most everything works but I cannot figure out why I cannot get the details row to expand properly.
Here is the common table component html/template:
common-table.component.html
<div>
<h3>Results</h3>
<ngx-datatable
#myTable
class="material expandable"
[rows]="data"
[columns]="columns"
[columnMode]="'force'"
[headerHeight]="50"
[footerHeight]="50"
[rowHeight]="'auto'"
[externalPaging]="hasServerPaging"
[count]="tablePaging.count"
[offset]="tablePaging.offset"
[limit]="tablePaging.limit"
(page)='setPage($event)'>
<ngx-datatable-row-detail *ngIf="hasDetails" [rowHeight]="rowDetailHeight" #myDetailRow [template]="rowDetails" (toggle)="onDetailToggle($event)">
</ngx-datatable-row-detail>
</ngx-datatable>
</div>
The parent component contains the definitions for the columns and templateRefs to pass around:
search-results.component.html
<ng-template #rowDropDownTemplate let-row="row" ngx-datatable-cell-template>
<a [class.datatable-icon-right]="!row.$$expanded" [class.datatable-icon-down]="!row.$$expanded" title="Expand/Collapse Details"
(click)="toggleExpandRow(row)">
</a>
</ng-template>
<ng-template #rowDetailsTemplate let-row="row" ngx-datatable-row-detail-template>
<div class="uk-grid">
<div class="uk-width-1-2">
left-side data
</div>
<div class="uk-width-1-2">
right-side data
</div>
</div>
</ng-template>
<app-common-table
*ngIf="results && results.length > 0"
[tablePaging]="tablePaging"
[columns]="columns"
[data]="tableData"
[rowDetails]="rowDetailsTemplate"
[rowDetailHeight]="200"
[hasServerPaging]="true"
(onPaging)="onPaging($event)"
></app-common-table>
Just for possible issues in the code, here is how the columns are being set:
search-results.component.ts
private setColumns(): void {
this._columns = [];
let templateTest: TemplateRef<any>;
let dropDownColumn: TableColumn = {
width: 50,
resizeable: false,
sortable: false,
draggable: false,
canAutoResize: false,
cellTemplate: this.rowDropDownTemplate,
}
this._columns.push(dropDownColumn);
let nameColumn: TableColumn = {
name: "Name",
width: 120
};
this._columns.push(nameColumn);
let positionsColumn: TableColumn = {
name: "Positions",
width: 200
};
this._columns.push(positionsColumn);
let experienceColumn: TableColumn = {
name: "Experience",
width: 80
};
this._columns.push(experienceColumn);
let leveleColumn: TableColumn = {
name: "Level",
width: 80
};
this._columns.push(leveleColumn);
let educationeColumn: TableColumn = {
name: "Education",
width: 80
};
this._columns.push(educationeColumn);
}
The data appears and so does the icon to expand the details row. Events fire and show the row data, but nothing is shown.
Any help would be greatly appreciated!!
I suspect your toggleExpandRow method is wrong
I would do it like this:
app.common-table.ts
export class AppCommonTableComponent {
#ViewChild('myTable') myTable: any;
parent.component.ts
#ViewChild(AppCommonTableComponent) commonTable: AppCommonTableComponent;
toggleExpandRow(row) {
console.log('Toggled Expand Row!', row);
this.commonTable.myTable.rowDetail.toggleExpandRow(row);
}
And you should fix your rowDropDownTemplate template. It should be
[class.datatable-icon-right]="!row.$$expanded" [class.datatable-icon-down]="row.$$expanded"
If you want to get the right classes
Plunker Example
This is isssue is fixed in version 16.0.3
Refer https://github.com/swimlane/ngx-datatable/blob/master/docs/changelog.md

How to implement "close expanded tagfield when its label is clicked in ExtJS6"?

By default a tagfield cannot be closed when clicking on its field label, so if there is a form full of tag fields it's hard to find a sweet spot where you can click without expanding one of them.
I'd like to keep the triggerOnClick behavior when it expands whenever you click on the field itself. Is there a way to just make its label collapse the expanded field (something better than wrapping label-less field into a container with a label).
xtype: 'tagfield'
fieldLabel: 'Tags',
queryMode: 'local',
triggerAction: 'all',
forceSelection: true,
editable: true,
anyMatch: true,
valueField: 'id',
displayField: 'name',
triggerOnClick: true,
store: store,
https://fiddle.sencha.com/#fiddle/17or
There ist a work around with labelableRenderTpl and for. How do I insert it to my code?
xtype: 'tag',
reference: 'mytagfield',
displayField: 'name',
valueField: 'id',
store: {type: 'laws'},
disabled: true,
bind: {
fieldLabel: '{i18n.law}',
blankText: '{i18n.mandfield}'
}
HTML Code looks like this:
<label id="mytagfield-labelEl" data-ref="labelEl" class="x-form-item-label x-form-item-label-default x-unselectable" style="padding-right:5px;width:205px;" for="mytagfield-inputEl">
I want to remove:
for="mytagfield-inputEl"
[SOLUTUION]: "OnClick"-listener for the label of the tagfield:
Extjs Tagfield: How to close its list by clicking on its label in IE11?
[Old Workaround]:
I found a Solution to edit the for-Attribute. You can edit the Value with
inputId: "myTagfieldIsNotSelectWhenIpressOnTheLabel"
This is a workaround when customer press on a Label of a Extjs Tagfield and the Field should close.

How do I dynamically change ng-grid table size when parent containing div size changes?

I am changing the size of the containing div using ng-class and an expression that evaluates whether or not an edit form is displayed. If the edit form is displayed I want to change the size of the div containing the ng-grid and the ng-grid itself.
<div class=" row-fluid">
<div ng-class="{'span7' : displayEditForm == true, 'span12': displayEditForm == false}" >
<ul class="nav nav-tabs" style="margin-bottom: 5px;">
<li class="active">Activities Needing My Approval</li>
<li>My Activities Needing Approval </li>
<li>My Activities</li>
</ul>
<div class="edus-admin-manage-grid span12" style="margin-left:0;" ng-grid="gridOptions"></div>
</div>
<div class="span5" ng-show="displayEditForm">
<div class="edus-activity-container">
<div class="edus-admin-activities-grid">
<div ng-include="'/partials/' + activity.object.objectType + '.html'" class="edus-activity"></div>
<!-- <div ng-include="'/partials/admin-activity-actions.html'"></div>-->
</div>
</div>
<div ng-include="'/partials/admin-edit-activity-grid-form.html'"></div>
</div>
</div>
The div containing the navbar and grid changes size via ng-class (from span12 to span7), but the ng-grid does not refresh. How can I trigger the refresh of ng-grid given the change in the parent div?
I've included my gridOptions below:
$scope.gridOptions = {
plugins: [gridLayoutPlugin],
data : 'activities',
showFilter: true,
/* enablePaging: true,*/
showColumnMenu: true,
/* showFooter: true,*/
rowHeight: 70,
enableColumnResize: true,
multiSelect: false,
selectedItems: $scope.selectedActivities,
afterSelectionChange: function(rowItem,event){
if($scope.selectedActivities && $scope.selectedActivities.length > 0){
$scope.activity = $scope.selectedActivities[0];
$scope.activityViewState.index = $scope.activities.indexOf($scope.activity);
$scope.displayEditForm = true;
console.log("DEBUG :::::::::::::::: updated displayEditForm.", $scope.displayEditForm);
if($scope.activity.ucdEdusMeta.startDate) {
// $scope.activity.ucdEdusMeta.startDate = new Date($scope.activity.ucdEdusMeta.startDate);
$scope.edit.startDate = moment($scope.activity.ucdEdusMeta.startDate).format("MM/DD/YYYY");
$scope.edit.startTime = moment($scope.activity.ucdEdusMeta.startDate).format("hh:mm A");
}
if($scope.activity.ucdEdusMeta.endDate) {
// $scope.activity.ucdEdusMeta.endDate = new Date($scope.activity.ucdEdusMeta.endDate);
$scope.edit.endDate = moment($scope.activity.ucdEdusMeta.endDate).format("MM/DD/YYYY");
$scope.edit.endTime = moment($scope.activity.ucdEdusMeta.endDate).format("hh:mm A");
}
}
},
/* pagingOptions: { pageSizes: [5, 10, 20], pageSize: 10, totalServerItems: 0, currentPage: 1 },*/
columnDefs: [
{field: 'title', displayName: 'Title', width:'15%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'actor.displayName', displayName: 'DisplayName', width:'10%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'object.content', displayName:'Content', width:'35%',
cellTemplate: '<div class="ngCellText", style="white-space: normal;">{{row.getProperty(col.field)}}</div>'},
{field: 'ucdEdusMeta.startDate', displayName: 'Start Date', width:'20%',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) | date:"short"}} </span></div>'},
{field: 'ucdEdusMeta.endDate', displayName: 'End Date', width:'20%',
cellTemplate: '<div class="ngCellText" ng-class="col.colIndex()"><span ng-cell-text>{{row.getProperty(col.field) | date:"short"}} </span></div>'}
// {field: '', displayName: ''},
]
};
Here's the CSS used by the grid:
.edus-admin-manage-grid {
border: 1px solid rgb(212,212,212);
width: 100%;
height: 700px
}
You can use ng-grid's layout plugin (ng-grid-layout.js). It should come with ngGrid located at:
ng-grid/plugins/ng-grid-layout.js
(UPDATED: now at https://github.com/angular-ui/ng-grid/blob/2.x/plugins/ng-grid-layout.js)
You will have to include an additional script tag pointing to this js file in your main index.html file. And the order of including this versus ng-grid.js is important.
You would have to set a watch on displayEditForm and then call the plugin's updateGridLayout() function.
So it would be something like:
var gridLayoutPlugin = new ngGridLayoutPlugin();
// include this plugin with your grid options
$scope.gridOptions = {
// your options and:
plugins: [gridLayoutPlugin]
};
// make sure grid redraws itself whenever
// the variable that ng-class uses has changed:
$scope.$watch('displayEditForm', function() {
gridLayoutPlugin.updateGridLayout();
});
From my understanding, watches generally belong in the link function rather than the controller but it will work in either spot. You could also go a bit further and say:
$scope.$watch('displayEditForm', function(newVal, oldVal) {
if (newVal !== undefined && newVal !== oldVal) {
gridLayoutPlugin.updateGridLayout();
}
});
To make sure this only fires when the data switches from true/false. This would matter if your data is initially undefined and you waste time calling grid redraw before you give it an initial value.

How to add button or images to dojo grid

I have a dojo grid with a json datastore (mysql resultset converted into json format). Currently my grid show 5 columns as shown below in the figure:
I have column named 'Action'. The rows under this 'Action' column should contain buttons or images(edit icon, delete icon) with hyperlinks such as edit.php?id=1 for edit, or delete.php?id=1 for delete.
Here is my dojo grid code:
<span dojoType="dojo.data.ItemFileReadStore" data-dojo-id="studentsStore" url="http://localhost/newsmis/public/studentManagement/student/fetchdata/data/1"></span>
<table dojoType="dojox.grid.DataGrid" id="studentsGrid" data-dojo-id="studentsGrid" columnReordering="true" sortFields="['idstudents','first_name','middle_name','last_name']" store="studentsStore" clientSort="true" selectionMode="single" rowHeight="25" noDataMessage="<span class='dojoxGridNoData'>No students found</span>">
<thead>
<tr>
<th field="idstudents" width="20%">Student ID</th>
<th field="first_name" width="20%">First Name</th>
<th field="middle_name" width="20%">Middle Name</th>
<th field="last_name" width="20%">Last Name</th>
<th field="action" width="20%">Action</th>
</tr>
</thead>
</table>
My json data format is
{"identifier":"idstudents","items":[{"idstudents":"11","first_name":"Pradip","middle_name":"Maan","last_name":"Chitrakar"}]}
How can i do it? Please suggest me some ideas
The one way I know is, that defining formatting method for that column in grid structure. So instead of defining the structure of the grid declaratively, define in JavaScript object like below
var structure = [
{
name: "First Name",
field: "first_name"
},
{
name: "Action",
field: "_item",
formatter: function(item){
var btn = new dijit.form.Button({
label: "Edit"
});
return btn;
}
}
]
and set this structure to the grid
<table dojoType="dojox.grid.DataGrid" id="studentsGrid" data-dojo-id="studentsGrid" columnReordering="true" sortFields="['idstudents','first_name','middle_name','last_name']" store="studentsStore" clientSort="true" selectionMode="single" rowHeight="25" noDataMessage="<span class='dojoxGridNoData'>No students found</span>" structure=structure >
Here is the working example,
Image in dojo Grid
As documentation of dojox.grid.DataGrid stays:
Beginning with Dojo 1.7, you should use dgrid or gridx, next-generation grid components that take full advantage of modern browsers and object stores.
piece of code example:
columns: [
{
field: "id",
label: "ID"
},
{
field: "name",
label: "Name"
},
{
field: "options",
label: "Options",
renderCell: function (obj) {
var cellContent = domConstruct.create("div",{});
var btn = new Button({
label: "Cell " + obj.id,
name: "idBtn"
})
btn.placeAt(cellContent);
on(btn, "click", function (evt) {
console.log(obj);
});
return cellContent;
}
}
]
This is JSfiddle example how to do it in dgrid by using function renderCell in column properties of dgrid.
renderCell(object, value, node, options) - An optional function that will be called to render the value into the target cell. object refers to the record from the grid’s store for the row, and value refers to the specific value for the current cell (which may have been modified by the column definition’s get function). node refers to the table cell that will be placed in the grid if nothing is returned by renderCell; if renderCell returns a node, that returned node will be placed in the grid instead. (Note: if formatter is specified, renderCell is ignored.)
If you don't want a button, but only an image icon, you can return a span-element from the formatter function like this:
formatter: function(value) {
var myValueClass = "dijitNoValue";
...
myValueClass = "ValueClass1";
...
return "<span class='dijitReset dijitInline dijitIcon " + myValueClass + "'></span>";
}
An css class has to be defined like
.ValueClass1 {
background-image: url('val_image1.png');
background-repeat: no-repeat;
width: 18px;
height: 18px;
text-align: center;
background-position: 1px;
}