Welcome back.
I took a bit of a stretch.
I'm feeling amped [excited].
I'm ready to go.
And let's get into it.
Let's start writing the JavaScript together.
So let's define here, "add javascript".
And you know, by now all our JavaScript has to be inserted within script tags.
The first thing I want to do is I want to grab the input of type range.
So let's define a variable called range.
Let's assign this the value of that input, right?
And we can do that by accessing the document object, and we can use a method called getElementById(),
and we gave it an ID of range.
Great.
So now we've got that input, right?
I also want to grab our output.
So let's define a variable called rangeOutput.
And of course same logic applies.
We can use getElementById(), and we gave it an ID of rangeValue.
Let's grab our input and output elements.
That's what we've just done.
So far, so good, right?
So far so good.
Next, my dear students, I want to define a function.
And this function is going to display that output onto the viewport.
So let's call it function show,
showValue().
And what do we want to do here?
Well, very, very easy.
All we want to do, is we want to grab our rangeOutput variable we've defined above,
we want to set its innerHTML value
to what?
Well, we could set it to the actual value of the range.
But remember how I said I want to put it into a span element?
I just want to show you that there are many different ways of doing things when it comes to coding,
which is pretty cool.
So here we can actually define an HTML span element and then we can include a variable by the dollar
sign and two curly braces. Inside that span,
I want to access our range, basically the input element.
And on that input element, there's a property called value, which is the value of the range.
And I want to insert that into the span.
And of course we need a closing span tag. Very, very simple.
So we've defined our function, but now we need to actually execute it.
So I want to set the initial value when page loads.
And to do that we can access the document directly, add an event listener.
Now, when the page loads, certain events are fired and one of them is called the DOMContentLoaded
event.
This just happens by the browser when your page renders to the screen. And then when that event fires,
I want to execute our function. To execute the function, we just have to type it out.
It's very, very simple.
So that sets the initial value
when the page loads. Let me go to the browser and show you. If we refresh the page, we can see that
we've got the 500.
Don't worry about the styling.
We're going to do that shortly, but at least it's showing.
But you'll notice as I drag, nothing happens because we've never called that function again, have
we.
We've only called it once when the page loads.
So of course we have to call the function every time an input
event
is fired.
And this is very, very easy.
We grab our input, which we defined in a variable called range.
We add an event listener,
and the event we want to listen to is the input event.
And every time that fires, we want to execute our showValue function.
Let's go to the browser now.
And let's move that widget.
How awesome!
We set the min to 0, the max to 100 and we set the starting value to 500.
Woohoo!
Okay, this is the first step.
There's a few things we've got to do here, but let's, you know, tackle one thing at a time.
They say in Africa, how do you eat an elephant 🐘?
And the answer is ... one fork at a time.
So that's it.
We've done the first step, but now I want to add some styling and then there's a bit more JavaScript
we're going to add here, but I'll show you shortly what I mean.
So let's hop into our CSS file and let's start styling this bad boy.
All right, let me display it side-by-side so you can see what we're doing as we go on.
Let's go to our styles.
And let's start styling this.
Let's access our rangeValue class,
but in here we've got a span now, right?
It's added dynamically.
We can set its width to 40 pixels.
You know what I'm actually going to do before I do this? Let me add a background and I want the background
to actually be the same as the one previously.
See, the IDE is so useful
because I don't have to remember what it was.
So there we go.
We've added a background.
I want the line height,
to be bit more, 24 pixels.
How's that?
Yep.
Text-align, center.
I don't want that color being black either.
It doesn't look that nice.
So let's set the color to white.
It's a bit better.
I want the position property to be absolute, because we want to be very specific where this is shown.
I don't like the square borders either, so let's give it a border-radius,
I don't know,
15%
does that look nice?
Yep.
Now I want to use the transform property.
Let's just say here, you want the center of the element,
I'm talking about the span element, to line up with the center of its parent element.
Right now, it's not, which is why it's shoved to the right.
So I want to access the transform property.
And on here, I want to translate this, right,
I want to shift it left 50% to be in line with its parent.
There we go.
Starting to take shape.
It's starting to take shape. And we're not quite done.
I want to add that little triangular kind-of design to it.
So it almost looks like, you know, speech bubble kind of thing.
How do we do that?
Well, again, I want to target the class of rangeValue, that output element,
we are targeting the span, but now I want to target the ::before pseudo element.
The content, of course, can be nothing, but I want the position.
Let me say set position absolute to the output element.
Right.
That's all I want to do here.
So I want to change the position to absolute.
It's starting ...
it's starting to get better.
Width we define as 0.
Height 0.
And now I want to kind of draw that little pointy piece at the bottom of this.
How do we do it?
One way is to use borders.
Let me show you what I mean.
All right.
Let's define border-top as 10px solid blue.
And then we do ...
and let's duplicate this a few times.
Of course, it's not going to be called "top" only. It's going to be border left,
border-right,
and border-bottom.
This is just kind of what I want to show you, right,
if we do this, we just get a square.
But what's interesting here, is if your left and right is red, just so you can see how this works,
red,
can you see we get, like those little triangular pieces.
Pretty cool, right?
So all I want to do is I want to remove the bottom border entirely.
So let's get rid of that,
right?
So now we've got only top, left and right.
The top, I want the color to be consistent with what we've defined above.
There we go.
It's consistent with the actual output widget itself.
The border-left, if we make it 5 pixels,
okay.
And we do the same with the right.
You can see the blue.
That's kind of the size I want, but I don't want to see the red.
So instead of red, all we need to do is make it transparent.
How awesome is this?
And now that triangular piece is just randomly at the top of that entire widget.
So all we have to do, is we have to push it down.
Okay, there we go.
So we've defined the top 100%, so we've pushed it all the way to the bottom.
We can also push it into the center.
And then give it some margin,
the left property
5 pixels.
There we go.
If we zoom out, this is what it looks like.
Oh, but you'll notice, my dear students that it's pushed too far down.
So, I think we defined ...
yes, you see the rangeValue,
we've got position absolute.
The rangeValue is this entire output element.
Well, I want to push that entire output element up so we can access its top property and push it up
by 50%.
And I think that'll do it.
I think that looks cool.
At least now it's the right height.
But you'll notice as we move this widget.
That output does not move.
But how,
my students?
How do we make it move?
Well, again, there are many ways in programming.
The way I want to do it here is I want to access the left property and change it dynamically.
So just remember, I want to access the left property and this needs to move in line with wherever this
range widget is.
And whenever you hear the word dynamic, you must think JavaScript.
So let's go to our JavaScript here, and let's start coding this. In our function showValue() before we even
get to changing the innerHTML, let's grab the value as a percent.
And you'll see why we use this shortly.
Okay, so let's define a new variable called newValue.
What should this be?
Well, I want it to be the current value of our range,
right.
And we've defined the range variable above.
It's just that input of type range.
So whatever that value is, I want to deduct the minimum, which we know is zero,
then what I want to do is I want to, like I mentioned, I want this to be a percentage.
So we need the entire range itself to get a percent.
So we know it's going to be a range.max minus range.min.
And of course, to get it into percentage terms, I want to multiply by 100.
Let's just console log this out,
newValue, then you can see what I mean.
Let's go to the browser.
Let's inspect the console.
And here you can see when the page loads, it's 50 and it's 50 because it's in the middle. If we go to
zero,
it's zero.
If we go to 100.
It's going to be 100%.
I'm just trying to get a percentage.
Where are we,
you know, in this whole thing.
That's all I've done.
Very simple. Let's refresh, and we are back at 50.
Okay, let's go back to our coding editor and let's continue. (swoosh) Because we have this this range value as
a percent,
why don't we just try, off the cuff, to assign the value of the left property to that percent and see
what happens?
Let's, let's give it a go.
So here, um, we are changing the output value and position of the output element.
That's what we're trying to do.
So we've done the value.
Let's now try and change the position. In order to change the position,
I want to grab that range output variable we defined above,
I want to access its style property and we're going to change its left property.
And if we just go and assign that to newValue, you'll see a problem with this.
Let me first show you.
Oh, the other thing is, let's put this in temperate literals.
Dollar sign,
curly brackets,
newValue.
Because I want a percentage sign afterwards.
Okay.
If we now look at this in the browser.
Oh, man, that looks perfect.
Right.
It looks perfect.
What are you talking about?
We need to change anything.
Well, just wait.
Let me scroll.
Look at what happens.
It's going off center 🙈.
It's going off center.
So we know it starts off correctly, right?
But as we go along.
It's off center.
So we need to dynamically push this right when we're at the very left and when we're at the very far
right, we need to push this output element to the left.
Okay.
Well, how do we know how much to push it?
Let's define a new variable here called adjustPosition and let's define it as 10.
Okay.
We're just going to move it 10 pixels and see what happens.
Then all I want to do in this value here, I want to access the calc() method.
Put that in brackets.
And what I want to calc? Well, I want to use this left position we've just calculated, but I want to
add now, right.
And what do I want to add?
Let's put new brackets.
Well, I want to add the adjustPosition variable we've just created, but it's going to be in pixels.
Like I said, I just want to push it right by 10 pixels.
Let's now save this, go to the browser.
And let's now scroll all the way to the left.
Oh, it's not quite right.
I think 10 pixels is too much.
Can you see?
So let's try 7.
And that looks bang on.
So when it's to the left, we want 7.
When it's to the center, we want nothing.
And when it's to the right, we actually need to push it the other way.
So our adjustPosition formula needs to be dynamic.
Put it this way, when it's to the very left, it needs to be 7.
So we know, right,
the newValue will be 0 times a percentage,
and I'll show you why it's 14% now,
okay.
Think about why I've done this
my dear students. The new value ranges from 0 to 100, remember?
So when it's in the middle, we know the new value is 50. 50 multiplied by 14% is 7.
7 minus 7 will be 0.
So when we start off the page, this is not going to be adjusted.
The output element will be dead on the center. When we at the very far left of the range, that newValue
is going to be zero and anything multiplied by zero is zero.
So we're going to adjust the position by 7 pixels.
When we are at the very far right, we know
the newRange value is 100, 100 times 14% is 14.
7-14 is -7, which pushes it left by 7.
And this is how it works.
I know it's a bit "mathy", but I hope you can understand how we got to that number.
So there we go.
This is a custom range widget.
Hope you're having a lot of fun, my dear students.
And the next challenge is also going to be quite fun because there, I want to create an entire form.
It's going to be really, really fun.
See you now.