Accessing nested json in ExpandRow of bootstrap table react component - javascript

I have a bootsrap table react component and I will like to add the nested json record as a table when each row in the bootstrap table, the row should expand and show the nested json has a table. However, I can not access the nested json in the expand row function.
My Goal: Presently I have a table showing the data of the outer json in a table. However, I want the elements in the the nested json summary to be represented in a table when each row is clicked.
const userList = [
{ id: 1, firstName: "james", lastName: "smith", age: 20,summary:{city:'lag', min:12} },
{ id: 2, firstName: "alex", lastName: "green", age: 20 , summary:{city:'lao', min:121}},
{ id: 3, firstName: "may", lastName: "jones", age: 18, summary:{city:'dag', min:112} }
];
columns=[
{text:'id',dataField:id},
{text:'firstName',dataField:id firstName},
{text:'lastName',dataField: lastName}
]
const expandRow = {
renderer: row => (
<BoostrapTable data={userList} columns={row.columns.summary}/>
)
};
<BoostrapTable data={userList} columns={columns} keyField="id expandRow={ExpandRow}/>

You are using the wrong variable, it's not rows, but row:
const expandRow = {
renderer: row => (
<BoostrapTable data={[row.summary]} columns={{text:'city',dataField:'city'},
{text:'min',dataField:'min'}}/>
)
};

Related

Looping ant design tag color in React Js

I use Ant Design and data which coming from API. I assume the data like this
data = [
{
name: "John",
job: "Freelancer",
},
{
name: 'Bob',
job: 'UI Designer'
},
{
name: 'Sam',
job: 'CEO'
},
{
name: 'Alex',
job: 'Mobile Dev'
},
{
name: 'Jess',
job: 'Web Dev'
},
];
I want to return the job with Tag from Ant Design which the tag has a different color
<Tag color="green">green</Tag>
<Tag color="cyan">cyan</Tag>
I have looped the data. but I don't know how to make the data have a different color tag
data.map((el) => {
//This example doesn't have color
return <Tag>{el.job}</Tag>
})
How to achieve that ? And sorry i'm not good enough in English. I hope you understand what i mean
Or you can visit code sandbox here
In your data, add a property something like tagColor for each object.
data = [
{
name: "John",
job: "Freelancer",
tagColor: "red"
},
{
name: 'Bob',
job: 'UI Designer'
tagColor: "green"
},
{
name: 'Sam',
job: 'CEO'
tagColor: "blue"
},
];
Then in the loop, use that property to dynamically add colors. Like,
data.map((el) => {
return <Tag color={el.tagColor}>{el.job}</Tag>
});
Updated
If the colors can be random, you can place all your colors in an array. And you can pick colors one by one using index or even a randomiser. Something like,
const colors = ["red", "blue", "green"];
data.map((el, i) => {
return <Tag color={colors[(i%colors.length)]}>{el.job}</Tag>
});
It will pick colors in the array one by one based on index.

insertAdjacentHTML not working with created element

