HTML Purifier messing up table - htmlpurifier

I'm using HTML Purifier with Laravel and it is messing up tables.
Instead of displaying this:
<table class="table-stripped">
<thead>
<tr>
<th>Test</th>
<th>Max score</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>3</td>
<td>5</td>
</tr>
</tbody>
</table>
HTML Purifier mess up the table above and turn it into this
<table class="table-stripped">
<thead></thead>
<tbody>
<tr>
<th>Test</th>
<th>Max score</th>
</tr>
</tbody>
<tbody></tbody>
<tbody>
<tr>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>3</td>
<td>5</td>
</tr>
</tbody>
</table>
I also tested this using PHP Artisan Tinker. See the picture below
My app/config/purifier.php
<?php
return [
'encoding' => 'UTF-8',
'finalize' => true,
'cachePath' => storage_path('app/purifier'),
'cacheFileMode' => 0755,
'settings' => [
'default' => [
'HTML.Doctype' => 'HTML 4.01 Transitional',
'HTML.Allowed' => 'h2[style|class],h3[style|class],h4[style|class],h5[style|class],h6[style|class],div[class|style],section,b,strong,i[style|class],em,a[href|title|class],ul[style|class],ol[style|class],li[style|class],p[style|class],br,span[style|class],img[width|height|alt|src|class],table[style|class],tbody[style|class],thead[style|class],tr[style|class],th[style|class],td[style|class],button,p,object[type|width|data|height|name|form|usemap|class],embed[src|type|width|height|class],iframe[src|height|width|class|name]',
'CSS.AllowedProperties' => 'text-decoration,padding,color,background-color,text-align,margin,height,width,max-height,max-width',
'AutoFormat.AutoParagraph' => false,
'AutoFormat.RemoveEmpty' => true,
'Attr.EnableID' => 'true',
],
"youtube" => [
"HTML.SafeIframe" => 'true',
"URI.SafeIframeRegexp" => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/)%",
],
'custom_definition' => [
'id' => 'html5-definitions',
'rev' => 1,
'debug' => false,
'elements' => [
// http://developers.whatwg.org/sections.html
['section', 'Block', 'Flow', 'Common'],
['nav', 'Block', 'Flow', 'Common'],
['article', 'Block', 'Flow', 'Common'],
['aside', 'Block', 'Flow', 'Common'],
['header', 'Block', 'Flow', 'Common'],
['footer', 'Block', 'Flow', 'Common'],
['table', 'Block', 'Flow', 'Common'],
// Content model actually excludes several tags, not modelled here
['address', 'Block', 'Flow', 'Common'],
['hgroup', 'Block', 'Required: h2 | h3 | h4 | h5 | h6', 'Common'],
// http://developers.whatwg.org/grouping-content.html
['figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'],
['figcaption', 'Inline', 'Flow', 'Common'],
// http://developers.whatwg.org/the-video-element.html#the-video-element
['video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [
'src' => 'URI',
'type' => 'Text',
'width' => 'Length',
'height' => 'Length',
'poster' => 'URI',
'preload' => 'Enum#auto,metadata,none',
'controls' => 'Bool',
]],
['source', 'Block', 'Flow', 'Common', [
'src' => 'URI',
'type' => 'Text',
]],
['object', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [
'data' => 'URI',
'form' => 'Text',
'name' => 'Text',
'usemap' => 'Text',
'type' => 'Text',
'width' => 'Length',
'height' => 'Length',
]],
['iframe', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [
'src' => 'URI',
'name' => 'Text',
'class' => 'Text',
'usemap' => 'Text',
'width' => 'Length',
'height' => 'Length',
]],
['embed', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', [
'src' => 'URI',
'type' => 'Text',
'width' => 'Length',
'height' => 'Length',
]],
//
['button', 'Inline', 'Flow', 'Common', [
'type' => 'Text',
'aria-label' => 'Text'
]],
// http://developers.whatwg.org/text-level-semantics.html
['s', 'Inline', 'Inline', 'Common'],
['var', 'Inline', 'Inline', 'Common'],
['sub', 'Inline', 'Inline', 'Common'],
['sup', 'Inline', 'Inline', 'Common'],
['mark', 'Inline', 'Inline', 'Common'],
['wbr', 'Inline', 'Empty', 'Core'],
// http://developers.whatwg.org/edits.html
['ins', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']],
['del', 'Block', 'Flow', 'Common', ['cite' => 'URI', 'datetime' => 'CDATA']],
],
'attributes' => [
['iframe', 'allowfullscreen', 'Bool'],
['table', 'height', 'Text'],
['td', 'border', 'Text'],
['th', 'border', 'Text'],
['tr', 'width', 'Text'],
['tr', 'height', 'Text'],
['tr', 'border', 'Text'],
],
],
'custom_attributes' => [
['a', 'target', 'Enum#_blank,_self,_target,_top'],
],
'custom_elements' => [
['u', 'Inline', 'Inline', 'Common'],
],
],
];
How to solve this problem?
I cannot disable Purifier because some users are able to create blog posts in HTML, so I need to display the HTML and Purifier seems to be the best option to disallow scripts and malicious attacks in case some hacker get access to those users' accounts.

