ag-grid react table not displaying? - reactjs

New to react and ag-grid. I'm trying to implement a trivial example of ag-grid in my react project. When I run the project, the grid doesn't display. No console warnings, just the grid doesn't display.
import React from 'react';
import {AgGridReact} from 'ag-grid-react';
import '../../node_modules/ag-grid/dist/styles/ag-grid.css';
import '../../node_modules/ag-grid/dist/styles/theme-material.css';
var headers = [{headerName: 'Name', field: 'name', width: 150, filter: 'text'},
{headerName: 'Last', field: 'last', width: 150, filter: 'text'}]
var data = [{name: 'bob', last:'dude'},
{name: 'will', last:'willdude'}]
export default class Accounts extends React.Component {
constructor() {
super();
this.state = {
showGrid: true,
columnDefs: headers,
rowData: data,
};
}
onGridReady(params) {
this.api = params.api;
this.columnApi = params.columnApi;
}
render() {
var gridTemplate;
gridTemplate = (
<div className="ag-material">
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
onGridReady={this.onGridReady.bind(this)}
showGrid={this.state.showGrid}
/>
</div>
);
return (
<div style={{width: '800px'}}>
<p>I see this</p>
{gridTemplate}
</div>
)
}
}

Okay got it, we need height on the parent div.
e.g.
<div className="ag-material" style={{height: '500px'}}>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
onGridReady={this.onGridReady.bind(this)}
showGrid={this.state.showGrid}
/>
</div>

its always better to give height and width otherwise ag-grid table will render by adjusting it to fit min content.
<div className="ag-material" style={{height: 500, width: 500}}>
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
onGridReady={this.onGridReady.bind(this)}
showGrid={this.state.showGrid}
/>
</div>

I was seeing a similar issue when the grid was not rendering. Adding the grid styles fixed the problem for me.
import '../../node_modules/ag-grid/dist/styles/ag-grid.css';
import '../../node_modules/ag-grid/dist/styles/theme-material.css';

Related

How to update props in Ag Grid status bar custom component