I want to display a table after an h1 with an id of pageHeading.
The HTML for the h1 is hardcoded: <h1 id="pageHeading">Table</h1>
const pageHeading = document.querySelector("#pageHeading")
The table is created with Javascript:
const table = document.createElement("table")
table.setAttribute("id", "table")
I tried the following:
document.body.appendChild(table)
This prints the table but after the last HTML element on the page.
Then I tried:
tableHeading.appendChild(table)
This prints the table but INSIDE the h1.
Finally, I tried:
pageHeading.insertAdjacentHTML(
"afterend",
table
)
This doesn't print the table at all. Instead I get (after the h1):
[object HTMLTableElement]
Could this be because I'm using .insertAdjacentHTML on the table contents (see full code below)?
const tableHeaders = [{
titleOne: "Name",
titleTwo: "Age",
titleThree: "Nationality",
}, ]
const persons = [{
name: "James",
age: "23",
nationality: "English",
},
{
name: "Isabella",
age: "21",
nationality: "Italian",
},
{
name: "Hank",
age: "25",
nationality: "American",
},
{
name: "Manon",
age: "27",
nationality: "French",
},
]
const pageHeading = document.querySelector("#pageHeading")
const table = document.createElement("table")
table.setAttribute("id", "table")
/* document.body.appendChild(table) this puts table AFTER the last item in the body <h2>Test</h2> */
/* tableHeading.appendChild(table) this puts table INSIDE <h1 id="tableHeading">Table</h1> */
pageHeading.insertAdjacentHTML(
"afterend",
table
) /* this returns: [object HTMLTableElement] */
const headers = tableHeaders.map(header => {
let ths = `<tr><th>${header.titleOne}</th><th>${header.titleTwo}</th><th>${header.titleThree}</th></tr>`
table.insertAdjacentHTML("afterbegin", ths)
})
const personDetails = persons.map(person => {
let tds = `<tr><td>${person.name}</td><td>${person.age}</td><td>${person.nationality}</td></tr>`
table.insertAdjacentHTML("beforeEnd", tds)
})
<h1 id="pageHeading">Table</h1>
<h2>Test</h2>
Instead of use insertAdjacentHTML you need insertAdjacentElement because is a element not an html string like:
const tableHeaders = [{
titleOne: "Name",
titleTwo: "Age",
titleThree: "Nationality",
}, ]
const persons = [{
name: "James",
age: "23",
nationality: "English",
},
{
name: "Isabella",
age: "21",
nationality: "Italian",
},
{
name: "Hank",
age: "25",
nationality: "American",
},
{
name: "Manon",
age: "27",
nationality: "French",
},
]
const pageHeading = document.querySelector("#pageHeading")
const table = document.createElement("table")
table.setAttribute("id", "table")
/* document.body.appendChild(table) this puts table AFTER the last item in the body <h2>Test</h2> */
/* tableHeading.appendChild(table) this puts table INSIDE <h1 id="tableHeading">Table</h1> */
pageHeading.insertAdjacentElement(
"afterend",
table
) /* this returns: [object HTMLTableElement] */
const headers = tableHeaders.map(header => {
let ths = `<tr><th>${header.titleOne}</th><th>${header.titleTwo}</th><th>${header.titleThree}</th></tr>`
table.insertAdjacentHTML("afterbegin", ths)
})
const personDetails = persons.map(person => {
let tds = `<tr><td>${person.name}</td><td>${person.age}</td><td>${person.nationality}</td></tr>`
table.insertAdjacentHTML("beforeEnd", tds)
})
<h1 id="pageHeading">Table</h1>
<h2>Test</h2>
Reference:
insertAdjacentHTML
insertAdjacentElement

How to pass a sectionlist sectionHeader's index to the reducer?

