I'm attempting to implement local JSON data into a Tabulator table. I specifically want to display the obj.File.Name JSON element.
I can render the data into a regular table, but when I incorporate Tabulator the data doesn't render at all. I think the problem lies with the Tabulator Section that's listed in the JS Snippet, but I'm not 100% sure. I'm interested in using Tabulator because of the features it offers.
Unless I misread it, the Tabulator docs on loading data seems to be less focused on local files and more on external URLs, which is why I've come to ask about it here.
I've included a JS Fiddle that shows the HTML and the JS.
JS snippet:
import $ from 'jquery';
import JSONfile from '../../../public/JSONfile.json';
import { basename } from 'path';
var Tabulator = require('tabulator-tables');
var categories = '';
var tableRes = '';
export default class {
constructor() {
this.loadData();
this.loadTableData();
}
loadTableData() {
let tableRes = JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
// "FileName": obj.FileLeafRef,
"Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name
}
});
///// Tabulator Section /////
let tableData = tableRes;
let table = new Tabulator("#km-table-id", {
data:tableData,
columns:[
{title:"", field:" "},
{title:"All Templates", field:"Name"},
{title:"My Favorites", field:"faves"}
],
pagination:"local",
paginationSize:100,
placeholder:"No data available"
});
table.setData(tableData);
} // ------------------ loadTableData
} // ------------- export default class
JSON snippet:
{
"d": {
"results": [
{
"__metadata": {
...
},
"File": {
"__metadata": {
...
},
"Name": "Guide to Product IDs.docx"
},
"FileLeafRef": "Guide to Product IDs.docx",
"ResourceType": {
...
},
"results": [
{
...
}
]
},
"EncodedAbsUrl": [redacted]
},
...
...
The issue you are having is because the data is not in the format that Tabulator is expecting.
Tabulator requires an array of row data objects, based on your column definitions it is looking for this:
[
{Name:"steve", faves:"this, that, the other"},
{Name:"bob", faves:"this, that, the other"},
]
Loading local data into the table is covered in the Documentation
Related
I have a table column that's populated by documents and in the next column I've rendered what the file extension of that document is (i.e. .docx).
I want to be able to replace the file extension text with icon images that are locally stored (folder/src/SiteAssets/Images/docx.gif).
Would I be able to work with the original code I have:
// -- Generating extension names -- //
function docType(fileName) {
return [fileName].filter(function() {
return true;
}).map(function(fileName) {
return fileName.split('.').pop();
}).pop();
}
to replace the text with the icons? I was thinking of something like if (extension===true), replace with icon.gif. If need be I can get rid of this code and work with something else.
Loading document data:
$.noConflict();
let tableRes = JSONfile.d.results.filter(function(val) {
return (val.FileLeafRef.trim().length > 0);
}).map(function(obj) {
return {
"Path": obj.EncodedAbsUrl,
"Titles": obj.File.Name,
"Categories": obj.ResourceType.results.map(function(val) {
return val.Label;
}).join(";"),
"Blank": "",
"docImg": docType(obj.File.Name) // "Getting the docType of obj.File.Name"
}
})
Rendering table:
$('#km-table-id').DataTable( {
columns: [
// { data: "Blank" },
{ data: "Categories" }, // hidden
{ data: "docImg" },
{ data: "Titles" }
],
...etc
I am looking for help with GatsbyJS and Contentful. The docs aren't quite giving me enough info.
I am looking to programmatically create pages based on contentful data. In this case, the data type is a retail "Store" with a gatsby page at /retail_store_name
The index.js for each store is basically a couple of react components with props passed in e.g. shop name and google place ID.
Add data to contentful. Here is my example data model:
{
"name": "Store"
"displayField": "shopName",
"fields": [
{
"id": "shopName",
"name": "Shop Name",
"type": "Symbol",
"localized": false,
"required": true,
"validations": [
{
"unique": true
}
],
"disabled": false,
"omitted": false
},
{
"id": "placeId",
"name": "Place ID",
"type": "Symbol",
"localized": false,
"required": true,
"validations": [
{
"unique": true
}
],
"disabled": false,
"omitted": false
}
}
I've added the contentful site data to gatsby-config.js
// In gatsby-config.js
plugins: [
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: `your_space_id`,
accessToken: `your_access_token`
},
},
];
Query contentful - I'm not sure where this should happen. I've got a template file that would be the model for each store webpage created from contentful data.
As mentioned this is just some components with props passed in. Example:
import React, { Component } from "react";
export default class IndexPage extends Component {
constructor(props) {
super(props);
this.state = {
placeId: "",
shopName: "",
};
}
render (){
return (
<ComponentExampleOne shopName={this.state.shopName} />
<ComponentExampleTwo placeId={this.state.placeId} />
);
}
I'm really not sure how to go about this. The end goal is auto publishing for non-tech users, who post new stores in Contentful to be updated on the production site.
You can create pages dynamically at build time and to do that you need to add some logic to the gatsby-node.js file. Here is a simple snippet.
const path = require('path')
exports.createPages = ({graphql, boundActionCreators}) => {
const {createPage} = boundActionCreators
return new Promise((resolve, reject) => {
const storeTemplate = path.resolve('src/templates/store.js')
resolve(
graphql(`
{
allContentfulStore (limit:100) {
edges {
node {
id
name
slug
}
}
}
}
`).then((result) => {
if (result.errors) {
reject(result.errors)
}
result.data.allContentfulStore.edges.forEach((edge) => {
createPage ({
path: edge.node.slug,
component: storeTemplate,
context: {
slug: edge.node.slug
}
})
})
return
})
)
})
}
the createPages that was exported is a Gatsby Node API function you can find the complete list in the docs here.
For the query allContentfulStore it's called like that because your contentType name is store the gatsby query will be allContentful{ContentTypeName}.
Finally, I created a youtube video series explaining how you can build a Gatsby website with Contentful. You can find it here
I hope this answer your question.
Cheers,
Khaled
Is it possible to export contents of kendo data grid to multiple sheets of Excel?
Yes, it is possible.
Setup your grid to capture excel export event
MVC:
.Events(e => e.ExcelExport("onExcelExportGrid"))
or javascript
"excelExport": onExcelExportGrid,
This javascript method will allow access to the workbook kendo will use to build excel file. This follows a very simple schema
var workbook = new kendo.ooxml.Workbook({
sheets: [
{
rows: [
{ cells: [ { value: "foo" } ] }
]
}
]
});
To prepend a new sheet, use something like
function excelPrependWorksheet(wb, worksheetName)
{
var sheet = {
"name": worksheetName,
"rows": [
{ "cells": [] }
]
}
wb["sheets"].unshift(sheet);
}
function onExcelExportGrid(e)
{
excelPrependWorksheet(e.workbook, "example");
// fill out row and cells values here.
}
Supported fields for cells, sheets, and workbook are documented at https://github.com/telerik/kendo-ui-core/blob/master/docs/api/javascript/ooxml/workbook.md
I'm new to vue.js and I'm confused about what to do next in the program. I want to add a new view page to collect customer information (see code below). I don't know how to write the function after I click the "confirm" button. I think I should go the DataService.js file to get the data or update the rules.
Here is the url for the project:
https://coding.net/u/benbenshi/p/vue-admin-test/git
// baseConfig.vue
<template>
<div class="system-base">
<el-input type="text">
<template slot="prepend">userInput:</template>
</el-input>
</div>
<div>
<el-button #click="somefunction">confirm</el-button>
</div>
</template>
<script>
import dataservice from '../../services/DataService'
export default {
components: {},
data () {
return {}
},
computed: {},
methods: {
// what should I do here? Should I write some function to handle the confirm event?
},
}
</script>
Right now I've got an api.json file with a structure like this: should I write the function in the dataServices.js file based on the API offered in the api.json file?
//api.json
{
"id": "",
"name": "api",
"description": "",
"order": [],
"folders": [],
"timestamp": 1234567,
"owner": "1234567",
"public": false,
"requests": [
// a lot of request api here.
]
}
Any help will be appreciated!
You can take a reference from the vue-hackernews-2.0 code, You can do whatever action you want to do, and than call this.$router.replace("/your/path") to redirect to desired page. Here is the stripped code from the repo:
methods: {
loadItems (to = this.page, from = -1) {
this.loading = true
this.$store.dispatch('FETCH_LIST_DATA', {
type: this.type
}).then(() => {
this.$router.replace(`/${this.type}/1`)
return
this.loading = false
})
}
I've got a query tool I've been working on, which has an angular form that is filled out, and then when it's submitted it uses AJAX which returns JSON, which is then rendered into ui-grid, that JSON response looks like
{
"success": true,
"message": "",
"columns": ["first_name", "last_name", "company", "employed"]
"results": [
{first_name: "John", last_name: "Smith", company: "Abc Inc", employed: true},
{first_name: "Johnny", last_name: "Rocket", company: "Abc Inc", employed: true}]
}
I'm working on both the PHP and angular so I have full control over this JSON response if need be. I'm running into an issue when my JSON response from a first AJAX call is rendered, and then I run another, seperate AJAX call on the same page and get a new data set: this new data set does not render any of the columns that were not in the original data set. This is hugely problematic as the table is essentially cleared when none of the columns are the same, and I often need to load completely different data into ui-grid in this single page app.
When the JSON is recieved I simply bind the jsonResult.results to the old $scope.myData variable that ui-grid is bound to.
I've made a plunker isolating this issue. A dataset with a "punk" column is loaded, and then clicking "swap data" will try to load a dataset with "employee" column instead of "punk". I've so far looked into directives that will refresh or reload when the $scope.myData variable changes using $watch, and looked at finding something like $scope.columnDefs to let ui-grid know. Relatively new to angular and javascript so directives are still a bit over my head.
I have updated your plunker slightly:
$scope.swapData = function() {
if ($scope.gridOpts.data === data1) {
$scope.gridOpts.columnDefs = [
{ name:'firstName' },
{ name:'lastName' },
{ name:'company' },
{ name:'employee' }
];
$scope.gridOpts.data = data2;
//punk column changes to employee
}
else {
$scope.gridOpts.columnDefs = [
{ name:'firstName' },
{ name:'lastName' },
{ name:'company' },
{ name:'punk' }
];
$scope.gridOpts.data = data1;
//employee column changes to punk
}
};
http://plnkr.co/edit/OFt86knctJxcbtf2MwYI?p=preview
Since you have the columns in your json, it should be fairly easy to do.
One additional piece that I figured out with the help of Kevin Sage's answer and the plunker example... If you are using the backward-compatible "field" attribute the swapping does not work properly when there are field name overlaps between the two sets of column definitions. The column headers and the column widths are not rendered properly in this case. Using the "name" attribute of the column definition corrects this.
$scope.swapData = function() {
if ($scope.gridOpts.data === data1) {
$scope.gridOpts.columnDefs = [
{ field:'firstName' },
{ field:'lastName' },
{ field:'company' },
{ field:'employee' }
];
$scope.gridOpts.data = data2;
//punk column changes to employee
}
else {
$scope.gridOpts.columnDefs = [
{ field:'firstName' },
{ field:'lastName' },
{ field:'company' },
{ field:'punk' }
];
$scope.gridOpts.data = data1;
//employee column changes to punk
}
};
Example here: Plunker
My solution:
$http.get('url').success(function(res) {
// clear data
gridOptions.data.length = 0;
// update data in next digest
$timeout(function() {
gridOptions.data = res;
});
});