This is a migrated thread and some comments may be shown as answers.

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

3 Answers 696 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Raef
Top achievements
Rank 1
Veteran
Raef asked on 29 May 2020, 04:16 AM

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

3 Answers, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 29 May 2020, 01:44 PM

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.
0
Raef
Top achievements
Rank 1
Veteran
answered on 29 May 2020, 03:11 PM

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

0
Stefan
Telerik team
answered on 01 Jun 2020, 01:37 PM

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.
Tags
General Discussions
Asked by
Raef
Top achievements
Rank 1
Veteran
Answers by
Stefan
Telerik team
Raef
Top achievements
Rank 1
Veteran
Share this question
or