Telerik Forums
KendoReact Forum
1 answer
128 views
I was wondering if we can draw objects in kendo react like rectangles and drag and drop them to different groups and join different groups by dynamically sized arrows?
Stefan
Telerik team
 answered on 25 Jun 2020
2 answers
454 views
Is there a way to customize the style of title of the window?
Like change the color of title heading and changing title colour itself.
Any help would be highly appreciated.
Tushaar
Top achievements
Rank 1
Veteran
 answered on 24 Jun 2020
13 answers
2.9K+ views

Hi

I'm using this example from the docs for my project: https://www.telerik.com/kendo-react-ui/components/grid/editing/editing-in-cell/

1) What is the editField in state used for in this example as it doesn't appear to affect anything

2) I've only got one cell in the grid that I want to edit. While setting editable={false} on the other columns stops them from being editable it doesn't stop them from getting the onClick enterEdit, I thought I could be able to do my own custom filtering here but it appears the editable prop isn't passed through.

3) How would you recommend sending data to the server after a user has updated the cell, I don't want to use a save changes button. I would like the data to be sent after the user has removed focus from the input so exitEdit seems perfect, but it doesn't fire unless you click off the row, if you click on another cell nothing happens.

4) I have a default value for this cell that says required if it's blank. On clicking the cell it clears the value so the input is empty. If the user doesn't add anything it should add the required value back on so it can be seen in the grid again. It works when I click away from the row but clicking on another cell the value stays blank.

I would be great if you could help me with these questions.

Thanks

 

Stefan
Telerik team
 answered on 24 Jun 2020
3 answers
695 views

Hello community,
I had a use case in which i want to shift the Kendo React window to bottom right of window on minimizing by using the button on toolbar(not by a separate button). And by default, it should be on top right.

Initially, window should be in top left as shown in first
figure , on minimizing, it should go to bottom right as shown in second
figure.

Can somebody help me with this issue?
Any help would be highly appreciated.

Tushaar
Top achievements
Rank 1
Veteran
 answered on 23 Jun 2020
1 answer
368 views

I decide to use webpack external to dynamically load the scipt files using CDN links. But, I am getting the below script error.

react-dom.production.min.js:125 TypeError: Cannot read property 'Button' of undefined
    at c (main.js:1)
    at we (react-dom.production.min.js:84)
    at zj (react-dom.production.min.js:226)
    at Th (react-dom.production.min.js:152)
    at tj (react-dom.production.min.js:152)
    at Te (react-dom.production.min.js:146)
    at Ja (react-dom.production.min.js:224)
    at md (react-dom.production.min.js:173)
    at react-dom.production.min.js:175
    at Rh (react-dom.production.min.js:147)
Me @ react-dom.production.min.js:125
react-dom.production.min.js:161 Uncaught TypeError: Cannot read property 'Button' of undefined
    at c (main.js:1)
    at we (react-dom.production.min.js:84)
    at zj (react-dom.production.min.js:226)
    at Th (react-dom.production.min.js:152)
    at tj (react-dom.production.min.js:152)
    at Te (react-dom.production.min.js:146)
    at Ja (react-dom.production.min.js:224)
    at md (react-dom.production.min.js:173)
    at react-dom.production.min.js:175
    at Rh (react-dom.production.min.js:147)

I know that Kendo React components could loaded only with script files but I want maintain the TypeScript standard. So, it is not possible. 

I have attached the simple example application. Please help me to clear this. I have gone through multiple resource but not able to get it worked with Kendo component. Without Kendo there is no issue. 

 

Stefan
Telerik team
 answered on 23 Jun 2020
2 answers
664 views

Hi  everybody

I was wondering how to style the tooltip, preferrably with styled components. It should have a white background and black font color. The text should spread over 3 lines and the tooltip should have a drop shadow.

But this looks not at all what I expect.

const StyledTooltip = styled(Tooltip)`
  background: white;
  color: black;
  height: 116px;
`;

 

I don't need a full solution, but a hint, how to style the tooltip.

Thanks in advance

Lukas

 

Lukas
Top achievements
Rank 1
 answered on 23 Jun 2020
6 answers
450 views

Hi,

I'm trying to figure out how to package my solution based on the "Create-React-App" template (TypeScript). I want to use the Externals node in the webpack configuration to ensure the KendoReact packages are excluded from the packaging procedures.

I saw this article: https://www.telerik.com/kendo-react-ui/components/installation/scripts-only . However, this approach means i need to reference all controls via the Window object. I rather keep the code base as is, so using import statements like

import { Grid, GridColumn as Column } from "@progress/kendo-react-grid

and use the control in Jsx. Is this possible?

