How to load data into lightening data table component using response from GraphQL query (wire call) - lwc

I have a requirement to load data using the graphQL response into the lightening data table.I am able to fetch the response from the grapghQL query into the js . I just need to map the corresponding fields to the data column and populate the table.The below is the dummy code. I have the response from grapgql in an object format just have to assign the value and populate the column headers and value. Could someone help me achieve this .Any pointers would help.
LigteningDataTable.html
<lightning-datatable
key-field="id"
data={data}
hide-checkbox-column="true"
columns={columns}>
</lightning-datatable>
LigteningDataTable.js
```
import { LightningElement, api, wire } from 'lwc';
import { CapabilityMixin } from 'laf/pageCapability';
import { gql, unstable_graphql } from 'lightning/uiGraphQLApi';
export default class ServiceDocumentListComponent extends CapabilityMixin(LightningElement) {
get data(){
return [...Array(100)].map((_, index) => {
return {
name: ` (${index})`,
website: 'www.salesforce.com1ß',
amount: Math.floor(Math.random() * 100),
phone: `${Math.floor(Math.random() * 9000000000) + 1000000000}`,
closeAt: new Date(
Date.now() + 86400000 * Math.ceil(Math.random() * 20)
),
};
});
}
get fields() {
[
{ label: 'Label', fieldName: 'name' , wrapText: true },
{ label: 'Website', fieldName: 'website', type: 'url' , wrapText: true },
{ label: 'Phone', fieldName: 'phone', type: 'phone' , wrapText: true },
{ label: 'Balance', fieldName: 'amount', type: 'currency', wrapText: true },
{ label: 'CloseAt', fieldName: 'closeAt', type: 'date', wrapText: true },
];
}
```

Related

Format Date in VueJS. Back-end to front-end