Related

HeIp solve Error in React. (Uncaught TypeError: baselineData is not iterable). baselineData is clearly an array. PLEASE heIp

I am running into an issue with trying to render a table in react using react table. I've narrowed the error down to the data variable around line 13 in figure 1.
When I hard code the data, as shown in figure 1, I have no issues and everything works fine. This hard coded array is a direct copy of the baselineData prop being passed into the PrectionsTable component.
My error only happens when the data object is changed to as shown in figure 2. Instead of the data being hard coded, I am spreading the baselineData prop data.
Figure 3 shows baselineData in react web dev tools and is in fact an array of objects located on the PredictionsTable.
The specific error I am making can be seen in figure 4.
Figure 1
import { useTable } from 'react-table';
import React from 'react';
import SpinnerCustom from '../Spinner.js';
export default function PredictionsTable({
predictions,
baselineData,
loading,
}) {
const checkIfValueIsNumberAndRound = (x) =>
typeof x === 'number' ? x.toFixed(2) : 'n/a';
const data = React.useMemo(() => {
return [
{
make_cut: 0.837075,
player_name: 'Finau, Tony',
top_10: 0.42559600288600297,
top_20: 0.5817631080031079,
top_5: 0.293940416666667,
win: 0.105025,
},
{
make_cut: 0.71215,
player_name: 'Day, Jason',
top_10: 0.228348582528583,
top_20: 0.366261590839716,
top_5: 0.136055932539683,
win: 0.0341,
},
{
make_cut: 0.719925,
player_name: 'Harman, Brian',
top_10: 0.223825056748807,
top_20: 0.366779750145688,
top_5: 0.12981958333333302,
win: 0.032675,
},
{
make_cut: 0.710225,
player_name: 'Montgomery, Taylor',
top_10: 0.21918973443223397,
top_20: 0.352992788086097,
top_5: 0.130785406746032,
win: 0.0324,
},
];
}, [baselineData]);
const columns = React.useMemo(
() => [
{
Header: 'Player',
accessor: 'player_name', // accessor is the "key" in the data
},
{
Header: 'Make Cut',
accessor: 'make_cut',
Cell: (props) =>
checkIfValueIsNumberAndRound(props.cell.row.original.make_cut),
},
{
Header: 'Top 20',
accessor: 'top_20',
Cell: (props) =>
checkIfValueIsNumberAndRound(props.cell.row.original.top_20),
},
{
Header: 'Top 10',
accessor: 'top_10',
Cell: (props) =>
checkIfValueIsNumberAndRound(props.cell.row.original.top_20),
},
{
Header: 'Top 5',
accessor: 'top_5',
Cell: (props) =>
checkIfValueIsNumberAndRound(props.cell.row.original.top_20),
},
{
Header: 'Win',
accessor: 'win',
Cell: (props) =>
checkIfValueIsNumberAndRound(props.cell.row.original.top_20),
},
],
[]
);
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
useTable({ columns, data });
return loading ? (
<SpinnerCustom />
) : (
<table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th
{...column.getHeaderProps()}
style={{
borderBottom: 'solid 3px red',
background: 'aliceblue',
color: 'black',
fontWeight: 'bold',
}}
>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row);
return (
<tr key={i} {...row.getRowProps()}>
{row.cells.map((cell, y) => {
return (
<td
{...cell.getCellProps()}
key={y}
style={{
padding: '10px',
border: 'solid 1px gray',
background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
);
}
Figure 2
const data = React.useMemo(() => {
return [...baselineData];
}, [baselineData]);
Figure 3
Figure 4 (ERROR)
this problem may related to initial data for baseLineData.
change the usesState initialize:
const [baselineData, setBaselineData] = useState([]);

how to display grouped header in muidatatable in react js

enter image description here
as shown in the above image i want to display it in a muidatatable with grouped header
i tried this below code but i didn't get proper table with grouped header it shows only the headers not to the grouped headers
const columns=[
{
name: 'Name',
headerCellProps: {
style: {
textAlign: 'center',
border: 0,
background: blue[500],
},
},
columns: [
{
name: 'firstName',
header: 'First Name',
},
{
name: 'lastName',
header: 'Last Name',
},
],
},
{
name: 'age',
header: 'Age',
headerCellProps: {
style: {
background: orange[500],
},
},
},
{
name: 'Job',
headerCellProps: {
style: { textAlign: 'center', border: 0, background: purple[500] },
},
columns: [
{
name: 'jobTitle',
header: 'Title',
},
{
name: 'jobArea',
header: 'Area',
},
],
},
]
const columns = [
{
name: 'Health & Safety',
// label:'Manual Handling',
options: {
filter: true,
customHeadRender: (tableMeta,value) =>
(<>
<th className={classes.thhead} >
<th className={classes.thsubhead} >
<span className={classes.headSpan} >Health & Safety</span>
{EMP.filter( item => item.TrainingCategory === 'Health & Safety').map((EMPLOYE)=>{
return(
<th style={{border:"0px",paddingLeft:"0px",paddingTop:"0px",paddingBottom:"0px"}} >
{/* <span className={classes.headSpan} >Health & Safety</span> */}
<th className={classes.headvalueOne} >
{EMPLOYE.TrainingName}
</th>
</th>
)
})
}
</th>
</th>
</>),
customBodyRender: (value) => (
<td className={classes.tdHead}>
<td className={classes.tdsubHead} >
{ EMP?
EMP.map((EMPLOYE)=>{
return(
<td className={classes.TablevalueOne} >{EMPLOYE.JobTitileNumber}</td>
)
}):null}
</td>
</td>
),
}
},
},
];

Can't fix the width of React-Table column

Super noob question here, I'm trying to fix the widths of my react-table columns but it doesn't change (it stays at generated according to the width of the items inside), most of this table is from a tutorial to be honest so I'm not sure how most of it works.
I'm using react hooks, and react-table v7.7!
const data = useMemo(() => expenses, [expenses]);
const columns = useMemo(
() => [
{
Header: "Date",
accessor: "date",
width: 100
},
{
Header: "Expense",
accessor: "expense",
width: 200
},
{
Header: "Amount",
accessor: "amount",
width: 100
},
{
Header: " ",
width: 100,
Cell: ({ row }) => (
<div>
<button onClick={() => editHandler(row.original)}>Edit</button>
<button onClick={() => deleteHandler(row.original)}>Delete</button>
</div>
),
},
],
[]
);
....
<table className="expenses-table" {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th className="table-header" {...column.getHeaderProps()}>
{column.render("Header")}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return (
<td className="table-data" {...cell.getCellProps()}>
{cell.render("Cell")}
</td>
);
})}
</tr>
);
})}
</tbody>
</table>
In order for width props to work, i think you need to add either of the following css/style to your expense-table class or to your <table> tag directly. This is to handle the overflowing behavior, since currently the contents have no choice but to resize the table column.
table.expense-table { table-layout:fixed; }
table.expense-table td { overflow: hidden; }