Best regards,

Ruud

Stefan
Telerik team
 answered on 18 Jun 2020
1 answer
389 views

Does anyone know where I could find an example of a Kendo React Grid that is databound programmatically to an API Endpoint data source.

The paging would be done by passing a page number to the Endpoint.

I have no idea how to sort or filter the entire dataset if the grid is only showing a subset (page) of the data.

Stefan
Telerik team
 answered on 17 Jun 2020
1 answer
398 views
Hi, I'm currently working on react functional component using Kendo React Grid. But, Couldn't process (using process from kendo-data-query)

data using functional state variable. Could you please provide a Kendo React Grid functional component (using useState, useEffect..) example?

 

Below is code i'm working on:

import React, { useEffect, useState } from "react";
import { getAllFmsForms } from "../../apis/fmsFormApi";
import { Grid, GridColumn } from "@progress/kendo-react-grid";
import { process } from "@progress/kendo-data-query";
import "@progress/kendo-theme-bootstrap/dist/all.css";
 
const Forms = () => {
  const [formsList, setFormsList] = useState([]);
 
  const dataStateObj = {
    skip: 0,
    take: 20,
    sort: [{ field: "formNumber", dir: "desc" }],
    group: [{ field: "formNumber" }],
  };
 
  useEffect(() => {
    const getAllForms = async () => {
      try {
        const response = await getAllFmsForms();
        setFormsList(response);
      } catch (error) {
        console.log("error in getAllForms ===> ", error);
    };
 
    getAllForms();
  }, []);
 
  return (
    <>
      <h3>List</h3>
        <Grid
          sortable
          filterable
          pageable={{ buttonCount: 4, pageSizes: true }}
          data={process(formsList,dataState)} ---> error
          onDataStateChange={(e) => {}}
        >
          <GridColumn field="formNumber" title="Form Number" />
          <GridColumn field="formTitle" title="Form Title" />
          <GridColumn
            field="revisionDate"
            title="Revision Date"
          />
          <GridColumn field="formStatus" title="Form Status" />
          <GridColumn field="responsibleOffice" title="Office" />
        </Grid>
    </>
  );
};
 
export default Forms;

 

I've tried below way too:

  const [dataState, setDataState] = useState({
    dataResult: process(formsList, dataStateObj),  ----> error with dataStateObj
    dataState: dataStateObj,
  });

Stefan
Telerik team
 answered on 16 Jun 2020
2 answers
1.6K+ views

Hello,

https://imgur.com/a/1zohd9u

I ask how to rerender master grid when i click in button from the detail grid (look the picture).

Once i click in Rejected/Accepted button in detail grid, the database will be updated and the statut field of master grid change (in database).

but the new value not displayed because i have to manually refresh the page.

I need to setState the data of the master grid to refresh it and display the updated value of Statut field knowing that the button is in detail grid, so how to get access to function that update the state of master grid data ?

Thank you

master grid :

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;
 
    jobId = this.props.dataItem.jobId;
 
    state = {
        filter: {
            logic: "and",
            filters: []
        },
        filterInUrl: '',
        dataStateDetail1:  dataStateDetail1,
        isLoading: true
    };
 
    // constructeur
    constructor(props) {
    super(props);
    this.CustomCell = MyCustomCell(this.getPostsDetailLevl1);
    }
 
    componentDidMount() {
 
        this.getPostsDetailLevl1();
    }
     
    // MycustomParam = (props) => <MyCustomCell {...props} myfonct = {this.getPostsDetailLevl1}/>
    // {...props} spread operator
 
    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="jobId" title="JOB ID" filterable={false} width="120px"/>
                    <Column field="PurchaseOrderNumber" title="PO NUMBER" width="170px"/>
                    <Column field="Statut" title="STATUS" width="170px"/>
                    <Column filter="date" format="{0:yyyy-MM-dd}" field="PODate" title="PO DATE" width="170px"/>
                    <Column field="ReceiverISA" title="PARTNER" />
                    <Column field="POType" title="PO 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 jobId = event.dataItem.jobId;
            this.setState({ ...this.state });
             if (!event.value || event.dataItem.tt_order_line) {
                return;
            }
        }
 
/*     // par la programmation laisser le row expanded
    keepExpanded = (dataItem) => {
        dataItem.expanded = true;
        this.setState({});
    } */
 
    // 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 = () => {
