uNmAnNeR / imaskjs

vanilla javascript input mask
https://imask.js.org
MIT License
4.95k stars 257 forks source link

TypeError: Cannot read property 'addEventListener' of undefined #163

Closed iamricky closed 5 years ago

iamricky commented 5 years ago

I've run into an issue, while using react-imask's mixin w/Ant Design's Input component. Here's a simple implementation:

import React from "react";
import { IMaskMixin } from "react-imask";
import { Input } from "antd";

export default IMaskMixin(({ ...props }) => <Input {...props} />);

and here are the errors I get:

HTMLMaskElement._toggleEventHandler
node_modules/imask/dist/imask.js:2935

  2932 |   }
  2933 | 
  2934 |   if (handler) {
> 2935 |     this.input.addEventListener(event, handler);
  2936 |     this._handlers[event] = handler;
  2937 |   }
  2938 | }

(anonymous function)
node_modules/imask/dist/imask.js:2907

  2904 |   var _this2 = this;
  2905 | 
  2906 |   Object.keys(handlers).forEach(function (event) {
> 2907 |     return _this2._toggleEventHandler(HTMLMaskElement.EVENTS_MAP[event], handlers[event]);
  2908 |   });
  2909 | }
  2910 | /**

HTMLMaskElement.bindEvents
node_modules/imask/dist/imask.js:2906

  2903 | value: function bindEvents(handlers) {
  2904 |   var _this2 = this;
  2905 | 
> 2906 |   Object.keys(handlers).forEach(function (event) {
  2907 |     return _this2._toggleEventHandler(HTMLMaskElement.EVENTS_MAP[event], handlers[event]);
  2908 |   });
  2909 | }

Any idea what could be the cause of this issue or how I can address it?

uNmAnNeR commented 5 years ago

hi! Sorry, don't have time to investigate Ant, but by this error it seems that HTML-element was not passed to imask plugin. You probably have to change code a little bit to correctly pass native element reference to imask mixin. Take a look as it was done for IMaskInput and try to modify it according to Ant docs.

iamricky commented 5 years ago

Hey, I ended up switching to Text Mask and got it up running instantly by creating a DOM ref. Thanks for replying anyways.

AdrianoRuberto commented 4 years ago

As Text Mask is not maintained anymore, here a solution to have an ant design "look" input:

IMaskMixin(({ inputRef, ...props }) => (
  <input className="ant-input" ref={inputRef} {...props} />
));
c01nd01r commented 3 years ago

To get the original input element, we can use callback on the ref prop and extract the element from input field of <Input/> component instance:

// types.d.ts
// based on https://github.com/uNmAnNeR/imaskjs/issues/329#issuecomment-708418004
export function IMaskMixin<T, D>(
  Component: React.ComponentType<{ inputRef: React.RefCallback<D> } & T>,
): React.ComponentType<T & IMaskInputProps>;

// NumberField.tsx
import React from 'react';
import { Input, InputProps } from 'antd'; // v. 4.5.14
import { IMaskMixin } from 'imask-react'

const MaskedInput = IMaskMixin<InputProps, HTMLInputElement>(({ inputRef, ...props }) => {
  const extractInputRef = React.useCallback(
    (inst: React.ElementRef<typeof Input>) => inputRef(inst?.input),
    [inputRef],
  );

  return <Input ref={extractInputRef} {...props} />;
});

export const NumberField = () => <MaskedInput mask={Number} size="large" />;