RonaldJerez / vue-input-facade

A lightweight and dependency free input masking library created specific for Vue
https://ronaldjerez.github.io/vue-input-facade/latest/
182 stars 27 forks source link

Money amount masking #1

Closed flamedmg closed 4 years ago

flamedmg commented 4 years ago

Having troubles using your amazing library to mask money amounts. I'm using the following mask

["$###################", "$###,###,###,###", "$##,###,###,###", "$#,###,###,###", "$###,###,###", "$##,###,###", "$#,###,###", "$###,###", "$##,###", "$#,###", "$###"]

With the following masks the value 123 isn't properly formatted: $1,23

I found that function dynamic is selecting mask that will be applied. Could you please suggest how to handle money amount?

flamedmg commented 4 years ago

Looks like i found solution with minimal impact on the codebase:

export function dynamic(value, config = {}) {
  const masks = config.masks.slice().sort((a, b) => a.length - b.length)
  const withConfig = (overrides) => Object.assign({}, config, overrides)
  const fullRawValue = formatter(value, withConfig({ mask: masks[masks.length - 1], short: true }))

  const compareWithFullRawValue = (currentMask) => {
    const maskedVal = formatter(value, withConfig({ mask: currentMask, short: true }))
    return maskedVal.raw === fullRawValue.raw
  }

  for (let i = 0; i < masks.length; i++) {
    const currentMask = masks[i]
    const nextMask = masks[i + 1]

    if (!nextMask || compareWithFullRawValue(currentMask)) {
      return formatter(value, withConfig({ mask: currentMask }))
    }
  }

  return new FacadeValue() // empty masks
}

Are you interested in PR

All tests are passing, including my own currency and works good on the webpage too.

RonaldJerez commented 4 years ago

Hello @flamedmg yes PR are welcome if you have a way to fix it. I can't tell what has changed based on the code snippet above, but open the PR and I'll review it.

RonaldJerez commented 4 years ago

On 2nd though. While what you have highlighted is definitely a bug that needs to be fixed. I do believe what you are trying to accomplish could be handled better than using that many different dynamic masks.

In the beta branch, I am working on a feature to allow to pipe the value through an additional formatting function supplied by the consumer.

Run the beta branch locally then in the dev page try this code, notice the pipe property:

const money = (value) => {
  if (value.unmasked) {
    const formatted = value.unmasked.match(/\d{1,3}/g).join(',')
    value.masked = `\$${formatted}`
    return true
  }
}

let value = ''

<example label="Enter Dollar Amount">
  <input-facade v-model="value" mask="#########" :pipe="money" masked />
</example>

<display :value="value" />

Also available in this jsFiddle you can also install the beta using npm i vue-input-facade@beta

My initial use case for this feature is no longer relevant so I didn't continue its development but if there is a need for it I could finish it and merge it into master.

jwkicklighter commented 4 years ago

Hey @RonaldJerez, just recently came across this project and wanted to take a look at open issues before adding it to our project.

I like the idea you have in that example/feature, I just have a small suggestion to consider changing the prop name to something like formatter, format-fn, etc. In my opinion, using something along these lines provides a clearer description of what this prop is used for. Could even put "pre" or "post" in the prop (e.g. post-formatter) to convey when in the processing workflow this function gets called. Just some thoughts from new eyes!

RonaldJerez commented 4 years ago

Thanks @jwkicklighter i think that’s a great idea I would look into changing the prop into something more descriptive.

RonaldJerez commented 4 years ago

@jwkicklighter I renamed it to formatter in the latest beta release npm -i vue-input-facade@beta

Closing this issue as I have proposed a workaround using the latest beta release. flamedmg has created a PR but have not addressed the comments. If this is still an issue we can reopen it and continue the conversation.

RonaldJerez commented 4 years ago

:tada: This issue has been resolved in version 1.2.0-beta.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

RonaldJerez commented 4 years ago

I found a separate issue in regards to UK postal code. The fix for that actually fixes this issue as well.

RonaldJerez commented 4 years ago

:tada: This issue has been resolved in version 1.3.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: