Load form data via REST into vue-form-generator - json

I am building a form, that needs to get data dynamically via a JSON request that needs to be made while loading the form. I don't see a way to load this data. Anybody out here who can help?
JSON calls are being done via vue-resource, and the forms are being generated via vue-form-generator.
export default Vue.extend({
template,
data() {
return {
model: {
id: 1,
password: 'J0hnD03!x4',
skills: ['Javascript', 'VueJS'],
email: 'john.doe#gmail.com',
status: true
},
schema: {
fields: [
{
type: 'input',
inputType: 'text',
label: 'Website',
model: 'name',
maxlength: 50,
required: true,
placeholder: companyList
},
]
},
formOptions: {
validateAfterLoad: true,
validateAfterChanged: true
},
companies: []
};
},
created(){
this.fetchCompanyData();
},
methods: {
fetchCompanyData(){
this.$http.get('http://echo.jsontest.com/key/value/load/dynamicly').then((response) => {
console.log(response.data.company);
let companyList = response.data.company; // Use this var above
}, (response) => {
console.log(response);
});
}
}
});

You can just assign this.schema.fields.placeholder to the value returned by the API like following:
methods: {
fetchCompanyData(){
this.$http.get('http://echo.jsontest.com/key/value/load/dynamicly').then((response) => {
console.log(response.data.company);
this.schema.fields.placeholder = response.data.company
}, (response) => {
console.log(response);
});
}
}

Related

Update echart on data change

i'm looking for a solution to update an echart when new data comes in. Currently i have a chart and a drop down with some data.When i open the page, data is displaying at the chart perfectly fine. But when i use the drop down and change option to next data, nothing is happening. The previous data is still on the chart. Any ideas how to update the chart (object) when data changes ?
My code:
chart1: EChartOption = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['Tests Open','Tests Approved', 'Tests Failed']
},
toolbox: {
show: true,
feature: {
mark: { show: true },
magicType: { title: '1', show: true, type: ['line', 'bar',] },
restore: { title: 'Restore', show: true },
saveAsImage: { title: 'Save Chart',show: true }
}
},
xAxis: [
{
type: 'category',
axisTick: { show: false },
data: []
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Tests Open',
type: 'bar',
data: [],
itemStyle: {
color: '#FDD051'
}
},
{
name: 'Tests Approved',
type: 'bar',
data: [],
itemStyle: {
color: '#2EAD6D'
}
},
{
name: 'Tests Failed',
type: 'bar',
data: [],
itemStyle: {
color:'#F0533F'
}
},
]
};
refreshChart(statistics: TestResultSiteStatistics) : void {
let months = [];
let open = [];
let approved = [];
let failed = [];
for (let month in statistics.monthly){
months.push(month);
approved.push(statistics.monthly[month].approved);
open.push(statistics.monthly[month].open);
failed.push(statistics.monthly[month].failed);
}
this.chart1.xAxis[0].data = months;
this.chart1.series[0].data = open;
this.chart1.series[1].data = failed;
this.chart1.series[2].data = approved;
}
<div #chart style="height:590px; width:1190px;" echarts [options]="chart1" ></div>
You cannot add data directly to instance because Echarts incapsulated diffucult logic to process data. You need to use method myChart.setOption({series: [new_data]}). It explained in API docs: https://echarts.apache.org/en/api.html#echartsInstance.setOption and https://echarts.apache.org/en/tutorial.html#Loading%20and%20Updating%20of%20Asynchronous%20Data

ng2-smart-table - How to Open Record in a Different View