Looking to map items with index using SectionList, I was successfully able to map the index of the sections and pass the state to the reducer, however, the section header has a different index and would like to do the same with it. Help me up with some examples if possible. This is something that I am developing for a food tech app which and I want to implement the Cart Functionality in the App.
SectionList:
<SectionList
sections={this.props.user.dailyMenuData.item.map(
({category, data}, index2) => ({category, data, index2}),
)}
keyExtractor={this.keyExtractor}
renderItem={this.renderMenu}
renderSectionHeader={({section: {category, index2}}) => (
<CText style={styles.headerStyle}>{category}</CText>
)}
/>
The above data is coming from MongoDB like below:
DATA = {
vendor_id: XXXXXX (For Mapping Vendor to the Menu)
company_id: XXXXX (For Mapping the Customer to the Menu)
item: [
{
category: 'A La Carte',
data: [
{
src:
'https://cdn.pixabay.com/photo/2017/08/01/14/22/fruits-2565817_960_720.jpg',
name: 'Coffee with Pancakes',
price: '160',
rating: 3.8,
calorie: '130',
},
}],
},
The AddtoCart Reducer is dynamically getting the value of the index of data[] however it is not able to get the index of item[] from the API called. The reducer code is given below:
case ADDTOCART:
return update(state, {
dailyMenuData: {
item: {
1: {
data: {
[payload.index]: {
quantity: {
$set:
state.dailyMenuData.item[1].data[payload.index].quantity +
1,
},
},
},
},
},
},
})

Tabulator 4.2 - How do I get the table object from the div element id

In the examples in the documentation, I'm told I can use
table.selectRow(1);
to select row with data.id = 1 in the table.
But what if I don't know what the table object is - how do I access the table object from the containing div?, i.e.
$('#divMyTabulatorDiv).someMethod().someOtherMethod().table
What are the methods/properties I need to use to access the table component for the Tabulator grid from the HTML element's id?
You can lookup a table using the findTable function on the Tabulator prototype, passing in either a query selector or DOM node for the table:
var table = Tabulator.prototype.findTable("#example-table")[0]; // find table object for table with id of example-table
The findTable function will return an array of matching tables. If no match is found it will return false
Full details can be found in the Tabulator Options Documentation
table is the object you create, its pure Javascript driven no Html selection needed
const tabledata1 = [{
id: 1,
name: "Oli ",
money: "0",
col: "red",
dob: ""
},
{
id: 2,
name: "Mary ",
money: "0",
col: "blue",
dob: "14/05/1982"
},
{
id: 3,
name: "Christine ",
money: "0",
col: "green",
dob: "22/05/1982"
},
{
id: 4,
name: "Brendon ",
money: "0",
col: "orange",
dob: "01/08/1980"
},
{
id: 5,
name: "Margret ",
money: "0",
col: "yellow",
dob: "31/01/1999"
},
];
const col1 = [ //Define Table Columns
{
title: "Name",
field: "name",
width: 150
},
{
title: "money",
field: "money",
align: "left",
formatter: "money"
},
{
title: "Favourite Color",
field: "col"
},
{
title: "Date Of Birth",
field: "dob",
sorter: "date",
align: "center"
},
];
const table = new Tabulator("#example-table", {
data: tabledata1, //assign data to table
layout: "fitColumns", //fit columns to width of table (optional)
columns: col1,
selectable: true,
});
$('#selectRow').click(function() {
table.selectRow(1);
});
<!DOCTYPE html>
<html lang="en">
<script src="https://unpkg.com/tabulator-tables#4.2.4/dist/js/tabulator.min.js"></script>
<link href="https://unpkg.com/tabulator-tables#4.2.4/dist/css/tabulator.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div id="example-table"></div>
<button id="selectRow">Select Row 1</button>
</body>
</html>
You can use Tabulator.prototype.findTable(querySelector) (I don't know what version this was added in, but it exists in 4.5 and 4.6) to get an array of tablulators that match the querySelector.
querySelector is any valid string for document.querySelectorAll.
https://jsfiddle.net/s60qL1hw/2/
const myTable = new Tabulator("#example-table1");
const findTable = Tabulator.prototype.findTable("#example-table1");
alert('Tables are the same?\n' + (myTable === findTable[0])); // true
Once you have the table object in the variable, you can use it as the document shows.
As of v5, tabulator has a more direct way to get the table object using css selector.
If your tabulator div was like:
<div id="tabulator1"></div>
then you can get the tabulator obj into a variable by:
let table = Tabulator.findTable("#tabulator1")[0];
after this i'm able to fetch data, do changes etc:
let data = table.getData();
Ref: http://tabulator.info/docs/5.0/options#find-table

Make a Tree view from JSON data using React JS

First of all i am very new to React JS. So that i am writing this question. I am trying this for three days.
What I have to do, make a list of category, like-
Category1
->Sub-Category1
->Sub-Category2
Categroy2
Category3
.
.
.
CategoryN
And I have this json data to make the listing
[
{
Id: 1,
Name: "Category1",
ParentId: 0,
},
{
Id: 5,
Name: "Sub-Category1",
ParentId: 1,
},
{
Id: 23,
Name: "Sub-Category2",
ParentId: 1,
},
{
Id: 50,
Name: "Category2",
ParentId: 0,
},
{
Id: 54,
Name: "Category3",
ParentId: 0,
},
];
I have tried many open source examples, but their json data format is not like mine. so that that are not useful for me. I have build something but that is not like my expected result. Here is my jsfiddle link what i have done.
https://jsfiddle.net/mrahman_cse/6wwan1fn/
Note: Every subcategory will goes under a category depend on "ParentId",If any one have "ParentId":0 then, it is actually a category, not subcategory. please see the JSON
Thanks in advance.
You can use this code jsfiddle
This example allows to add new nested categories, and do nested searching.
code with comments:
var SearchExample = React.createClass({
getInitialState: function() {
return {
searchString: ''
};
},
handleChange: function(e) {
this.setState({
searchString: e.target.value.trim().toLowerCase()
});
},
isMatch(e,searchString){
return e.Name.toLowerCase().match(searchString)
},
nestingSerch(e,searchString){
//recursive searching nesting
return this.isMatch(e,searchString) || (e.subcats.length && e.subcats.some(e=>this.nestingSerch(e,searchString)));
},
renderCat(cat){
//recursive rendering
return (
<li key={cat.Id}> {cat.Name}
{(cat.subcats && cat.subcats.length) ? <ul>{cat.subcats.map(this.renderCat)}</ul>:""}
</li>);
},
render() {
let {items} = this.props;
let {searchString} = this.state;
//filtering cattegories
if (searchString.length) {
items = items.filter(e=>this.nestingSerch(e,searchString))
console.log(items);
};
//nesting, adding to cattegories their subcatigories
items.forEach(e=>e.subcats=items.filter(el=>el.ParentId==e.Id));
//filter root categories
items=items.filter(e=>e.ParentId==0);
//filter root categories
return (
<div>
<input onChange={this.handleChange} placeholder="Type here" type="text" value={this.state.searchString}/>
<ul>{items.map(this.renderCat)}</ul>
</div>
);
}
});

Categories