IgniteUI / igniteui-react-wrappers

Ignite UI components for React
https://igniteui.github.io/igniteui-react-wrappers/
MIT License
168 stars 12 forks source link

HierarchicalGrid doesn't work at all. #72

Closed marc314 closed 7 years ago

marc314 commented 7 years ago

Uncaught Error: Syntax error, unrecognized expression: # at Function.at.error (https://code.jquery.com/jquery-1.10.2.min.js:4:15710)

ChronosSF commented 7 years ago

Is it possible to share a sample to look at? I created one just now and the hierarchical grid seems to render just fine:

hierarchicalGridReact.zip

marc314 commented 7 years ago

I had adopted a hGrid example from the web into the project samples here.. Thanks for getting back to me, indeed your sample works. If there is a mistake in this code please feel free to delete the thread.

Best, Marc

<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8" />
    <title>IgniteUI ReactJS Grid</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!--IgniteUI CSS refs-->
    <link type="text/css" href="https://secure-cdn-na.infragistics.com/igniteui/latest/css/themes/infragistics/infragistics.theme.css" rel="stylesheet" />
    <link type="text/css" href="https://secure-cdn-na.infragistics.com/igniteui/latest/css/structure/infragistics.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" type="text/css" />
    <link rel="stylesheet" href="../sample.css" />
    <!--//IgniteUI CSS refs-->  
    <style>
        .ui-state-hover, .ui-widget-content .ui-state-hover {
            color: #070707;
        }
    </style>
    <script type="text/javascript">
        var sourceData = {
             "d": [
            {
                "ID": 0,
                "Name": "Food",
                "Category": { "ID": 0, "Name": "Food", "Active": true, "Date": "\/Date(1059660800000)\/" },
                "Products": [
                    { "ID": 0, "Name": "Bread", "Price": "2.5" }
                ]
            },
            {
                "ID": 1,
                "Name": "Beverages",
                "Category": { "ID": 2, "Name": "Beverages", "Active": true, "Date": "\/Date(1159660800000)\/" },
                "Products": [
                    { "ID": 1, "Name": "Milk", "Price": "3.5" },
                    { "ID": 2, "Name": "Vint soda", "Price": "20.9" }
                ]
            },
            {
                "ID": 2,
                "Name": "Electronics",
                "Category": { "ID": 5, "Name": "Electronics", "Active": false, "Date": "\/Date(1859660800000)\/" },
                "Products": [
                    { "ID": 7, "Name": "DVD Player", "Price": "35.88" },
                    { "ID": 8, "Name": "LCD HDTV", "Price": "1088.8" }
                ]
            }
        ]
            // "Products": [
            //  { "ProductID": 1, "Name": "Chairs", "UnitsInStock": 385, "UnitPrice": 358.74353459046387, "DateAdded": "2004-06-20T20:18:20.469", InStock: true },
            //  { "ProductID": 2, "Name": "Kitchen knifes", "UnitsInStock": 602, "UnitPrice": 140.2894189303226, "DateAdded": "2000-02-21T22:56:16.331", InStock: true },
            //  { "ProductID": 3, "Name": "Screwdrivers", "UnitsInStock": 608, "UnitPrice": 567.43131092164253, "DateAdded": "2002-04-21T09:06:07.142", InStock: true },
            //  { "ProductID": 4, "Name": "Desk lamps", "UnitsInStock": 402, "UnitPrice": 785.99307722691128, "DateAdded": "2001-03-27T03:57:27.373", InStock: true },
            //  { "ProductID": 5, "Name": "Monitors", "UnitsInStock": 338, "UnitPrice": 157.42114473014192, "DateAdded": "2006-02-28T21:22:04.059", InStock: true },
            //  { "ProductID": 6, "Name": "Beds", "UnitsInStock": 163, "UnitPrice": 178.17069924351324, "DateAdded": "1996-10-24T06:51:53.93", InStock: true },
            //  { "ProductID": 7, "Name": "Dinner tables", "UnitsInStock": 163, "UnitPrice": 641.50092314998665, "DateAdded": "1999-11-19T06:10:35.984", InStock: true },
            //  { "ProductID": 8, "Name": "Dinner tables", "UnitsInStock": 163, "UnitPrice": 641.50092314998665, "DateAdded": "1999-11-19T06:10:35.984", InStock: true },
            //  { "ProductID": 9, "Name": "Dinner tables", "UnitsInStock": 163, "UnitPrice": 641.50092314998665, "DateAdded": "1999-11-19T06:10:35.984", InStock: true },
            //  { "ProductID": 10, "Name": "Dinner tables", "UnitsInStock": 163, "UnitPrice": 641.50092314998665, "DateAdded": "1999-11-19T06:10:35.984", InStock: true },
            //  { "ProductID": 11, "Name": "Dinner tables", "UnitsInStock": 163, "UnitPrice": 641.50092314998665, "DateAdded": "1999-11-19T06:10:35.984", InStock: true }
            // ]
        }
    </script>
