Angular ag-grid how to conditionally render header - ag-grid

I am new to ag-grid with Angular. I have simple html table to list users. And i want to use ag-grid for this. There are few columns which shouldn't be displayed if there is no permission. I am not sure how to achieve this using ag-grid. Can anyone please help me how to achieve this?
Existing html table:
<table>
<thead>
<tr>
<th width="30"> </th>
<th>Name</th>
<ng-container *requireAnyPermission="[SensitiveAccessPermission]">
<th>Modified by</th>
<th>Modified date</th>
</ng-container>
<th *requireAnyPermission="[SensitiveAccessPermission]">Active</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let person of people">
<td> </td>
<td data-label="Name">{{ person.name }}</td>
<ng-container *requireAnyPermission="[SensitiveAccessPermission]">
<td data-label="Modified by">{{ person.modifiedBy }}</td>
<td data-label="Modified date">
{{ person.modified | dateTimeFormat }}
</td>
</ng-container>
<td *requireAnyPermission="[SensitiveAccessPermission]" data-label="Active">
<ng-container *ngIf="person.isActive; then checkTemplate"></ng-container>
</td>
</tr>
</tbody>
</table>
I have the ag-grid column definition as below:
const COLUMNS: ColDef[] = [
{ headerName: '', field: '' },
{ headerName: 'Name', field: 'name', filter: true },
{ headerName: 'Modified by', field: 'modifiedBy', filter: true },
{ headerName: 'Modified date', field: 'modified', filter: true },
{ headerName: 'Active', field: 'isActive', filter: true },
];
How to achieve the same with ag-grid.
*requireAnyPermission is custom directive
#Directive({
// tslint:disable-next-line: directive-selector
selector: '[requireAnyPermission]'
})
export class RequireAnyPermissionDirective implements OnDestroy {
private _onDestroy = new Subject();
private _reverse = false;
private _anyPermissions: Array<string | PermissionCodeWithMask>;
#Input() set requireAnyPermission(
permissions: Array<string | PermissionCodeWithMask>
) {
this._anyPermissions = permissions;
this.updateView();
}
#Input() set requireAnyPermissionReverse(reverse: boolean) {
this._reverse = reverse;
this.updateView();
}
constructor(
private templateRef: TemplateRef<HTMLElement>,
private viewContainerRef: ViewContainerRef,
private userService: UserService
) {}
ngOnDestroy(): void {
this._onDestroy.next();
}
private updateView() {
if (this._anyPermissions) {
this.userService
.userHasAnyPermissions(this._anyPermissions)
.pipe(takeUntil(this._onDestroy))
.subscribe((hasPermission) => {
this.viewContainerRef.clear();
if (
(hasPermission && !this._reverse) ||
(!hasPermission && this._reverse)
) {
this.viewContainerRef.createEmbeddedView(this.templateRef);
}
});
}
}
}
Thanks

You can do that by either constructing the column definitions array programmatically based on the permissions the user have OR remove the columns you want to hide from COLUMNS on component initialization
In both cases you would have to call
gridOptions.api.setColumnDefs(columnDefs);
after you are done
Look at updating column defs example here
You wanna do something similar.

You can show/hide columns:-
this.gridColumnApi.setColumnsVisible([...visibleCols], true); // show columns
this.gridColumnApi.setColumnsVisible([...hiddenCols], false); // hide columns
If you want those column, not available in the grid:-
when creating columnDefs for grid, dont add in columnDefs conditionally

In my opinion this is simple method (* For Big Project and multiple change)
First get all column list for grid like.
getKeys(obj: []) {
var keys = [];
for (var key in obj) {
keys.push(key);
}
return keys;
}
this getKeys method give you all ColumnName of over array
//item is json response from over server.
var columns = this.getKeys(item[0]);
var colObj = {};
var gridcolumnDefs = [];
for (var i = 0; i & lt; columns.length; i++) {
var visible = true;
switch (columns[i].toLocaleLowerCase()) {
case 'columnname1':
colObj = {
field: columns[i],
sortable: false
}
break;
case 'columnname2':
visible = false;
colObj = {
field: columns[i],
sortable: false
}
break;
default:
break;
}
if (visible) {
if (colObj != undefined)
this.gridcolumnDefs.push(colObj);
}
}
// set column grid
this.GridName.setColumnDefs(this.gridcolumnDefs)
please try and check.

