Show Posts
|
Pages: [1] 2 3 ... 15
|
1
|
General Category / EasyUI for React / Re: DataGrid dynamic column order rendering different
|
on: November 29, 2022, 07:39:38 AM
|
this does work, using a ref to make sure each render gets new indexes. though I'm not sure if this will cause issues long term. the page won't be that long lived, so probably OK in this use case. import './App.css'; import { useRef, useState } from 'react'; import { ComboBox, DataGrid, GridColumn, LinkButton } from 'rc-easyui';
function App() { const refColIdx = useRef(1);
const [myData, setData] = useState({ hasopt2: false, info: [ { title: "Item 1", opt1: 50, opt2: 0, opt3: "Thing 1", opt3e: 25 }, { title: "Item 2", opt1: 75, opt2: 0, opt3: "Thing 2", opt3e: 45 }, ], selected: {} });
const [currentType, setType] = useState(""); const [gridCols, setGridCols] = useState([]);
function ColPre(coltype) { let cols = [ <GridColumn key={refColIdx.current++} field="title" title=" " width={140} />, ]; switch (coltype) { case "C": cols.push(<GridColumn key={refColIdx.current++} field="opt1" title={"Option 1"} width={65} />); break; default: break; } return cols; }
function ColPost(coltype) { function onSelPrice(row) { let newdata = { ...myData }; if (coltype === "C") { newdata.selected = { title: row.title, opt3: row.opt3, opt3e: row.opt3e, }; } else { newdata.selected = { title: row.title, opt3: row.opt3, }; } setData(newdata); }
let cols = []; switch (coltype) { case "C": cols.push(<GridColumn key={refColIdx.current++} field="opt3e" title={"Option 3 X"} width={80} />); break; default: break; }
cols.push(<GridColumn key={refColIdx.current++} field="select" title=" " width={45} render={({ row }) => (<LinkButton onClick={() => onSelPrice(row)}>Use</LinkButton>)} />); return cols; }
function GetCols(coltype) { return [ ...ColPre(coltype), <GridColumn key={refColIdx.current++} field="opt2" title={"Option 2"} hidden={!myData.hasopt2} width={65} />, <GridColumn key={refColIdx.current++} field="opt3" title={"Option 3"} />, ...ColPost(coltype), ]; }
return ( <div className="App"> <ComboBox value={currentType} data={[ { value: "A", text: "Type A" }, { value: "B", text: "Type B" }, { value: "C", text: "Type C" }, ]} onSelectionChange={selection => { setType(selection.value); setGridCols(GetCols(selection.value)); }} > </ComboBox> <DataGrid style={{ maxHeight: 150, width: 600 }} data={myData.info} > {gridCols} </DataGrid> ColIdx: {refColIdx.current} Selected: {JSON.stringify(myData.selected)}<br /> Cols: <pre>{JSON.stringify(gridCols, null, 2)}</pre> </div> ); }
export default App;
|
|
|
3
|
General Category / EasyUI for React / DataGrid dynamic column order rendering different
|
on: November 28, 2022, 03:19:07 PM
|
This example is simplified from my actual use, but represents the pattern. My Pre and Post functions have a lot more logic. When you change to type C you can see the column order displayed does not match the column array. import './App.css'; import { useState } from 'react'; import { ComboBox, DataGrid, GridColumn, LinkButton } from 'rc-easyui';
function App() {
const [myData, setData] = useState({ hasopt2: false, info: [ { title: "Item 1", opt1: 50, opt2: 0, opt3: "Thing 1", opt3e: 25 }, { title: "Item 2", opt1: 75, opt2: 0, opt3: "Thing 2", opt3e: 45 }, ], selected: {} });
const [currentType, setType] = useState(""); const [gridCols, setGridCols] = useState([]);
function ColPre(coltype) { let cols = [ <GridColumn key={"a1"} field="title" title=" " width={140} />, ]; switch (coltype) { case "C": cols.push(<GridColumn key={"a2"} field="opt1" title={"Option 1"} width={65} />); break; default: break; } return cols; }
function ColPost(coltype) { function onSelPrice(row) { let newdata = { ...myData }; if (coltype === "C") { newdata.selected = { title: row.title, opt3: row.opt3, opt3e: row.opt3e, }; } else { newdata.selected = { title: row.title, opt3: row.opt3, }; } setData(newdata); }
let cols = []; switch (coltype) { case "C": cols.push(<GridColumn key={"c1"} field="opt3e" title={"Option 3 X"} width={80} />); break; default: break; }
cols.push(<GridColumn key={"c2"} field="select" title=" " width={45} render={({ row }) => (<LinkButton onClick={() => onSelPrice(row)}>Use</LinkButton>)} />); return cols; }
function GetCols(coltype) { return [ ...ColPre(coltype), <GridColumn field="opt2" title={"Option 2"} hidden={!myData.hasopt2} width={65} />, <GridColumn field="opt3" title={"Option 3"} />, ...ColPost(coltype), ]; }
return ( <div className="App"> <ComboBox value={currentType} data={[ { value: "A", text: "Type A" }, { value: "B", text: "Type B" }, { value: "C", text: "Type C" }, ]} onSelectionChange={selection => { setType(selection.value); setGridCols(GetCols(selection.value)); }} > </ComboBox> <DataGrid style={{ maxHeight: 150, width: 600 }} data={myData.info} > {gridCols} </DataGrid> Selected: {JSON.stringify(myData.selected)}<br /> Cols: <pre>{JSON.stringify(gridCols, null, 2)}</pre> </div> ); }
export default App;
I haven't tried putting every possible column in and using the hidden property, I think that code would be rather cumbersome. Is there some way to force it to re-render correctly?
|
|
|
4
|
General Category / EasyUI for React / Issue: DateBox onFocus fires twice
|
on: November 07, 2022, 01:18:43 PM
|
When clicking a datebox, the onFocus even fires twice, and fires another 2 times when either closing the drop down or selecting a date, which really it shouldn't fire at all for those actions. Example: import React from 'react'; import { DateBox } from 'rc-easyui'; class App extends React.Component { constructor() { super(); this.state = { value: new Date(), } this.times = React.createRef(); this.times.current = 0; } formatDate(date) { let y = date.getFullYear(); let m = date.getMonth() + 1; let d = date.getDate(); return [m, d, y].join('/') } handleChange(value) { this.setState({ value: value }) } handleFocus(){ console.log("focus",this.times.current) this.times.current++; } render() { return ( <div> <h2>Restrict Date Range in DateBox</h2> <p>This example shows how to restrict the user to select only ten days from now.</p> <DateBox panelStyle={{ width: 250, height: 300 }} editable={false} value={this.state.value} onChange={this.handleChange.bind(this)} onFocus={this.handleFocus.bind(this)} /> <p>{this.formatDate(this.state.value)}</p> </div> ); } } export default App;
|
|
|
7
|
General Category / EasyUI for React / DataGrid keyboard navigation
|
on: October 10, 2022, 05:51:38 AM
|
in EasyUI for jQuery I was able to add keyboard navigation (up, down, enter) to a DataGrid using this: .datagrid('getPanel').panel('panel').attr('tabindex',1).unbind('keydown').bind('keydown', ... I've tried setting tabIndex={1} on the datagrid, but the onKeyDown still doesn't fire, even after clicking a row to make sure it has focus. I've also tried tabIndex 0, -1, and 5000 just in case it was a index conflict. any hidden little tricks to enable this feature?
|
|
|
8
|
General Category / EasyUI for React / event bubbling in Accordion headers
|
on: October 05, 2022, 07:11:19 AM
|
I'm trying add a ComboBox to an AccordionPanel header such that the I will expand the panel manually when a valid option is selected in the combo. Issue is the panel toggles as though i clicked the header itself with every click of the combobox. Is there some way to cancel bubbling that event? ComboBox onClick doens't seem to fire, and a "window.event.stopPropagation();window.event.cancelBubble=true;" on focus and blur have no effect <Accordion animate multiple selectedIndex={selectedPanel} > <AccordionPanel header={() => { return ( <div key={1} > <div className="panel-title">Reports</div> <ComboBox data={[ { value: 0, text: "Option 0"}, { value: 1, text: "Option 1"}, ]} onSelectionChange={LoadOption} /> </div> ); }} onPanelSelect={() => { if (selectedPanel.length === 0) { setselectedPanel([0]); } }} onPanelUnselect={() => { setselectedPanel([]); }} > Selected option {selectedoptioninfo} </AccordionPanel> </Accordion>
I do still expect the panel to expand and collapse as normal when clicking part of the header that isn't the combobox, I just dont' think the clicks on the combo should bubble up, probably at all. I can't think if a single case where dropping down a combo should fire a click on any parent elements.
|
|
|
9
|
General Category / EasyUI for React / Feature request: Messager async/await return
|
on: September 16, 2022, 09:35:39 AM
|
I'm currently doing this to async/await Messager dialogs calls. (this is in a functional component with useRef() ) let res = await new Promise(resolve => { messager.current.confirm({ title: "Question", msg: "Do you like async/await?", buttons: [ { text: "yes", value: true }, { text: "no", value: false }, ], result: r => { resolve(r); } }); }); Would it be possible to add an async/await pattern when the "result" callback isn't provided? Examples for how that would be called: let res = await messager.current.confirm({ title: "Question", msg: "Do you like async/await?", buttons: [ { text: "yes", value: true }, { text: "no", value: false }, ], });
or let answer = await messager.current.confirm({ title: "Question", msg: "Do you like async/await?", buttons: [ { text: "yes", value: true }, { text: "no", value: false }, ], }).then(r=> { return r ? "I like it" : "I can do without" });
|
|
|
11
|
General Category / EasyUI for React / DataGrid/ListBase filterDelay not behaving in the expected way
|
on: June 17, 2022, 10:41:17 AM
|
this might only apply when remote filtering as a test, I set filterDelay={5000} I would expect that each new keystroke would reset the delay, and as long as I press any kind of key, including arrows, the actual filtering would not happen. what happens is that every 5 seconds as long as I'm typing a another filter request is done. My requests take a bit to process, and since it's all async it's not only causing extra server load, but also the requests don't come back in the same order, especially since a more specific filter will return faster, so sometimes the final search will return before the previous one completes, resulting in the desired data being replaced by the previous! I think the below test case based on your remote filter example should show the issue, though I can't test it because your server doesn't allow CORS from http://localhost:3000/. The console should show the requests with a timestamp import React from 'react'; import { DataGrid, GridColumn, NumberBox } from 'rc-easyui'; class App extends React.Component { constructor(props) { super(props); this.state = { total: 0, data: [], pageNumber: 1, loading: false, filterRules: null, operators: ["nofilter", "less", "greater"] } } componentDidMount() { this.fetchData(); } fetchData() { const { pageNumber, filterRules } = this.state; const config = { credentials: 'include', method: 'post', mode: 'cors', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }, body: `page=${pageNumber}&rows=10&filterRules=${filterRules}` }; const url = 'https://www.jeasyui.com/demo/main/datagrid33_getdata.php'; this.setState({ loading: true }) fetch(url, config).then(res => { return res.json(); }).then(data => { this.setState({ total: parseInt(data.total, 10), data: data.rows, loading: false }) }) } handlePageChange({ pageNumber, refresh }) { if (refresh) { this.fetchData(); } else { this.setState({ pageNumber: pageNumber }, () => { this.fetchData(); }) } } handleFilterChange(filterRules) { console.log(new Date().getTime(), JSON.stringify(filterRules)) this.setState({ filterRules: JSON.stringify(filterRules) }, () => { this.fetchData() }) } render() { return ( <div> <h2>Remote Filtering</h2> <DataGrid style={{ height: 250 }} total={this.state.total} data={this.state.data} pageSize={10} pageNumber={this.state.pageNumber} loading={this.state.loading} pagination lazy filterable filterDelay={5000} onPageChange={this.handlePageChange.bind(this)} onFilterChange={this.handleFilterChange.bind(this)} > <GridColumn field="itemid" title="Item ID"></GridColumn> <GridColumn field="productid" title="Product"></GridColumn> <GridColumn field="listprice" title="List Price" align="right" filterOperators={this.state.operators} defaultFilterOperator="nofilter" filter={() => <NumberBox></NumberBox>} /> <GridColumn field="unitcost" title="Unit Cost" align="right" filterOperators={this.state.operators} defaultFilterOperator="nofilter" filter={() => <NumberBox></NumberBox>} /> <GridColumn field="attr1" title="Attribute" width="30%"></GridColumn> </DataGrid> </div> ); } } export default App;
|
|
|
13
|
General Category / EasyUI for React / Re: error: null is not an object (evaluating 'this.view2.body')
|
on: May 27, 2022, 11:29:13 AM
|
another from user agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36
Cannot read property 'body' of null
I'm pretty sure these are all the same error, I do see some null check on view2, but not everywhere. I still can't figure why it's null, or at what point. I'm also not sure how view2 relates to my data or code.
|
|
|
14
|
General Category / EasyUI for React / Re: EasyUI React Dialog
|
on: May 27, 2022, 10:00:21 AM
|
I have seen then on various UI kits when the mouse is released outside the browser viewport. I don't think it's a jeasyui issue so much that the browser isn't raising the proper events
|
|
|
|