NumericTextBox Scroll Wheel changes numeric value

1 Answer 284 Views
NumericTextBox
Jimmy
Top achievements
Rank 1
Iron
Jimmy asked on 16 Feb 2022, 01:57 PM
I am trying to stop the NumericTextBox  Scroll Wheel from changing the value in the Text Box.  

1 Answer, 1 is accepted

Sort by
1
Stefan
Telerik team
answered on 16 Feb 2022, 02:02 PM

Hello,

That can be done by stoping the wheel event propagation using the component ref:

https://stackblitz.com/edit/react-3zbode-ax72nd?file=app/main.tsx

Regards,
Stefan
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Jimmy
Top achievements
Rank 1
Iron
commented on 16 Feb 2022, 02:24 PM

I am fairly new to React.  We have created a component for the input.  Can you see how to make this happen using this code?

 

import React from "react"
import { connect } from "react-redux";
import { RouteComponentProps } from "react-router"
import { Label } from "reactstrap";
import { Col, Row } from "reactstrap";
import { ApplicationState } from "../../../../store";
import { DatePicker } from "@progress/kendo-react-dateinputs";
import * as CashModuleStore from '../../../../model/application/CashModuleStore';
import * as CDUBalanceStore from '../../../../model/aggregates/cdu/CDUBalanceStore';
import { CashModule } from "../../../../model";
import CDUBalanceUploadPAS from "../../../../model/aggregates/cdu/CDUBalanceUploadPAS";
import CDUBalanceUploadExcelPAS from "../../../../model/aggregates/cdu/CDUBalanceUploadExcel";
import CDU from '../../../../model/aggregates/cdu/CDU';
import { NumericTextBox } from "@progress/kendo-react-inputs";
type state = {
}
type OwnProps = {
    description: string;
    amount: number;
    date?: Date | null;
    amountName: string;
    dateName?: string;
    showDate?: boolean;
}
type CDUBalanceInputProps =
    CashModuleStore.CashModuleState &
    CDUBalanceStore.CDUBalanceState &
    typeof CashModule.CashModuleActions &
    typeof CDUBalanceUploadPAS.CDUBalanceUploadPASActions &
    typeof CDUBalanceUploadExcelPAS.CDUBalanceUploadExcelActions &
    typeof CDU.CDUActions &
    OwnProps &
    RouteComponentProps<{}>
class CDUBalanceInput extends React.Component<CDUBalanceInputProps, state>{
    processUpdate(name: string, value: any) {
        this.props.cduBalanceUploadIsModified(); //Flag the CDU as modified.
        this.props.updateCDUBalanceUploadInput(name, value); //Update the store.
    }
    handleFocus = (e) => {
        e.target.element.select()
    }
    public render(): React.ReactNode {
        return <React.Fragment>
            <Col sm={{ size: 12 }}>
                <Row style={{ marginTop: '5px' }}>
                    <Col sm={{ size: 3 }}>
                        <Row style={{ display: 'inline-block' }}>
                            <Label style={{ display: 'inline-block', textAlign: 'right' }}>{this.props.description}</Label>
                        </Row>
                    </Col>
                    <Col sm={{ size: 4 }}>
                        <NumericTextBox
                            format='c2'
                            spinners={false}
                            value={this.props.amount ?? 0}
                            name={this.props.amountName}
                            onChange={(e) => this.processUpdate(e.target.name, e.target.value)}
                            disabled={this.props.isCDUBalanceUploadLoading}
                            onFocus={this.handleFocus}
                        />
                    </Col>
                    {this.props.showDate && <Col sm={{ size: 3 }} style={{ marginLeft: '6px' }}>
                        <DatePicker
                            name={this.props.dateName}
                            value={this.props.date}
                            format="dd/MMM/yyyy"
                            defaultShow={false}
                            onChange={(e) => this.processUpdate(e.target.name, e.target.value)}
                            disabled={this.props.isCDUBalanceUploadLoading} />
                    </Col>}
                </Row>
            </Col>
        </React.Fragment>
    }
}
export default connect((state: ApplicationState, ownProps: OwnProps) => ({ ...state.cashModule, ...state.cduBalancePAS, ...ownProps }), {
    ...CashModule.CashModuleActions, ...CDUBalanceUploadPAS.CDUBalanceUploadPASActions, ...CDUBalanceUploadExcelPAS.CDUBalanceUploadExcelActions, ...CDU.CDUActions
})(CDUBalanceInput as any)
Stefan
Telerik team
commented on 16 Feb 2022, 02:39 PM

Hello,

There are two main points:

1) Create e ref to the component:

https://reactjs.org/docs/refs-and-the-dom.html

2) When the component mounts, add the event listener:

https://reactjs.org/docs/react-component.html#componentdidmount

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

3) Remove the event listener when the component un-mounts:

https://reactjs.org/docs/react-component.html#componentwillunmount

https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener

There are the steps when using a class component. Based on the code I see that you are using a class component.

Jimmy
Top achievements
Rank 1
Iron
commented on 16 Feb 2022, 03:21 PM

I tried to add it this way:

import React from "react"