I was able to add a custom action to the table but I still don't know how to use that custom action to open a record in a different page/modal when it's clicked. How to assign the ID to that record row? How to pass it to a different view?
in the component.html
<ng2-smart-table [settings]="settings" [source]="source" (custom)="onCustomAction($event)"></ng2-smart-table>
in the component.ts
settings = {
mode: 'external',
hideSubHeader: true,
actions: {
position: 'right',
add: false,
edit:false,
delete: false,
custom: [
{ name: 'viewRecord', title: '<i class="far fa-file-alt"></i>'},
],
},
columns: {
firstName: {
title: 'First Name',
type: 'string',
},
lastName: {
title: 'Last Name',
type: 'string',
},
username: {
title: 'Username',
type: 'string',
},
email: {
title: 'E-mail',
type: 'string',
},
age: {
title: 'Age',
type: 'number',
},
},
};
onCustomAction(event): void {
//WHAT TO DO HERE?
}
SOLVED
onCustomAction(event): void {
//get action name to switch in case of different actions.
var actionName = event.action;
//get row id.
var id = event.data.id;
//navigate to edit/view url.
this.router.navigate(url)
}
your can inject NbdialogService in constuctor to open in dialog/Modal
private dialogService: NbDialogService
onCustomAction(event) {
switch (event.action) {
case 'view-details':
this.service.getDetails(event.data.Id)
.pipe(
tap(res => {
this.dialogService.open(UserDetailsComponent, { // inject your component will be displayed in modal
context: {
details: res,
},
});
})
).subscribe();
break;
default:
console.log('Not Implemented Action');
break;
}
or navigate sure as you did by this.router.navigate(url)

GraphQL - operating elements of array

I would like to display some information about members, but I don't know how to resolve array of field 'time'. This is array, because it shows their login time. What should I do?
I used GraphQLString, but I am aware of this bad solution.
So I'm getting an error:
"message": "String cannot represent value: [\"12:08\"]",
Here is schema.js
const axios = require("axios");
const {
GraphQLObjectType,
GraphQLString,
GraphQLList,
GraphQLSchema
} = require("graphql");
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: GraphQLString
}
})
});
//Root Query
const RootQuery = new GraphQLObjectType({
name: "RootQueryType",
fields: {
users: {
type: new GraphQLList(memberType),
description: "List of members",
resolve(parent, args) {
return axios
.get("http://25.98.140.121:5000/data")
.then(res => res.data);
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
});
And here is JSON
[
{
"time": [
"12:08"
],
"nick": "Cogi12",
"name_and_surname: "John Steps"
},
{
"time": [
"12:16"
],
"nick": "haris22",
"name_and_surname": "Kenny Jobs"
},
{
"time": [
"12:07",
"12:08",
"12:17",
"12:19",
"12:45",
"13:25"
],
"nick": "Wonski",
"name_and_surname": "Mathew Oxford"
}
]
you can use GraphQLList along with GraphQLString for time type like this,
const memberType = new GraphQLObjectType({
name: "Member",
fields: () => ({
nick: {
type: GraphQLString
},
name_and_surname: {
type: GraphQLString
},
time: {
type: new GraphQLList(GraphQLString)
}
})
});

aurelia bridge kendo grid refresh

I'm trying to use Aurelia KendoUi Bridge in my application.
In my code I have a service which returns a new KendoDataSource :
export class KendoDataSource {
ToKendoDataSource(data: any, recordCount: number, pageSize: number, currentPage: number): any {
return {
transport: {
read: (p) => {
p.success({ data: data, recordCount: recordCount });
}
},
pageSize: pageSize,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
schema: {
data: (result) => {
console.log('Transforming data to kendo datasource.');
return result.data;
},
total: (result) => {
return result.recordCount;
}
}
};
}
}
And this is my viewModel:
#inject(HttpService, KendoDataSource, EventAggregator)
export class GroupList {
grid: any;
gridVM: any;
datasource: any;
pageable: any;
subscriber: any;
paginationDetailsRequest: PaginationDetailsRequest;
test: string;
constructor(private httpService: HttpService, private kendoDataSource: KendoDataSource, private eventAggregator: EventAggregator) {
this.httpService = httpService;
this.kendoDataSource = kendoDataSource;
this.eventAggregator = eventAggregator;
this.paginationDetailsRequest = new PaginationDetailsRequest(4, 1);
this.GetGroups(this.paginationDetailsRequest);
this.datasource = {
transport: {
read: {
url: 'PersonGroup/GetGroups',
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: 'json'
},
parameterMap: function (data, type) {
if (type == "read") {
let paginationDetails = new PaginationDetailsRequest(data.pageSize, data.page);
if(data.sort && data.sort.length > 0){
paginationDetails.orderBy = data.sort[0].field;
paginationDetails.OrderDesc = (data.sort[0].dir == 'desc');
}
console.log(this.datasource);
return JSON.stringify(paginationDetails);
}
}
},
schema: {
data: "data.currentPageData",
total: "data.totalCount"
},
pageSize: 2,
serverPaging: true,
serverFiltering: true,
serverSorting: true
};
};
attached() {
this.subscriber = this.eventAggregator.subscribe('Search', response => {
this.search(response);
});
}
activate() {
this.pageable = {
refresh: true,
pageSizes: true,
buttonCount: 10
};
}
GetGroups(paginationDetails: PaginationDetailsRequest): void {
this.httpService.post('PersonGroup/GetGroups', paginationDetails)
.then(response => response.json())
.then(groups => {
console.log(groups);
if (groups.succeeded) {
this.datasource = this.kendoDataSource.ToKendoDataSource(groups.data.currentPageData, groups.totalCount, groups.pageSize, groups.currentPage);
this.grid.setDataSource(this.datasource); // initialize the grid
}
else {
//TODO: Show error messages on screen
console.log(groups.errors);
}
})
.catch(error => {
//TODO: Show error message on screen.
console.log(error);
});
}
search(searchDetails: Filter) {
console.log(searchDetails);
this.paginationDetailsRequest.filters.push(searchDetails);
console.log(this.paginationDetailsRequest);
this.GetGroups(this.paginationDetailsRequest);
}
detached() {
this.subscriber.dispose();
}
}
I understand that kendo does not have two-way data binding, But I'm trying to find a way to refresh the grid when I filter the data and the data source has changed.
Thanks.
I had this problem and found the solution by creating a new dataSource and assigning it to setDataSource, as follows... Note, getClients() is a search activated by a button click.
Here is the grid:
<ak-grid k-data-source.bind="datasource"
k-pageable.bind="{ input: true, numeric: false}"
k-filterable.bind="true"
k-sortable.bind="true"
k-scrollable.bind="true"
k-widget.bind="clientgrid"
k-selectable.bind="true">
<ak-col k-title="First Name" k-field="firstName" k-width="120px"></ak-col>
<ak-col k-title="Last Name" k-field="lastName" k-width="120px"></ak-col>
<ak-col k-title="Email Address" k-field="primaryEmail" k-width="230px"></ak-col>
</ak-grid>
And here is the code that updates the dataSource
public getClients()
{
console.log("ClientService.getClients");
this.clientService.getClients()
.then(result =>
{
this.clientList = result;
// the new datasource in the next line is displayed
// after the call to setDataSource(ds) below.
let ds: kendo.data.DataSource = new kendo.data.DataSource({
data: this.clientList,
schema: {
model: {
id: "id",
fields: {
firstName: { type: 'string' },
id: { type: 'number' },
lastName: { type: 'string' },
primaryEmail: { type: 'string' }
}
}
},
pageSize: 10
});
this.clientgrid.setDataSource(ds);
this.clientgrid.refresh();
})
.catch(err => console.log("Error returned from getClients " + err));
}
You don't really need to create a brand new datasource. To refresh the grid after changing the underlying data you can just replace the data element in the dataSource like so:
this.clientgrid.dataSource.data(this.datasource.data);

Web API Odata not returning correct metadata

I'm using OData v4 with Web API to communicate with my AngularJS web application.
More specifically I'm trying to display my data using Kendo UI Grid.
My problem is, that my Web API does not return the correct metadata, resulting in Kendos datasource not being able to display the data.
I'm doing paging, and to do that I need the "count" property in my response for Kendo UI Grid datasource to be able work properly.
The response I'm expecting the Web API should look something like this:
http://docs.oasis-open.org/odata/odata-json-format/v4.0/errata02/os/odata-json-format-v4.0-errata02-os-complete.html#_Toc403940644
However, the result I'm seeing in the response is:
{
"#odata.context":"http://localhost:1983/odata/$metadata#TestReports","value":[
{
"Id":1,"Name":"Test Testesen","Purpose":"Kendo UI Grid Test","Type":"Rumraket","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":2,"Name":"Gunner Testesen","Purpose":"OData Web API Test","Type":"Sutsko","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":3,"Name":"Bertram Didriksen","Purpose":"Server Paging Test","Type":"Flyver","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":4,"Name":"Oluf Petersen","Purpose":"Test","Type":"B\u00e5d","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
},{
"Id":5,"Name":"Alfred Butler","Purpose":"Opvartning","Type":"Batmobil","ReportedDate":"2015-02-04T10:03:59.4173323+01:00"
}
]
}
My code for retrieving the data is:
$scope.pendingReports = {
dataSource: {
type: "odata",
transport: {
read: {
beforeSend: function (req) {
req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
},
url: "/odata/TestReports",
dataType: "odata"
},
parameterMap: function (options, type) {
var paramMap = kendo.data.transports.odata.parameterMap(options);
console.log(paramMap);
delete paramMap.$inlinecount; // <-- remove inlinecount parameter
delete paramMap.$format; // <-- remove format parameter
console.log(paramMap);
return paramMap;
}
},
schema: {
data: function (data) {
return data; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data.length; // <-- The total items count is the data length, there is no .Count to unpack.
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "Name",
title: "Navn"
}, {
field: "ReportedDate",
title: "Indberetet den"
}, {
field: "Purpose",
title: "Formål"
}, {
field: "Type",
title: "Type"
}, {
field: "options",
title: "Muligheder"
}
]
};
My WebApiConfig class is corrently like this:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create());
config.MapODataServiceRoute(
routeName: "odata",
routePrefix: "odata",
model: GetModel()
);
}
public static Microsoft.OData.Edm.IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<TestReport>("TestReports");
return builder.GetEdmModel();
}
}
Does anyone have any suggestions on how I get the Web API to return the correct metadata?
Apparently Kendo UI Grid is not supporting OData v4.
The fix was to modify the parameterMap of the Kendo datasource, and tell it to use $count instead of $inlinecount.
Besides that I had to tell the schema to read "#odata.count" as the "total" value.
After I edited the before posted code to the ode below, I got the correct data in my response:
$scope.pendingReports = {
dataSource: {
type: "odata",
transport: {
read: {
beforeSend: function (req) {
req.setRequestHeader('Accept', 'application/json;odata=fullmetadata');
},
url: "/odata/TestReports",
dataType: "json"
},
parameterMap: function (options, type) {
var d = kendo.data.transports.odata.parameterMap(options);
delete d.$inlinecount; // <-- remove inlinecount parameter
d.$count = true;
return d;
}
},
schema: {
data: function (data) {
return data.value; // <-- The result is just the data, it doesn't need to be unpacked.
},
total: function (data) {
return data['#odata.count']; // <-- The total items count is the data length, there is no .Count to unpack.
}
},
pageSize: 5,
serverPaging: true,
serverSorting: true
},
sortable: true,
pageable: true,
dataBound: function () {
this.expandRow(this.tbody.find("tr.k-master-row").first());
},
columns: [
{
field: "Name",
title: "Navn"
}, {
field: "ReportedDate",
title: "Indberetet den"
}, {
field: "Purpose",
title: "Formål"
}, {
field: "Type",
title: "Type"
}, {
field: "options",
title: "Muligheder"
}
]
};