I want to show contacts of an account, for that I have created LWC, I am calling Apex method here and I want to show all contacts of an account using data table, but data is not showing in the UI.
I am using custom label to pass account to Apex class.
please help me to achieve this
below is my code
JS Code:
const columns = [
{ label: "Name", fieldName: "Name" },
{ label: "Phone", fieldName: "Phone"},
{ label: "Email", fieldName: "Email"}
];
#track contactsList =[];
#wire(GetContacts,{AccountId:this.AccountId})
WireContactRecords({error, data}){
console.log('Entering WireContactRecords');
console.log('Entering WireContactRecords===='+this.AccountId);
if(data){
console.log('data*********+'+JSON.stringify(data))
this.contactsList = data;
this.error = undefined;
}else{
this.error = error;
this.contactsList = undefined;
}
}
Apex class
#AuraEnabled(cacheable = true)
public static Contact GetContacts(String AccountId){
String query = 'SELECT Name,Phone,Email FROM Contact WHERE AccountId =: AccountId';
return Database.query( query );
}
HTML CODE
<lightning-datatable
data={contactsList}
columns={columns}
key-field="id"
hide-checkbox-column>
</lightning-datatable>
The syntax to pass the value of a property defined in the JS class to a wired function is: #wire(functionName, { param: '$propertyName' })
Therefore, assuming that your class has an AccountId property, you have to change
#wire(GetContacts,{AccountId:this.AccountId})
to
#wire(GetContacts,{AccountId: '$AccountId'})
Moreover in the HTML you can use only property defined in your JS class, so if columns is defined only outside it, you should provide a getter:
get columns() {
return columns;
}
Related
I have made my research, but couldn't find the answer.
I have a Lightning App in Salesforce, I used LWC Js and Apex.
In one part of the app the user can add a 'desk item' (by typing its name) and select from a checkbox 1-2 items to add them to the 'desk'.
I used Apex to transfer the value of the 'desk item' to an Object and I can show it in a list (in the app).
How can I add the checkbox value(s) to the submitDesk(){...} so it sends its value(s) along with the 'desk item' value?
I don' know where/how exactly to add and to get it back?
The JS Code
import { LightningElement, track } from 'lwc';
import createDesk from '#salesforce/apex/FlexOfficeController.createDesk';
import getDesks from '#salesforce/apex/FlexOfficeController.getDesks';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
export default class DeskList extends LightningElement {
// Desk
#track data_desks = [];
//table to show the desks's Id + Name, and the checkbox
columns = [
{ label: 'Id', fieldName: 'Id', type: 'text' },
{ label: 'Name', fieldName: 'Name', type: 'text' },
{ label: 'Accessories', fieldName: **the checkbox value**, type: 'text' }
];
// value to the picklist
connectedCallback(){
this.retreiveDesk();
}
retreiveDesk(){
getDesks({})
.then(d => {
this.data_desks = JSON.parse(d);
})
}
desk = {};
changeValue(event){
this.desk[event.target.name] = event.target.value
}
submitDesk(){
console.log(this.desk, this.value + 'Hi there');
createDesk({desk:JSON.stringify(this.desk)})
.then(data=> {
console.log(data + 'hello');
this.retreiveDesk();
// toaster
const evt = new ShowToastEvent({
title: "New desk",
message: `succefully created. Check out your reservation.`,
variant: "success"
})
this.dispatchEvent(evt);
})
}
// Checkbox
value = [];
get options() {
return [
{ label: 'Mouse', value: 'mouse' },
{ label: 'Screen', value: 'screen' },
];
}
// put the checkbox values into a string ('join')
get checkboxValues() {
console.log(this.value);
return this.value.join(',');
}
handleCheckboxChange(event) {
this.value = event.detail.value;
}
}
Apex Controller
public class FlexOfficeController {
#AuraEnabled
public static string createDesk(String desk){
try {
Desk__c d = (Desk__c)JSON.deserialize(desk, Desk__c.class);
insert d;
return d.id;
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
#AuraEnabled
public static string getDesks(){
try {
List<Desk__c> desks = new List<Desk__c> ();
desks = [SELECT Id, Name FROM Desk__c];
return JSON.serialize(desks);
} catch (Exception e) {
throw new AuraHandledException(e.getMessage());
}
}
}
HTML
<template>
<lightning-card>
<div class="slds-m-around_medium slds-theme_alert-texture">
<lightning-input name="Name" label="Name your desk" onchange={changeValue}></lightning-input>
<lightning-checkbox-group name="Accessories" label="Checkbox Group" options={options} value={value}
onchange={handleCheckboxChange}></lightning-checkbox-group>
<p>{checkboxValues}</p>
<lightning-button onclick={submitDesk} label="Submit"></lightning-button>
<lightning-datatable key-field="id" data={data_desks} columns={columns} hide-checkbox-column></lightning-datatable>
</div>
</lightning-card>
</template>
Here I have a JSON array
demoList = [
{ name:"asian003", model:"hyper20", class:"selina0127" },
{ name:"asian003", model:"hyper21", class:"selina0127" },
{ name:"norva", model:"hyper21", class:"gowri.14" },
{ name:"sparks007", model:"NNc22", class:"gowri.14" },
{ name:"asian003", model:"NNc22", class:"selina0127" }
]
This array showing in an HTML table using Angular. I want to add dropdowns separately such as name dropdown, model dropdown, class dropdown. When I select drop-down values I want to filter table records.
For example, if I select asian003 from name and selina0127 from class and do not select the value model dropdown, I want to get the below result into the table preview
demo1List = [
{name:"asian003",model:"hyper20",class:"selina0127"},
{name:"asian003",model:"hyper21",class:"selina0127"},
{name:"asian003",model:"NNc22",class:"selina0127"}
]
You can create and bind one property to each dropdown. Then on any dropdown change, you can call filter_demo_list() function:
const demoList = [
{ name:"asian003", model:"hyper20", class:"selina0127" },
{ name:"asian003", model:"hyper21", class:"selina0127" },
{ name:"norva", model:"hyper21", class:"gowri.14" },
{ name:"sparks007", model:"NNc22", class:"gowri.14" },
{ name:"asian003", model:"NNc22", class:"selina0127" }
]
public table_data;
public selected_name;
public selected_class;
public selected_model;
filter_demo_list() {
this.table_data = demoList;
if (this.selected_name) this.table_data.filter((item)=> item.name === this.selected_name);
if (this.selected_class) this.table_data.filter((item)=> item.class === this.selected_class);
if (this.selected_model) this.table_data.filter((item)=> item.model === this.selected_model);
}
I am using Master detail in Kendo Grid in AngularJS.
Here is the setup of the code:
In cshtml is:
<script type="text/x-kendo-template" id="template">
<div>
<div class="orders"></div>
</div>
</script>
In the AngularJS controller is
The MasterRowId is the id of the Column in the Master row. So the Master grid is a grid with
columns Id and name
$scope.getorders = function (masterRowId)
{
myservice.getorders(masterRowId)
.then(function (result) {
for (var j = 0; j < result.data.length; j++)
$scope.ordergroupdata.push(result.data[j]);
});
}
In the master grid definition i have
......
detailTemplate: kendo.template($("#template").html()),
detailInit: $scope.detailInit,
The definition of $scope.detailInit is
$scope.detailInit = function (e)
{
$scope.MasterRowId = e.data.Id;
$scope.getorders ($scope.MasterRowId);
var orderdata = $scope.ordergroupdata;
var orderdatasource = new kendo.data.DataSource({
transport: {
read: function (e) {
e.success(orderdata);
},
update: function (e) {
e.success();
},
create: function (e) {
var item = e.orderdata;
item.Id = orderdata.length + 1;
e.success(item);
}
},
schema: {
model: {
id: "Id",
fields: {
OrderId: { type: 'string'},
}
}
},
});
e.detailRow.find(".orders").kendoGrid({
dataSource: orderdatasource,
columns: [
{ field: "OrderId", title: "OrderId" },
]
});
}
The issue is that if i click on the first row , i can retrieve the data according to the MasterRowId from my MVC action method. So If i click on the first row and the MasterRowId is for example 10 , then i get an OrderId of "1234" .
I can click on the second row with MasterRowID of 15 and it will retrieve the OrderId of "8231", BUT if i go back to the first row the data (OrderId) in the details grid is actually the data from the second row, so its "8321" NOT "1234".
How can i always call the $scope.detailInit so that i can go back to the MVC Action method and always retrieve the correct data for that particular row with that MasterRowId ?
Once i expand the row and move on to another row , the detailsInit doesnt get called any more for that row ?
detailInit is only called on first expand, but you can use detailExpand that is called every time you expand the detail table.
Offical example:
<script>
$("#grid").kendoGrid({
columns: [
{ field: "name" },
{ field: "age" }
],
dataSource: [
{ name: "Jane Doe", age: 30 },
{ name: "John Doe", age: 33 }
],
detailTemplate: "<div>Name: #: name #</div><div>Age: #: age #</div>",
detailExpand: function(e) {
console.log(e.masterRow, e.detailRow);
}
});
</script>
Docs: detailExpand
Official example: detailExpand example
response : {initial_data: [{
"Did I see this plant in 2016?"=>"No",
"Did I see this plant in 2017?"=>"Yes",
"How Many?"=>1,
"User Data 4"=>"x",
"User Data 5"=>nil,
"Did I see this plant in 2022?"=>"No",
"Name"=>"Abronia alpina"},
{"Did I see this plant in 2016?"=>"No",
"Did I see this plant in 2017?"=>"No",
"How Many?"=>11,
"User Data 4"=>"x",
"User Data 5"=>nil,
"Did I see this plant in 2022?"=>"Yes",
"Name"=>"Abronia alpina1"}]
}
Based on above response I am executing below code to print the header and there values dynamically.
const CUSTOM_COLUMNS = (Object.keys(props.initial_data[0].map((item, index) =>
[{
id: 'user_data',
Header: item,
headerClassName: 'family-header',
accessor: item,
className: 'centered capitalize',
show: true
}][0]
));
const columns = [
...CUSTOM_COLUMNS,
{
Header: 'Actions',
accessor: 'id',
show: true,
className: 'centered',
Cell: (props) => (
<span className="label label-danger link" onClick={this.deletePlant.bind(this, props.value)}>
<i className="fa fa-trash"></i> Delete
</span>
)
}
];
I able to correctly print the header dynamically, but my values are not coming dynamically and it's displaying my last hash key values in each column.
My header should be :
["Did I see this plant in 2016?", "Did I see this plant in 2017?", "How Many?", "User Data 4", "User Data 5", "Did I see this plant in 2022?", "Name"]
and row values should be:
Row1 : ["No", "Yes", 1, "x", "", "No", "Abronia alpina"]
Row1 : ["No", "No", 11, "x", "", "Yes", "Abronia alpina1"]
Can you please help me to get it dynamically, or let me know what I am doing wrong here. I am new in react so maybe i am missing here so please correct me.
If you are using react-table, to render the table, I think your logic of creating columns is wrong. It should be something like this.
const columns = Object.keys(response.initial_data[0]).map((key, id)=>{
return {
Header: key,
accessor: key
}
})
I have tried to create a snippet with your data. Let me know if this helps.
const ReactTable = window.ReactTable.default
const response = {
initial_data: [
{
"Did I see this plant in 2016?":"No",
"Did I see this plant in 2017?":"Yes",
"How Many?":1,
"User Data 4":"x",
"User Data 5":"",
"Did I see this plant in 2022?":"No",
"Name":"Abronia alpina"
},
{
"Did I see this plant in 2016?":"No",
"Did I see this plant in 2017?":"No",
"How Many?":11,
"User Data 4":"x",
"User Data 5":"",
"Did I see this plant in 2022?":"Yes",
"Name":"Abronia alpina1"
}]
}
class App extends React.Component {
render() {
const data = response.initial_data
const columns = Object.keys(response.initial_data[0]).map((key, id)=>{
return {
Header: key,
accessor: key
}
})
return <ReactTable
data = { data }
columns = { columns }
/>
}
}
ReactDOM.render( < App / > , document.getElementById("app"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-table/6.7.6/react-table.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/react-table/6.7.6/react-table.css"></link>
<div id="app"></div>
With React-Table you header must have a accessor and your data must be mapped with accessor as the key
You would create your columns like
getColumns() {
return Object.keys(data.initial_data[0]).map(key => {
return {
Header: key,
accessor: key
};
});
}
and you Table can then look like
class App extends React.Component {
getColumns() {
return Object.keys(data.initial_data[0]).map(key => {
return {
Header: key,
accessor: key
};
});
}
render() {
const columns = this.getColumns();
console.log(data.initial_data);
return (
<div>
<ReactTable
data={data.initial_data}
columns={columns}
defaultPageSize={10}
className="-striped -highlight"
/>
<br />
<Tips />
<Logo />
</div>
);
}
}
According to documentation:
accessor: 'propertyName', // or Accessor eg. (row) => row.propertyName
Accessors are functions that return the value to populate the row's
value for the column. This lets the render function not have to worry
about accessing the correct data, the value is automatically populated
in it's props.
If a string or array is passed the default accessor is used. The
default accessor will parse the input into an array and recursively
flatten it. Any values that contain a dot (.) will be split. Any
values that contain bracket ([]) will be split. This array is then
used as the path to the value to return.
Working Codesandbox
i have the next code, i want change the class when the value is equal to "abc" but i can't add some class :
$scope.formFields = [
{
key: 'email',
type: 'input',
templateOptions: {
type:'email',
placeholder: 'Correo',
required:true,
class: 'some-clase'
}
}]
now, I know well then the change is done but I can not even add a simple class :
expressionProperties: {
'templateOptions.class': '"glyphicon form-control-feedback glyphicon-"'
}
help me please , if they can add an example in jsbin, codepen... thanks
Your expressionProperties property is a formly expression and can therefore be a function. It should probably be something more like this:
'templateOptions.class': function($viewValue, $modelValue, scope) {
if ($viewValue === 'abc') {
return 'some-class';
} else {
return 'some-other-class';
}
}