1

Part of my tool allows a user to enter a string into a textfield, check if any words entered match with a preset array.

If the user's string contains a name object in the array then I want it to be replaced with a link.

I've created the function and onClick it should get the user's content, loop through the array to see if any names match the user's content and then replace that name with a link.

Currently, it's only doing it per array object where as I need it to replace all and only return one string.

  const generateContent = () => {
var arr1 = [{
link: 'https://www.link1.com/',
name: 'Link1'
}, {
  link: 'https://www.link2.com/',
    name: 'Link2'
}];

const findArrayItem =  arr1.find(obj => content.includes(obj.name))
const final = content.replaceAll(findArrayItem.name, "<a href=" + findArrayItem.link + ">" + findArrayItem.name + "</a>")

    setFinalContent(final)
  }

2 Answers 2

1

const content = 'Link1Link2';
const generateContent = (content) => {
  var arr1 = [
    {
      link: 'https://www.link1.com/',
      name: 'Link1',
    },
    {
      link: 'https://www.link2.com/',
      name: 'Link2',
    },
  ];

  const final = arr1.reduce((a, b) => {
    return a.replaceAll(b.name, '<a href=' + b.link + '>' + b.name + '</a>');
  }, content);

  return final;
};

generateContent(content);

Sign up to request clarification or add additional context in comments.

Comments

0

This is a possible implementation. It triggers the change when you hit a space after the link name to avoid an endless replace loop.

const { useState } = React // for inline use
// import { useState } from 'react' // for normal use

const linkMapping = [
  {
    link: 'https://www.link1.com/',
    name: 'Link1'
  },
  {
    link: 'https://www.link2.com/',
    name: 'Link2'
  }
]

const replaceToLink = (text, linkMapping) => {
  return linkMapping.reduce((acc, { name, link }) =>  {
    return acc.replaceAll(`${name} `, `<a href="${link}">${name}</a> `)
  }, text)
}

const App = () => {
  const [value, setValue] = useState('')
  
  const handleChange = ({ target }) => {
    setValue(target.value)
  }
  
  return (
    <div>
      <textarea value={value} onChange={handleChange} />
      <div dangerouslySetInnerHTML={{ __html: replaceToLink(value, linkMapping) }} />
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

2 Comments

This works great but only if a user types out the content. Is there a way for a user to paste the content in and it read it?
It works with paste too as long as you put a space after "Link1". You can enhance this behavior. The only important thing is to detect somehow whether the "Link1" text is wrapped within an anchor tag. If yes, skip replacing it again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.