How to call parent function from child child hooks when they are in separate file

4 posts, 0 answers
  1. Raef
    Raef avatar
    6 posts
    Member since:
    May 2020

    Posted 28 May 2020 Link to this post

    Dear all,

    I have to call a parent function getPostsDetailLevl1() that update the state of my datagrid , i use in the gridcolumn a custom cell with hook function that display a button on the grid column.

    the parent class and the hook function are in two separate files.

    how to call my function when i click on my button from hook function ?

    this is the code :

    parent class :

    import { GridColumn as Column, Grid, GridDetailRow } from '@progress/kendo-react-grid';
     
    import MyCustomCell from '../grids/CustomCell';
    import React from 'react';
    import axios from "axios";
    import { filterBy } from '@progress/kendo-data-query';
    import gridDetailInputSecondLevel from '../gridsDetails/gridDetailInputSecondLevel';
     
    const loadingPanel = (
        <div className="k-loading-mask">
          <span className="k-loading-text">Loading</span>
          <div className="k-loading-image"></div>
          <div className="k-loading-color"></div>
        </div>
      );
     
    const dataStateDetail1 = {
        posts: [],
        sort: [],
        take: 25,
        skip: 0,
        total_record: 10000,
        pageNumber: 1,
        filterUrl: ''
      };
     
    class gridDetailInputFirstLevel extends GridDetailRow {
     
        terminalId = window.SERVER_DATA.terminalid;
        functionId = window.SERVER_DATA.functionid;
        hostname = window.SERVER_DATA.hostname;
     
        idfile = this.props.dataItem.idfile;
     
        state = {
            filter: {
                logic: "and",
                filters: []
            },
            filterInUrl: '',
            dataStateDetail1:  dataStateDetail1,
            isLoading: true
        };
     
        // constructeur
        constructor(props) {
        super(props);
        this.CustomCell = MyCustomCell();
        }
     
        componentDidMount() {
     
            this.getPostsDetailLevl1();
        }
     
        oncl = ()=>{console.log("button clicked");}
     
        render() {
            const { isLoading, dataStateDetail1 } = this.state;
                return (
                    <div>
                    {isLoading && loadingPanel}
                    <Grid
                    data={filterBy(dataStateDetail1.posts,dataStateDetail1.filter)}
                    skip={dataStateDetail1.skip}
                    take={dataStateDetail1.take}
                    total={dataStateDetail1.total_record}
                    pageable
                    filterable
                    sortable
                    onPageChange={this.pageChange}
                    filter={this.state.filter}
                    onFilterChange={this.onFilterChange}
                    total={this.state.dataStateDetail1.total_record}
     
                    detail={gridDetailInputSecondLevel}
                    expandField="expanded"
                    onExpandChange={this.expandChange}
                    >
                        <Column field="idfile" title="ID Fichier" filterable={false} width="120px"/>
                        <Column field="purchaseordernumber" title="Ordre d'achat" width="170px"/>
                        <Column field="statut" title="Statut" width="170px"/>
                        <Column filter="date" format="{0:yyyy-MM-dd}" field="podate" title="Date ordre d'achat" width="170px"/>
                        <Column field="partner" title="Partenaire" />
                        <Column field="potype" title="Type" width="170px"/>
                        <Column
                        width="200px"
                        filterable={false}
                        cell={this.CustomCell}/>
                    </Grid>
                    </div>
                );
        }
     
            // cette fct permet d'ouvrir une sous grid
            expandChange = (event) => {
                event.dataItem.expanded = event.value;
                // let item_no = event.dataItem.item_no;
                this.setState({ ...this.state });
                if (!event.value || event.dataItem.tt_itemWhsBin) {
                    return;
                }
            }
     
        // formatter les dates dans le fichier json
        replacerDateinJSON (key, value) {
            if (key === 'podate') {
                var d = new Date(value);
                d.setDate(d.getDate() + 1);
                return new Date(d);
            }
            return value;
          }
     
          formatDateForFiltre = (e) => {
            if (e.field === "podate")
                {
                    var d = new Date(e.value);              
                    var month = "" + (d.getMonth() + 1);
                    var day = "" + d.getDate();
                    var year = d.getFullYear();
                    if (month.length < 2) month = "0" + month;
                    if (day.length < 2) day = "0" + day;
                    return [day,month,year].join("/");
                }
                return e.value;
            }
     
        getPostsDetailLevl1() {
            axios
              .get(
     
                this.hostname+`edipo/xediPurchaseOrder.p?terminalid=` +
                this.terminalid +
                "&Funct=bb1.EdiManager" +
                "&FunctionID=" + this.functionid +
                "&pageSize=25" +
                "&skip=" + this.state.dataStateDetail1.skip +
                "&take=" + this.state.dataStateDetail1.take +
                "&page=" + this.state.dataStateDetail1.pageNumber +
                "&lastRecord=false" +
                "&filter[logic]=and&filter[filters][0][field]=idFile&filter[filters][0][operator]=eq&filter[filters][0][value]=" + this.idfile +
                (this.state.filterUrl ? this.state.filterUrl : '')
     
              )
              .then(response => {
     
                let pos = response.data.ProDataSet.tt_order ? response.data.ProDataSet.tt_order.map(dataItem => Object.assign({ selected: false }, dataItem)):[];
             
                // format date to dd/MM/yyyy
                pos = JSON.parse(JSON.stringify(pos), this.replacerDateinJSON);
     
                console.log("pos=",pos);
     
                this.setState({
                    dataStateDetail1: {
                    ...this.state.dataStateDetail1,
                    posts: pos,
                    total_record: response.data.ProDataSet.tt_Misc[0].total_record,
                },
                isLoading: false
                },()=>{console.log(this.state.dataStateDetail1.posts);});
              })
              .catch(error => this.setState({ error, isLoading: false  }));
          }
     
          pageChange = (event) => {
            this.setState({
                dataStateDetail1: {
                    ...this.state.dataStateDetail1,
                    skip: event.page.skip,
                    take: event.page.take,
                    pageNumber: (event.page.skip + event.page.take) / 25
                },
                isLoading: true
            },()=>{this.getPostsDetailLevl1();});
        }
     
        onFilterChange = (event) => {
     
            let filterUrl = ''; // créer le filtre à ajouter dans l'url
            if (event.filter != null){
            const filters = event.filter.filters;
            filters.map((filedValue,index) => {    
            filterUrl = filterUrl + "&filter[filters][" + (index + 1) +
            "][operator]=" + filedValue.operator + "&filter[filters][" +
            (index + 1) + "][value]=" + this.formatDateForFiltre (filedValue) + "&filter[filters][" + (index + 1) +
            "][field]=" + filedValue.field;      
            }  
            );
        }
                 
        console.log("filterUrl",filterUrl);
         
        this.setState({
                    dataStateDetail1: {
                        ...this.state.dataStateDetail1,
                                skip: 0},
                filter: event.filter,
                filterUrl,
                isLoading: true
            },()=>{this.getPostsDetailLevl1()});
        }
    }
     
    export default gridDetailInputFirstLevel;

     

    this is the hook function :

    import React, { useState } from "react";
     
    import { Button } from "@progress/kendo-react-buttons";
    import { GridCell } from "@progress/kendo-react-grid";
    import axios from "axios";
     
    function CustomCell() {
         
      function statutChange(dataItemx, props) {
     
        const SESSION = window.SERVER_DATA;
        let url = SESSION.hostname +
        `edipo/xediPurchaseOrder.p?terminalid=` +
        SESSION.terminalid +
        "&Funct=bb1.EdiManager" +
        "&FunctionID=" +
        SESSION.functionid +
        "&update=true"
        axios
          .post(
            url,
            dataItemx
          )
          .then((res) => props.getPostsDetailLevl1);
      }
      return class extends GridCell {
           
        render() {
          let { dataItem } = this.props;
          // const { oncl } = this.props;
          console.log("this.props = ",this.props);
          delete dataItem.selected;
          const dataItemx = JSON.stringify({ tt_order: [dataItem] });
          return (
            <td>
              <Button
                icon="check"
                style={{ marginRight: "5px" }}
                title="Accept"
                className="k-button"
                onClick={() => statutChange(dataItemx, this.props)}
              >
                Accepter
              </Button>
              <Button
                icon="close"
                title="Reject"
                className="k-button"
                onClick={() => {
                  console.log("rejected : ", this.props.dataItem);
                }}
              >
                Rejeter
              </Button>
            </td>
          );
        }
      };
    }
    export default CustomCell;

     

    Thank you for your help

  2. Stefan
    Admin
    Stefan avatar
    3034 posts

    Posted 29 May 2020 Link to this post

    Hello, Raef,

    Thank you for the code.

    We can send additional props to the custom cell regardless of its location (another file) using the approach shown here:

    https://www.telerik.com/kendo-react-ui/components/grid/cells/

    In the parent file:

    myCustomCell = (props) => <CustomCell {...props} getDetails={this.getPostsDetailLevl1}/>
    
    // in the Grid
    
    cell={this.myCustomCell}
    Then in the functional component:

    function CustomCell(props) {
    // later in the code
    
    props.getDetails()
    I hope this is helpful.

    Regards,
    Stefan
    Progress Telerik

    Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
    Our thoughts here at Progress are with those affected by the outbreak.
  3. Raef
    Raef avatar
    6 posts
    Member since:
    May 2020

    Posted 29 May 2020 in reply to Stefan Link to this post

    Hello Stefan

     

    Thank you for your response

    unfortunately, this is doesn't work, this is how i insert your changement :

    in parent :

    import MyCustomCell from '../grids/CustomCell';

     

    ....

    ....
    // constructeur
        constructor(props) {
        super(props);
        this.CustomCell = MyCustomCell();
        }
     
        componentDidMount() {
     
            this.getPostsDetailLevl1();
        }
     
        myCustomCell = (props) => <CustomCell {...props} getDetails={this.getPostsDetailLevl1}/>
     
        render() {
            const { isLoading, dataStateDetail1 } = this.state;
                return (

    ....

    ....

     

    in the grid :

    ....

    ....

    <Column
                        width="200px"
                        filterable={false}
                        cell={this.myCustomCell}/>
                    </Grid>

    ....

    ....

     

    this is what i receive

    Failed to compile.

    ./src/components/gridsDetails/gridDetailInputFirstLevel.jsx
      Line 58:32:  'CustomCell' is not defined  react/jsx-no-undef

    Search for the keywords to learn more about each error.

    it seems that he dosen't know <CustomCell/>

     

    could you help please

  4. Stefan
    Admin
    Stefan avatar
    3034 posts

    Posted 01 Jun 2020 Link to this post

    Hello, Raef

    Apologies for the misleading code snippet, I just noticed that the name of the file was CustomCell where the actual component is imported like MyCustomCell.

    This means that the code should be:

    myCustomCell = (props) => <MyCustomCell{...props} getDetails={this.getPostsDetailLevl1}/>
    Please have in mind that as I do not have full access to the application code, we can only give suggestions, but the actual names and implementation will depend on the application setup.

     

    Regards,
    Stefan
    Progress Telerik

    Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
    Our thoughts here at Progress are with those affected by the outbreak.
Back to Top