Related

how can i pass declared data from frontend to backend without button and inputfield to a paramter called $payload

if you have any method for passing data to a parameter to be used in backend please help.
i try using post man it works but i need it in code.
as u can see i have comment line in api.php in fuction httpget($payload), i want the data to be pass there inside $payload which is a parameter. thanks guys
indexpage
<template>
<q-page>
<div class="absolute-center">
<button #click="getRequest()">SHOW</button>
<h5 class="text-center">X Report</h5>
<table v-for="row in data" :key="row.discount" class="flex row">
<tr>
<td v-if="row.discount_type === '1'">PWD</td>
<td v-if="row.discount_type === '2'">Senior Citizen</td>
<td v-if="row.discount_type === '3 '">NACBIA</td>
</tr>
<tr>
<td>{{ row.discount_percentage }}%</td>
</tr>
<tr>
<td>{{ row.X_SUM_discount }}</td>
</tr>
<!-- <tr>
<td>{{ row.less_vat_amount }}</td>
</tr> -->
</table>
<button #click="getRequest2()">SHOW</button>
<h5 class="text-center">Y Report</h5>
<table v-for="row in data2" :key="row.discount" class="">
<tr>
<td v-if="row.discount_type === '1'">PWD</td>
<td v-if="row.discount_type === '2'">Senior Citizen</td>
<td v-if="row.discount_type === '3 '">NACBIA</td>
<td>{{ row.discount_percentage }}%</td>
<td>{{ row.X_SUM_discount }}</td>
</tr>
<tr>
<td>NACBIA</td>
<td>{{ row.NACBIA_discount_percentage }}%</td>
<td>{{ row.NACBIA_discount_amount }}</td>
</tr>
<tr></tr>
<!-- <tr>
<td>{{ row.less_vat_amount }}</td>
</tr> -->
</table>
</div>
</q-page>
</template>
<script>
import { data, data2, getRequest, getRequest2 } from "../composables/IndexPage";
export default {
name: "IndexPage.vue",
setup() {
return {
data,
data2,
getRequest,
getRequest2,
};
},
};
</script>
composable
import { defineComponent, ref } from "vue";
import { api } from "boot/axios";
let data = ref([]);
let data2 = ref([]);
const getRequest = () => {
api.get("api.php").then((response) => {
data.value = response.data;
console.log(data.value);
});
};
const getRequest2 = () => {
api.get("api.php").then((response) => {
data2.value = response.data;
console.log(data2.value);
});
};
export { data, data2, getRequest, getRequest2 };
api.php
<?php
// Tells the browser to allow code from any origin to access
header("Access-Control-Allow-Origin: *");
// Tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials) is include
header("Access-Control-Allow-Credentials: true");
// Specifies one or more methods allowed when accessing a resource in response to a preflight request
header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE");
// Used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request
header("Access-Control-Allow-Headers: Content-Type");
require_once('../MysqliDb.php');
class API
{
public function __construct()
{
$this->db = new MysqliDB('localhost', 'root', '', 'discount');
}
public function httpGet($payload)
{
// iwant to pass the data in this $payload from frontend without inputfeild
// $to_decode = $payload;
// $terminal= $to_decode->terminal;
// $from = $to_decode->from;
// $to = $to_decode->to;
// $data = Array (
// "terminal" => $terminal,
// "from" => $from,
// "to" => $to,
// );
// $to_json = json_encode($data);
// $to_json = json_decode($to_json,true);
// $terminal = $to_json['terminal'];
// $from = $to_json['from'];
// $to = $to_json['to'];
$terminal_id = 3;
$from = "2022-07-07 15:14:23";
$to = "2022-07-07 15:23:10";
$query = $this->db->rawQuery(
" SELECT
(SELECT SUM(TBL1.discounted_amount) FROM tbl_transactions TBL1 WHERE TBL1.date_created
BETWEEN '$from' AND ' $to') AS SUM_Xreport ,
(SELECT SUM(TBL1.discounted_amount) FROM tbl_transactions TBL1 WHERE TBL1.terminal_id = 3)
AS SUM_Yreport,
T.less_vat_amount,(SELECT ROUND(TP.discount_percentage, 0) )AS discount_percentage,
(SELECT discounted_amount FROM tbl_transactions WHERE is_nacbia_discounted =1) AS NACBIA_discount_amount,
(SELECT ROUND(discount_percentage,0) FROM tbl_transacted_products WHERE id = 1675 )
AS NACBIA_discount_percentage
,
CASE
WHEN T.is_pwd_discounted= 1 THEN '1'
WHEN T.is_SC_discounted= 1 THEN '2'
WHEN T.is_nacbia_discounted= 1 THEN '3'
END discount_type
FROM tbl_transacted_products AS TP
LEFT JOIN tbl_transactions AS T
ON TP.transaction_id=T.id
WHERE T.date_created BETWEEN '2022-07-07 15:14:23' AND '2022-07-07 15:23:10'
GROUP BY
T.terminal_id,
TP.transaction_id
");
$to_json = json_encode($query);
$to_json = json_decode($to_json,true);
$dataObj = [];
foreach ($to_json as $to_json) {
array_push($dataObj, (object)[
'NACBIA_discount_amount' => $to_json["NACBIA_discount_amount"],
'NACBIA_discount_percentage' => $to_json["NACBIA_discount_percentage"],
'X_SUM_discount' => $to_json["SUM_Xreport"],
'Y_SUM_discount' => $to_json["SUM_Yreport"],
'discount_type' => $to_json["discount_type"],
'less_vat_amount' => $to_json["less_vat_amount"],
'discount_percentage' => $to_json["discount_percentage"]
]);
}
echo json_encode(array('data'=> reset($dataObj)));
// echo json_encode(array('method' => 'GET'));
}
public function httpPost($payload)
{
// $this->db->insert();
echo json_encode(array('method' => $payload ));
}
public function httpPut($payload)
{
// $this->db->update();
echo json_encode(array('method' => 'PUT'));
}
public function httpDelete($payload)
{
// $this->db->delete();
echo json_encode(array('method' => 'DFLETE'));
}
}
/* END OF CLASS */
$request_method = $_SERVER['REQUEST_METHOD'];
$received_data = json_decode(file_get_contents('php://input'));
$response_data = $received_data;
$api = new API;
if ($request_method == 'GET') {
$api->httpGet($received_data);
}
if ($request_method == 'POST') {
$api->httpPost($received_data);
}
if ($request_method == 'PUT') {
$api->httpPut($received_data);
}
if ($request_method == 'DELETE') {
$api->httpDelete($received_data);
}
// echo(json_encode($api));

LWC - wrapper object values are nullified on input tag value change

I have a Apex method which returns the list of wrapper class as JSON string
having LWC js controller to call the method in connnectedCallback() and the wrapper list is assigned to a property this.coreAttributes which is show in html page using basic html tags along with other property defined in LWC noOfBlocks, faltHierarchy, and one more. code given below.
When I enter some value in coreAttribute's related input filed and enter some value in noOfBlocks input field, the value entered in the coreAttribute related fields are gone. please check the attached gif and help me to resolve this.
Image : https://easyupload.io/g1h772
#AuraEnabled(cacheable=true)
public static String queryCoreAttributes() {
List<Core_Attribute__c> coreAttributesList = new List<Core_Attribute__c>();
Map<Id,List<String>> picklistValuesToPicklistMasterMap = new Map<Id,List<String>>();
coreAttributesList = [SELECT Id, Name, Data_Type__c, Type__c, Picklist_Master__c
FROM Core_Attribute__c WHERE Base_Asset_Name__c IN (SELECT Id FROM Base_Asset_Template__c WHERE Name = 'Base PV Plant')
ORDER BY Name ASC];
picklistValuesToPicklistMasterMap = Utils.getPicklistValues();
System.debug(' picklistValuesToPicklistMasterMap '+ picklistValuesToPicklistMasterMap);
List<coreAttributesWrapper> coreAttributesWrapperList = new List<coreAttributesWrapper>();
for(Core_Attribute__c coreAttribute : coreAttributesList){
coreAttributesWrapper coreAttWrapper = new coreAttributesWrapper();
coreAttWrapper.attributeHeader = coreAttribute.Name;
coreAttWrapper.attributeDataType = coreAttribute.Data_Type__c.toLowerCase();
coreAttWrapper.picklistValues = (coreAttribute.Data_Type__c == 'Picklist') ? picklistValuesToPicklistMasterMap.get(coreAttribute.Picklist_Master__c): null;
coreAttWrapper.isPicklist = (coreAttribute.Data_Type__c == 'Picklist');
coreAttWrapper.attributeValue = '';
coreAttributesWrapperList.add(coreAttWrapper);
}
System.debug(' core Att '+ coreAttributesWrapperList);
return JSON.serialize(coreAttributesWrapperList);
}
JS
import { LightningElement, track, api } from "lwc";
import getPlantAssetRecord from "#salesforce/apex/P1PlantInfoPromptSolar.queryPlantAssetRecord";
import queryCoreAttributes from "#salesforce/apex/P1PlantInfoPromptSolar.queryCoreAttributes";
import saveP1PlantInfoPromptMetadata from "#salesforce/apex/P1PlantInfoPromptSolar.saveP1PlantInfoPromptMetadata";
export default class P1PlantInfoPromptSolar extends LightningElement {
#api plantAssetId='';
#track plantAssetDetail;
#track coreAttributes;
#track noOfBlocks='';
#track flatHierarchy=false;
#track drivePlus=false;
#track promptSpecificAttributes;
connectedCallback() {
console.log(' connected callback ');
getPlantAssetRecord({
recordId: 'a060p000001hGLxAAM',
})
.then(result => {
this.plantAssetDetail = result;
})
.catch(error => {
this.error = error;
});
queryCoreAttributes()
.then(result => {
console.log(' result ' + result);
console.log(' JSON result ' + JSON.parse(result));
this.coreAttributes = JSON.parse(result);
})
.catch(error => {
this.error = error;
});
}
inputTagValueChangeHandler(event){
console.log(' test '+ JSON.stringify(this.coreAttributes));
console.log(' value -> '+ event.target.value + ' name -> ' + event.target.name);
if(event.target.name === 'Blocks') this.noOfBlocks = event.target.value;
if(event.target.name === 'Flat Hierarchy') this.flatHierarchy = event.target.value;
if(event.target.name === 'Drive+') this.drivePlus = event.target.value;
}
HTML
<tr data-row="1">
<th># Blocks</th>
<td><input type="number" name="Blocks"
value={noOfBlocks} onchange={inputTagValueChangeHandler}/></td>
</tr>
<tr data-row="2">
<th>Flat Hierarchy</th>
<td><input type="checkbox" name="Flat Hierarchy"
value={flatHierarchy} onchange={inputTagValueChangeHandler}/></td>
</tr>
<tr data-row="2">
<th>Drive+</th>
<td><input type="checkbox" name="Drive+"
value={drivePlus} onchange={inputTagValueChangeHandler}/></td>
</tr>
<template for:each={coreAttributes} for:item="coreAttribute">
<tr key={coreAttribute.key}>
<th>{coreAttribute.attributeHeader}</th>
<td>
<template if:false={coreAttribute.isPicklist}>
<input type={coreAttribute.attributeDataType} name={coreAttribute.attributeHeader}
value={coreAttribute.attributeValue}/>
</template>
<template if:true={coreAttribute.isPicklist}>
<select size="1" name={coreAttribute.attributeHeader}>
<option value="None">--None--</option>
<template for:each={coreAttribute.picklistValues} for:item="attributePickValues">
<option key={coreAttribute.key} value={coreAttribute.attributeValue}>{attributePickValues}</option>
</template>
</select>
</template>
</td>
</tr>
</template>

angular2 how to call method of object

I have an model in which I have a method is valid
export class ModelClass{
id: number;
text : String,
isValid() : boolean {
return true;
}
}
a second model
export class Rows{
editable: boolean;
modelClass: ModelClass;
}
how to call it in html ???
<table border="1p;">
<tbody >
<tr *ngFor="let link of modelClassRows">
<td>
<div>toto {{link.applicationLink.isValid()}}</div>
</td>
</tr>
</tbody>
</table>
a part of my component where object are initialized
export class ApplicationLinkListComponent implements OnInit {
modelClassRows: Rows[] = new Array<Rows>();
constructor() {
}
ngOnInit() {
// fill modelClassRows
.....
}
You need to instantiate the ModelClass class this way:
let row = new Rows();
row.modelClass = new ModelClass();
row.modelClass.id = 'some id';
row.modelClass.title = 'some title';
modelClassRows.push(row);
If you instantiate it literally and cast it to the type, you won't be able to use the method.
For example:
let row = new Rows();
row.modelClass = <ModelClass>{
id: 'some id',
title: 'some title'
};
modelClassRows.push(row);

Best way to make a Backbone app with RESTful Slim Framework

I'm using this video-example (https://www.youtube.com/watch?v=FZSjvWtUxYk) in order to make an errors reporting app. The problem comes when in the View when it passes the object that comes from the REST-AJAX call, _.template says that errores is not defined.
Here is my code:
var Error = Backbone.Model.extend({
defaults: {
iderror: '',
title: '',
url: ''
},
idAttribute: 'iderror'
});
var Errores = Backbone.Collection.extend({
model: Error,
url: '/errores'
});
var ErrorList = Backbone.View.extend({
el: '.page',
render: function (eventName) {
var that = this;
var errores = new Errores();
errores.fetch({
success: function (errores) {
var template = _.template($('#error-list-template').html(),{errores: errores.models});
that.$el.html(template);
}
});
}
});
My Template code:
<script type="text/template" id="error-list-template">
Registrar Error
<hr/>
<table class="table striped">
<thead>
<tr>
<th>Id Error</th>
<th>Título</th>
<th>URL</th>
<th></th>
</tr>
</thead>
<tbody>
<%
_.each(errores, function(error) { %>
<tr>
<td><%= error.get('iderror') %></td>
<td><%= error.get('title') %></td>
<td><%= error.get('url') %></td>
<td>Editar</td>
</tr>
<% }); %>
</tbody>
</table>
</script>
My RESTful GET function made with SLIM Framework:
$app->get('/errores/', function () {
//echo "Hello, ";
$datos = array();
$db = NewADOConnection('mysqli');
$db->Connect("localhost", "root", "mypassword", "tt1r");
$sql = "SELECT * FROM tt1r.course";
$qry = $db->execute($sql);
/*while (!$qry->EOF) {
//print_r($qry->fields);
$datos = [$qry->iderror => ['title' => $qry->title, 'url' => $qry->url]];
$qry->MoveNext();
}*/
if($qry) {
foreach($qry as $re){
//return $re['ADM_ID'];
$datos[] = array("iderror" => $re['iderror'],"title" => $re['title'],"url" => $re['url']);
}
$db = null;
//echo json_encode($datos);
//echo '{"user": ' . json_encode($datos) . '}';
echo json_encode($datos);
}
});
I have to say that I do get the JSON array with the data from the RESTful function, but it doesn't show it.
Thank you for your help.
Best regards.
Rafa
I read the answer in a post made by RyanP13.
So the fixed View code is:
var ErrorList = Backbone.View.extend({
el: '.page',
render: function () {
var that = this;
var errores = new Errores();
errores.fetch({
success: function(errores, response, options){
var template = _.template($('#error-list-template').html());
that.$el.html(template({ errores: errores.toJSON()}));
}
});
}
});
The problem was that I did not had any reference from the Collection.
Hope this help you as well.
Best regards
Rafa

kendo mvvm not updating after ajax call

I have a page (relevant code below) which carries out the following :
User enters a value into an auto-complete text box
2, Upon selecting an auto complete option, an ajax call is made in order to fill 2 dropdownlists
User is required to select a value from each dropdownlist
Once a value has been selected on both, they click on the add button and my bound table is updated
User can remove rows added to the table
The rows added in step 4 are contained in an array in the observable object.
The first time the page loads points 1 to 5 work as expected.....
However, if the user enters a new search into the auto-complete box and fires the select event, the second time the ajax call is made, the relationship between my viewmodel and UI objects are broken.
The code which is executing is identical so please could someone shed some light on why the second time around this breaks.
<input type="text" id="txtBox" style="width:300px;" />
<div id="fixturesBindable" style="padding:0 !Important;">
<table>
<thead>
<tr>
<th>Col1</th>
<th>Col2</th>
</tr>
</thead>
<tbody data-template="row-template" data-bind="source: Fixtures"></tbody>
</table>
<select id="a_teamsdropdown" data-role="dropdownlist" data-text-field="TeamFullName" data-value-field="Id" data-bind="source: Teams" style="width:200px;"></select>
<select id="a_oppteamsdropdown" data-role="dropdownlist" data-text-field="TeamFullName" data-value-field="Id" data-bind="source:
OpponentTeams" style="width:200px;"></select>
<button type="button" data-bind="click: addFixture">Add Fixture</button>
<script id="row-template" type="text/x-kendo-template">
<tr>
<td><input type="hidden" id="team" data-bind="attr: { name: TeamModelName, value: TeamId }" /></td>
<td><input type="hidden" id="oppteam" data-bind="attr: { name: OppModelName, value: OppTeamId }" /></td>
</tr>
</script>
</div>
<script>
$(document).ready(function () {
var viewModel = kendo.observable({
Teams: <%= Model.Teams %>,
OpponentTeams: [],
Fixtures: [],
addFixture: function (e) {
var Fixtures = this.get("Fixtures");
var teamId = $("#a_teamsdropdown").val();
var teamName = $("#a_teamsdropdown>option:selected").text();
var oppteamId = $("#a_oppteamsdropdown").val();
var oppteamName = $("#a_oppteamsdropdown>option:selected").text();
this.get("Fixtures").push({
TeamFullName: teamName,
TeamId: teamId,
OppTeamFullName: oppteamName,
OppTeamId: oppteamId,
OrderIndex: this.get("Fixtures").length,
TeamModelName: 'Fixtures[' + this.get("Fixtures").length + '].TeamId',
OppModelName: 'Fixtures[' + this.get("Fixtures").length + '].OpponentTeamId'
});
},
resetFixture: function(){
var Fixtures = this.get("Fixtures");
$.each(Fixtures, function (key, fixture) {
Fixtures.splice(0, 1);
});
}
});
opponents = $("#txtBox").kendoAutoComplete({
minLength: 3,
dataTextField: "Name",
filter: "contains",
dataSource: new kendo.data.DataSource({
transport: {
read: {
url: "/url/Ajax",
type: "POST",
data: function () { return { searchText: $("#txtBox").val()}
},
complete: function (data) {
opponents.list.width(400);
}
}
},
pageSize: 10,
serverPaging: true,
serverSorting: true,
schema: {
total: "count",
data: "data",
model: {
id: "Id",
fields: {
Id: { editable: false }
}
}
}
}),
change: function () {
this.dataSource.read();
},
select: function (e) {
$.each(opponents.dataSource.data(), function (index, value) {
if (e.item.text() == value.Name) {
selectedOpponent = value;
$('#Fixture_OpponentTeam_Id').val(selectedOpponent.Id);
$('#OpponentName').val(selectedOpponent.Name);
$.ajax({
url: 'GetOpponentTeams',
data: { schoolId: selectedOpponent.Id, seasonId: seasonId, sportId: sportsId },
type: 'GET',
success: function (data) {
viewModel.OpponentTeams = data;
kendo.bind($("#fixturesBindable"), viewModel);
},
error: function (xhr, ajaxOptions, thrownError) {
//alert('Error during process: \n' + xhr.responseText);
alert(thrownError);
}
});
return;
}
});
}
}).data("kendoAutoComplete");
</script>
Not sure if this will fix your issue or not, but in general I would advise against re-binding everything in your ajax success callback. If you just .set("OpponentTeams") instead of assigning the value directly, does that help?
success: function (data) {
viewModel.set("OpponentTeams", data);
},
The call to .set() should trigger a refresh of the #a_oppteamsdropdown element.