/*         let ji;
        if (d != undefined) {
            ji = d.tt_order[0].jobId;
        } */
        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]=jobId&filter[filters][0][operator]=eq&filter[filters][0][value]=" + this.jobId +
            (this.state.filterUrl ? this.state.filterUrl : '')
 
          )
          .then(response => {
 
            let pos = response.data.ProDataSet.tt_order ? response.data.ProDataSet.tt_order:[];
            // let pos = response.data.ProDataSet.tt_order ? response.data.ProDataSet.tt_order.map(dataItem => ji===dataItem.jobId?Object.assign({ expanded: !dataItem.expanded }, dataItem):dataItem):[];
 
            // format date to dd/MM/yyyy
            pos = JSON.parse(JSON.stringify(pos), this.replacerDateinJSON);
 
            this.setState({
                dataStateDetail1: {
                ...this.state.dataStateDetail1,
                posts: pos,
                total_record: response.data.ProDataSet.tt_Misc[0].total_record,
            },
            isLoading: false
            });
          })
          .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;

 

detail grid :

import { GridColumn as Column, Grid, GridDetailRow } from '@progress/kendo-react-grid';
import { Dialog, DialogActionsBar } from '@progress/kendo-react-dialogs';
import React, { useState } from 'react';
 
import { Button } from "@progress/kendo-react-buttons";
import MyCustomCell from '../grids/CustomCell';
import axios from "axios";
import { filterBy } from '@progress/kendo-data-query';
 
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 dataStateDetail2 = {
    posts: [],
    sort: [],
    take: 25,
    skip: 0,
    total_record: 10000,
    pageNumber: 1,
    filterUrl: ''
  };
 
 
 const ConfirmAcceptPoLine =  (props) =>  {
 
    return (
        <td>
          <Button
            icon="track-changes-enable"
            title="Confirm"
            primary={true}
            className="k-button"
            onClick={props.myProp}
            style={{ paddingLeft:55, paddingRight:55 }}
          >
                         Envoyer        
          </Button>
        </td>
    );
}
 
 
class gridDetailInputSecondLevel extends GridDetailRow {
 
    terminalId = window.SERVER_DATA.terminalid;
    functionId = window.SERVER_DATA.functionid;
    hostname = window.SERVER_DATA.hostname;
 
    PurchaseOrderNumber = this.props.dataItem.PurchaseOrderNumber;
 
    rowRender(trElement, props) {
        const st = props.dataItem.Statut;
        const green = { backgroundColor: "rgb(55, 180, 0,0.32)" };
        const red = { backgroundColor: "rgb(243, 23, 0, 0.32)" };
        const defau = {};
        let val = {};
        switch(st) {
            case 'Accepted':  val = green;
            break;
            case 'Rejected':  val = red;
            break;
            default:  val = defau;
                     }
        const trProps = { style: val    };
        return React.cloneElement(trElement, { ...trProps }, trElement.props.children);
    }
     
    state = {
        filter: {
            logic: "and",
            filters: []
        },
        filterInUrl: '',
        dataStateDetail2:  dataStateDetail2,
        isLoading: true,
        visible: false
    };
 
    // constructeur
    constructor(props) {
    super(props);
    this.CustomCell = MyCustomCell(this.getPostsDetailLevl2);
    }
 
    toggleDialog = () => {
        this.setState({
            visible: !this.state.visible
        });
    }
 
    toggleDialogNo = () => {
        this.setState({
            visible: !this.state.visible
        });
 
        console.log("Nooooo");
    }
 
    toggleDialogYes = () => {
        this.setState({
            visible: !this.state.visible
        });
         
 
        this.processOrdre();
 
 
 
    }
 
 
    componentDidMount() {
 
        this.getPostsDetailLevl2();
 
    }
 
    MyCell = (props) => <ConfirmAcceptPoLine {...props} myProp={this.toggleDialog} />
 
    render() {
        const { isLoading, dataStateDetail2 } = this.state;
            return (
                <div>
                {isLoading && loadingPanel}
                <Grid
                data={filterBy(dataStateDetail2.posts,dataStateDetail2.filter)}
                skip={dataStateDetail2.skip}
                take={dataStateDetail2.take}
                total={dataStateDetail2.total_record}
                pageable
                filterable
                sortable
                // height="200px"
                onPageChange={this.pageChange}
                filter={this.state.filter}
                onFilterChange={this.onFilterChange}
                total={this.state.dataStateDetail2.total_record}
                rowRender={this.rowRender}
                >
                    <Column field="PurchaseOrderNumber" title="PO Number" filterable={false}/>
                    <Column field="POLineNumber" title="PO Line Number" />
                    <Column field="Statut" title="STATUS" />
                    <Column field="VendorProductNumberCode" title="ITEM" />
                    <Column field="Descriptionsequence" title="DESCRIPTION" />
                    <Column field="OrderedQty" title="ORDERED QTY" />
                    <Column field="SellingPrice" title="SELLING PRICE" />
                    <Column
                    width="200px"
                    filterable={false}
                    cell={this.CustomCell }
                    footerCell={this.MyCell}
                    />
                </Grid>
                {this.state.visible && <Dialog title={"Please confirm"} onClose={this.toggleDialog}>
                    <p style={{ margin: "25px", textAlign: "center" }}>Are you sure you want to continue?</p>
                    <DialogActionsBar>
                        <button className="k-button" onClick={this.toggleDialogNo}>No</button>
                        <button className="k-button" onClick={this.toggleDialogYes}>Yes</button>
                    </DialogActionsBar>
                </Dialog>}
                </div>
            );
    }
 
