uNmAnNeR / imaskjs

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

Deleting part of date not working in react-imask as imask. #193

Closed ejuo closed 5 years ago

ejuo commented 5 years ago

In react-imask deleting part of the date removes the remaining parts. react-imask

ejuo commented 5 years ago

I suspect the problem that for each key press, the mask is validated. Is that IMask.MaskedRange does not allow placeholderChar character to be entered.

@uNmAnNeR Can enable IMask.MaskedRange for placeholderChar?

ejuo commented 5 years ago

Find bad solution, but works:

<IMaskInput
  value={value}

  mask={Date}
  pattern={'d1d2{.}`m1m2{.}`Y'}
          blocks={{
              d1: {
              mask: IMask.MaskedRange,
              from: 0,
              to: 3,
            },
            d2: {
              mask: IMask.MaskedRange,
              from: 0,
              to: 9,
            },
            m1: {
              mask: IMask.MaskedRange,
              from: 0,
              to: 1,
            },
            m2: {
              mask: IMask.MaskedRange,
              from: 0,
              to: 9,
            },
            Y: {
              mask: IMask.MaskedRange,
              from: 1900,
              to: 2099,
            },
          }}
  format={ (date: Date) => {
    const day = String(date.getDate()).padStart(2, '0');
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const year = date.getFullYear();

    return [day, month, year].join('.');
  }}
  parse={ (str: string) => {
    const [day, month, year] = str.split('.');
    return new Date(Number(year), Number(month) - 1, Number(day));
  }}
  lazy={false}
  overwrite={true}

  onBlur={this.onBlur}
  onComplete={this.onComplete}
  onInput= {this.onChange}
/>
uNmAnNeR commented 5 years ago

Hi! Probably i don't get what exactly does not work. But yes, there were some issues with range mask, that was fixed recently and not released yet. But it might solve the problem and you can try it from master branch. Btw, have you tried it on vanila version so far? just to be sure that the problem is only React related.

Can enable IMask.MaskedRange for placeholderChar?

no, it does not work this way.

ejuo commented 5 years ago

I'm using controlled component, added listener on change event. That update value for IMask component for each key press. To reproduce it in vanila, you can copy typed value '12.1_.2009' and paste, and you get '12.12.____'.

ejuo commented 5 years ago

Then I delete first letter it's ok. Then second, year part shifts. In console onAccept event emitted twice. react-imask2

uNmAnNeR commented 5 years ago

thanks for details, i'll check if i can do smth.

ejuo commented 5 years ago

Thanks, @uNmAnNeR. I found the solution above, it is not very native, but it works. If the default realization cannot work according to some principles, you can close the problem.

ejuo commented 5 years ago

@uNmAnNeR, I made sandbox examples https://codesandbox.io/s/imask-date-problems-s50re All solutions not clear.

uNmAnNeR commented 5 years ago

Thanks

ejuo commented 5 years ago

@uNmAnNeR Tried to figure out the cause. That's what I think.

  1. I can be wrong, but, rebuild mask used unmasked value. And for masks eg. 01._2.2007 and 0_.12.2009 has one value 0122009. It is necessary to teach to build the mask bijectively or very carefully to cause its rebuilding.
  2. For the mask of type Date, updateOptions always calling rebuilding the mask. Even if the options have not changed. I can not see the full picture, as I investigated only the date mask. But I think this is not necessary.
  3. In react plugin, when component did updated, mask update options. It's right. To solve my problem, I'm forked react plugin and put the crutch here if (!getNumberFromValue(this.props.value).length) this.maskRef.updateOptions(maskOptions); Since I need to rebuild the mask only on an empty field to set lazy option.
ejuo commented 5 years ago

@uNmAnNeR made PR. Transferred the check and set the mask value from the date mask update function. Added function comparision for deep equal check. For good, I would get rid of this heavy comparison in objectIncludes. I would add the necessary options to the dictionary and compare only them.

uNmAnNeR commented 5 years ago

@ejuo hi! I've checked it. About objectIncludes i suppose it already works as you said. It finds all new options in current options. May be fact that a and b arguments is in reversed order is confusing.