</head>
<body class="container">
    <div class="navbar navbar-default navbar-fixed-top" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">Ignite UI ReactJS Component</a> 
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="/igniteui-react/index.html">Home</a></li>
                    <li><a href="https://github.com/IgniteUI/igniteui-react">View on GitHub <i class="fa fa-github"></i></a></li>
                </ul>
            </div>
        </div>
    </div>

<div >
    <h1 class="push-down-md"><a href="https://igniteui.com/grid/overview" target="_blank">igGrid</a></h1>

    <div class="row description">
        <div class="alert alert-info col-md-5 try-it-out">
            <span class="h4">TRY IT OUT:</span>
            <hr />
            <ul>
                <li>Select a row that you would like to edit</li>
                <li>Change a product's name in the group of textboxes below, click update and see how the names change in the grid</li>
                <li>Delete a product either through the grid's UI or with the button bellow the current selected product in the window next to the grid</li>
            </ul>
        </div>
        <div class="col-md-4">
            <p class="lead">This sample demonstrates how ReactJS can be used to create igGrid and add two-way data binding. </p>
            <p><a href="https://github.com/IgniteUI/igniteui-react/blob/master/samples/igGrid/igGrid.html" class="btn btn-default btn-lg btn-primary" target="_blank"><i class="fa fa-code fa-lg"></i> View Source</a></p>
        </div>
    </div>

    <div id="app">
         <!-- to use JSX in our HTML -->
        <script type="text/babel">
            // everything below will be up to the users to write
            var IgEditBox = React.createClass({
                render: function () {
                    var rowId =  this.props.rowId,
                        v = rowId > -1;
                    return (
                        <div className="editorBox" style={{"display": v ? "block": "none"}}>
                            <h4>Change values in row with ID <span style={{"fontWeight": "bold"}}>{this.props.rowId}</span>:</h4>
                            <div className="well well-sm">
                                <div className="row">
                                    <label htmlFor="editor1" className="col-xs-2 col-form-label" style={{"marginTop": "5px"}}>Name: </label>
                                    <div className="col-xs-10">
                                        <IgTextEditor
                                            ref="editorName"
                                            id="editor1"
                                            width="100%"
                                            keypress={this.handleTextEditorKeyPress}
                                            value={this.props.nameValue}/>
                                    </div>
                                </div>
                                <div className="row">
                                    <label htmlFor="editor2" className="col-xs-2 col-form-label" style={{"marginTop": "5px"}}>Stock: </label>
                                    <div className="col-xs-10">
                                        <IgNumericEditor
                                            ref="editorStock"
                                            id="editor2"
                                            width="100%"
                                            textAlign="left"
                                            keypress={this.handleTextEditorKeyPress}
                                            value={this.props.stockValue}/>
                                    </div>
                                </div>
                                <div className="row">
                                    <label htmlFor="editor3" className="col-xs-2 col-form-label" style={{"marginTop": "5px"}}>Price: </label>
                                    <div className="col-xs-10">
                                        <IgNumericEditor
                                            ref="editorPrice"
                                            id="editor3"
                                            width="100%"
                                            textAlign="left"
                                            keypress={this.handleTextEditorKeyPress}
                                            value={this.props.priceValue}/>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-md-6"><div style={{ "float": "right" }}><IgButton id="btnUpdate" labelText="Update" click={this.handleButtonUpdateClick} /></div></div>
                                    <div className="col-md-6"><div style={{ "float": "left" }}><IgButton id="btnDelete" labelText="Delete" click={this.handleButtonDeleteClick} /></div></div>
                                </div>

                            </div>
                        </div>
                    );
                },
                handleTextEditorKeyPress: function (e, args) {
                    if (args.key === $.ui.keyCode.ENTER) {
                        this.handleButtonUpdateClick(e);
                    }
                },
                handleTextEditorKeyDown: function (e) {
                    if (e.keyCode === $.ui.keyCode.ENTER) {
                        this.handleButtonUpdateClick(e);
                    }
                },
                handleButtonDeleteClick: function (e) {
                    var func = this.props.btnDeleteClicked;
                    if (func) {
                        func(e, this.props.rowId);
                    }
                },
                handleButtonUpdateClick: function (e) {
                    var func = this.props.btnUpdateClicked;
                    if (func) {
                        func(e,
                            this.props.rowId,
                            this.refs.editorName.igControl.value(),
                            this.refs.editorStock.igControl.value(),
                            this.refs.editorPrice.igControl.value());
                    }
                }
            });

            var IgDialogBox = React.createClass({
                render: function () {
                    return (
                        <IgDialog
                            id="dialog1"
                            ref="deleteDialog"
                            width="325px"
                            height="210px"
                            resizable="false"
                            headerText="Confirm Row Delete"
                            state={this.props.dialogState}
                            stateChanging={this.handleDialogStateChanging}>
                            <h3 ref="dialogText">Are you sure you want to delete row with ID {this.props.rowId} ?</h3>
                            <br />
                            <div className="col-md-6" style={{ "textAlign": "center" }}>
                                <IgButton id="btnAccept" labelText="Accept" click={this.handleDeleteDialogAccept} />
                            </div>
                            <div className="col-md-6" style={{ "textAlign": "center" }}>
                                <IgButton id="btnCancel" labelText="Cancel" click={this.handleDeleteDialogCancel} />
                            </div>
                        </IgDialog>
                    );
                },
                componentWillReceiveProps(nextProps) {
                  if (this.props.rowId !== nextProps.rowId) {
                    $(this.refs.dialogText).html("Are you sure you want to delete row with ID " + nextProps.rowId + " ?");
                  }
                },
                handleDialogStateChanging: function (evt, ui) {
                    this.props.dialogStateChanging(evt, ui);
                },
                handleDeleteDialogAccept: function () {
                    this.props.deleteDialogAccept();
                },
                handleDeleteDialogCancel: function () {
                    this.props.deleteDialogCancel();
                }               
            });
            // main component
            var App = React.createClass({
                componentDidMount() {
                console.log($(this).igGridSelection(this, 'selectRow', 1))
                },
                getInitialState: function () {
                    return {
                        // the view is the grid data source in this case
                        view: sourceData,
                        gridHeight: "400px",
                        gridWidth: "100%",
                        selectedRowId: -1,
                        deleteRowId: -1,
                        nameValue: null,
                        stockValue: null,
                        priceValue: null,
                        dialogState: "closed"
                    }
                },

                render: function () {
                    return (
                        <div id="bar">
                            <div className="row">
                                <div className="col-md-8" id="foo">
                                <IgHierarchicalGrid
                                    initialDataBindDepth={1}
                                    dataSource={sourceData}
                                    dataSourceType="json"
                                    responseDataKey="d"
                                    autoGenerateColumns={false}
                                    primaryKey="ID"
                                    columns={[
                                            { headerText: "ID", key: "ID", width: "50px", dataType: "number" },
                                            { headerText: "Name", key: "Name", width: "130px", dataType: "string" }
                                    ]}
                                    autoGenerateLayouts={false}
                                    columnLayouts={[
                                    {
                                        key: "Products",
                                            responseDataKey: "",
                                            childrenDataProperty: "Products",
                                            autoGenerateColumns: false,
                                            primaryKey: "ID",
                                            columns: [
                                                    { key: "ID", headerText: "ID", width: "25px" },
                                                    { key: "Name", headerText: "Product Name", width: "90px" },
                                                    { key: "Price", headerText: "Price", dataType: "number", width: "55px" }
                                            ]
                                        }
                                    ]}
                                />
                                </div>
                                <div id="editArea" className="col-md-4">
                                    <h3>Grid options</h3>
                                    <div className="well well-sm">
                                        <div className="row">
                                            <label htmlFor="editor2" className="col-xs-2 col-form-label" style={{"marginTop": "5px"}}>Width: </label>
                                            <div className="col-xs-10">
                                                <IgTextEditor id="editor2"
                                                    width="100%"
                                                    ref="editorGridWidth"
                                                    value={this.state.gridWidth}
                                                    valueChanged={this.widthChanged} />
                                            </div>
                                        </div>
                                        <div className="row">
                                            <label htmlFor="editor3" className="col-xs-2 col-form-label" style={{"marginTop": "5px"}}>Height: </label>
                                            <div className="col-xs-10">
                                                <IgTextEditor id="editor3"
                                                    width="100%"
                                                    ref="editorGridHeight"
                                                    value={this.state.gridHeight}
                                                    valueChanged={this.heightChanged} />
                                            </div>
                                        </div>
                                    </div>

                                    <IgEditBox
                                        ref="selectedRowInfo"
                                        btnDeleteClicked={this.editBoxHandleDelete}
                                        btnUpdateClicked={this.editBoxHandleUpdate}
                                        nameValue={this.state.nameValue}
                                        stockValue={this.state.stockValue}
                                        priceValue={this.state.priceValue}
                                        rowId={this.state.selectedRowId}
                                        />
                                </div>
                                <IgDialogBox
                                    dialogState={this.state.dialogState}
                                    rowId={this.state.deleteRowId}
                                    dialogStateChanging={this.handleDialogStateChanging}
                                    deleteDialogAccept={this.handleDeleteDialogAccept}
                                    deleteDialogCancel={this.handleDeleteDialogCancel}
                                />
                            </div>
                        </div>
                    );
                },
                /* helper functions */
                getGridInstance: function (gridRefName) {
                    gridRefName = gridRefName || "grid1";
                    return (this.refs[gridRefName] || {}).igControl;
                },
                getGridUpdating: function (gridRefName) {
                    var grid = this.getGridInstance(gridRefName);
                    if (!grid || !grid.element) {
                        return null;
                    }
                    return grid.element.data("igGridUpdating");
                },
                getNameByRowId: function (rowId) {
                    var grid = this.getGridInstance(),
                        Name, record;
                    if (rowId > -1 && grid) {
                        record = grid.dataSource.findRecordByKey(rowId) || {};
                        Name = record["Name"];
                    }
                    return Name;
                },
                getStockByRowId: function (rowId) {
                    var grid = this.getGridInstance(),
                        Stock, record;
                    if (rowId > -1 && grid) {
                        record = grid.dataSource.findRecordByKey(rowId) || {};
                        Stock = record["UnitsInStock"];
                    }
                    return Stock;
                },
                getPriceByRowId: function (rowId) {
                    var grid = this.getGridInstance(),
                        Price, record;
                    if (rowId > -1 && grid) {
                        record = grid.dataSource.findRecordByKey(rowId) || {};
                        Price = record["UnitPrice"];
                    }
                    return Price;
                },
                /* //helper functions */
                /* handle edit box specific events */
                editBoxHandleDelete: function (e, rowId) {                      
                    this.setState({
                        deleteRowId: rowId,
                        dialogState: "opened"
                    });
                },
                editBoxHandleUpdate: function (e, rowId, name, stock, price) {
                    var grid = this.getGridInstance(),
                        upd;
                    if (grid && rowId > -1) {
                        upd = this.getGridUpdating();
                        if (upd) {
                            upd.updateRow(rowId,
                                {
                                    "Name": name,
                                    "UnitsInStock": stock,
                                    "UnitPrice": price
                                });
                        }
                    }
                },
                handleDialogStateChanging: function (evt, ui) {
                    if(ui.action === "close" && this.state.dialogState === "opened" ) {
                        this.setState({ dialogState: "closed" });
                    }
                },
                handleDeleteDialogAccept: function () {
                    var grid = this.getGridInstance(),
                        rowId = this.state.deleteRowId,
                        upd;
                    if (grid && rowId > -1) {
                        upd = this.getGridUpdating();//grid.dataSource.deleteRow(rowId, true);
                        if (upd) {
                            upd.deleteRow(rowId);
                            this.setState({ selectedRowId: -1, deleteRowId: -1 });
                        }
                    }
                    this.setState({ dialogState: "closed" });
                },
                handleDeleteDialogCancel: function () {
                    this.setState({ dialogState: "closed" });
                },
                /* //handle edit box specific events */
                /* interactions with igGrid - rowDeleted, updated, etc. */
                gridRowUpdated: function (evt, ui) {
                    var rowId = ui.rowID;
                    if (this.state.selectedRowId !== rowId) {
                        return;
                    }
                    if (!ui.rowAdding &&
                        (ui.values["Name"] !== ui.oldValues["Name"] ||
                        ui.values["UnitsInStock"] !== ui.oldValues["UnitsInStock"] ||
                        ui.values["UnitPrice"] !== ui.oldValues["UnitPrice"])) {
                        this.setState({
                            nameValue: this.getNameByRowId(rowId),
                            stockValue: this.getStockByRowId(rowId),
                            priceValue: this.getPriceByRowId(rowId)
                        });
                    }
                },
                gridRowDeleted: function (evt, ui) {
                    var rowId = ui.rowID;
                    if (this.state.selectedRowId === rowId) {
                        this.setState({ selectedRowId: -1 });
                    }
                },
                gridRowSelectionChanged: function (evt, ui) {
                    var rowId = ui.row.id;
                    this.setState({ selectedRowId: rowId, 
                        nameValue: this.getNameByRowId(rowId),
                        stockValue: this.getStockByRowId(rowId),
                        priceValue: this.getPriceByRowId(rowId)
                    });
                },
                /* //interactions with igGrid - rowDeleted, updated, etc. */
                heightChanged: function (evt) {
                    // change grid height option
                    var editor = this.refs.editorGridHeight;
                    this.setState({ gridHeight: editor.igControl.value() });
                },
                widthChanged: function (evt) {
                    // change grid width option
                    var editor = this.refs.editorGridWidth;
                    this.setState({ gridWidth: editor.igControl.value() });
                },
                initialized: function(evt, ui) {
                    console.log('initialized', ui, $(ui), this, $(this))

                },
                dataRendered: function(evt, ui) {
                    console.log('dataRendered', evt, ui)
                },
                dataBound: function(evt, ui) {
                    console.log('dataBound', evt, ui)
                },
                rowsRendered: function(evt, ui) {
                    console.log('rowsRendered', evt, ui, this)
                  console.log($($.ig.react.core.getElement(this)))

                },
                rendered: function(evt, ui) {
                    console.log('rendered', evt, ui, this.refs.grid1)
                }
            });
