- vừa được xem lúc

Textarea có thể insert vào một đường link tại sao không?

0 0 7

Người đăng: Mai Ngọc Trí

Theo Viblo Asia

Nếu bạn làm về dự án có nhiều form thì chắc sẽ không tránh khỏi việc có thể copy paste một đường link vào input hoặc textarea nhỉ.

Nhưng vấn đề ở đây là input và textarea chỉ cho phép bạn paste vào một đường dẫn dạng văn bản chứ không phân biệt được đây là một đường link có thể click vào.

Ở bài viết này mình sẽ hướng dẫn bạn làm nó nhé. Bắt đầu nào ??????

Create component

Vì để có thể chèn một thẻ link vào thì bắt buộc ô textarea của mình nó phải là một thẻ div. Đơn giản là vì textarea bình thường không thể chèn thêm thẻ nào vào cả.

div nó có một thuộc tính là contenteditable nó cho phép bạn có thể gõ những gì mình thích vào đó y hệt như một ô textarea bình thường.

<div className="editor" contentEditable suppressContentEditableWarning
/>

Bạn có thể tự style css lại cho editor của mình thật đẹp nhé.

Event paste

Để có thể insert một thẻ link vào editor thì bạn cần phải handle event paste của editor nhé.

Mình gắn vào editor một ref để có thể handle event của nó.

const editorRef = useRef(null) <div className="editor" contentEditable suppressContentEditableWarning ref={editorRef}
/>

Bây giờ mình sẽ handle event paste của nó nhé.

 useEffect(() => { if (editorRef.current) { editorRef.current.addEventListener('paste', (e) => { e.preventDefault() const contentCopied = e.clipboardData.getData('text/plain') // lấy ra nội dung của bạn đã copy từ trước đó // Tạo một thẻ link để insert trực tiếp vào editor const el = `<div class="link" contenteditable="false"><a href="${contentCopied}" target="_blank">${contentCopied}</a></div>` document.execCommand("insertHTML", false, el) }) } }, [editorRef])

Ở đây nếu thẻ div mình vừa tạo ra có class="link" nó đang là một thẻ block nên sẽ gặp vấn đề là bạn sẽ không thể gõ chữ cùng hàng với nó được. Vậy thì nhớ thêm style cho thẻ div đó thành inline-block nhé.

Phân biệt link và text

Nếu chỉ làm như trên thì bạn chỉ mới có thể insert link vào và mặc định những thứ bạn copy paste nó đều hiển thị ra một cái link.

Bây giờ mình sẽ validate những nội dung được copy và phân chia nó ra làm 2 loại là text bình thường và url.

Function validate

function isUrlValid(userInput) { var res = userInput.match(/(http(s)?:\/\/.)?(www\.)?[_@.com:%._\+~#=]{2,256}\.[a-z]{2,6}\b([_@.com:%_\+.~#?&//=]*)/g); return !!res
}
 useEffect(() => { if (editorRef.current) { editorRef.current.addEventListener('paste', (e) => { e.preventDefault() const contentCopied = e.clipboardData.getData('text/plain') if (isUrlValid(contentCopied)) { const el = `<div class="link" contenteditable="false"><a href="${contentCopied}" target="_blank">${contentCopied}</a></div>` document.execCommand("insertHTML", false, el) } else { document.execCommand("insertText", false, contentCopied) } }) } }, [editorRef])

Convert link to text

Thay vì hiển thị những đường link bạn vẫn có thể thay thế đường link đó bằng một đoạn text tương ứng nhé.

VD: https://www.facebook.com/ ---> Facebook, ...

convertLinkToText.js

// Bạn có thể thêm những đường link mình cần vào đây nhé
const listLink = [ { link: "https://www.facebook.com", text: "Facebook", }, { link: "https://github.com", text: "Github", }, { link: "https://viblo.asia", text: "Viblo", }, { link: "https://www.google.com", text: "Google", },
] const convertLinkToText = (link) => { const existLink = listLink.find(item => link.includes(item.link)) return !!existLink ? existLink.text : link
} export default convertLinkToText
if (isUrlValid(contentCopied)) { const el = `<div class="link" contenteditable="false"><a href="${contentCopied}" target="_blank">${convertLinkToText(contentCopied)}</a></div>` document.execCommand("insertHTML", false, el) } else { document.execCommand("insertText", false, contentCopied)
}

Trên đây chỉ là một component nhỏ nhỏ mà mình tìm hiểu được và cũng cảm thấy hay hay nên chia sẻ cho những ai cần.

Mình không chắc là nó hoàn hảo nhé ? nếu gặp bug thì mình ráng fix thôi ???

Cảm ơn các bạn đã đọc bài viết nhá ???

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tìm hiểu về Redux Thunk

Chào mọi người, nếu bạn là người đã biết về React và đang làm quen với Redux chắc hẳn bạn đang rất mơ hồ về các khái niệm cơ bản của Redux như dispatch, store, action creator,... bạn còn đang vật lộn với đống document của Redux để hiểu những khái niệm đó và bạn nghe ai đó trong team nói về Redux Thu

0 0 373

- vừa được xem lúc

[React] Giới thiệu tổng quát về Redux Toolkit

1. Redux Toolkit (RTK) là gì và tại sao lại có nó. . .

0 0 6.6k

- vừa được xem lúc

Uống Pepsi code Vue đi - Uống Cocacola code React nha ;)

. (Nguồn ảnh: Internet). Chào các bạn, chào các bạn. Let's go . 1.

0 0 130

- vừa được xem lúc

Cài đặt taillwind css cho dự án React

Trong bài viết cùng mình tìm hiểu cách cài đặt tailwind css cho một dự án React sẵn có. .

0 0 128

- vừa được xem lúc

Formik vs React Hook Form (Phần 1)

Các lập trình viên Front End đều làm việc rất nhiều với form cùng sự phức tạp của ứng dụng. Do vậy chúng ta cần những thư viện form mạnh mẽ hỗ trợ quản lý các form state, form validation... Thành phần module. Formik bao gồm có 9 dependencies khác. . React Hook Form thì không có.

0 0 346

- vừa được xem lúc

Hướng dẫn React Redux cho người mới bắt đầu - Phần 1

Lời mởi đầu. Chào các bạn, ở thời điểm thực hiện bài viết này mình cũng là một người đang bắt đầu tìm hiểu và học với ReactJs và Redux, trong quá trình tìm hiểu đọc các tài liệu về thư viện này mình có tìm được một bài hướng dẫn khá hay nên đã quyết định chia sẻ với mọi người .

0 0 262