So, I need to format a date coming from the back-end into the front-end.
I have a table:
<vue-good-table
:columns="columns"
:rows="formatedItems"
:paginate="true"
:lineNumbers="true">
<script>
export default {
components: {
Datepicker
},
data(){
return {
DatePickerFormat: 'dd/MM/yyyy',
items: [],
columns: [
{
label: 'Number',
field: 'number',
type: 'String',
filterable: true,
placeholder: 'Number'
},
{
label: 'Identification number',
field: 'identNumber',
type: 'String',
filterable: true,
placeholder: 'Identification number'
},
{
label: 'Name',
field: 'name',
type: 'String',
filterable: true,
placeholder: 'Name'
},
{
label: 'Code',
field: 'code',
type: 'String',
filterable: true,
placeholder: 'Code'
},
{
label: 'From',
field: 'dateFrom',
type: 'String',
filterable: true,
placeholder: 'dd/mm/yyyy'
},
{
label: 'To',
field: 'dateTo',
type: 'String',
filterable: true,
placeholder: 'dd/mm/yyyy'
},
{
label: 'Last change',
field: 'dateChanged',
type: 'String',
filterable: true,
placeholder: 'dd/mm/yyyy'
},
{},
{}
],
fields : {
"Number": "number",
"Identification numer": "identNumber",
"Name": "name",
"Code": "code",
"From": "dateFrom",
"To": "dateTo",
"Last Change": "dateChanged"
},
json_meta: [
[{
"key": "charset",
"value": "utf-8"
}]
]
}
},
computed: {
formatedItems () {
if (!this.items || this.items.length === 0) return []
return this.rows.map(item => {
return {
...items,
dateFrom: moment(item.dateFrom).format('DD/MM/YYYY'),
dateTo: moment(item.dateTo).format('DD/MM/YYYY'),
dateChanged: moment(item.dateChanged).format('DD/MM/YYYY')
}
})
}
}
</script>
Is this the correct code segment? Because I can't get it working for some reason?
Upon hitting the "search" button the data comes from the back-end and vizualize in the table. However, the date format right now is 1554163200000. How I can make it and format it in dd/mm/yyyy?
Error:
TypeError: Cannot read property 'map' of undefined
at s.formattedItems (eoriTable.vue:231)
at xt.get (vue.esm.js:3142)
at xt.evaluate (vue.esm.js:3249)
at s.formattedItems (vue.esm.js:3507)
at s.render (eoriTable.vue?d724:1)
at s.A._render (vue.esm.js:4544)
at s.<anonymous> (vue.esm.js:2788)
at xt.get (vue.esm.js:3142)
at xt.run (vue.esm.js:3219)
at Lt (vue.esm.js:2981)
JA # vue.esm.js:1741
That's the error when I build it. When I change :rows: formattedItems to items (which was the default value) everything is fine it renders but the date is not formatted.
You can use moment.js and computed properties
import moment from 'moment'
....
computed: {
formatedItems () {
if (!this.items || this.items.length === 0) return []
return this.items.map(item => {
return {
...item,
dateFrom: moment(item.dateFrom).format('DD/MM/YYYY'),
dateTo: moment(item.dateTo).format('DD/MM/YYYY'),
dateChanged: moment(item.dateChanged).format('DD/MM/YYYY')
}
})
}
}
and in your component
<vue-good-table
:columns="columns"
:rows="formatedItems"
:paginate="true"
:lineNumbers="true">
Another option is using table-row slot of vue-good-table

Submit all of grid rows with Extjs form submit

I have a grid panel in a form. Any row of the grid panel have a filefield. I want to send any row (name field and filename field) to server.
Model:
Ext.define('FM.model.DefineCode', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'filename', type: 'string'}
],
validations: [
{type: 'presence', field: 'id'},
{type: 'presence', field: 'name'},
{type: 'presence', field: 'filename'}
]
});
Store:
Ext.define('FM.store.DefineCode', {
extend: 'Ext.data.Store',
model: 'FM.model.DefineCode',
autoLoad: true,
data: []
});
View:
Ext.define('FM.view.map.DefineCode', {
extend: 'Ext.window.Window',
title: 'Define Code',
alias: 'widget.mmDefineCode',
width: 600,
modal: true,
items: [{
xtype: 'form',
items: [{
xtype: 'gridpanel',
title: 'myGrid',
store: 'DefineCode',
columns: [
{
text: 'Id',
xtype: 'rownumberer',
width: 20
}, {
text: 'Name',
dataIndex: 'name',
flex: 1,
editor:{
xtype: 'textfield'
}
}, {
text: 'File',
dataIndex: 'filename',
width: 200,
editor:{
xtype: 'filefield',
emptyText: 'Select your Icon',
name: 'photo-path',
buttonText: '',
flex: 1,
buttonConfig: {
iconCls: 'icon-upload-18x18'
},
listeners: {
change: function(e, ee, eee) {
var grid = this.up('grid');
var store = grid.getStore();
var newStore = Ext.create('FM.store.DefineCode',{});
store.insert(store.data.items.length, newStore);
}
}
},
}, {
text: '',
width: 40
}
],
height: 200,
width: 600,
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
]}
],
}],
buttons: [{text: 'OK', action: 'OK'}],
initComponent: function() {
var me = this;
Ext.apply(me, {});
me.callParent(arguments);
}
});
Controller:
...
form.submit({
url: 'icon/create',
});
When I submit form, only last row is sending to server.
Where is problem?
Why you using this ?
var newStore = Ext.create('FM.store.Path', {});
store.insert(store.data.items.length, newStore);
try using rowEditing to edit/submit 1 row data :
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2,
clicksToMoveEditor: 1,
listeners: {
'validateedit': function(editor, e) {},
'afteredit': function(editor, e) {
var me = this;
var jsonData = Ext.encode(e.record.data);
Ext.Ajax.request({
method: 'POST',
url: 'your_url/save',
params: {data: jsonData},
success: function(response){
e.store.reload({
callback: function(){
var newRecordIndex = e.store.findBy(
function(record, filename) {
if (record.get('filename') === e.record.data.filename) {
return true;
}
return false;
}
);
me.grid.getSelectionModel().select(newRecordIndex);
}
});
}
});
return true;
}
}
});
and place it to your plugin.
I don't try it first, but may be this will help you a little.
AND this is for your controller to add a record from your grid, you need a button to trigger this function.
createRecord: function() {
var model = Ext.ModelMgr.getModel('FM.model.DefineCode');
var r = Ext.ModelManager.create({
id: '',
name: '',
filename: ''
}, model);
this.getYourgrid().getStore().insert(0, r);
this.getYourgrid().rowEditing.startEdit(0, 0);
}
check this for your need, this is look a like. You need to specify the content-type.
And for your java need, please read this method to upload a file.

