yairEO / tagify

🔖 lightweight, efficient Tags input component in Vanilla JS / React / Angular / Vue
https://yaireo.github.io/tagify/
Other
3.55k stars 436 forks source link

Limit the characters or remove the character if max exceeds. #1306

Closed khaziq-sfy034 closed 8 months ago

khaziq-sfy034 commented 8 months ago

Prerequisites

Demo Page - clone one of the below:

https://jsbin.com/jekuqap/edit?html,js,output

React issue template: https://codesandbox.io/s/tagify-react-issue-template-4ub1r?file=/src/index.js

I am using tagify in one of my react projects. I was trying to limit the max characters that a user can input in mix mode. A total of tags and text.

Somehow managed to removed the last tag using the onChange callback, but this is also not accurate as it will remove all the tags if user keeps on typing text.

const tagify = new Tagify(input, {
    mode: "mix",
    duplicates: true,
    placeholder: "Enter Text",
    callbacks: {
      change: (e) => {
        if (e.detail.value.length > 100) {
          tagify.removeTags();
        }
      },
    },
  });

Can we somehow set the useInput to false at this position I tried the below, but nothing happened.

callbacks: {
      change: (e) => {
        if (e.detail.value.length > 100) {
          tagify.removeTags();
          tagify.settings.userInput=false;
        }
      },
    },

Have been trying in many different ways but no success. In simple words the input text should be sliced after max char increase, and if there's a tag at the end it should be removed not sliced.

yairEO commented 8 months ago

For now you can use tagify.setContentEditable(false) to disallow editing

khaziq-sfy034 commented 8 months ago

If this is set to false the user cannot edit or update the text. There should be a way that user can remove the text and type until the limit reaches.

khaziq-sfy034 commented 8 months ago

isn't there a way that we can simply remove the characters those exceeded the max length ?

yairEO commented 8 months ago

you can tap into the input event and then count the number or characters and disallow submitting the form/field until your max count is satisfied.

const MAX_CHARS = 100;

const tagify = new Tagify(...)

tagify.on('input', e => {
  console.log(e.detail)

  // count the number of characters 

  // you can also call this with either `true` or an error string to mark the field as invalid:
  tagify.toggleScopeValidation(true || 'maximum characters reached')
})
khaziq-sfy034 commented 8 months ago

So I managed to disable the button by getting the total. But I am facing weird behavior in non react input, it clears the input if state is called inside the INPUT callback, but works fine in the react version.

Issues facing with react and non react version:

  1. When added tag from the selected it always takes the cursor to the first position in the textearea, in react input comp.
  2. Slice the text only works for the first time using the change callback, if input callback used in the react comp it slices the text if there are spaces and takes the cursor to the first position. In non react working there's a weird behaviour cannot call react hooks inside the input call back.
  3. In non react comp it only updates the state if you click away from the textarea.

Expected: The react component can somehow slice down the text to the max length and allows the tags to be entered accurately using the select.

Sharing the sandbox link below https://codesandbox.io/p/sandbox/tagify-test-5ftnvt

khaziq-sfy034 commented 8 months ago

Also I just noticed tha in react version if you add the tag by clicking on it from the dropdown it moves the cursor to the start of sentence, if you use keyboard to add it then works fine. But in the normal version it works perfect the cursor moves to the end position of added tag using click.

yairEO commented 8 months ago

you should open a new issue and please be clearer. You mean caret, not cursor which is the mouse pointer. I can barely understand the issue.