    // formatter les dates dans le fichier json
    replacerDateinJSON (key, value) {
        if (key === 'deliveryreq') {
            var d = new Date(value);
            d.setDate(d.getDate() + 1);
            return new Date(d);
        }
        return value;
      }
 
      formatDateForFiltre = (e) => {
        if (e.field === "deliveryreq")
            {
                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;
        }
 
    getPostsDetailLevl2 = () => {
        axios
          .get(
            this.hostname+`edipo/xediPurchaseOrderLine.p?terminalid=` +
            this.terminalId +
            "&Funct=bb1.EdiManager" +
            "&FunctionID=" + this.functionId +
            "&pageSize=25" +
            "&skip=" + this.state.dataStateDetail2.skip +
            "&take=" + this.state.dataStateDetail2.take +
            "&page=" + this.state.dataStateDetail2.pageNumber +
            "&lastRecord=false" +
            "&filter[logic]=and&filter[filters][0][field]=PurchaseOrderNumber&filter[filters][0][operator]=eq&filter[filters][0][value]=" + this.PurchaseOrderNumber +
            (this.state.filterUrl ? this.state.filterUrl : '')
          )
          .then(response => {
 
            let pos = response.data.ProDataSet.tt_order_line ? response.data.ProDataSet.tt_order_line:[];
         
            // format date to dd/MM/yyyy
            pos = JSON.parse(JSON.stringify(pos), this.replacerDateinJSON);
 
 
            this.setState({
                dataStateDetail2: {
                ...this.state.dataStateDetail2,
                posts: response.data.ProDataSet.tt_order_line,
                total_record: response.data.ProDataSet.tt_Misc[0].total_record,
            },
            isLoading: false
            },()=>{console.log(this.state.dataStateDetail2.posts);});
          })
          .catch(error => this.setState({ error, isLoading: false  }));
      }
 
      pageChange = (event) => {
        this.setState({
            dataStateDetail2: {
                ...this.state.dataStateDetail2,
                skip: event.page.skip,
                take: event.page.take,
                pageNumber: (event.page.skip + event.page.take) / 25
            },
            isLoading: true
        },()=>{this.getPostsDetailLevl2();});
    }
 
    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]=" + filedValue.value + "&filter[filters][" + (index + 1) +
        "][field]=" + filedValue.field;      
        }  
        );
    }
            this.setState({
                dataStateDetail2: {
                    ...this.state.dataStateDetail2,
                            skip: 0},
            filter: event.filter,
            filterUrl,
            isLoading: true
        },()=>{this.getPostsDetailLevl2()});
    }
 
    processOrdre = () => {
 
      const SESSION = window.SERVER_DATA;
        let url = SESSION.hostname +
        "edipo/xediPurchaseOrder.p?terminalid=" +
        SESSION.terminalid +
        "&Funct=bb1.EdiManager" +
        "&FunctionID=" +
        SESSION.functionid +
        "&po=" + this.PurchaseOrderNumber + "&processed=yes"
        axios
          .post(url)
          .then((res) => {console.log("Processed");});
      }
 
     
}
 
export default gridDetailInputSecondLevel;

 

 

 

 

Raef
Top achievements
Rank 1
Veteran
 answered on 11 Jun 2020
Narrow your results
Selected tags
Tags
+? more
Top users last month
Bohdan
Top achievements
Rank 3
Iron
Iron
Iron
Rob
Top achievements
Rank 3
Bronze
Bronze
Iron
Elliot
Top achievements
Rank 1
Iron
Iron
Iron
Sunil
Top achievements
Rank 1
Cynthia
Top achievements
Rank 1
Iron
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Bohdan
Top achievements
Rank 3
Iron
Iron
Iron
Rob
Top achievements
Rank 3
Bronze
Bronze
Iron
Elliot
Top achievements
Rank 1
Iron
Iron
Iron
Sunil
Top achievements
Rank 1
Cynthia
Top achievements
Rank 1
Iron
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?