ExtJS 5.0.1 tagfield

Can anyone explain me, what am I doing wrong?
I'm trying to load data to store and select some of that on form load.
Here is what I came up with so far:
https://fiddle.sencha.com/#fiddle/cjd
Ext.define('TagModel', {
extend: 'Ext.data.Model',
fields: [{
name: 'some_id',
type: 'int'
}, {
name: 'some_value',
type: 'string'
}]
});
Ext.define('MyPanel',{
extend: 'Ext.panel.Panel',
renderTo: Ext.getBody(),
title: 'Some title',
width: 200,
heigh: 500,
layout: 'anchor',
items: [{
xtype: 'tagfield',
anchor: '100%',
displayField: 'some_value',
valueField: 'some_id',
store: Ext.create('Ext.data.Store', {
model: 'TagModel',
data: [{
some_id: 0,
some_value: 'value0'
}, {
some_id: 1,
some_value: 'value1'
}]
}),
// value: ['0']
}]
});
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('MyPanel');
}
});
It works well, but if you uncomment line 40, which should tell component to select items by their valueField config, it shows error in the console:
Uncaught TypeError: Cannot read property 'isModel' of undefined ext-all-debug.js:144157
According to the specification, value can be set as an array of strings associated to this field's configured valueField.
As posted by the OP Панов Владимир:
OK, I've found a solution:
The problem is in the source code of ExtJS. If anyone have same problem, you can use this override:
Ext.override(Ext.form.field.Tag, {
findRecord: function(field, value) {
var store = this.store,
matches;
if (store) {
matches = store.queryBy(function(rec) {
return rec.get(field) === value;
});
}
return matches ? matches.getAt(0) : false;
},
});

Kendo grid date column not formatting