I am working on a basic Ag Grid React application, and I added a custom status bar component to the grid, using their docs. My goal is to update the "total rows" item in the status bar when a filter is applied to the grid, however I cannot get the value in the status bar to change. The status bar component uses a state variable inherited from the Grid as a prop, but when the prop changes, the status bar does not re-render to reflect that.
Here's a demo that shows that even when the prop passed to the status bar component changes, nothing happens. You can test this by clicking the button and the console will show the "total" variable incrementing, yet the status bar remains unchanged.
Relevant code snippet:
import React, { useState } from 'react';
import { render } from 'react-dom';
import { AgGridColumn, AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
import 'ag-grid-enterprise';
const CustomStatusBar = props => {
return (
<div className="ag-status-bar-center">
<div className="ag-status-name-value ag-status-panel ag-status-panel-total-row-count">
<span className="label">Total Rows</span>:
<span className="ag-status-name-value-value">{props.total}</span>
</div>
</div>
);
};
const App = () => {
const rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
const [total, setTotal] = useState(3);
return (
<div className="ag-theme-alpine" style={{ height: 400, width: 600 }}>
<AgGridReact
rowData={rowData}
frameworkComponents={{
customStatusBar: CustomStatusBar
}}
statusBar={{
statusPanels: [
{
statusPanel: 'customStatusBar',
align: 'center',
statusPanelParams: { total: total }
}
]
}}
>
<AgGridColumn field="make" />
<AgGridColumn field="model" />
<AgGridColumn field="price" />
</AgGridReact>
<button
onClick={() => {
setTotal(prevTotal => {
console.log(prevTotal);
return prevTotal + 1;
});
}}
>
Click me
</button>
</div>
);
};
render(<App />, document.getElementById('root'));
Instead of passing total inside the statusPanelParams. I'd recommend defining a getter/setter helper method on the Custom Status Bar, and pass in the total value when needed so that you can update it.
You can get the Status Bar Instance like this:
// example - get status bar component
const statusBarComponent = gridOptions.api.getStatusPanel('statusBarCompKey');
if (statusBarComponent) {
componentInstance = statusBarComponent.getFrameworkComponentInstance();
}
And if you define a method e.g. updateTotal on the status bar, you can call it like this:
componentInstance.updateTotal(total)
See this example for more information: https://www.ag-grid.com/react-data-grid/component-status-bar/#accessing-status-bar-panel-instances

React + Ag-grid + Webpack

I am using ag-grid with react. And i am unable to display grid properly,
please find below my code,
import React, {Component} from 'react'
import {render} from 'react-dom'
import {AgGridReact} from 'ag-grid-react'
import Logo from './components/Logo/'
import Link from './components/Link/'
import Child from './child.jsx'
export default class App extends Component {
constructor(props){
super(props);
this.state = {
columnDefs: [
{headerName: "Name", field: "Name"},
{headerName: "Age", field: "Age"}
],
rowData: [
{"Name": "Man", "Age":"25"},
{"Name": "Pal", "Age":"27"}
]
}
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
render() {
return (
<div>
<p className="f5p"><img className="f5logo" src="./src/assets/index.png" alt="F5 Logo"></img></p>
<h2 className="f5h1">CTU Log Viewer</h2>
<ul className="f5ul">
<li className="f5li">Logs</li>
<li className="f5li">Command Logs</li>
<li className="f5li">Installed Packages</li>
<li className="f5liabout">About</li>
</ul>
<div className="ag-fresh">
<AgGridReact
columnDefs = {this.state.columnDefs}
rowData = {this.state.rowData}
onGridReady = {this.onGridReady}
/>
</div>
</div>
)
}
}
I am also using webpack, and not sure if webpack causing the issue.
I am using babel, css-loader modules in webpack.
The grid rows are not coming properly, data is displayed in vertical manner.
I am unable to understand what is the issue.
Any help is much appreciated.
Thanks in advance.

Embed Typeform in React app

How can I embed a Typeform form in my React app?
The embed code that Typeform provide doesn't compile in JSX.
This is a sample of the embed code:
<div class="typeform-widget" data-url="https://sample.typeform.com/to/32423" style="width: 100%; height: 500px;"></div> <script> (function() { var qs,js,q,s,d=document, gi=d.getElementById, ce=d.createElement, gt=d.getElementsByTagName, id="typef_orm", b="https://embed.typeform.com/"; if(!gi.call(d,id)) { js=ce.call(d,"script"); js.id=id; js.src=b+"embed.js"; q=gt.call(d,"script")[0]; q.parentNode.insertBefore(js,q) } })() </script> <div style="font-family: Sans-Serif;font-size: 12px;color: #999;opacity: 0.5; padding-top: 5px;"> powered by Typeform </div>
You can use a React wrapper component I created: https://github.com/alexgarces/react-typeform-embed
It uses the official Typeform Embed SDK under the hood. Basically you have to pass your form url, but it also supports other SDK options.
import React from 'react';
import { ReactTypeformEmbed } from 'react-typeform-embed';
class App extends React.Component {
render() {
return <ReactTypeformEmbed url="https://demo.typeform.com/to/njdbt5" />;
}
}
You can view Typeform documentation for embedding with JavaScript here.
And their official npm module here.
Use React refs to trigger initialisation similarly to how you would initialise a jQuery plugin for instance.
import React from 'react';
import * as typeformEmbed from '#typeform/embed'
class Form extends React.Component {
constructor(props) {
super(props);
this.el = null;
}
componentDidMount() {
if (this.el) {
typeformEmbed.makeWidget(this.el, "https://sample.typeform.com/to/32423", {
hideFooter: true,
hideHeaders: true,
opacity: 0
});
}
}
render() {
return (
<div ref={(el) => this.el = el} style={{width: '100%', height: '300px'}} />
)
}
}
export default Form;
Inspired by Elise Chant's solution and using function based components, hooks and Typescript, this is what I come up with for my project. I did not want to install another thin wrapper on top of the official SDK.
import * as typeformEmbed from '#typeform/embed';
import React, { useEffect, useRef } from 'react';
interface EmbeddedTypeformProps {
link: string;
hideFooter?: boolean;
hideHeaders?: boolean;
opacity?: number;
}
export const EmbeddedTypeform: React.FunctionComponent<EmbeddedTypeformProps> = ({
link,
hideFooter = true,
hideHeaders = true,
opacity = 90,
}) => {
const elementRef = useRef(null);
useEffect(() => {
typeformEmbed.makeWidget(elementRef.current, link, {
hideFooter,
hideHeaders,
opacity,
});
}, [link]);
return (
<div
ref={elementRef}
style={{ width: '100%', height: '100%', flex: '1 1 auto' }}
/>
);
};
If you are using Typescript with react and you got this error just make sure that noImplicitAny set to false in tsconfig file :
"noImplicitAny": false,

How to make owl-carousel responsive in React?

I am using react-owl-carousel package.
https://www.npmjs.com/package/react-owl-carousel
I have successfully implemented the code as instructed and the carousel is running smoothly.
Problem : Currently I am displaying 4 items simultaneously. And in every screen , these 4 items are coming . Instead of 4 , I want to show 3 items for devices between 768px to 1200px , 2 items between 500px to 767px and 1 item for the devices below 499px.
The option of including "responsive" is there in owl carousel doc. But I am wondering How to include it to achieve the same.
Here is what I have done so far.
import React, { Component } from 'react';
import {Grid, Row, Col , ProgressBar } from 'react-bootstrap';
import UserAvtar from '../common/UserAvtar.js';
import SectionHeaderOfCards from '../common/SectionHeaderOfCards.js';
import OwlCarousel from 'react-owl-carousel';
const options = {
items: 4,
};
class DashboardPage extends Component {
render() {
return (
<div>
<section className="has-small__padding has-grey__bg">
<UserAvtar />
</section>
<section className="has-small__padding">
<Grid>
<SectionHeaderOfCards title="Recommended Matches" />
<OwlCarousel margin={10} >
<div class="item"><h4>1</h4></div>
<div class="item"><h4>2</h4></div>
<div class="item"><h4>3</h4></div>
<div class="item"><h4>4</h4></div>
<div class="item"><h4>5</h4></div>
<div class="item"><h4>6</h4></div>
</OwlCarousel>
</Grid>
</section>
</div>
);
}
}
export default DashboardPage;
You have to use OwlCarousel Options responsive.
Please check official documentation of owlcarousel2 API options to here.
For example use following options for your items state.
options:{
loop: true,
margin:10,
nav:true,
responsive:{
0:{
items:1
},
600:{
items:3
},
1000:{
items:5
}
}
},
Please check demo example to here.
Hope this will help you.
You can follow -
import OwlCarousel from 'react-owl-carousel';
import 'owl.carousel/dist/assets/owl.carousel.css';
const options = {
margin: 30,
responsiveClass: true,
nav: true,
dots: false,
autoplay: false,
navText: ["Prev", "Next"],
smartSpeed: 1000,
responsive: {
0: {
items: 1,
},
400: {
items: 1,
},
600: {
items: 2,
},
700: {
items: 3,
},
1000: {
items: 5,
}
},
};
class Slider extends Component {
render() {
return (
<div>
<OwlCarousel className="slider-items owl-carousel" {...options}>
...
</OwlCarousel>
</div>
);
}
}
export default Slider;
You can make owl-carousel responsive in React like this explained bellow:
Step 1: you need to create state in same component where you want owl-carousel....
Like you have slider.js component so you have to create state in same file ..Like this;
Step 2: And the state you created initialize in responsive property in owl-carousel
import OwlCarousel from 'react-owl-carousel';
import $ from 'jquery';
import 'owl.carousel/dist/assets/owl.carousel.css';
import 'owl.carousel/dist/assets/owl.theme.default.css';
class Slider extends Component {
state= {
responsive:{
0: {
items: 1,
},
450: {
items: 2,
},
600: {
items: 3,
},
1000: {
items: 4,
},
},
}
render() {
return (<OwlCarousel className={'owl-theme'}
loop={true}
margin={10}
nav={true}
dots={false}
autoplay={true}
autoplayTimeout={2000}
items={4}
responsive={this.state.responsive} >
<div className={'item'}>
Item 1
</div>
<div className={'item'}>
Item 2
</div>
<div className={'item'}>
Item 3
</div>
<div className={'item'}>
Item 4
</div>
<div className={'item'}>
Item 5
</div>
</OwlCarousel>
I was getting a type error in typescript, here is the version without type error :
<OwlCarousel
mouseDrag= {false} touchDrag={true}
stagePadding={0} margin={0} autoplay ={true} merge={true} nav dots={true} slideBy={2} dotsEach={1} loop={true}
responsive= {
{
'1':{
items: 1
},
'1025': {
items: 2
}
}
}
>
{reviews}
</OwlCarousel>
hope it helps : )

ag-grid-react does not render properly

Following the sample from the docs:
https://www.ag-grid.com/best-react-data-grid/index.php
After creating new react app (have tried several times on different machines)
create-react-app whatever
If I apply the stylesheets (ag-grid.css & theme-fresh.css) all that is rendered is a gray line across the page. Any other combination renders a blank page. Removing ag-grid.css renders the grid but its jumbled all over the place.
Has anyone used this lately successfully with React? Does anyone recommend something different? (requirements: paging, sorting, filtering, selectable row(s))
thanks :-)
import React, { Component } from 'react';
import {AgGridReact} from 'ag-grid-react';
import '../node_modules/ag-grid/dist/styles/ag-grid.css';
import '../node_modules/ag-grid/dist/styles/theme-fresh.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [
{headerName: 'First Name', field: 'name' },
{headerName: 'Last Name', field: 'lname' }
],
rowData: [
{ name: 'Dave', lname: 'Smith' },
{ name: 'Tommy', lname: 'Smith' },
{ name: 'Lea', lname: 'Jones' }
]
}
}
render() {
return (
<div className="ag-fresh">
<AgGridReact
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
rowSelection="multiple"
enableColResize="true"
enableSorting="true"
enableFilter="true"
groupHeaders="true"
rowHeight="22"
debug="true"
/>
</div>
);
}
}
export default App;
The outer grid required a height :-(
The documentation does not show this. Not sure why there is no min default height for the grid, but there is not.
So essentially you need something like this, where the grid is wrapped with an element which has a height:
<div className="ag-fresh">
<div className="grid_height_fix">
<AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.data.gridDate} >
</AgGridReact>
</div>
</div>
.grid_height_fix {height:800px;}
The new and better way to do this :
const GridExample = () => {
// I use 100% because I set the height of the higher element manually, you can set something like 500px for the height here instead, or calculate it based on the screen size
const containerStyle = useMemo(() => ({ width: '100%', height: '100%' }), []);
const gridStyle = useMemo(() => ({ height: '100%', width: '100%' }), []);
return (
<div style={containerStyle}>
<div style={gridStyle} className="ag-theme-alpine">
<AgGridReact
...
></AgGridReact>
</div>
</div>
);
};
this way you have better controle over the dimensions.

Resources