Hello welcome to a coding challenge. This coding challenge is called I'm not sure
because after i record this I'm gonna come up with the name of it. Right now its
called Word Interactor. You might see it called something different. The point
of this coding challenge is actually not really to make anything that interesting
but to give you a template for creating a creative project that allows a user to
interact with text on a word by word basis So each word being an individual token.
For example, I'm gonna add a little bit of code here I'm starting with a code
base from some other example. Right now i have the text here, I hit submit, and I
see this text. I can't interact with this text, I can copy and paste it but what
I want the user to be able to do is interact with each one of these words
individually. So for example what if everytime I click on this word or hover
over this word I query an API and return a synonym and replace it? Or based on
some property of it I change it's color. This actually is a project that, so theres
a lot of possibilities in what I could do with this. Lets figure out how I do that.
The first thing that I need to do, is figure out a way of splitting that text
up into an array of separate words. If you've been watching some of my other
videos you'll notice theres a whole video about split and regular expressions.
So I'm gonna use the concepts from that video and just split this up. What i'm
gonna do here first is I'm gonna say, I had a little bit of a code base where I'm
just selecting some HTML elements, a text field, an output paragraph, and a
submit button, because I'm gonna use those things. First thing I'm gonna do is
I'm gonna say var words equals S dot split S is all the text that comes in from that
text field. Of course you could get the text from a variety of other sources. I'm
just using a text field. I want to split it up, and I need to pass the split an
argument which is a delimiter. So what should that delimiter be? It could be
space, it could be comma, it could be space or comma. Im gonna do something
simple for now, I'm gonna write a regular expression that says anything thats not
a letter or a number, one or more not letters or numbers. So backslash lower case
'w' is any A through Z or Zero through Nine. Capital 'W' is anything thats not
A through Z or Zero through Nine, and plus I guess the case sensitivity doesn't
matter here. Lets just make sure that works. Im gonna say console log words.
Just so we can see that. I'm gonna refresh this, and we can see that looks good.
I've got now an array of everything as a separate word. Why do I want to do that
Because what I want to do is create an individual DOM-HTML element for
each word. The kind of element I'm gonna use is a 'Span' element. If you're not so
used to this developer console, I'm in the javascript console right here. Another
thing thats gonna be really useful is the elements tab of this console.
Because if you look at this, I have this paragraph here and I have this
paragraph here. Look at this, this paragraph element here is all this
single body of text highlighted there. What i want instead is to make individual
things. I'm going to loop through the array of words and I'm going to create
a DOM element for each one, I'm gonna make it the Span element. Span element
is useful because its something I can style and have control over but it rests
inline as if the text just flows in a regular paragraph. So i'm gonna say
create span words index i. I'm gonna take this out and I'm gonna take this out too.
Lets look at this, now we can see, submit, Look what I got there. So first of all I
made all of these spans but theres no spaces in between them. But you can see
there they are. They're all separate individual span elements. Magic,
fascinating, wonderful! Ok this is great. I want to do 2 things here, #1 I want to
put some spaces in between them... Now we can see look at that I also have
these span spaces, theres probably another way I can put those spaces without having
those be spans. But its fine you can see it looks like an individual block of text
but they're separate DOM elements that I can control individually. In my HTML
file, I have this paragraph called output. Let me run this again, I hit submit, look
at this output paragraph and then all of these spans. I kind of want the spans to
be inside the paragraph element just so if I have to style it or do something
with it as a whole I don't want the spans to be free floating they should be in a
paragraph element. This won't look any different to you, but what I want to do
is say in the code, var span equals create, I'm gonna say span 1, var
span 2 equals, and then I'm gonna say span 1 dot parent output. By
the way I'm using the p5 DOM library of course I could do this with native
javascript, append this, document get element ID this, I could do this with
jQuery and have dollar signs all over my code. But I'm doing this with the p5
library because its what I work on and what I use, its good for sort of
sketching and quick experiments. So i'm gonna do this, same thing parent this
So now look at this, I now have all of those spans inside this paragraph.
Again why is this useful? If I wanted to I could add some CSS styling to style that
paragraph as a whole as well as access the spans individually. Heres the thing
that I want to discuss, notice how the original text has periods, spaces, and
commas. But this text does not. It only has the spaces because I split by anthing
but then I didn't retain I just automatically inserted spaces. Even though
this will make it more complicated and take another 5 minutes, lets rebuild the
text with the original punctuation. I think thats gonna be something you might
want to actually do if you're gonna use this as a template for a creative project.
How do I do that? One thing I need to do in the split regular expression, I need to
use capture in parentheses. Notice what happens when I use capture in parentheses
And I run this again. We should see, oops I put the parentheses in the wrong place.
They go inside here, the capturing parentheses are part of the regular
expression itself, in between the slashes Lets do this again, hit submit, now you
can see look, theres some sort of Frankenstein thing where theres extra
spaces and the periods. Its because I'm also adding the extra spaces, I don't need
to do that anymore. So now I can get rid of this. The array actually, that array,
if I say, console dot log words. Just to look at that array, with the capture in
parentheses. You can see that this array actually keeps the commas, the spaces,
it keeps everything. But heres the question, I don't necessarily want to
One thing I could do in p5, i can say span dot style. Im gonna say span dot
style, background color, I'm gonna give it some arbitrary background color, I'm gonna
run this again, hit submit. It also gives the background color to every space and
every punctuation mark. What if I don't want that, one thing I could do is use a
regular expression to validate whether its a word or a delimiter so what can I do now
remember this regular expression that I used, i could use it again. I can say
if, and I'm just gonna write a regular expression right here, backslash capital
W plus dot test words index I, then only apply this styling. Now this looks a
little bit crazy and I actually got it wrong. I want to check if this regular
expression I want to test it against this. Actually this is gonna do the inverse.
Watch what happens, this actually highlighted for me only the delimiters.
Let me go back, if not, now I'm highlighting only not the delimiters.
Of course I could make them all a random color, I think recent version of p5 will
allow me to pass in three arguments as a RGB value. Lets see if this really works
No, I thought it allows you to do this. Maybe I could do a color object, that must
be what it is, there we go watch this now >From this alone you can see how I can
apply an algorithm to how its colored. Of course I could do something more
like, I could color it by part of speech, I could color it by length of character
that sort of thing. Theres a lot of possibilities here in how you might color
this text. But really I want to show you is how you interact with it. So how you
interact with it is by giving the span an event listener. So I only want an event
listener for the elements that are words and not the delimiters. I'm gonna comment
this out, I don't need this line. What i want to do is I want to say span and I
want to say mouse over. So i'm gonna use the p5 event mouse over. This is the
equivalent of a native javascript saying the element dot add event listener.
Im gonna pass it a function, I'm gonna call it highlight or something. What this
means, I could write an anonymous function here, but I'm gonna write a
function somewhere else called highlights. Just to make sure this is working,
console dot log hover. To see what happens Let me run this, hit submit, now look at
this. Everytime I move my mouse around to go over a word we can see that in the
console the word hover is spit out. So i have these events firing for every single
individual word. Thats good news. The question is how do i know which word
I'm hovering over? Thers just this one function highlight for all of them. How
do i know which one. There is kind of an answer to this which involves the use of
something called a closure in Javascript. Next week I'm gonna make a coding
challenge where I use that. Lets say I wanted to make an API call everytime
I hover over a word, I'm gonna need to employ some more sophisticated logic.
But for right now I can actually do something rather simple because I'm
using p5. In javascript there is a key word called this. I should probably
make a separate video about 'this' Another way of thinking about this
is context. If you ever just say this in p5 or setup or something, its referring
to something called 'window' which is like the global Javascript context that you're
in, in a webpage. If you've ever done something like write a constructor
function which you can see other videos that I do. Where i say something like
function particle this dot x equals, this dot y equals. When i say new particle
javascript behind the scenes creates a new context which is a new particle object
and it attaches the x and y properties to that new object. Theres a function in
javascript called bind which I could do a video about at some point, which binds
the context the keyword this to something arbitrary that you might want to bind to.
The keyword this can mean different things depending on where you're programming
what you're doing, where you're living in the world. P5 does something really
magical behind the scenes for you and it makes working with p5 DOM events very
easy. What it does is it automatically, in here, binds the context, assigns the
context to the DOM element you happen to be hovering over. Im gonna say console
dot log this. Watch this now, submit, hover, look at this. All these different
p5 elements are showing up here. This automatically equals what I'm hovering
over. By the way just to prove the point if I say console dot log this right here
in setup, look at this, thats like the global context. Which is like the window
object which is all sorts of properties and things we could investigate and look
at. So this doesn't mean something different depending on whats going on
Often a library or something that java script does will assign it to something
behind the scenes for you, for your convenience. In this case the convenience
is the DOM element. Look at what I can do I can say, console dot log this dot HTML
This dot HTML, HTML is a dom element function in p5 that returns the contents
of that element. So i can hover of it and we can see the words in the console
are whatever I'm hovering over are appearing. Now what could i do?
I could do something like var s equals this dot HTML dot replace. I could use
the replace function to say hey search for any word that is...Let me just do
something simple. This dot HTML rainbow and this dot HTML dot style, background
color, var c equals a color random 255, random 255, random 255. I'm gonna say
c here. Anything you hover over change it to the word rainbow and give it a color.
Sorry this dot style, style just like HTML is a function that sets its value. Style
is a function that sets its CSS styling dynamically. So whenever I hover over
a word it changes to rainbow and gives it a color. So heres my rainbow web
application. I should probably do something which sets the property so
that when I'm hovering it changes to that mouse hovering thing, I have to click on
it. Come up with your ideas of what you might do thats more intersting. How might
you replace the text, how might you use a regular expression maybe with a callback
to replace the text, to translate it. How can you interact with a body of text
on a word by word, sentence by sentence, character by character level. So i hope
you take this code, expand on it, and create some interesting web based
experiments out of it. Next week I'm gonna do a similar coding challenge
where when you click on each of these words I make an API query and replace
it with either its definition or another word or something like this, OK?
Thank you so much for watching this coding challenge and see you soon in
another video!~~~
Subtitles by the Amara.org community