Pasting into multiple fields at once
I recently came across a situation where I wanted to extract YouTube video data into a form to feed to an LLM to extract some information. I wanted to collect the video title, description, and transcript. I wrote a simple Chrome extension to extract this information from the current video in the tab and copy it as a json object to the clipboard.
let title = await getVideoTitle();
let description = await getVideoDescription();
let transcript = await getVideoTranscript();
let data = JSON.stringify({title, description, transcript})
await navigator.clipboard.writeText(data);
Each of these async functions uses css selectors and document.querySelector
to get a handle on the appropriate elements, click them if needed, and then essentially get the text via element.textContent
. The end result is that I have a json object copied to my clipboard.
I have a simple form in my Remix app to submit this data. It looks something like this:
<Form method="post">
<Label>Title</Label>
<Input name="title" />
<Label>Description</Label>
<Input name="description" />
<Label>Transcript</Label>
<Input name="transcript" />
<Button>Submit</Button>
</Form>
Now let's get fancy.
We're going to add an onPaste
to fill out this form all at once from our json data.
function YouTubeForm() {
let getFormInput = (name: string): HTMLInputElement => {
return document.querySelector(`[name="${name}"]`)!;
};
let handlePaste: ClipboardEventHandler<HTMLInputElement> = (e) => {
let pasted = e.clipboardData.getData("text");
try {
let data = JSON.parse(pasted);
getFormInput("title").value = data.title;
getFormInput("description").value = data.description;
getFormInput("transcript").value = data.transcript;
// prevents the json from being pasted into the input
e.preventDefault();
} catch (e) {
// ignore and paste normally
}
};
return (
<Form method="post">
<Label>Title</Label>
<Input name="title" onPaste={handlePaste} />
<Label>Description</Label>
<Input name="description" onPaste={handlePaste} />
<Label>Transcript</Label>
<Input name="transcript" onPaste={handlePaste} />
<Button>Submit</Button>
</Form>
)
}
Boom! Now we have a pretty slick and easy way to fill out our form in one go that seems a little magical to those aren't aware of what's happening behind the scenes. You can check out a simple codesandbox demo of this idea here.
This combo of using a Chrome extension to copy the data and then this paste event to fill out all the fields at once has saved me a ton of time. If you don't want the hassle of creating a Chrome extension you can go the simpler route and create a Chrome Snippet. It's more cumbersome to use since you have to pop open the dev tools, locate your snippet, and then click to run it but it'll get the job done.
Hope you enjoyed this and got your wheels turning on how and where you can implement this concept to benefit you and/or your app's users.
Categories: Remix, React Router, Javascript