Deleting record from table in React moves the input value of column to the adjacent row input

There is the table which holds records, that is the oust-standing amount to be paid. Amount is paid by entering the transaction ID in the input field of table and clicking the pay button. When clicked on the pay button the record gets deleted but the transaction id moves to the adjacent row( input type in row ). How to avoid this problem ?
The code:-
import React, { useState, useEffect } from 'react';
import { Row, Form, Button, Table, Spinner, Modal } from 'react-bootstrap';
const dummyData = [
{
createdDate: '2020-11-27T18:25:56.827',
modifiedDate: '2020-12-20T15:20:37.739',
createdBy: 1,
modifiedBy: 1,
id: 175,
name: 'Delicious Point',
description: 'Kitchen 4',
email: 'saqqasc#gmail.com',
address: 'djshdjsdsdssdassssh',
locality: 'Andheri',
type: 'Home',
recommended: true,
available: true,
logo: '0073217b-e4eb-4400-9cef-6f03dbce80f0.jpeg',
status: 'ACTIVE',
deliveryPrice: 20.0,
ownerName: 'Kitchen 4',
alternatePhone: '4256879097',
fssaiLicenceApplied: true,
fssaiLicence: null,
gstNumber: '',
gstPercent: 0.0,
pendingAmount: 200.0,
totalAmount: 200.0,
transactionAmount: 0,
settlementDate: '2020-12-20',
},
{
createdDate: '2020-11-03T12:35:18.751',
modifiedDate: '2020-12-20T14:25:21.601',
createdBy: 1,
modifiedBy: 1,
id: 163,
name: 'Shop321',
description: 'description',
email: 'rehan123#gmail.com',
address: 'description',
locality: 'near Gausiya hotel',
type: 'Restaurant',
recommended: true,
available: true,
logo: null,
status: 'ACTIVE',
deliveryPrice: 23.0,
ownerName: 'Shop321',
fssaiLicenceApplied: true,
fssaiLicence: null,
gstNumber: '0',
gstPercent: 5.0,
pendingAmount: 460.0,
totalAmount: 460.0,
transactionAmount: 0,
settlementDate: '2020-12-20',
},
{
createdDate: '2020-11-03T12:35:18.751',
modifiedDate: '2020-12-20T14:25:21.601',
createdBy: 1,
modifiedBy: 1,
id: 168,
name: 'Shop3212',
description: 'description',
email: 'rehan1232#gmail.com',
address: 'description',
locality: 'near Gausiya hotelz',
type: 'Restaurant',
recommended: true,
available: true,
logo: null,
status: 'ACTIVE',
deliveryPrice: 23.0,
ownerName: 'Shop321',
fssaiLicenceApplied: true,
fssaiLicence: null,
gstNumber: '0',
gstPercent: 5.0,
pendingAmount: 460.0,
totalAmount: 460.0,
transactionAmount: 0,
settlementDate: '2020-12-20',
},
{
createdDate: '2020-11-03T12:35:18.751',
modifiedDate: '2020-12-20T14:25:21.601',
createdBy: 1,
modifiedBy: 1,
id: 169,
name: 'Shop32134',
description: 'description',
email: 'reh14#gmail.com',
address: 'description',
type: 'Restaurant',
recommended: true,
available: true,
logo: null,
status: 'ACTIVE',
deliveryPrice: 23.0,
ownerName: 'Shop321',
fssaiLicenceApplied: true,
fssaiLicence: null,
gstNumber: '0',
gstPercent: 5.0,
pendingAmount: 460.0,
totalAmount: 460.0,
transactionAmount: 0,
settlementDate: '2020-12-20',
},
];
export default function Settelments(props) {
const [date, setData] = useState([]);
useEffect(() => {
setalert1(true);
setDdata(dummyData);
),[]}
const sendData = (e) => {
const sid = e.target.id;
setShopid(sid);
setDeleteId(parseInt(e.target.id));
const dat = ddate
.filter((f) => f.id !== parseInt(e.target.id))
.map((m) => {
return m;
});
setDdata(dat);
setValues({
val: [],
});
setSdata({
...sdata,
date: time,
});
};
const handleChange = (e, index) => {
setValues(e.target.value);
};
return(
<Table responsive>
<thead>
<tr>
<th className="text-center">Sr.no</th>
<th className="text-center">Shop Name</th>
<th
className="text-center"
style={{ backgroundColor: 'red', color: 'white' }}
>
Pending Amount
</th>
<th className="text-center">Type</th>
<th className="text-center">Transaction Id</th>
<th className="text-center">Settlement</th>
<th className="text-center">{''}</th>
</tr>
</thead>
<tbody>
{noofelement == 0 ? (
<tr className="text-center">
<td className="align-middle">
<div className="text-danger">No Data Found</div>
</td>
</tr>
) : null}
{ddate.map((m, index) => (
<tr id={m.id} className="text-center">
<td scope="row">{index + 1}</td>
<td>{m.name}</td>
<td className="text-danger">
<b>{m.totalAmount}</b>
</td>
<td>{m.type}</td>
<td>
<div className="transaction-settelment">
<Form.Group controlId={m.id}>
<Form.Control
type="text"
placeholder="Transaction ID"
name={`tid${m.id}`}
size="sm"
onChange={(e, index) => {
handleChange(e, index);
}}
/>
</Form.Group>
</div>
</td>
<td>
<Button size="sm" id={m.id} onClick={(e) => sendData(e)}>
Pay!
</Button>
</td>
</tr>
))}
</tbody>
</Table>
)
}