/*
                gridRowSelectionChanged: function (evt, ui) {
                    var rowId = ui.row.id;
                    this.setState({ selectedRowId: rowId, 
                        nameValue: this.getNameByRowId(rowId),
                        stockValue: this.getStockByRowId(rowId),
                        priceValue: this.getPriceByRowId(rowId)
                    });
            */

            ReactDOM.render(
                <App />,
                document.getElementById("app")
            );
        </script>
    </div>
</div>

    <footer>
        <p>
            <a href="/igniteui-react/index.html">Home</a> |
            <a href="https://github.com/IgniteUI/igniteui-react/issues">Feedback &amp; Questions</a> |
            <a href="https://github.com/IgniteUI/igniteui-react">Clone &amp; Fork</a>
        </p>
        <p class="small">For more information or to download a trial of Ignite UI, please visit: <a href="https://igniteui.com">https://igniteui.com</a></p>
    </footer>

    <!--JavaScript refs-->
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.6.16/browser.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

    <!--IgniteUI refs-->
    <script src="https://secure-cdn-na.infragistics.com/igniteui/latest/js/infragistics.core.js"></script>
    <script src="https://secure-cdn-na.infragistics.com/igniteui/latest/js/infragistics.lob.js"></script>

    <!--React-->
    <script src="../../src/util/ignite-react.js"></script>
    <script src="../../src/components/igHierarchicalGrid.js"></script>
        <script src="../../src/components/igGrid.js"></script>
    <script src="../../src/components/igEditors.js"></script>
    <script src="../../src/components/igShared.js"></script>
    <script src="../../src/components/igDialog.js"></script>
    <script src="../../src/props/igGrid.js"></script>
    <script src="../../src/props/igHierarchicalGrid.js"></script>
    <script src="../../src/props/igEditors.js"></script>
    <script src="../../src/props/igShared.js"></script>
    <script src="../../src/props/igDialog.js"></script>
    <!--//React-->
    <!--IgniteUI refs-->
</body>
</html>
ChronosSF commented 7 years ago

Your definition is missing the id property that's necessary for the internal workings of the underlying HierarchicalGrid widget. Change it to something like:

<IgHierarchicalGrid
    id="grid1"
    initialDataBindDepth={1}
    dataSource={sourceData}
    dataSourceType="json"
    responseDataKey="d"
    autoGenerateColumns={false}
    primaryKey="ID"
    columns={[
        { headerText: "ID" , key: "ID" , width: "50px" , dataType: "number" },
        { headerText: "Name" , key: "Name" , width: "130px" , dataType: "string" }
    ]}
    autoGenerateLayouts={false}
    columnLayouts={[
        {
            key: "Products",
            childrenDataProperty: "Products",
            autoGenerateColumns: false,
            primaryKey: "ID",
            columns: [
                { key: "ID" , headerText: "ID" , width: "25px" },
                { key: "Name" , headerText: "Product Name" , width: "90px" },
                { key: "Price" , headerText: "Price" , dataType: "number" , width: "55px" }
            ]
        }
    ]} 
/>

The id prop for each component is marked as required so React will complain in the console that you missed it.

marc314 commented 7 years ago

Thanks man. Feel free to delete this issue.