I have a KendoGrid like below and when I run the application, I'm not getting the expected format for date column.
$("#empGrid").kendoGrid({
dataSource: {
data: empModel.Value,
pageSize: 10
},
columns: [
{
field: "Name",
width: 90,
title: "Name"
},
{
field: "DOJ",
width: 90,
title: "DOJ",
type: "date",
format:"{0:MM-dd-yyyy}"
}
]
});
When I run this, I'm getting "2013-07-02T00:00:00Z" in DOJ column. Why it is not formatting? Any idea?
I found this piece of information and got it to work correctly. The data given to me was in string format so I needed to parse the string using kendo.parseDate before formatting it with kendo.toString.
columns: [
{
field: "FirstName",
title: "FIRST NAME"
},
{
field: "LastName",
title: "LAST NAME"
},
{
field: "DateOfBirth",
title: "DATE OF BIRTH",
template: "#= kendo.toString(kendo.parseDate(DateOfBirth, 'yyyy-MM-dd'), 'MM/dd/yyyy') #"
},
...
References:
format-date-in-grid
jsfiddle
kendo ui date formatting
just need putting the datatype of the column in the datasource
dataSource: {
data: empModel.Value,
pageSize: 10,
schema: {
model: {
fields: {
DOJ: { type: "date" }
}
}
}
}
and then your statement column:
columns: [
{
field: "Name",
width: 90,
title: "Name"
},
{
field: "DOJ",
width: 90,
title: "DOJ",
type: "date",
format:"{0:MM-dd-yyyy}"
}
]
This is how you do it using ASP.NET:
add .Format("{0:dd/MM/yyyy HH:mm:ss}");
#(Html.Kendo().Grid<AlphaStatic.Domain.ViewModels.AttributeHistoryViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(c => c.AttributeName);
columns.Bound(c => c.UpdatedDate).Format("{0:dd/MM/yyyy HH:mm:ss}");
})
.HtmlAttributes(new { #class = ".big-grid" })
.Resizable(x => x.Columns(true))
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(c => c.Id);
})
.Read(read => read.Action("Read_AttributeHistory", "Attribute", new { attributeId = attributeId })))
)
Try formatting the date in the kendo grid as:
columns.Bound(x => x.LastUpdateDate).ClientTemplate("#= kendo.toString(LastUpdateDate, \"MM/dd/yyyy hh:mm tt\") #");
The option I use is as follows:
columns.Bound(p => p.OrderDate).Format("{0:d}").ClientTemplate("#=formatDate(OrderDate)#");
function formatDate(OrderDate) {
var formatedOrderDate = kendo.format("{0:d}", OrderDate);
return formatedOrderDate;
}
As far as I'm aware in order to format a date value you have to handle it in parameterMap,
$('#listDiv').kendoGrid({
dataSource: {
type: 'json',
serverPaging: true,
pageSize: 10,
transport: {
read: {
url: '#Url.Action("_ListMy", "Placement")',
data: refreshGridParams,
type: 'POST'
},
parameterMap: function (options, operation) {
if (operation != "read") {
var d = new Date(options.StartDate);
options.StartDate = kendo.toString(new Date(d), "dd/MM/yyyy");
return options;
}
else { return options; }
}
},
schema: {
model: {
id: 'Id',
fields: {
Id: { type: 'number' },
StartDate: { type: 'date', format: 'dd/MM/yyyy' },
Area: { type: 'string' },
Length: { type: 'string' },
Display: { type: 'string' },
Status: { type: 'string' },
Edit: { type: 'string' }
}
},
data: "Data",
total: "Count"
}
},
scrollable: false,
columns:
[
{
field: 'StartDate',
title: 'Start Date',
format: '{0:dd/MM/yyyy}',
width: 100
},
If you follow the above example and just renames objects like 'StartDate' then it should work (ignore 'data: refreshGridParams,')
For further details check out below link or just search for kendo grid parameterMap ans see what others have done.
http://docs.kendoui.com/api/framework/datasource#configuration-transport.parameterMap
This might be helpful:
columns.Bound(date=> date.START_DATE).Title("Start Date").Format("{0:MM dd, yyyy}");

How to dynamically create form.Fields from Stores in ExtJS 4

I have two stores, Assessor.store.Question and Assessor.store.Choice, along with their respective Models and Proxies. The load data from the server as intended. I also have a Panel, Assessor.view.QuizCards, with a "card" layout. This works fine and I can create dummy cards, Assessor.view.QuestionCard, and navigate through them fine using the Assessor.controller.Quiz controller.
What I need help with is programatically populating my QuizCards panel with questions and choices from the Questions and Choices stores. I've tried just about everything I can think of based on the docs and have had absolutely no success.
Specifically, I want the "value" of the "displayfield" on a QuestionCard to be the "text" property from the Question store/model. The "boxlabel" values in the "radiogroup" should come from the associated Choice store/model.
The detailed code is below. Thanks for any guidance you can provide.
Ext.define('Assessor.controller.Quiz', {
extend: 'Ext.app.Controller',
itemId: 'quizcontroller',
models: ['Question', 'Choice'],
stores: ['Question', 'Choice'],
views: ['QuestionCard'],
// Constants, kinda
NUM_QUESTIONS: 4,
// Custom Functions
/**
* create store instances
*/
createStores: function(){
if (Ext.getStore('questionstore') == null) {
var qs = Ext.create('Assessor.store.Question');
qs.load();
};
if (Ext.getStore('choicestore') == null) {
var cs = Ext.create('Assessor.store.Choice');
cs.load();
};
}, //end createStores
/**
* update buttons
*/
updateButtons: function(){
var index = this.getCardIndex();
var nb = Ext.ComponentQuery.query('#nextbutton')[0];
var pb = Ext.ComponentQuery.query('#prevbutton')[0];
var fb = Ext.ComponentQuery.query('#finishbutton')[0];
if (index<this.NUM_QUESTIONS) {
nb.enable();
fb.disable();
} else {
nb.disable();
fb.enable();
};
if (index>0){
pb.enable();
} else {
pb.disable();
};
}, //end updateButtons
/**
* get active question card index
*/
getCardIndex: function(){
return (Ext.ComponentQuery.query('quizcards')[0].getLayout().activeItem.itemId.split('-')[1]);
},
/**
* set active question card index
*/
setCardIndex: function(index){
Ext.ComponentQuery.query('quizcards')[0].getLayout().setActiveItem('questioncard-'+index);
},
/**
* start the quiz
*/
startQuiz: function(args) {
this.createQuestionCards();
var sb = Ext.ComponentQuery.query('#startbutton')[0];
sb.disable();
this.updateButtons();
},
/**
* create the UI cards with questions from server.
*/
createQuestionCards: function() {
var qc = Ext.ComponentQuery.query('quizcards')[0];
for (i=0; i<this.NUM_QUESTIONS; i++) {
card = Ext.create('Assessor.view.QuestionCard');
card.itemId = 'questioncard-' + i.toString();
qc.add(card);
};
this.updateButtons();
},
/**
* finishQuiz -- finishes and scores the quiz
* #param {Object} args
*/
finishQuiz: function(args) {
this.localState.set('quizFinished', true);
},
//
nextQuestion: function(args) {
console.log('\nnextQuestion');
var cardlayout = Ext.ComponentQuery.query('quizcards')[0].getLayout();
var activeIndex = cardlayout.activeItem.itemId.split('-')[1];
console.log(activeIndex);
if (activeIndex < this.NUM_QUESTIONS) {
activeIndex++;
this.setCardIndex(activeIndex);
};
this.updateButtons();
},
//
prevQuestion: function(args) {
console.log('\nprevQuestion');
var cardlayout = Ext.ComponentQuery.query('quizcards')[0].getLayout();
var activeIndex = cardlayout.activeItem.itemId.split('-')[1];
console.log(activeIndex);
if (activeIndex > 0) {
activeIndex--;
this.setCardIndex(activeIndex);
};
this.updateButtons();
},
//
init: function(){
this.control({
'#nextbutton': {
click: this.nextQuestion
},
'#prevbutton': {
click: this.prevQuestion
},
'#startbutton': {
click: this.startQuiz
},
'#finishbutton': {
click: this.finishQuiz
},
})
}
})
Ext.define('Assessor.view.QuizCards', {
extend: 'Ext.panel.Panel',
alias: 'widget.quizcards',
itemId: 'quizcards',
layout: 'card',
activeItem: 0,
items: []
})
Ext.define('Assessor.view.QuestionCard', {
extend: 'Ext.form.Panel',
alias: 'widget.questioncard',
layout: 'anchor',
items: [{
xtype: 'displayfield',
itemId: 'questionfield',
name: 'questionfield',
fieldLabel: 'Question',
value: ''
}, {
xtype: 'radiogroup',
itemId: 'choicegroup',
columns: 1,
vertical: true,
items: [{
boxLabel: '',
name: 'choice',
value: 1
}, {
boxLabel: (100*Math.random()),
name: 'choice',
value: 2
}, {
boxLabel: (100*Math.random()),
name: 'choice',
value: 3
}]
}]
})
Ext.define('Assessor.store.Question', {
extend: 'Ext.data.Store',
autoLoad: true,
autoSync: true,
model: 'Assessor.model.Question',
storeId: 'questionstore'
})
Ext.define('Assessor.model.Question', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'text', type: 'string'},
{name: 'resource_uri', type: 'string'}
],
proxy: {
type: 'rest',
url: '/api/v1/question/',
headers: {
'accept':'application/json',
'content-type':'application/json'
},
noCache: false,
reader: {
type: 'json',
root: 'objects',
idAttribute: 'id'
},
writer: {
type: 'json'
}
}
})
Choice model and store are similar, I'll post them if needed. Thanks
What I would suggest for the start is to make Assessor.view.QuestionCard more smart. I would rewrite initComponent there and pass record from the store during construction. This way you would have all logic for creating specific UI elements inside Assessor.view.QuestionCard and would call it something like that:
card = Ext.create('Assessor.view.QuestionCard', {
questionRecord: rec,
lastQuestion: true/false...
... whatever else you need
})