TypeError: h is undefined

I have the following code working properly except when I click on the following button inside projectSpacedGrid function, I get errors in the browser's console as shown below the code:
<Button
label="Associate Project Spaces"
icon="pi pi-plus"
style={{ marginRight: ".25em", marginTop: ".25em" }}
onClick={e =>
this.setState({
assocAssetsVisible: true
})
}
/>
Here's my full code( I've removed lot of code to keep it as small as possible):
import React from "react";
import * as ReactDOM from "react-dom";
import JqxTabs from "jqwidgets-scripts/jqwidgets-react-tsx/jqxtabs";
import JqxGrid, {
IGridProps,
jqx
} from "jqwidgets-scripts/jqwidgets-react-tsx/jqxgrid";
import JqxButton from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxbuttons';
import JqxInput from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxinput';
import JqxDateTimeInput from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxdatetimeinput';
import JqxWindow from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow';
import JqxDropDownList, { IDropDownListProps } from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxdropdownlist';
import JqxNotification from 'jqwidgets-scripts/jqwidgets-react-tsx/jqxnotification';
import { Button } from "primereact/button";
import { Growl } from "primereact/growl";
import { properties } from ".././properties";
import { Messages } from "primereact/messages";
import axios from "axios/index";
type Props = {
project,
username
};
export interface AssetsState extends IGridProps {
//export interface AssetsState extends IDropDownListProps {
visible: boolean,
assocAssetsVisible: boolean,
project: {},
selectedAsset: [],
addEditLabel: {},
selectedRowIndex: number,
deleteDialogVisible: boolean,
dropdownlistSource:IDropDownListProps["source"];
rendertoolbar: (toolbar: any) => void;
}
export class Assets extends React.PureComponent<Props, AssetsState> {
private growl = React.createRef<Growl>();
//Created Refs for a particular div
private projectSpacesGridElement = React.createRef<HTMLDivElement>();
//Created Refs for the desired widgets (JQXGrid and JQXTabs)
private assetsDataGrid = React.createRef<JqxGrid>();
private myTabs = React.createRef<JqxTabs>();
//Created Refs for editing popups for project spaces tab
private assetsEditWindow = React.createRef<JqxWindow>();
private assetsAddWindow = React.createRef<JqxWindow>();
private id = React.createRef<JqxInput>();
private assetsTypeId = React.createRef<JqxInput>();
private assetCategoryId = React.createRef<JqxInput>();
private locationTypeId = React.createRef<JqxInput>();
private statusIndicatorId = React.createRef<JqxInput>();
private uri = React.createRef<JqxInput>();
private fileName = React.createRef<JqxInput>();
private fileAddCDSName = React.createRef<JqxInput>();
private fileVersion = React.createRef<JqxInput>();
private fileEncodingId = React.createRef<JqxInput>();
private ownerId = React.createRef<JqxInput>();
private createdDate = React.createRef<JqxDateTimeInput>();
private updatedDate = React.createRef<JqxDateTimeInput>();
private createdBy = React.createRef<JqxInput>();
private assetDescription = React.createRef<JqxInput>();
private assetCDSDescription = React.createRef<JqxInput>();
private msgNotification = React.createRef<JqxNotification>();
private firstTabButtonContent = "Add New Project Space ";
private editrow: number = -1;
private baseUrl = properties.baseUrlWs;
private messages = React.createRef<Messages>();
constructor(props: Props) {
super(props);
this.saveEditCDSBtn = this.saveEditCDSBtn.bind(this);
this.cancelEditCDSBtn = this.cancelEditCDSBtn.bind(this);
this.savenewCDSpaceBtn = this.savenewCDSpaceBtn.bind(this);
this.cancelnewCDSpaceBtn = this.cancelnewCDSpaceBtn.bind(this);
const rendertoolbar = (toolbar: any): void => {
const addPSRowClick = () => {
this.assetsAddWindow.current!.open();
};
ReactDOM.render(
<div style={{ margin: '5px' }}>
<div id="button1" style={{ float: 'left' }}>
<JqxButton theme={'material'} onClick={addPSRowClick} width={155} value={'Add Project Space'} />
</div>
</div>,
toolbar[0]
);
};
this.state = {
visible: false,
project: {},
assocAssetsVisible: false,
selectedAsset: [],
addEditLabel: {},
selectedRowIndex: null,
deleteDialogVisible: false,
rendergridrows: (params: any): any[] => {
const data = params.data;
return data;
},
rendertoolbar,
dropdownlistSource:[
{value:0, label:'Individual'},
{value:1, label:'Project'},
{value:2, label:'Institution'},
{value:3, label:'Public'}
]
};
}
public render() {
console.log(this.state.selectedAsset);
return (
<div>
<JqxTabs
ref={this.myTabs}
theme={"arctic"}
width="1390px"
//height={560}
//height={100}
initTabContent={this.initWidgets}
onSelected={this.onTabSelected}
>
<ul>
<li style={{ marginLeft: 30 }}>
<div style={{ height: 20, marginTop: 5 }}>
<div style={{ float: "left" }}></div>
<div
style={{
marginLeft: 4,
verticalAlign: "middle",
textAlign: "center",
float: "left"
}}
>
Project Spaces
</div>
</div>
</li>
</ul>
<div style={{ overflow: "hidden" }}>
<div id="jqxGrid" ref={this.projectSpacesGridElement} />
<div style={{ marginTop: 10, height: "15%", width: "100%" }}></div>
</div>
</JqxTabs>
<JqxWindow ref={this.assetsEditWindow} width={250} height={230} resizable={false}
isModal={false} autoOpen={false} modalOpacity={'0.01'} position={{ x: 68, y: 368 }}>
<div>Edit</div>
<div style={{ overflow: 'hidden' }}>
<table>
<tbody>
<tr>
<td align={'right'}>Name :</td>
<td align={'left'}>
<JqxInput ref={this.fileName} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Version:</td>
<td align={'left'}>
<JqxInput ref={this.fileVersion} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Description:</td>
<td align={'left'}>
<JqxInput ref={this.assetDescription} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Visibility Indicator:</td>
<td align={'left'}>
{/* <JqxInput ref={this.visibilityIndicatorID} width={150} height={23} /> */}
<JqxDropDownList width={100} height={20} source={this.state.dropdownlistSource} selectedIndex={0} autoDropDownHeight={true}/>
</td>
</tr>
<tr hidden>
<td align={'right'}>ID:</td>
<td align={'left'}>
<JqxInput ref={this.id} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Location Type ID:</td>
<td align={'left'}>
<JqxInput ref={this.locationTypeId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Asset Category ID:</td>
<td align={'left'}>
<JqxInput ref={this.assetCategoryId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Asset Type ID:</td>
<td align={'left'}>
<JqxInput ref={this.assetsTypeId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Status Indicator ID:</td>
<td align={'left'}>
<JqxInput ref={this.statusIndicatorId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>URI:</td>
<td align={'left'}>
<JqxInput ref={this.uri} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>File Encoding ID:</td>
<td align={'left'}>
<JqxInput ref={this.fileEncodingId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Owner ID:</td>
<td align={'left'}>
<JqxInput ref={this.ownerId} width={150} height={23} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Created Date:</td>
<td align={'left'}>
<JqxDateTimeInput ref={this.createdDate}
width={150} height={23} formatString={'F'} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Updated Date:</td>
<td align={'left'}>
<JqxDateTimeInput ref={this.updatedDate}
width={150} height={23} formatString={'F'} />
</td>
</tr>
<tr hidden>
<td align={'right'}>Created By:</td>
<td align={'left'}>
<JqxInput ref={this.createdBy} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'} />
<td style={{ paddingTop: '10px' }} align={'right'}>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.saveEditCDSBtn} width={50}>
Save
</JqxButton>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.cancelEditCDSBtn} width={50}>
Cancel
</JqxButton>
</td>
</tr>
</tbody>
</table>
</div>
</JqxWindow>
<JqxWindow ref={this.assetsAddWindow} width={250} height={230} resizable={false}
isModal={false} autoOpen={false} modalOpacity={'0.01'} position={{ x: 68, y: 368 }}>
<div>{this.firstTabButtonContent}</div>
<div style={{ overflow: 'hidden' }}>
<table>
<tbody>
<tr>
<td align={'right'}>Name:</td>
<td align={'left'}>
<JqxInput ref={this.fileAddCDSName} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Description:</td>
<td align={'left'}>
<JqxInput ref={this.assetCDSDescription} width={150} height={23} />
</td>
</tr>
<tr>
<td align={'right'}>Visibility Indicator:</td>
<td align={'left'}>
<JqxDropDownList width={100} height={20} source={this.state.dropdownlistSource} selectedIndex={0} autoDropDownHeight={true} />
</td>
</tr>
<tr>
<td align={'right'} />
<td style={{ paddingTop: '10px' }} align={'right'}>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.savenewCDSpaceBtn} width={50}>
Save
</JqxButton>
<JqxButton style={{ display: 'inline-block', marginRight: '5px' }} onClick={this.cancelnewCDSpaceBtn} width={50}>
Cancel
</JqxButton>
</td>
</tr>
</tbody>
</table>
</div>
</JqxWindow>
<JqxNotification ref={this.msgNotification}
width={250} position={'top-left'} opacity={0.9} autoOpen={false}
autoClose={true} animationOpenDelay={800} autoCloseDelay={3000} template={'info'} appendContainer={'#forNotification'}>
<div>
Record Deleted Successfully!
</div>
</JqxNotification>
</div>
);
}
//Tab 1
private projectSpacesGrid = () => {
const source: any = {
datafields: [
{ name: "id", type: "long" },
{ name: "assetsTypeId", type: "long" },
{ name: "fileName", type: "string" },
{ name: "locationTypeId", type: "long" },
{ name: "uri", type: "string" },
{ name: "fileVersion", type: "string" },
{ name: "fileEncodingId", type: "long" },
{ name: "ownerId", type: "long" },
{ name: "createdDate", type: "date",format: "dd-MMM-yy" },
{ name: "assetCategoryId", type: "long" },
{ name: "assetDescription", type: "string" },
{ name: "createdBy", type: "string" },
{ name: "updatedDate", type: "date",format: "dd-MMM-yy" },
{ name: "statusIndicatorId", type: "long" },
{ name: "visibilityIndicatorId", type: "long" },
{ name: "displayedValues", type: "string" }
],
deleterow: (rowid: number,commit:any): void => {
console.log("Delete row method called in source of Project Spaces");
console.log("Role ID:" + rowid);
commit(true);
},
datatype: "json",
root: "assets",
url: this.baseUrl + `api/assets/search/getAssetsByProjectId`
};
const dataAdapter = new jqx.dataAdapter(source, {
//async: false,
autoBind: true,
downloadComplete: (data: any, status: any, xhr: any): void => {
source.totalrecords = parseInt(data["page"].totalElements);
console.log("Total Assets Records check"+source.totalrecords);
},
formatData: (data: any): any => {
data.value = this.props.project.id;
data.page = data.pagenum;
data.size = data.pagesize;
if (data.sortdatafield && data.sortorder) {
data.sort = data.sortdatafield + "," + data.sortorder;
}
return data;
},
loadError: (xhr: any, status: any, error: any) => {
alert('Error loading "' + source.url + '" : ' + error);
}
});
const columns: IGridProps["columns"] = [
{ datafield: "id", text: "ID Number", width: 100,hidden:true },
{ datafield: "assetsTypeId", text: "Assets Type ID", width: 100, hidden: true },
{ datafield: "fileName", text: "Name", width: 275 },
{ datafield: "fileVersion", text: "File Version", width: 275, hidden: true },
{ datafield: "fileEncodingId", text: "File Encoding", width: 275, hidden: true },
{ datafield: "ownerid", text: "Owner ID", width: 100, hidden: true },
{ datafield: "assetCategoryId", text: "Asset Category ID", width: 100, hidden: true },
{ datafield: "statusIndicatorId", text: "Status Indicator ID", width: 100, hidden: true },
{ datafield: "visibilityIndicatorId", text: "Visibility Indicator ID", width: 100, hidden: true },
{ datafield: "displayedValues", text: "Display Values", width: 100, hidden: true },
{
datafield: "assetDescription",
text: "Description",
width: 250
},
{ datafield: "locationTypeId", text: "Location Type", width: 150 },
{ datafield: "uri", text: "URI", width: 150 },
{ datafield: "ownerId", text: "Owner", width: 150 },
{
//cellsformat: "d",
cellsformat: "MM/dd/yyyy",
datafield: "createdDate",
text: "Created Date",
width: 150
},
{
//cellsformat: "d",
cellsformat: "MM/dd/yyyy",
datafield: "updatedDate",
text: "Updated Date",
width: 100
},
{
text: "Delete ",
buttonclick: (): void => {
},
cellsrenderer: (): string => {
return "Delete";
},
columntype: "button",
datafield: "Delete",
width: 80
},
{
text: "Edit Asset",
buttonclick: (row: number): void => {
// show the popup window.
this.assetsEditWindow.current!.open();
},
cellsrenderer: (): string => {
return "Edit";
},
columntype: "button",
datafield: "Edit",
width: 80
}
];
const grid =
this.state.visible || this.state.assocAssetsVisible ? null : (
<div>
<JqxGrid
ref={this.assetsDataGrid}
width={"100%"}
height={"100%"}
theme={"arctic"}
source={dataAdapter}
columns={columns}
showtoolbar={true}
pageable={true}
pagesize={50}
scrollmode={"default"}
rendertoolbar={this.state.rendertoolbar}
sortable={true}
/>
<Button
label="Associate Project Spaces"
icon="pi pi-plus"
style={{ marginRight: ".25em", marginTop: ".25em" }}
onClick={e =>
this.setState({
assocAssetsVisible: true
})
}
/>
</div>
);
ReactDOM.render(grid, this.projectSpacesGridElement.current!);
};
private saveEditCDSBtn(): void {
if (this.editrow >= 0) {
this.assetsEditWindow.current!.hide();
}
}
private cancelEditCDSBtn(): void {
this.assetsEditWindow.current!.hide();
}
private savenewCDSpaceBtn(): void {
this.assetsAddWindow.current!.hide();
}
private cancelnewCDSpaceBtn(): void {
this.assetsAddWindow.current!.hide();
}
private initWidgets = (tab: any) => {
switch (tab) {
case 0:
this.projectSpacesGrid();
break;
}
};
private onTabSelected = (event: any) => {
if (event.args) {
let tabIndex = event.args.item;
switch (event.args.item) {
case 0:
this.assetsAddWindow.current!.setTitle(this.firstTabButtonContent);
break;
}
}
};
}
Error Below:
The above error occurred in the <JqxWindow> component:
in JqxWindow (created by Assets)
in div (created by Assets)
in Assets (created by ProjectTabView)
in div (created by TabView)
in div (created by TabView)
in div (created by TabView)
in TabView (created by ProjectTabView)
in ProjectTabView (created by ProjectView)
in div (created by ProjectView)
in ProjectView (created by Route)
in Route (created by Main)
in Switch (created by Main)
in div (created by Main)
in div (created by Main)
in Router (created by BrowserRouter)
in BrowserRouter (created by Main)
in Main
in ErrorBoundary
React will try to recreate this component tree from scratch using the error boundary you provided, ErrorBoundary.
TypeError: "h is undefined"
propertyChangedHandler webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxwindow.js?:8
setvalueraiseevent webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
set webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
each webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:8
set webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
jqxWidgetProxy webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
b.jqx.jqxWidget/b.fn[h]/< webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
each webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:8
each webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:8
h webpack:///./node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js?:16
setOptions webpack:///./node_modules/jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow/react_jqxwindow.esm.js?:88
componentDidUpdate webpack:///./node_modules/jqwidgets-scripts/jqwidgets-react-tsx/jqxwindow/react_jqxwindow.esm.js?:82
React 6
unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:818
React 5
unstable_runWithPriority webpack:///./node_modules/scheduler/cjs/scheduler.development.js?:818
React 6
Adding screenshots of complete error from the browser console:
Is it something related to associateAssetsVisible:true variable that I'm using?

Resources