import { connect } from "react-redux";
import { RouteComponentProps } from "react-router"
import { Label } from "reactstrap";
import { Col, Row } from "reactstrap";
import { ApplicationState } from "../../../../store";
import { DatePicker } from "@progress/kendo-react-dateinputs";
import * as CashModuleStore from '../../../../model/application/CashModuleStore';
import * as CDUBalanceStore from '../../../../model/aggregates/cdu/CDUBalanceStore';
import { CashModule } from "../../../../model";
import CDUBalanceUploadPAS from "../../../../model/aggregates/cdu/CDUBalanceUploadPAS";
import CDUBalanceUploadExcelPAS from "../../../../model/aggregates/cdu/CDUBalanceUploadExcel";
import CDU from '../../../../model/aggregates/cdu/CDU';
import { NumericTextBox } from "@progress/kendo-react-inputs";
type state = {
}
type OwnProps = {
    description: string;
    amount: number;
    date?: Date | null;
    amountName: string;
    dateName?: string;
    showDate?: boolean;
}
type CDUBalanceInputProps =
    CashModuleStore.CashModuleState &
    CDUBalanceStore.CDUBalanceState &
    typeof CashModule.CashModuleActions &
    typeof CDUBalanceUploadPAS.CDUBalanceUploadPASActions &
    typeof CDUBalanceUploadExcelPAS.CDUBalanceUploadExcelActions &
    typeof CDU.CDUActions &
    OwnProps &
    RouteComponentProps<{}>
const ref = React.useRef(null);
class CDUBalanceInput extends React.Component<CDUBalanceInputProps, state>{
    handleOnWheel = event => {
        event.stopPropagation();
    };
    componentDidMount(): void {
        ref.current.element.addEventListener('wheel', this.handleOnWheel);
    }
    processUpdate(name: string, value: any) {
        this.props.cduBalanceUploadIsModified(); //Flag the CDU as modified.
        this.props.updateCDUBalanceUploadInput(name, value); //Update the store.
    }
    handleFocus = (e) => {
        e.target.element.select()
    }
    public render(): React.ReactNode {
        return <React.Fragment>
            <Col sm={{ size: 12 }}>
                <Row style={{ marginTop: '5px' }}>
                    <Col sm={{ size: 3 }}>
                        <Row style={{ display: 'inline-block' }}>
                            <Label style={{ display: 'inline-block', textAlign: 'right' }}>{this.props.description}</Label>
                        </Row>
                    </Col>
                    <Col sm={{ size: 4 }}>
                        <NumericTextBox
                            format='c2'
                            spinners={false}
                            value={this.props.amount ?? 0}
                            name={this.props.amountName}
                            onChange={(e) => this.processUpdate(e.target.name, e.target.value)}
                            disabled={this.props.isCDUBalanceUploadLoading}
                            onFocus={this.handleFocus}
                        />
                    </Col>
                    {this.props.showDate && <Col sm={{ size: 3 }} style={{ marginLeft: '6px' }}>
                        <DatePicker
                            name={this.props.dateName}
                            value={this.props.date}
                            format="dd/MMM/yyyy"
                            defaultShow={false}
                            onChange={(e) => this.processUpdate(e.target.name, e.target.value)}
                            disabled={this.props.isCDUBalanceUploadLoading} />
                    </Col>}
                </Row>
            </Col>
        </React.Fragment>
    }
}
export default connect((state: ApplicationState, ownProps: OwnProps) => ({ ...state.cashModule, ...state.cduBalancePAS, ...ownProps }), {
    ...CashModule.CashModuleActions, ...CDUBalanceUploadPAS.CDUBalanceUploadPASActions, ...CDUBalanceUploadExcelPAS.CDUBalanceUploadExcelActions, ...CDU.CDUActions

})(CDUBalanceInputasany)

 

 

But I get this error:


Stefan
Telerik team
commented on 17 Feb 2022, 05:47 AM

Hello,

The error occurs because of this line:

`const ref = React.useRef(null);`
The useRef method is a hook that is only available in functional components, not class components.

I made a class version of the same example to showcase the approach:

https://stackblitz.com/edit/react-3zbode-px8k2o?file=app/main.tsx

Jimmy
Top achievements
Rank 1
Iron
commented on 17 Feb 2022, 02:56 PM

SO I tried to move this over to your version an still running into several errors :(

 

Jimmy
Top achievements
Rank 1
Iron
commented on 17 Feb 2022, 02:57 PM

Here are the errors:

Jimmy
Top achievements
Rank 1
Iron
commented on 17 Feb 2022, 02:57 PM

And this:

 

Stefan
Telerik team
commented on 17 Feb 2022, 02:59 PM

Hello,

These are all TypeScript errors. They can be resolved by setting `this.ref` as type `any`.
Jimmy
Top achievements
Rank 1
Iron
commented on 17 Feb 2022, 03:30 PM

That worked 100 percent.  Thank you for all the help...  You were awesome!!!!!
Tags
NumericTextBox
Asked by
Jimmy
Top achievements
Rank 1
Iron
Answers by
Stefan
Telerik team
Share this question
or