1
00:00:00,506 --> 00:00:08,816
[ Silence ]

2
00:00:09,316 --> 00:00:11,826
>> Okay. Welcome back to
Computer Science S-75.

3
00:00:11,826 --> 00:00:13,956
This is Lecture Six, JavaScript.

4
00:00:13,956 --> 00:00:15,806
This seems to be fun
to start these classes

5
00:00:15,806 --> 00:00:17,166
by asking what we did last time

6
00:00:17,166 --> 00:00:19,026
because no one ever
seems to know.

7
00:00:19,116 --> 00:00:20,956
So let's go there first.

8
00:00:20,956 --> 00:00:25,316
So, last time on Monday we
dived a bit deeper into SQL,

9
00:00:25,606 --> 00:00:29,216
talked about a few
topics, among which were?

10
00:00:30,756 --> 00:00:31,446
Axle?

11
00:00:31,816 --> 00:00:33,876
>> Well, joining tables.

12
00:00:34,246 --> 00:00:36,486
>> Okay, so joining tables
which refers to what?

13
00:00:38,996 --> 00:00:42,996
>> It's defining something
in the tables [inaudible].

14
00:00:43,336 --> 00:00:43,556
>> Okay.

15
00:00:43,556 --> 00:00:46,946
>> Which refers to a similar
field in another table

16
00:00:47,036 --> 00:00:51,236
of these two and [inaudible]
join those two together

17
00:00:51,476 --> 00:00:55,686
and simply gives you the things
associated with that [inaudible]

18
00:00:55,836 --> 00:01:02,226
from one table and puts
it next to another one.

19
00:01:02,396 --> 00:01:02,966
>> Okay, good.

20
00:01:02,966 --> 00:01:05,156
So just to summarize, if you
have a relational database,

21
00:01:05,156 --> 00:01:07,836
inside of which is at
least two tables and one

22
00:01:07,836 --> 00:01:10,116
of those is a primary
key, like an ID,

23
00:01:10,396 --> 00:01:14,766
and another of those
is the same ID but not

24
00:01:14,846 --> 00:01:16,536
in the same kind
of relationship.

25
00:01:17,186 --> 00:01:20,516
You can join those two
tables on that shared ID

26
00:01:20,516 --> 00:01:23,356
so that you get back essentially
the union of the rows

27
00:01:23,356 --> 00:01:25,996
from this table with
the corresponding rows

28
00:01:26,056 --> 00:01:27,256
from this table.

29
00:01:27,506 --> 00:01:30,436
And when I said it's the idea
is a little bit different

30
00:01:30,436 --> 00:01:32,686
in the second table, we
call this a foreign key,

31
00:01:32,916 --> 00:01:34,376
because it's there
not necessarily

32
00:01:34,376 --> 00:01:38,006
to uniquely identify the row but
to somehow link that row back

33
00:01:38,316 --> 00:01:40,516
to a corresponding primary key.

34
00:01:40,516 --> 00:01:43,136
So what was an example that
we did involving primary

35
00:01:43,136 --> 00:01:44,186
and foreign keys?

36
00:01:44,926 --> 00:01:48,236
>> We had an inputting table
and then we had a sales table --

37
00:01:48,326 --> 00:01:48,576
>> Okay.

38
00:01:48,576 --> 00:01:52,936
>> -- so we joined the actual
sales to the [inaudible].

39
00:01:53,746 --> 00:01:54,186
>> Okay, good.

40
00:01:54,186 --> 00:01:57,126
So we had an order -- a sales
table, an orders -- sorry.

41
00:01:57,416 --> 00:02:01,226
We had products, we had orders,

42
00:02:01,526 --> 00:02:05,326
and there were some keys
shared among those tables,

43
00:02:05,326 --> 00:02:06,966
for instance, an employee ID.

44
00:02:07,206 --> 00:02:09,336
Sorry, we had an
employees table,

45
00:02:09,376 --> 00:02:11,776
and we had an orders
table, and the shared key

46
00:02:11,776 --> 00:02:14,556
between those two tables was
some employee identifier.

47
00:02:14,806 --> 00:02:18,026
So what's an upside of
actually factoring out something

48
00:02:18,026 --> 00:02:20,326
like an order into
an orders table?

49
00:02:20,326 --> 00:02:23,666
What was the motivation for
introducing two tables on Monday

50
00:02:23,666 --> 00:02:25,226
as opposed to just
one bigger table?

51
00:02:29,546 --> 00:02:33,066
Like if we already have an
employees table on day one

52
00:02:33,066 --> 00:02:36,166
and we only have that one table,
why not just add another column

53
00:02:36,416 --> 00:02:39,796
that lists the product
ID that that person sold?

54
00:02:40,196 --> 00:02:40,396
Jack?

55
00:02:40,556 --> 00:02:41,006
>> [Inaudible] a whole lot

56
00:02:43,296 --> 00:02:44,916
of redundant information
that's taking up space

57
00:02:44,916 --> 00:02:45,286
on wherever [inaudible].

58
00:02:45,286 --> 00:02:45,526
>> Okay, good.

59
00:02:45,526 --> 00:02:47,566
You could end up with a whole
bunch of redundant information.

60
00:02:47,566 --> 00:02:49,866
For instance, if you clutter
the employees' table with all

61
00:02:49,866 --> 00:02:53,236
of your orders you might
have Jack, Jack, Jack,

62
00:02:53,236 --> 00:02:55,626
just because Jack sold
three different items,

63
00:02:55,786 --> 00:02:57,706
and we certainly don't
need three different copies

64
00:02:57,706 --> 00:02:58,316
of his name.

65
00:02:58,546 --> 00:03:01,956
And alternatively, if we didn't
-- if we weren't as bad as that,

66
00:03:01,956 --> 00:03:04,046
if we didn't actually
just duplicate Jack's name

67
00:03:04,046 --> 00:03:05,566
or the employee's
name again and again,

68
00:03:06,016 --> 00:03:08,606
what if we instead
just put another column

69
00:03:08,876 --> 00:03:10,056
in the employees' table?

70
00:03:10,426 --> 00:03:12,286
>> Well that wouldn't be good
either because that would be

71
00:03:12,286 --> 00:03:14,876
like faking a table because
you would have to use commas

72
00:03:14,986 --> 00:03:16,726
or some kind of [inaudible]
characters

73
00:03:16,726 --> 00:03:19,026
to actually identify
the individual sales.

74
00:03:19,356 --> 00:03:20,686
>> Okay. So, okay.

75
00:03:20,686 --> 00:03:23,346
So, you've interpreted my
proposal of another column,

76
00:03:23,346 --> 00:03:26,986
let's call it the orders column,
as potentially containing zero

77
00:03:26,986 --> 00:03:30,206
or more order ID's, or
product ID's, and we would have

78
00:03:30,206 --> 00:03:33,136
to resort to some kind of hack
whereby we just separate those

79
00:03:33,136 --> 00:03:35,536
product ID's by commas
and at that point we might

80
00:03:35,536 --> 00:03:37,186
as well just have
multiple columns.

81
00:03:37,346 --> 00:03:38,216
Okay, so let's do that.

82
00:03:38,216 --> 00:03:40,086
That was a stupid mistake
I made the first time,

83
00:03:40,336 --> 00:03:44,986
let me have one column per
order in the employees' table.

84
00:03:44,986 --> 00:03:45,766
Why not go that route?

85
00:03:47,106 --> 00:03:48,846
Why introduce this
additional complexity

86
00:03:48,846 --> 00:03:50,166
of a whole other table?

87
00:03:55,236 --> 00:03:58,336
Let me sort of -- let me
play naive for a moment.

88
00:03:58,336 --> 00:03:59,936
So what would I name
this column?

89
00:03:59,936 --> 00:04:01,216
I'm going to call it Order One.

90
00:04:01,216 --> 00:04:02,646
What would I name
the second column?

91
00:04:03,406 --> 00:04:03,986
Order Two.

92
00:04:04,186 --> 00:04:05,306
What do I name the third column?

93
00:04:05,306 --> 00:04:05,876
Order Three.

94
00:04:05,996 --> 00:04:08,756
Now, start to find
faults with my proposal.

95
00:04:09,236 --> 00:04:09,446
Jack?

96
00:04:09,566 --> 00:04:11,876
>> Well, so you have
one customer --

97
00:04:12,046 --> 00:04:15,346
well, one employee that
sells, let's say, 300 items.

98
00:04:15,346 --> 00:04:15,496
>> Okay.

99
00:04:15,836 --> 00:04:18,746
>> And another who sells
maybe two or three.

100
00:04:18,876 --> 00:04:19,096
>> Okay.

101
00:04:19,576 --> 00:04:23,476
>> First of all, now you
have 300 columns in your --

102
00:04:23,476 --> 00:04:23,696
>> Good.

103
00:04:24,076 --> 00:04:26,406
>> -- table, which is
way more than you need

104
00:04:27,816 --> 00:04:29,746
for the one who's only
sold two or three items.

105
00:04:29,746 --> 00:04:33,246
And let's say if you [inaudible]
the customer that sold 300 items

106
00:04:33,246 --> 00:04:35,566
but you want to keep the sales
you wouldn't be able to do

107
00:04:35,566 --> 00:04:37,796
that because they're
all on the same page.

108
00:04:37,886 --> 00:04:38,336
>> Excellent.

109
00:04:38,336 --> 00:04:40,796
So a couple problems arise here.

110
00:04:40,796 --> 00:04:43,286
One, the table just
gets really wide.

111
00:04:43,326 --> 00:04:46,046
For instance, to handle an
employee who has sold as many

112
00:04:46,046 --> 00:04:48,976
as 300 items you now need
Order One, Order Two,

113
00:04:48,976 --> 00:04:50,686
Order dot, dot, dot, Order 300.

114
00:04:50,686 --> 00:04:52,236
Which literally means
300 columns,

115
00:04:52,466 --> 00:04:54,456
but remember this is a
spreadsheet of sorts,

116
00:04:54,456 --> 00:04:57,886
it has rows and columns and it
has the same number of columns

117
00:04:57,886 --> 00:04:59,026
for every one of the rows,

118
00:04:59,306 --> 00:05:02,336
so now just because you have
a really good salesperson he

119
00:05:02,336 --> 00:05:04,766
or she has 300 orders
to his or her name,

120
00:05:05,116 --> 00:05:07,256
but suppose the norm
is far fewer than that.

121
00:05:07,256 --> 00:05:09,336
Or you have a guy
who's not doing so well

122
00:05:09,336 --> 00:05:11,136
and he only has two
orders to his name,

123
00:05:11,336 --> 00:05:13,596
well you're wasting it seems
a huge amount of space.

124
00:05:13,596 --> 00:05:14,546
Even if we've not filled

125
00:05:14,546 --> 00:05:16,736
in the blanks there's definitely
some overhead involved

126
00:05:16,736 --> 00:05:20,736
in having all of these columns
there for all of the rows.

127
00:05:20,736 --> 00:05:24,406
So you just have
this very ragged edge

128
00:05:24,406 --> 00:05:27,426
to your table whereby it
might be 300 orders long,

129
00:05:27,426 --> 00:05:28,776
it might be two orders long,

130
00:05:28,776 --> 00:05:30,666
but this doesn't feel
like the best design.

131
00:05:30,666 --> 00:05:32,696
As moreover, as Jack
points out, if you delete

132
00:05:33,126 --> 00:05:36,906
or fire an employee, you're
going to lose in this model all

133
00:05:36,906 --> 00:05:39,776
of his or her order numbers,
which doesn't seem ideal.

134
00:05:39,776 --> 00:05:41,736
Now we can mitigate
that one by instead

135
00:05:41,736 --> 00:05:44,746
of deleting the employee we
could just have another field

136
00:05:45,046 --> 00:05:49,206
that's called terminated and
it's one if yes or zero if no.

137
00:05:49,376 --> 00:05:51,726
So that might mitigate that
but still this doesn't feel

138
00:05:51,726 --> 00:05:52,796
like the cleanest design.

139
00:05:53,026 --> 00:05:55,946
So the where we ended up
on Monday was pretty good.

140
00:05:56,096 --> 00:05:58,646
So the [inaudible] schools table
still had some other faults

141
00:05:58,646 --> 00:06:00,966
with it but at least this
factoring out of orders

142
00:06:01,166 --> 00:06:02,646
and having it as
a distinct table

143
00:06:02,646 --> 00:06:03,936
from employees was a good thing

144
00:06:04,066 --> 00:06:06,266
because we can always
recover the relationships

145
00:06:06,556 --> 00:06:10,336
by doing joins, whether
implicitly or explicitly.

146
00:06:10,426 --> 00:06:12,526
So what was the analog
now for project one?

147
00:06:12,616 --> 00:06:14,756
Even though you probably
haven't dived into it

148
00:06:14,756 --> 00:06:18,686
yet project one involves stocks,
and portfolios, and users,

149
00:06:18,686 --> 00:06:22,596
and so forth, so what's
the similarity there

150
00:06:22,596 --> 00:06:23,246
with this project?

151
00:06:23,906 --> 00:06:24,186
Axle?

152
00:06:24,396 --> 00:06:26,566
>> Maybe you would want to have
one table containing all the

153
00:06:28,556 --> 00:06:29,446
portfolios on your entire site.

154
00:06:29,446 --> 00:06:29,656
>> Okay.

155
00:06:29,716 --> 00:06:31,866
>> And another table
containing all your user names

156
00:06:31,866 --> 00:06:32,866
and passwords.

157
00:06:32,946 --> 00:06:33,546
>> Okay, good.

158
00:06:33,546 --> 00:06:36,416
So maybe you'd have one table
for all of your portfolios.

159
00:06:36,416 --> 00:06:39,946
And on Monday we defined a
portfolio somewhat arbitrarily

160
00:06:40,146 --> 00:06:43,746
as being a stock
symbol, a quantity,

161
00:06:44,226 --> 00:06:47,316
and it also had one other
field associated with it,

162
00:06:47,636 --> 00:06:48,886
in the portfolios table.

163
00:06:49,336 --> 00:06:51,786
Stock symbol, quantity, and?

164
00:06:52,426 --> 00:06:53,426
>> Sales price?

165
00:06:53,426 --> 00:06:55,646
>> Could have sales price
if we wanted to remember

166
00:06:55,646 --> 00:06:59,426
that information, but we
crucially need one other field

167
00:06:59,426 --> 00:07:00,866
in this portfolios table.

168
00:07:01,406 --> 00:07:01,496
Yeah?

169
00:07:02,736 --> 00:07:06,606
>> How much money is
[inaudible] sorry.

170
00:07:06,836 --> 00:07:08,886
>> Okay. Retracted.

171
00:07:10,206 --> 00:07:12,726
So I've got my users table, now
I've got my portfolios table,

172
00:07:12,726 --> 00:07:16,786
and at the moment my portfolios
table only has quantity

173
00:07:16,786 --> 00:07:17,536
and symbol.

174
00:07:17,536 --> 00:07:20,106
>> You need to tell --
you need to [inaudible]

175
00:07:20,106 --> 00:07:21,886
which user actually
has [inaudible].

176
00:07:22,636 --> 00:07:23,066
>> Exactly.

177
00:07:23,066 --> 00:07:23,906
We need the user ID.

178
00:07:23,906 --> 00:07:26,316
We need some kind of
identification for the user

179
00:07:26,466 --> 00:07:28,896
so that we know who owns
four shares of GOOG,

180
00:07:28,896 --> 00:07:30,106
in the case of a Google stock.

181
00:07:30,256 --> 00:07:33,126
Now we could store price if we
did care about that history,

182
00:07:33,126 --> 00:07:36,586
and that's ultimately up to
you, the [inaudible] allows you

183
00:07:36,586 --> 00:07:40,186
to simplify and allows a user to
sale all of his or her shares,

184
00:07:40,416 --> 00:07:41,496
not just individual ones.

185
00:07:41,496 --> 00:07:43,136
So you don't really
have to know exactly

186
00:07:43,136 --> 00:07:44,546
which of your shares
you're selling.

187
00:07:44,546 --> 00:07:45,856
But that could be a
compelling feature.

188
00:07:46,126 --> 00:07:48,056
Now in terms of this
user ID, let's go there.

189
00:07:48,246 --> 00:07:50,816
In the users table we
presumably have a username,

190
00:07:50,816 --> 00:07:52,256
which might as well
be email address,

191
00:07:52,636 --> 00:07:55,366
password, or a hash thereof.

192
00:07:55,366 --> 00:07:57,746
Shouldn't be storing clear text
passwords even though we did

193
00:07:57,746 --> 00:07:59,466
initially for John Harvard.

194
00:07:59,756 --> 00:08:03,356
What should the primary key be

195
00:08:03,356 --> 00:08:05,006
in the users table
for project one?

196
00:08:05,216 --> 00:08:07,056
And again, don't
take this as law,

197
00:08:07,286 --> 00:08:09,446
different designs are
possible, but what could be?

198
00:08:10,406 --> 00:08:10,526
Yeah?

199
00:08:11,016 --> 00:08:12,116
>> A unique identifier.

200
00:08:12,216 --> 00:08:14,636
>> Okay. Unique identifier,
I propose an email address.

201
00:08:14,636 --> 00:08:18,776
Like it or hate it?

202
00:08:18,966 --> 00:08:20,216
Or do you like it or hate it?

203
00:08:21,326 --> 00:08:24,616
>> Well, you can
do email address.

204
00:08:24,616 --> 00:08:26,616
>> Okay. So you say,
okay, you kind of like it.

205
00:08:26,616 --> 00:08:28,276
Email address, who
dislikes email address

206
00:08:28,276 --> 00:08:31,346
as the unique identifier as the
primary key for my users table?

207
00:08:31,506 --> 00:08:31,666
Ben?

208
00:08:32,166 --> 00:08:35,886
>> It seems to be easier
just to use a number.

209
00:08:35,886 --> 00:08:35,996
>> Okay.

210
00:08:43,726 --> 00:08:44,006
>> If you're [inaudible]

211
00:08:44,006 --> 00:08:44,836
who owns [inaudible] a
number [inaudible] link

212
00:08:44,926 --> 00:08:47,456
that to an email address.

213
00:08:47,456 --> 00:08:48,486
>> Good. So just to recap,

214
00:08:48,486 --> 00:08:51,346
the upside of using a numeric
identifier, like an int,

215
00:08:51,456 --> 00:08:52,916
that just auto increments,
would be one,

216
00:08:52,916 --> 00:08:55,096
it's a little more efficient
because you just search on a 32,

217
00:08:55,096 --> 00:08:58,356
or 64-bit value rather than
some arbitrary length varchar.

218
00:08:58,356 --> 00:09:01,346
And you can also index
it a bit more readily

219
00:09:01,346 --> 00:09:02,936
because there's just less --

220
00:09:02,936 --> 00:09:04,986
there's fewer bits
to actually index.

221
00:09:04,986 --> 00:09:07,026
So it feels like that
should be higher performing,

222
00:09:07,026 --> 00:09:08,176
certainly for large datasets.

223
00:09:08,226 --> 00:09:08,506
Jack?

224
00:09:08,756 --> 00:09:12,316
>> You're also saving space
from also repeatedly putting

225
00:09:12,316 --> 00:09:15,176
in whatever someone's email
is and however long it is

226
00:09:15,176 --> 00:09:17,666
when you could just be
putting in some sort of --

227
00:09:17,666 --> 00:09:20,556
>> Exactly, so the space savings
can certainly add up because

228
00:09:20,556 --> 00:09:22,696
if this user owns a
lot of stocks and his

229
00:09:22,696 --> 00:09:24,966
or her email address
was in every row

230
00:09:24,966 --> 00:09:27,346
of the portfolios table it
just feels kind of ridiculous

231
00:09:27,346 --> 00:09:28,376
to store 10 or 12

232
00:09:28,376 --> 00:09:31,536
or 20 characters just too
uniquely identify that user.

233
00:09:31,756 --> 00:09:33,626
Moreover there's another
problem that would arise.

234
00:09:33,626 --> 00:09:37,896
Suppose that I wasn't this
savvy, I didn't use numbers,

235
00:09:38,126 --> 00:09:39,456
I just used email address.

236
00:09:40,896 --> 00:09:43,376
Think about other corner
cases that arise --

237
00:09:43,656 --> 00:09:47,106
could arise, not necessarily in
project one, but if you continue

238
00:09:47,106 --> 00:09:50,206
to roll out project one as sort
of an actual commercial website.

239
00:09:50,706 --> 00:09:54,016
What's a design flaw you might
regret a few months later?

240
00:09:54,136 --> 00:09:58,176
>> Email addresses change, they
disappear [inaudible] password.

241
00:09:58,696 --> 00:09:59,336
>> Good.

242
00:09:59,336 --> 00:09:59,836
[ Inaudible Speaker ]

243
00:09:59,836 --> 00:10:02,486
Good. So you leave Harvard

244
00:10:02,486 --> 00:10:03,976
and you lose your
Harvard.edu address.

245
00:10:04,136 --> 00:10:05,836
You leave your company;
you just decide you got

246
00:10:05,836 --> 00:10:07,536
to stop using that
AOL.com address.

247
00:10:07,536 --> 00:10:09,126
You want to change
your email address.

248
00:10:09,486 --> 00:10:10,666
Now what's the implication?

249
00:10:10,666 --> 00:10:13,196
Well, you the programmer
could certainly allow a user

250
00:10:13,196 --> 00:10:14,696
to change his or
her email address,

251
00:10:15,296 --> 00:10:18,746
but how many different
tables or rows are you going

252
00:10:18,746 --> 00:10:19,826
to have to update now?

253
00:10:20,266 --> 00:10:21,566
If they change their
email address you have

254
00:10:21,566 --> 00:10:22,756
to minimally update what?

255
00:10:22,756 --> 00:10:24,196
>> You have to -- if you have
a separate table for user ID's

256
00:10:24,196 --> 00:10:27,746
and emails then it's
easily done you just need

257
00:10:27,746 --> 00:10:31,386
to deal with that table.

258
00:10:31,386 --> 00:10:33,026
But if you have it on
all stocks it's a mess.

259
00:10:33,206 --> 00:10:33,746
>> Exactly.

260
00:10:33,746 --> 00:10:35,776
Right? You have to do an
update on the users table,

261
00:10:35,776 --> 00:10:37,806
you have to do an update
on the portfolios table,

262
00:10:37,806 --> 00:10:39,136
or wherever else you've used it.

263
00:10:39,366 --> 00:10:41,616
And then there's the issue
of well, how do you do

264
00:10:41,616 --> 00:10:45,966
that all atomically because it'd
kind of be ideal that this kind

265
00:10:45,966 --> 00:10:49,636
of change happen all at once
and not a little bit of change

266
00:10:49,636 --> 00:10:51,656
over here, then over
here, then over here,

267
00:10:51,656 --> 00:10:55,056
because for whatever reason if
that user decides to hit reload

268
00:10:55,056 --> 00:10:57,496
in some other browser window
in which they're already logged

269
00:10:57,496 --> 00:11:01,126
in you could end up with some
very funky undefined behavior

270
00:11:01,276 --> 00:11:04,356
if some of your tables
have malan@harvard.edu

271
00:11:04,356 --> 00:11:06,506
and other tables
have malan@yale.edu,

272
00:11:06,506 --> 00:11:09,606
just because you happen to
look at your database while

273
00:11:09,606 --> 00:11:10,746
that change was in process.

274
00:11:11,416 --> 00:11:11,596
Jack?

275
00:11:11,596 --> 00:11:13,746
>> And beyond that if
you do have some sort

276
00:11:14,796 --> 00:11:17,446
of [inaudible] atomic
process so it does it all

277
00:11:17,446 --> 00:11:19,336
at once you're going
to shut down the --

278
00:11:19,336 --> 00:11:22,256
using the SQL database for all
the other users who [inaudible].

279
00:11:22,506 --> 00:11:22,936
>> Well, good.

280
00:11:22,936 --> 00:11:24,806
So if you resort to
lock specifically

281
00:11:24,806 --> 00:11:27,576
and you're using MyISAM tables,
which was one of the formats

282
00:11:27,696 --> 00:11:29,886
that you can have for a table,
then you would indeed have

283
00:11:29,886 --> 00:11:31,416
to lock out other users.

284
00:11:31,416 --> 00:11:34,026
In this case you could
use NoDB, which now is

285
00:11:34,026 --> 00:11:37,196
in fact the default, and
transactions would not be as --

286
00:11:37,196 --> 00:11:40,416
would not have the
same impact on users.

287
00:11:40,706 --> 00:11:42,166
So we can at least
mitigate that.

288
00:11:42,166 --> 00:11:44,876
But there's then at least
the additional complexity

289
00:11:44,876 --> 00:11:47,536
of just updating all of
these darn tables just

290
00:11:47,536 --> 00:11:50,436
because you made a foolish
design decision upfront.

291
00:11:50,436 --> 00:11:52,856
So, realize that when I say
there's many different ways

292
00:11:52,856 --> 00:11:55,736
of doing these things, it's fine
if you still for this project,

293
00:11:55,736 --> 00:11:58,066
for instance, want to use email
address as your identifier,

294
00:11:58,326 --> 00:11:59,796
but you're going to have
to justify that to us.

295
00:11:59,796 --> 00:12:01,366
For instance, in the
[inaudible] that you were asked

296
00:12:01,366 --> 00:12:04,576
for project zero and also now
for project one, you're invited

297
00:12:04,576 --> 00:12:06,406
to explain your various
design decision,

298
00:12:06,406 --> 00:12:08,166
so if you feel strongly
about something that's fine.

299
00:12:08,336 --> 00:12:09,396
But what we're really looking

300
00:12:09,396 --> 00:12:12,246
for when evaluating projects
is did you give it the thought

301
00:12:12,246 --> 00:12:14,646
and did you make a
judgment call as opposed

302
00:12:14,646 --> 00:12:16,556
to just picking something
because it seemed easy

303
00:12:16,556 --> 00:12:18,786
without really thinking
through the implications?

304
00:12:18,786 --> 00:12:20,886
So do be mindful of
those kinds of things.

305
00:12:21,166 --> 00:12:22,516
So in terms of project zero,

306
00:12:22,786 --> 00:12:25,246
it has been distributed
among the TF's.

307
00:12:25,246 --> 00:12:26,376
You should soon, if
you haven't already,

308
00:12:26,376 --> 00:12:28,066
heard from your specific TF.

309
00:12:28,066 --> 00:12:30,086
We have a team of
four this semester

310
00:12:30,086 --> 00:12:31,386
and so they'll be
reaching our via email

311
00:12:31,386 --> 00:12:34,586
and they'll also be providing
you with feedback, both numeric

312
00:12:34,586 --> 00:12:37,126
and qualitative on the
project, and the aim is to get

313
00:12:37,126 --> 00:12:38,866
that feedback back
to you at least a day

314
00:12:38,866 --> 00:12:42,826
or two before the next project's
deadline so that you can absorb

315
00:12:42,826 --> 00:12:45,096
that feedback and make
any last minute changes

316
00:12:45,096 --> 00:12:47,706
to your current code
for project one based

317
00:12:47,706 --> 00:12:50,946
on any repeated mistakes or
decisions you might have made

318
00:12:50,946 --> 00:12:52,336
that maybe weren't optimal.

319
00:12:52,426 --> 00:12:54,336
So feel free to reach
out to me and also

320
00:12:54,336 --> 00:12:57,586
to your specific TF via email
anytime if you have questions.

321
00:12:58,466 --> 00:13:02,706
All right, so without
further ado we move

322
00:13:02,706 --> 00:13:04,936
on to things more client side.

323
00:13:04,936 --> 00:13:08,016
So whereas thus far, we've
looked at XML, and we've looked

324
00:13:08,016 --> 00:13:10,096
at SQL, and we've looked at PHP.

325
00:13:10,096 --> 00:13:13,816
All of that stuff thus far has
been server side, and so we're

326
00:13:13,816 --> 00:13:16,146
at the sort of midpoint of the
course now where we transition

327
00:13:16,146 --> 00:13:17,456
to things more client side.

328
00:13:17,686 --> 00:13:20,696
Where we don't do away with all
of our server side capabilities,

329
00:13:20,836 --> 00:13:23,496
but we start focusing more on
writing code that was going

330
00:13:23,496 --> 00:13:25,786
to execute in the
confines of the browser.

331
00:13:25,786 --> 00:13:29,616
So JavaScript is an interpreted
language, just like PHP,

332
00:13:29,616 --> 00:13:31,346
and what does that
mean, to be interpreted

333
00:13:31,346 --> 00:13:32,686
as a programming language?

334
00:13:33,186 --> 00:13:33,336
Yeah?

335
00:13:34,256 --> 00:13:37,326
>> It's read line by line
when it's run as opposed

336
00:13:37,566 --> 00:13:42,216
to being compiled when it's
translated into [inaudible].

337
00:13:42,216 --> 00:13:42,526
>> Exactly.

338
00:13:42,526 --> 00:13:46,586
So there's no step as there
is with some languages like C,

339
00:13:46,586 --> 00:13:49,936
or C++, or even Java, where
you have to compile your code

340
00:13:49,976 --> 00:13:52,736
from source code into
some other representation,

341
00:13:52,736 --> 00:13:53,896
often zeros and ones.

342
00:13:53,896 --> 00:13:56,636
With JavaScript, as with
PHP, you just write it

343
00:13:56,766 --> 00:13:59,466
and then you hit reload on
your browser, or you hit run

344
00:13:59,466 --> 00:14:01,676
on the server, you do some
execution of a command

345
00:14:01,916 --> 00:14:04,666
that just starts to interpret
that file line by line.

346
00:14:04,666 --> 00:14:07,636
The upside of this is that there
is quite simply no compilation

347
00:14:07,636 --> 00:14:09,576
process, just a little
more interactive

348
00:14:09,576 --> 00:14:10,626
in terms of the programming.

349
00:14:11,086 --> 00:14:14,536
But the downside is some
degree of performance.

350
00:14:14,686 --> 00:14:16,846
And so on the PHP side,
and we'll talk about this

351
00:14:16,846 --> 00:14:19,506
in our scalability lecture,
there are ways of mitigating

352
00:14:19,506 --> 00:14:23,346
that cost of interpreting
the same darn PHP file again

353
00:14:23,346 --> 00:14:23,826
and again.

354
00:14:24,076 --> 00:14:27,106
You can do what's called
cache, the up codes,

355
00:14:27,106 --> 00:14:28,426
which is a fancy way of saying

356
00:14:28,426 --> 00:14:31,376
that the PHP interpreter
can save the results

357
00:14:31,376 --> 00:14:33,866
of its first interpretation
so that the second, and third,

358
00:14:33,866 --> 00:14:36,186
and fourth interpretations
are much faster

359
00:14:36,376 --> 00:14:37,786
but that's purely server side.

360
00:14:37,786 --> 00:14:40,176
On the client side
you might have noticed

361
00:14:40,176 --> 00:14:43,676
in the popular press
that when Google comes

362
00:14:43,676 --> 00:14:45,436
out with a new version
of Chrome, or Fire --

363
00:14:45,486 --> 00:14:47,856
or Mozilla comes out with
a new Firefox version,

364
00:14:48,116 --> 00:14:51,206
everyone's touting their various
JavaScript performance numbers.

365
00:14:51,206 --> 00:14:53,446
And that's in particular
because so much more

366
00:14:53,446 --> 00:14:57,556
of the web these days is
based on client side code

367
00:14:57,766 --> 00:15:00,676
and the faster that code
executes the better the user

368
00:15:00,676 --> 00:15:02,486
experience tends to be.

369
00:15:02,486 --> 00:15:03,856
And the more necessary it is

370
00:15:03,856 --> 00:15:05,676
to have good JavaScript
interpreters,

371
00:15:05,886 --> 00:15:08,196
especially in older
hardware, or mobile phones,

372
00:15:08,426 --> 00:15:11,546
or netbooks where you
just have fewer CPU cycles

373
00:15:11,546 --> 00:15:13,326
and less RAM to play with.

374
00:15:13,586 --> 00:15:15,156
So let's take a look
at JavaScript,

375
00:15:15,156 --> 00:15:16,776
and you should find overall

376
00:15:16,916 --> 00:15:20,576
that syntactically it's pretty
similar to what you would find

377
00:15:20,576 --> 00:15:22,766
in other interpreted
languages, among them PHP,

378
00:15:22,766 --> 00:15:25,456
but there's a few features
and a few approaches

379
00:15:25,456 --> 00:15:28,076
that are generally good to be
mindful of out of the gate.

380
00:15:28,076 --> 00:15:31,526
So, one, in terms of references,
these are some okay references.

381
00:15:31,526 --> 00:15:34,346
The first two are more
authoritative than W3Schools,

382
00:15:34,626 --> 00:15:37,636
but you'll find that these links
might be some useful reading.

383
00:15:37,936 --> 00:15:39,986
But today what we'll focus on
are some of the core features

384
00:15:39,986 --> 00:15:42,726
of JavaScript, the syntax, most
of which you'll find familiar,

385
00:15:42,876 --> 00:15:44,446
and then some concrete examples.

386
00:15:44,446 --> 00:15:47,346
And then what we'll do next
Monday is focus in particular

387
00:15:47,346 --> 00:15:50,266
on Ajax, asynchronous
JavaScript and XML,

388
00:15:50,516 --> 00:15:52,976
although it doesn't
necessarily involve XML anymore.

389
00:15:52,976 --> 00:15:55,716
Rather, Ajax is all
about using JavaScript

390
00:15:55,896 --> 00:15:58,066
to program more dynamic
websites,

391
00:15:58,066 --> 00:15:59,806
things like Google
Maps, and Facebook,

392
00:15:59,806 --> 00:16:03,416
that even once you have landed
on their homepage they continue

393
00:16:03,416 --> 00:16:06,476
to pull in more and more data,
whether it's different parts

394
00:16:06,476 --> 00:16:09,306
of a map, whether it's status
updates from your friends,

395
00:16:09,306 --> 00:16:11,686
and that's all thanks to
JavaScript and the ability

396
00:16:11,686 --> 00:16:15,596
in JavaScript these days to
make additional HTTP requests

397
00:16:15,976 --> 00:16:17,596
without reloading
the whole page.

398
00:16:17,736 --> 00:16:21,656
You can instead make other HTTP
requests that get back subsets

399
00:16:21,656 --> 00:16:24,426
of content and incorporate
that content

400
00:16:24,426 --> 00:16:26,116
into an existing webpage.

401
00:16:26,116 --> 00:16:28,336
So we'll also see
the topic of DOM

402
00:16:28,596 --> 00:16:32,436
and tree structures recur
today and next week as well.

403
00:16:32,916 --> 00:16:34,606
So how do you go about
writing JavaScript?

404
00:16:34,846 --> 00:16:38,016
So JavaScript is not
fundamentally tied to the web

405
00:16:38,016 --> 00:16:42,356
or to HTML, but it's generally
found inside of webpages,

406
00:16:42,356 --> 00:16:44,256
or inside of JS files --

407
00:16:44,406 --> 00:16:47,666
.js files that themselves
are included in webpages.

408
00:16:47,856 --> 00:16:50,366
Now as an aside they're
increasingly common is

409
00:16:50,406 --> 00:16:52,186
to actually use JavaScript
server side.

410
00:16:52,476 --> 00:16:56,216
A very popular framework,
if familiar, is node.js,

411
00:16:56,216 --> 00:16:58,736
which we'll talk briefly about
toward the end of the semester,

412
00:16:58,736 --> 00:17:01,966
but this is an alternative
type of tool that allows you

413
00:17:01,966 --> 00:17:03,776
to actually write
JavaScript code on a server,

414
00:17:03,776 --> 00:17:06,316
or even on your Mac, or
your PC, and run it locally

415
00:17:06,316 --> 00:17:08,036
without actually
needing a browser.

416
00:17:08,036 --> 00:17:11,716
So just realize that unto itself
JavaScript is a full-fledged

417
00:17:11,716 --> 00:17:14,146
programming language but
tends to be used in webpages

418
00:17:14,326 --> 00:17:16,996
and it tends to be used
in between script tags

419
00:17:17,216 --> 00:17:19,116
that look quite simply
like that.

420
00:17:19,306 --> 00:17:21,506
However, if you actually want
to put your JavaScript code,

421
00:17:21,506 --> 00:17:22,596
such as the stuff
we're going to write,

422
00:17:22,806 --> 00:17:26,916
in a separate file you can
include it in a separate file

423
00:17:27,226 --> 00:17:28,236
by a syntax like this.

424
00:17:28,586 --> 00:17:31,186
So the script tag takes an
optional source attribute,

425
00:17:31,376 --> 00:17:34,356
which references a file, and
then also a type attribute

426
00:17:34,626 --> 00:17:37,766
which informs the browser what
the type of that script is.

427
00:17:37,766 --> 00:17:39,116
It's almost always JavaScript,

428
00:17:39,116 --> 00:17:41,626
but in theory other
languages could be supported.

429
00:17:42,146 --> 00:17:44,286
So without knowing
much about JavaScript,

430
00:17:44,286 --> 00:17:46,746
without actually even seeing
any JavaScript just yet,

431
00:17:46,976 --> 00:17:49,856
just instinctively, why
might you want to be able

432
00:17:49,856 --> 00:17:53,366
to embed JavaScript code
between script tags in a webpage

433
00:17:53,876 --> 00:17:57,836
versus doing it via an
inclusion mechanism like this?

434
00:17:58,576 --> 00:18:02,606
When might you go one route
versus the other do you think?

435
00:18:02,786 --> 00:18:02,886
Yeah?

436
00:18:03,056 --> 00:18:06,646
>> [Inaudible] a user
to look at my code.

437
00:18:06,816 --> 00:18:06,976
>> Okay.

438
00:18:07,516 --> 00:18:10,546
[ Inaudible Speaker ]

439
00:18:11,046 --> 00:18:13,516
Okay. So we can raise the bar
to the user seeing my code

440
00:18:13,516 --> 00:18:16,086
by putting it in a
secondary file rather

441
00:18:16,086 --> 00:18:18,946
than my .html file,
or my .php file.

442
00:18:19,186 --> 00:18:20,406
The one pushback there is

443
00:18:20,406 --> 00:18:23,476
that because JavaScript is an
interpreted client side language

444
00:18:23,476 --> 00:18:24,416
when used in the web,

445
00:18:24,786 --> 00:18:28,176
the reality is we can still see
file.js, it's just not going

446
00:18:28,176 --> 00:18:30,996
to be in the body
of the main webpage.

447
00:18:31,296 --> 00:18:33,696
But for instance, if
we use Chrome, or IE's,

448
00:18:33,696 --> 00:18:36,566
or Firefox's Inspector, it's
a little debugging window

449
00:18:36,566 --> 00:18:39,326
at the bottom, we can absolutely
still see the contents

450
00:18:39,326 --> 00:18:40,296
of my JavaScript file.

451
00:18:40,296 --> 00:18:42,426
So it raises the bar a little
bit but not fundamentally.

452
00:18:42,706 --> 00:18:42,976
Jack?

453
00:18:42,976 --> 00:18:45,416
>> It lets you use the
same JavaScript commands

454
00:18:45,736 --> 00:18:47,236
on all sorts of different pages.

455
00:18:47,236 --> 00:18:47,326
>> Good.

456
00:18:47,326 --> 00:18:50,786
>> Instead of having to paste
and copy and all that stuff.

457
00:18:50,946 --> 00:18:53,766
>> Good. So much like CSS it can
be used across multiple pages

458
00:18:53,766 --> 00:18:56,456
if you factor it out into an
individual file and then include

459
00:18:56,456 --> 00:18:59,066
that file with a link tag
in the head of your webpage.

460
00:18:59,376 --> 00:19:01,356
Same deal here, with
JavaScript if you want

461
00:19:01,356 --> 00:19:03,826
to use the same functions
or the same widgets

462
00:19:03,826 --> 00:19:08,346
in different webpages, whether
it's a .html file, or .php file,

463
00:19:08,346 --> 00:19:11,436
or whatever, you can factor
it out here, include this tag

464
00:19:11,436 --> 00:19:14,236
in every one of those pages
so that you can then use

465
00:19:14,276 --> 00:19:16,716
that JavaScript functionality
anywhere you want.

466
00:19:16,716 --> 00:19:18,696
So there's just an
efficiency mechanism to it.

467
00:19:18,696 --> 00:19:22,366
One, you don't have to download
the same file again and again,

468
00:19:22,366 --> 00:19:24,726
indeed you get the benefits
of caching in this case,

469
00:19:24,906 --> 00:19:26,536
because if the browser
realizes, wait a minute,

470
00:19:26,536 --> 00:19:28,886
I already downloaded
file.js before,

471
00:19:29,066 --> 00:19:31,816
even if you're including this
tag in 20 different webpages

472
00:19:31,816 --> 00:19:33,986
of yours the browser
most likely is not going

473
00:19:33,986 --> 00:19:35,846
to keep re-downloading file.js.

474
00:19:36,396 --> 00:19:39,206
By contrast, if you paste it, a
whole bunch of JavaScript code

475
00:19:39,206 --> 00:19:43,046
between script tags in your
HTML, well then that just has

476
00:19:43,046 --> 00:19:44,856
to be downloaded
again and again,

477
00:19:44,856 --> 00:19:47,816
because when you request a file
via HTTP you really get the

478
00:19:47,816 --> 00:19:51,316
whole thing typically, you don't
get everything but the part

479
00:19:51,316 --> 00:19:52,946
of it that you downloaded
before.

480
00:19:53,266 --> 00:19:54,206
So there's that mechanism.

481
00:19:54,206 --> 00:19:57,146
And then there's just the design
opportunity whereby you don't

482
00:19:57,146 --> 00:20:00,456
have to comingle it with your
aesthetic markup, your HTML,

483
00:20:00,626 --> 00:20:04,126
you can really relegate your
logic to a separate file

484
00:20:04,316 --> 00:20:06,796
and it lends itself
therefore to better designs,

485
00:20:06,796 --> 00:20:07,976
certainly for complex projects.

486
00:20:08,676 --> 00:20:11,016
So initially we'll start by
just embedding everything

487
00:20:11,016 --> 00:20:13,326
in our HTML files
because one, we don't care

488
00:20:13,326 --> 00:20:15,606
yet about performance
because these are going

489
00:20:15,606 --> 00:20:17,396
to be tiny little
scripts at first.

490
00:20:17,656 --> 00:20:19,656
Two, it's a little bit
easier to read pedagogically

491
00:20:19,656 --> 00:20:20,836
if it's all in the same file.

492
00:20:21,096 --> 00:20:22,386
But as soon as we
get to the point

493
00:20:22,386 --> 00:20:25,386
of doing more powerful things
with JavaScript it'll make sense

494
00:20:25,976 --> 00:20:27,766
to adopt this model here.

495
00:20:28,576 --> 00:20:31,876
All right, so here is
JavaScript in list format.

496
00:20:32,416 --> 00:20:35,496
These aren't all the keywords
but I tossed these up here

497
00:20:35,496 --> 00:20:38,046
in bullet form really
just to convey the message

498
00:20:38,046 --> 00:20:41,856
that JavaScript is quite
similar to most of the languages

499
00:20:41,856 --> 00:20:43,346
with which you're
probably already familiar.

500
00:20:43,346 --> 00:20:46,986
So not just PHP but whatever
languages you've used before

501
00:20:46,986 --> 00:20:47,606
coming into the class.

502
00:20:48,126 --> 00:20:50,106
You have break statements
to break out of things

503
00:20:50,106 --> 00:20:52,286
like loops, or switches.

504
00:20:52,656 --> 00:20:55,426
You have do while,
you have for loops,

505
00:20:55,426 --> 00:20:56,846
you have while loops
and the like.

506
00:20:56,846 --> 00:21:01,096
You have the return statement,
switches, throw, try, and catch,

507
00:21:01,096 --> 00:21:02,656
which relate to exception
handling,

508
00:21:02,656 --> 00:21:04,696
which we talked briefly
about on Monday

509
00:21:04,696 --> 00:21:06,856
and also is quite
popular in Java.

510
00:21:07,066 --> 00:21:09,736
Var for variable we'll see is
a little bit different from PHP

511
00:21:09,736 --> 00:21:13,126
where we sometimes want
to declare explicitly

512
00:21:13,126 --> 00:21:15,296
that something's a
variable before using it.

513
00:21:15,586 --> 00:21:17,856
And functions are actually
going to be quite powerful.

514
00:21:17,856 --> 00:21:21,016
One of the most powerful and
useful features of JavaScript is

515
00:21:21,016 --> 00:21:23,336
that it supports
anonymous functions

516
00:21:23,336 --> 00:21:25,766
and in turn things
called closures

517
00:21:25,766 --> 00:21:27,216
which for now [inaudible]
are going

518
00:21:27,216 --> 00:21:30,076
to let us do some fairly
sophisticated things

519
00:21:30,286 --> 00:21:33,066
like passing functions
around as arguments

520
00:21:33,306 --> 00:21:36,336
and not just passing
variables around as arguments.

521
00:21:36,336 --> 00:21:39,526
So this is quite a fancy feature
that's now present in PHP

522
00:21:39,526 --> 00:21:42,936
and other languages but it's
quite a very common paradigm

523
00:21:43,086 --> 00:21:44,306
in JavaScript.

524
00:21:44,786 --> 00:21:47,976
All right, so some basic syntax.

525
00:21:48,216 --> 00:21:51,576
In JavaScript to declare
an array, call it a,

526
00:21:51,576 --> 00:21:53,526
you can do syntax
as simple as this.

527
00:21:53,526 --> 00:21:55,396
Var, which means give
me a variable, a,

528
00:21:55,396 --> 00:21:56,826
which means here's the
name of the variable,

529
00:21:56,826 --> 00:21:58,406
equals open square bracket,

530
00:21:58,406 --> 00:21:59,916
closed square bracket,
semicolon.

531
00:22:00,006 --> 00:22:00,456
That's it.

532
00:22:00,716 --> 00:22:03,686
So this returns to
you an empty array.

533
00:22:04,146 --> 00:22:07,406
These arrays in JavaScript
are only numerically indexed.

534
00:22:07,506 --> 00:22:10,816
So whereas in PHP we
saw associative arrays

535
00:22:10,816 --> 00:22:14,216
and you could use an array by
way of indexing in with numbers,

536
00:22:14,576 --> 00:22:16,956
or you could use
actual keywords,

537
00:22:17,076 --> 00:22:19,656
like the super globals,
get, and post, and session,

538
00:22:19,656 --> 00:22:21,776
and cookie are all
associative arrays.

539
00:22:22,046 --> 00:22:25,796
In JavaScript arrays are by
definition numerically indexed.

540
00:22:25,796 --> 00:22:28,916
So for now, if I want to
add things to an array

541
00:22:28,916 --> 00:22:30,816
in JavaScript I can do this
in a few different ways,

542
00:22:30,816 --> 00:22:32,956
I can do a [0] gets equal 'foo'.

543
00:22:33,206 --> 00:22:35,536
Totally arbitrary example
but it just shows the syntax.

544
00:22:35,826 --> 00:22:38,396
If your array is called
a, and you want to get

545
00:22:38,396 --> 00:22:40,916
at location zero, even
if nothing is there yet,

546
00:22:41,266 --> 00:22:45,306
you just go ahead and
say gets equals bar --

547
00:22:45,306 --> 00:22:47,026
or 'foo' in this
case, or number,

548
00:22:47,026 --> 00:22:48,226
whatever value you
want to store there.

549
00:22:48,226 --> 00:22:49,956
Same deal for bracket
one and bracket two.

550
00:22:50,516 --> 00:22:52,376
The one thing to realize here is

551
00:22:52,736 --> 00:22:54,126
that they array is
actually going

552
00:22:54,126 --> 00:22:55,776
to grow automatically for you.

553
00:22:56,016 --> 00:22:58,286
You don't have to resize it
as you might in a language

554
00:22:58,286 --> 00:22:59,476
like C. You don't have to know

555
00:22:59,476 --> 00:23:00,916
in advance how big
this array is.

556
00:23:01,126 --> 00:23:03,466
You can just keep pushing
additional items onto it

557
00:23:03,466 --> 00:23:05,326
by knowing at what
index you want

558
00:23:05,326 --> 00:23:07,326
to place foo, or bar, or baz.

559
00:23:07,626 --> 00:23:09,506
So you can actually be
a little more deliberate

560
00:23:09,756 --> 00:23:11,526
and you can actually
call functions.

561
00:23:11,526 --> 00:23:14,676
So JavaScript arrays
are actually objects,

562
00:23:14,946 --> 00:23:16,356
even though you're
initializing it

563
00:23:16,356 --> 00:23:18,686
with this somewhat shorthand
notation of open bracket,

564
00:23:18,816 --> 00:23:22,326
closed bracket, they are
themselves full-fledged objects

565
00:23:22,436 --> 00:23:24,336
in an object-oriented
programming sense,

566
00:23:24,646 --> 00:23:26,946
and therefore they have
methods associated with them.

567
00:23:26,946 --> 00:23:28,576
And one of the methods
associated

568
00:23:28,576 --> 00:23:31,486
with a JavaScript
array is a push method,

569
00:23:31,486 --> 00:23:32,756
which pretty much
does what it says,

570
00:23:33,136 --> 00:23:37,566
a.push means call the push
method inside of the array,

571
00:23:37,566 --> 00:23:40,626
called a, and give it an
argument in this case of foo.

572
00:23:40,626 --> 00:23:43,536
And that has the exact same
effect of just adding foo

573
00:23:43,536 --> 00:23:46,236
in this case to the first
location in the array.

574
00:23:46,236 --> 00:23:48,616
Why? Well the array is
initialized to nothing

575
00:23:48,616 --> 00:23:51,286
so pushing an element onto it
means you now have a bracket

576
00:23:51,326 --> 00:23:52,086
zero location.

577
00:23:52,086 --> 00:23:53,076
Call it again and again,

578
00:23:53,076 --> 00:23:54,846
you have bracket
one and bracket two.

579
00:23:54,846 --> 00:23:57,336
So push appends an
element to an array,

580
00:23:57,336 --> 00:23:58,936
it does not prepend the element.

581
00:23:59,286 --> 00:24:03,116
As an aside you may also see
syntax whereby you can declare

582
00:24:03,116 --> 00:24:07,816
an array with var
a equals new Array.

583
00:24:08,056 --> 00:24:13,816
So A-R-R-A-Y, capital A, is
actually the name of a class,

584
00:24:13,966 --> 00:24:16,076
though JavaScript doesn't
technically have classes,

585
00:24:16,076 --> 00:24:18,286
it's the name of a
JavaScript object that exists

586
00:24:18,526 --> 00:24:21,586
but the common notation,
daresay preferred notation,

587
00:24:21,586 --> 00:24:23,706
is just to use the
simpler square brackets.

588
00:24:23,706 --> 00:24:26,386
But realize you might see
that in various tutorials.

589
00:24:27,076 --> 00:24:29,306
So good, we have arrays, which
means we have the ability

590
00:24:29,306 --> 00:24:31,246
to store lists of things
and arrays are going

591
00:24:31,246 --> 00:24:33,236
to be super useful
once we get to Ajax

592
00:24:33,546 --> 00:24:36,956
and more generally the retrieval
of more data from a server

593
00:24:36,956 --> 00:24:38,346
because if you can
imagine how something

594
00:24:38,346 --> 00:24:41,066
like Facebook is
implemented or Google Maps,

595
00:24:41,256 --> 00:24:44,206
you're often not just getting
one thing back from the server,

596
00:24:44,406 --> 00:24:46,476
you want to get back
multiple tiles for your map.

597
00:24:46,616 --> 00:24:48,836
You want to get back multiple
friend status updates.

598
00:24:48,836 --> 00:24:52,556
So you want to get back an array
of stuff, so JavaScript is going

599
00:24:52,556 --> 00:24:53,986
to lend itself to that

600
00:24:54,476 --> 00:24:58,126
and you'll see it's a
common syntactic tool.

601
00:24:58,636 --> 00:25:01,966
So let's do an example and just
to see how we might use this,

602
00:25:02,336 --> 00:25:07,206
a very common thing in a
webpage is to have a form,

603
00:25:07,206 --> 00:25:09,826
like a login form with a
username and a password.

604
00:25:10,056 --> 00:25:12,776
And at least me, who is a little
uptight, it drives me nuts

605
00:25:12,906 --> 00:25:16,146
if upon visiting a page and
being prompted to login I have

606
00:25:16,146 --> 00:25:18,946
to manually click
with my mouse inside

607
00:25:18,946 --> 00:25:21,526
of the username field just so
I can start typing my username.

608
00:25:21,526 --> 00:25:24,016
Right? This is completely
unnecessary, but if you think

609
00:25:24,016 --> 00:25:26,586
about it any of the forms
you've implemented thus far

610
00:25:26,586 --> 00:25:30,836
without using JavaScript code
do not automatically give focus

611
00:25:31,146 --> 00:25:32,266
to any given field.

612
00:25:32,496 --> 00:25:34,006
You have a text field,
text field,

613
00:25:34,006 --> 00:25:36,226
and however many more you
have declared in your HTML,

614
00:25:36,436 --> 00:25:37,666
but if you want to
start typing stuff

615
00:25:37,666 --> 00:25:40,506
into those text fields you have
to click with your mouse just

616
00:25:40,506 --> 00:25:42,106
like we did for the
past couple of weeks

617
00:25:42,106 --> 00:25:43,716
when we've been doing
form examples

618
00:25:43,966 --> 00:25:44,846
in order to start typing.

619
00:25:45,376 --> 00:25:47,186
So this is not the best
user experience, right?

620
00:25:47,186 --> 00:25:49,196
If I visited Facebook.com,
I'm not logged in,

621
00:25:49,336 --> 00:25:51,876
let me just start typing my
username and then my password,

622
00:25:51,876 --> 00:25:54,846
don't make me click and then
type my username and password.

623
00:25:55,056 --> 00:25:57,096
So how can we express that
idea programmatically?

624
00:25:57,286 --> 00:26:01,006
So this is out of context, just
in HTML element, called script,

625
00:26:01,006 --> 00:26:03,286
inside of which is some
actual JavaScript code.

626
00:26:03,286 --> 00:26:04,876
So here we go,

627
00:26:04,876 --> 00:26:08,706
if document.forms.login
.username.value.

628
00:26:09,216 --> 00:26:12,036
So, ridiculously verbose and
we'll see before long ways

629
00:26:12,036 --> 00:26:14,896
to clean this up and just make
it a lot more straightforward,

630
00:26:15,246 --> 00:26:16,486
but what is this referring to?

631
00:26:16,756 --> 00:26:19,766
So in the context of a
webpage you have a special,

632
00:26:19,956 --> 00:26:25,156
super global, really just
global variable called document.

633
00:26:25,486 --> 00:26:27,596
And this variable
is of type object

634
00:26:27,976 --> 00:26:30,826
which means it has stuff inside
of it, properties inside of it

635
00:26:30,826 --> 00:26:33,056
and possibly methods
associated with it.

636
00:26:33,486 --> 00:26:37,356
So document actually refers
to essentially the DOM

637
00:26:37,436 --> 00:26:38,446
that we've been talking about.

638
00:26:38,446 --> 00:26:40,846
We talked about DOM mostly
in the context of XML,

639
00:26:41,376 --> 00:26:43,526
but quick refresher,
what was a DOM?

640
00:26:43,916 --> 00:26:46,406
What is document
object model all about?

641
00:26:51,956 --> 00:26:52,656
DOM, yeah?

642
00:26:52,986 --> 00:26:57,116
>> It's like the
structure of the document.

643
00:26:57,116 --> 00:26:59,126
>> Okay, it refers to the
structure of the document.

644
00:26:59,126 --> 00:27:00,666
It was a tree structure, recall.

645
00:27:00,866 --> 00:27:04,436
In fact we drew a tree in
picture form on a slide

646
00:27:04,636 --> 00:27:06,616
that represented
a snippet of XML.

647
00:27:06,846 --> 00:27:09,896
So DOM is a way of
modeling hierarchical data,

648
00:27:09,896 --> 00:27:14,376
for instance XML, or HTML, in
a tree structure and the roots

649
00:27:14,506 --> 00:27:18,886
of that DOM is generally
called the document node.

650
00:27:19,006 --> 00:27:21,146
It was capital D the last
time we talked about it,

651
00:27:21,146 --> 00:27:22,956
here it's lower case d,
but it's the same thing.

652
00:27:23,276 --> 00:27:25,156
So when you're writing
JavaScript code inside

653
00:27:25,156 --> 00:27:28,776
of a webpage, inside of a whole
bunch of HTML, you can access

654
00:27:28,826 --> 00:27:30,816
that tree structure
programmatically

655
00:27:31,226 --> 00:27:32,706
by saying document.

656
00:27:33,126 --> 00:27:36,186
And document dot means
go inside of this object

657
00:27:36,186 --> 00:27:38,636
and access some property
inside of it.

658
00:27:38,636 --> 00:27:41,026
So for those unfamiliar with
object oriented programming,

659
00:27:41,026 --> 00:27:43,466
though most of you would
be from prior experience,

660
00:27:43,726 --> 00:27:45,846
realize that object
oriented programming is

661
00:27:45,846 --> 00:27:48,686
about having data
structures in memory,

662
00:27:48,986 --> 00:27:52,256
generally called objects, and
objects can have both data

663
00:27:52,256 --> 00:27:55,906
and methods associated
with them, our properties

664
00:27:55,906 --> 00:27:57,476
and methods associated
with them.

665
00:27:57,846 --> 00:28:02,886
So, in the case thus far
with document it turns

666
00:28:02,886 --> 00:28:05,316
out there is a property
called forms.

667
00:28:05,746 --> 00:28:08,876
Forms happens to be
a collection of all

668
00:28:08,876 --> 00:28:10,596
of the forms in that document.

669
00:28:10,726 --> 00:28:13,136
And there might be zero forms,
there might be 10 forms.

670
00:28:13,136 --> 00:28:15,846
It totally depends on how many
form tags are in that document.

671
00:28:16,346 --> 00:28:21,026
So document.forms.login
specifically means get me the

672
00:28:21,026 --> 00:28:25,106
form whose name is login
among all of the forms

673
00:28:25,106 --> 00:28:27,646
in the current page,
whether there's one or more.

674
00:28:28,406 --> 00:28:31,896
Document.forms.login.username,
take a guess here,

675
00:28:32,086 --> 00:28:34,326
what is username
referring to in the context

676
00:28:34,326 --> 00:28:35,236
of this story thus far?

677
00:28:35,236 --> 00:28:35,586
Axle?

678
00:28:35,876 --> 00:28:36,116
>> Well, [inaudible] field

679
00:28:39,296 --> 00:28:40,146
of the ID username
inside of that form.

680
00:28:40,146 --> 00:28:41,296
>> Good, so in this
case it's referring

681
00:28:41,296 --> 00:28:43,626
to the input called
username, happens to be name

682
00:28:43,626 --> 00:28:45,966
as opposed to ID in this case.

683
00:28:46,126 --> 00:28:50,716
Username field in the form whose
name is login in the collection

684
00:28:50,716 --> 00:28:52,456
of forms inside of the DOM.

685
00:28:52,456 --> 00:28:54,856
So there's a hierarchy to
these dots, just like in Xpath

686
00:28:55,416 --> 00:28:58,196
and in the simple XML API there
was this notion of stepping

687
00:28:58,306 --> 00:28:59,396
where the arrow notation

688
00:28:59,396 --> 00:29:01,036
that said go deeper,
go deeper, go deeper.

689
00:29:01,266 --> 00:29:02,056
Same idea here.

690
00:29:02,436 --> 00:29:06,076
Document is sort of the highest
level object you have access to,

691
00:29:06,256 --> 00:29:08,286
document.forms dives
in a little deeper,

692
00:29:08,286 --> 00:29:10,306
document.forms.login
a little deeper,

693
00:29:10,306 --> 00:29:12,266
and .username even deeper.

694
00:29:12,466 --> 00:29:16,596
Now, username really refers
to the node in the tree that's

695
00:29:16,596 --> 00:29:19,866
of type input, so think about
how you would make a login form.

696
00:29:19,866 --> 00:29:22,186
We've got at least two
input HTML elements,

697
00:29:22,526 --> 00:29:23,826
username and a password one.

698
00:29:24,406 --> 00:29:30,036
So, username is now referring
to a rectangle in DOM --

699
00:29:30,316 --> 00:29:32,526
a rectangle in the sense
that's how we drew it

700
00:29:32,526 --> 00:29:33,606
on the screen the other day.

701
00:29:34,126 --> 00:29:37,076
So dot value is actually
referring to its string value,

702
00:29:37,106 --> 00:29:40,486
whatever text is actually
in that text field.

703
00:29:40,816 --> 00:29:43,106
So let's see this in the
context of some actual HTML.

704
00:29:43,226 --> 00:29:46,306
Let me go over to the
appliance and let me open

705
00:29:46,306 --> 00:29:55,506
up a file called form1.html and
let me skip the JavaScript code

706
00:29:55,506 --> 00:29:57,556
for a moment and
focus only on this.

707
00:29:57,946 --> 00:29:59,766
So I propose this as one

708
00:29:59,766 --> 00:30:02,936
of the simplest possible
login screens we could have,

709
00:30:02,936 --> 00:30:04,976
and I have a few
things going on here.

710
00:30:05,096 --> 00:30:06,776
One, I have a form.

711
00:30:07,116 --> 00:30:09,066
Two, I have an element
called email.

712
00:30:09,066 --> 00:30:11,916
Next, I have another
input called password1,

713
00:30:11,916 --> 00:30:16,896
and then third I have another
field called password2.

714
00:30:16,896 --> 00:30:19,066
So you can imagine this
being in the context

715
00:30:19,066 --> 00:30:20,776
of a registration form.

716
00:30:20,776 --> 00:30:23,426
So not necessarily login but
registration where you want

717
00:30:23,426 --> 00:30:25,106
to ask the user for the
same password twice,

718
00:30:25,416 --> 00:30:28,666
that'll lend itself to some
validity checking in just a bit.

719
00:30:28,986 --> 00:30:31,996
And then lastly I
have a submit button.

720
00:30:32,086 --> 00:30:33,406
So that's it.

721
00:30:33,966 --> 00:30:36,176
Well, what if now I want

722
00:30:36,176 --> 00:30:38,196
to start getting
programmatic access

723
00:30:38,196 --> 00:30:40,206
to these various
fields, let's do this.

724
00:30:40,406 --> 00:30:46,946
Let's open up instead
version two of this, form2,

725
00:30:47,046 --> 00:30:50,436
and let me propose the
following approach.

726
00:30:51,696 --> 00:30:55,356
Down here now let's do
a registration form.

727
00:30:55,646 --> 00:31:00,316
So I've given this form
an ID, registration,

728
00:31:00,816 --> 00:31:05,836
and I have given it similarly an
email field, a password field,

729
00:31:05,836 --> 00:31:08,796
another password field,
and then a submit button.

730
00:31:08,796 --> 00:31:11,586
But what I want to do this
time is when the user tries

731
00:31:11,636 --> 00:31:14,096
to submit this form I
want to use JavaScript

732
00:31:14,096 --> 00:31:17,206
to actually check the values
that they've typed in and yell

733
00:31:17,206 --> 00:31:20,366
at the user, reject their
input if the passwords

734
00:31:20,366 --> 00:31:22,366
for instance don't match,
or if they haven't filled

735
00:31:22,366 --> 00:31:23,546
out this form properly.

736
00:31:23,956 --> 00:31:27,766
So we could do this in PHP,
think back a few lectures now

737
00:31:28,086 --> 00:31:30,266
where we had those
various login examples,

738
00:31:30,396 --> 00:31:32,776
and if the user did
not give me a username

739
00:31:32,916 --> 00:31:36,446
or a password we would reject
their input and we would check

740
00:31:36,446 --> 00:31:38,246
for that server side
by checking the value

741
00:31:38,246 --> 00:31:40,126
of dollar sign, underscore,
post.

742
00:31:40,816 --> 00:31:43,646
So we can already
check the validity

743
00:31:43,646 --> 00:31:46,926
of a user submission server
side, so what's the point

744
00:31:46,926 --> 00:31:52,276
of even doing form-checking, or
validity-checking client side

745
00:31:52,276 --> 00:31:53,076
with JavaScript today?

746
00:31:53,076 --> 00:31:54,936
>> We can check without even
having to reload the page

747
00:31:54,936 --> 00:32:00,816
or deal with anything
[inaudible] can immediately be

748
00:32:00,906 --> 00:32:01,076
done [inaudible].

749
00:32:01,076 --> 00:32:01,656
>> Exactly.

750
00:32:01,716 --> 00:32:03,246
So, with JavaScript now,

751
00:32:03,246 --> 00:32:05,816
with client side code we can
check whether the form has been

752
00:32:05,816 --> 00:32:09,326
filled out correctly immediately
client side without even talking

753
00:32:09,326 --> 00:32:10,816
to the server and
to be more clear,

754
00:32:10,816 --> 00:32:12,626
like what is really the
value of doing that?

755
00:32:12,626 --> 00:32:12,726
Yeah?

756
00:32:12,726 --> 00:32:13,726
>> Well, [inaudible] efficiency,
you're not sending any,

757
00:32:13,726 --> 00:32:19,766
in this case, useless data
to the server for validation

758
00:32:19,766 --> 00:32:22,056
and then receiving it again.

759
00:32:22,056 --> 00:32:22,386
>> Exactly.

760
00:32:22,386 --> 00:32:23,956
Really it boils down
to performance.

761
00:32:23,956 --> 00:32:28,026
With JavaScript on really any
computer, any phone these days,

762
00:32:28,026 --> 00:32:29,516
it can execute so quickly

763
00:32:29,516 --> 00:32:32,156
that you pretty much get
immediate feedback for the user,

764
00:32:32,326 --> 00:32:34,746
which means they see whatever
problems they've created

765
00:32:34,746 --> 00:32:35,336
right away.

766
00:32:35,546 --> 00:32:38,146
Moreover you're just not
adding extra load to the server

767
00:32:38,146 --> 00:32:41,096
for really no good reason so you
can reduce load on the server

768
00:32:41,096 --> 00:32:43,486
which can potentially help
with scalability if it has

769
00:32:43,486 --> 00:32:45,626
to do less per a
given unit of time.

770
00:32:45,906 --> 00:32:47,426
So a couple of advantages here.

771
00:32:47,616 --> 00:32:49,156
So let's take a look
at this form

772
00:32:49,206 --> 00:32:52,296
in the browser before teasing
apart how we can impose this

773
00:32:52,296 --> 00:32:53,816
kind of error checking.

774
00:32:53,816 --> 00:32:57,826
So here's the original form,
very simple, very ugly,

775
00:32:58,056 --> 00:33:00,586
but it has my email
field, password film,

776
00:33:00,586 --> 00:33:03,606
password again field, and then I
also decided I'm going to throw

777
00:33:03,606 --> 00:33:05,346
in a terms and conditions
checkbox,

778
00:33:05,346 --> 00:33:06,856
because this really
lends itself now

779
00:33:06,856 --> 00:33:09,946
to did the user do everything
we wanted them to do,

780
00:33:10,036 --> 00:33:12,426
a very common certainly
on webpages today.

781
00:33:12,756 --> 00:33:15,886
But notice if I don't do
anything here except type

782
00:33:15,886 --> 00:33:19,276
in malan, but that's not even a
valid email address, a password,

783
00:33:19,276 --> 00:33:21,256
I'm going to type in whatever,

784
00:33:21,256 --> 00:33:23,126
and then this time it's
definitely not going to match

785
00:33:23,126 --> 00:33:25,726
because it's only one character,
and I'm not going to check this.

786
00:33:25,826 --> 00:33:27,546
When I submit version
one of this form,

787
00:33:27,546 --> 00:33:30,246
which recall had no
JavaScript, just the HTML,

788
00:33:30,576 --> 00:33:32,596
here's all that happens
on the server.

789
00:33:32,886 --> 00:33:35,076
I have submitted to a file

790
00:33:35,076 --> 00:33:36,636
on the server called
what apparently?

791
00:33:37,916 --> 00:33:37,996
Yeah?

792
00:33:38,636 --> 00:33:39,386
>> Process.php.

793
00:33:40,026 --> 00:33:42,996
>> Process.php, which
clearly does not much at all.

794
00:33:42,996 --> 00:33:46,026
All it does is apparently call
the print r function in PHP,

795
00:33:46,026 --> 00:33:48,616
the recursive print function,
just because I needed a quick

796
00:33:48,616 --> 00:33:51,216
and dirty tool to see what was
actually sent to the server.

797
00:33:51,446 --> 00:33:54,336
In this case that's what I
just typed in on my keyboard.

798
00:33:54,456 --> 00:33:56,886
Notice that the checkbox
value was not even sent

799
00:33:57,006 --> 00:33:59,596
because it wasn't checked,
but the takeaway here is

800
00:33:59,596 --> 00:34:03,446
that I could check
on the server whether

801
00:34:03,446 --> 00:34:04,666
or not the user cooperated.

802
00:34:04,706 --> 00:34:06,836
Did they give me a syntactically
valid email address?

803
00:34:07,296 --> 00:34:09,286
Did they give me two
passwords that match?

804
00:34:09,466 --> 00:34:10,346
Did they check the box?

805
00:34:10,346 --> 00:34:12,436
All of those things I
can check server side,

806
00:34:12,746 --> 00:34:15,406
quite like I did a few
lectures ago with checking

807
00:34:15,406 --> 00:34:17,386
if John Harvard gave me the
right username and password.

808
00:34:17,586 --> 00:34:19,836
So all of that you can
sort of do already in PHP.

809
00:34:19,836 --> 00:34:22,126
But let's do it better

810
00:34:22,126 --> 00:34:24,646
or at least more
rapidly in JavaScript.

811
00:34:24,646 --> 00:34:29,296
So now, let me go back
here to version two of form

812
00:34:29,906 --> 00:34:31,946
and let me not cooperate
this time, too.

813
00:34:31,946 --> 00:34:36,036
Let me type in a whole bunch of
nonsense and not check the box

814
00:34:36,036 --> 00:34:38,646
and click submit and
this time what I want

815
00:34:38,736 --> 00:34:41,636
to see is an error message.

816
00:34:41,946 --> 00:34:44,706
So this is sort of like a poor
man's approach to error-checking

817
00:34:44,706 --> 00:34:46,906
where I'm just using the
JavaScript alert function.

818
00:34:47,156 --> 00:34:48,316
Those of you who've
been using the web

819
00:34:48,316 --> 00:34:50,466
for some time will remember
these used to be the scourge

820
00:34:50,466 --> 00:34:52,426
of the internet whereby you
would visit some website

821
00:34:52,746 --> 00:34:56,586
that had spam or wanted you
to click links and whatnot,

822
00:34:56,586 --> 00:34:58,486
and you would just get peppered
with all of these popups,

823
00:34:58,696 --> 00:35:01,766
so not the best approach yet,
but very easy way of signaling

824
00:35:01,766 --> 00:35:03,116
to the user that
an error happens.

825
00:35:03,116 --> 00:35:04,616
So we can improve
upon this eventually.

826
00:35:04,836 --> 00:35:05,696
What's the error?

827
00:35:05,876 --> 00:35:07,426
You must provide the same twice.

828
00:35:07,986 --> 00:35:09,816
So that came from
me it turns out.

829
00:35:09,816 --> 00:35:11,676
So let's take a look
at the JavaScript code

830
00:35:11,676 --> 00:35:14,806
that underlies this
particular error-checking.

831
00:35:15,046 --> 00:35:16,676
Let me go ahead and
open this up.

832
00:35:17,376 --> 00:35:19,396
Let me use a different
color background here.

833
00:35:20,196 --> 00:35:24,636
We're going to go ahead
and open up form2.html.

834
00:35:25,356 --> 00:35:26,466
And I'll zoom in here.

835
00:35:27,126 --> 00:35:31,666
So here again is the html,
here's the form in question.

836
00:35:32,646 --> 00:35:36,436
Let me scroll over to
the right deliberately.

837
00:35:37,076 --> 00:35:39,936
What is new or different
about this version

838
00:35:39,936 --> 00:35:42,566
of the form than last time?

839
00:35:42,686 --> 00:35:43,296
Yeah, Axle?

840
00:35:43,566 --> 00:35:46,966
>> You intercept the submit
and run the function validate

841
00:35:47,346 --> 00:35:49,836
on submit, which means
that the submission

842
00:35:50,206 --> 00:35:52,306
with PHP is not really done

843
00:35:52,306 --> 00:35:54,456
until that function
is [inaudible].

844
00:35:54,676 --> 00:35:55,366
>> Exactly.

845
00:35:55,476 --> 00:35:58,146
So in this case I
have on submit,

846
00:35:58,436 --> 00:36:01,266
which is a new HTML
attribute, and it is attached

847
00:36:01,566 --> 00:36:04,176
if we scroll back to the
left to the form element,

848
00:36:04,516 --> 00:36:07,366
and in this case I've said
form, then ID, and then method,

849
00:36:07,366 --> 00:36:10,606
and all that other stuff, on
submit equals "something."

850
00:36:10,836 --> 00:36:13,836
What is the value of
this on submit attribute?

851
00:36:14,186 --> 00:36:16,696
Well it's meant to be
actual programing code.

852
00:36:16,696 --> 00:36:18,916
Either the name of the
function that I want to call,

853
00:36:19,226 --> 00:36:21,866
or a string of JavaScript
that I want to execute

854
00:36:21,866 --> 00:36:22,936
and return some value.

855
00:36:23,186 --> 00:36:26,326
So I've literally said return
validate open print close print

856
00:36:26,326 --> 00:36:29,096
semi-colon, and we've not
written much JavaScript yet,

857
00:36:29,096 --> 00:36:31,656
but validate is apparently
the name of a function,

858
00:36:32,176 --> 00:36:34,316
and open print close print
means it takes no argument,

859
00:36:34,386 --> 00:36:35,906
semicolon means that's
the end of the line,

860
00:36:35,906 --> 00:36:37,356
though it's not strictly
necessary,

861
00:36:37,636 --> 00:36:40,856
and return means do
something with this value.

862
00:36:41,176 --> 00:36:44,266
And indeed, the way the
onsubmit handler is defined,

863
00:36:44,266 --> 00:36:45,796
if I were to read
the documentation,

864
00:36:46,176 --> 00:36:50,956
is that if the code between
quotes returns true submit the

865
00:36:50,956 --> 00:36:52,376
form to the server as usual.

866
00:36:52,596 --> 00:36:55,406
If the code between quotes
returns false don't submit the

867
00:36:55,406 --> 00:36:56,126
form at all.

868
00:36:56,376 --> 00:36:58,236
So here seems to
be our mechanism

869
00:36:58,236 --> 00:36:59,866
that Jack proposed,
being more efficient.

870
00:36:59,866 --> 00:37:02,166
We can yell at the user
right away and give feedback

871
00:37:02,476 --> 00:37:05,326
by returning false and maybe
triggering an error message

872
00:37:05,636 --> 00:37:07,796
but if everything looks
good we just return true

873
00:37:07,796 --> 00:37:09,596
and the user doesn't
even know we've validated

874
00:37:09,596 --> 00:37:10,236
their submission.

875
00:37:10,666 --> 00:37:12,936
So it's a nice transparent
way of doing something

876
00:37:12,936 --> 00:37:15,076
and then maybe intercepting
the form submission.

877
00:37:15,436 --> 00:37:17,476
So where is this
validate function defined?

878
00:37:17,476 --> 00:37:21,336
It doesn't come with JavaScript,
I had to write it myself,

879
00:37:21,736 --> 00:37:23,346
so let's scroll up
to the top here.

880
00:37:23,946 --> 00:37:25,306
So here's my script tag,

881
00:37:25,776 --> 00:37:29,646
and notice below the script tag
I have my validate function,

882
00:37:29,936 --> 00:37:32,366
and here is how you define
a function in JavaScript.

883
00:37:32,366 --> 00:37:35,106
Inside that script tag I have
function validate open print

884
00:37:35,106 --> 00:37:37,076
close print which does
what you would expect.

885
00:37:37,156 --> 00:37:40,036
In fact the syntax is pretty
much identical to PHP;

886
00:37:40,036 --> 00:37:42,836
the only difference is involving
how you would declare arguments

887
00:37:42,966 --> 00:37:44,466
or these default
arguments and the like.

888
00:37:44,736 --> 00:37:46,946
So function validate means
here comes a function

889
00:37:46,946 --> 00:37:48,306
called validate.

890
00:37:48,776 --> 00:37:51,386
All right, so now I'm using
my verbose syntax for now,

891
00:37:51,386 --> 00:37:55,096
if document.forms
.registration.email .value

892
00:37:55,096 --> 00:37:58,866
equals equals "" then I'm
going to yell at the user

893
00:37:58,866 --> 00:38:01,216
with an alert function
which comes with JavaScript,

894
00:38:01,216 --> 00:38:02,226
I did not write that one.

895
00:38:02,516 --> 00:38:05,286
What it does is it triggers that
popup with the message inside

896
00:38:05,286 --> 00:38:08,336
of it, and its argument is, "You
must provide an email address."

897
00:38:08,786 --> 00:38:09,846
And then I return false.

898
00:38:10,216 --> 00:38:11,346
So we didn't see this one

899
00:38:12,056 --> 00:38:14,586
but under what circumstances
would I have been yelled

900
00:38:14,586 --> 00:38:18,896
at with, "You must
provide an email address?"

901
00:38:18,896 --> 00:38:18,963
Yeah?

902
00:38:18,963 --> 00:38:21,856
>> If you didn't enter anything
at all in the email field.

903
00:38:21,936 --> 00:38:22,476
>> Exactly.

904
00:38:22,476 --> 00:38:25,516
If I had not typed in Malan,
but I just left that field blank

905
00:38:25,516 --> 00:38:27,076
at the very top of the form,

906
00:38:27,076 --> 00:38:28,726
I would have been yelled
at with this message.

907
00:38:28,726 --> 00:38:32,006
And just to be clear, why
do I not only call alert,

908
00:38:32,006 --> 00:38:34,416
I also return false?

909
00:38:35,046 --> 00:38:35,166
Isaac?

910
00:38:37,656 --> 00:38:45,586
>> Well, it has to be
false or true on submit.

911
00:38:46,216 --> 00:38:46,736
>> Okay.

912
00:38:47,496 --> 00:38:54,676
>> So it has to return
true or false for the sake

913
00:38:54,676 --> 00:38:57,696
of the onsubmit handler, but
why false, just to be clear?

914
00:38:58,656 --> 00:38:59,446
>> So that it doesn't
[inaudible].

915
00:38:59,966 --> 00:39:02,446
>> Good. So that the form
rather doesn't submit fully.

916
00:39:02,676 --> 00:39:05,646
So it does not initiate
an HTTP get or post,

917
00:39:05,926 --> 00:39:07,486
sending the form's
data to the server.

918
00:39:07,486 --> 00:39:09,246
We want to stop that because
we're not ready to do it.

919
00:39:09,246 --> 00:39:10,776
So we don't want to
trouble the server just yet.

920
00:39:11,086 --> 00:39:13,626
Okay. So now we have
some branching code here.

921
00:39:13,626 --> 00:39:15,716
So turns out that if
conditions else if [inaudible]

922
00:39:15,716 --> 00:39:19,156
in JavaScript pretty much
identical in JavaScript to PHP,

923
00:39:19,156 --> 00:39:22,216
you need the curly braces
if it's more than one line,

924
00:39:22,216 --> 00:39:25,096
and in general I would encourage
always using the curly braces

925
00:39:25,096 --> 00:39:26,906
because of the process
called minification.

926
00:39:26,906 --> 00:39:28,926
Which we'll talk about
later, but that has to do

927
00:39:28,926 --> 00:39:31,416
with eliminating
unnecessary white space

928
00:39:31,416 --> 00:39:33,646
and even shrinking variable
names in JavaScript.

929
00:39:33,646 --> 00:39:36,886
So generally braces
are a helpful thing.

930
00:39:37,236 --> 00:39:37,896
So, else

931
00:39:37,896 --> 00:39:42,956
if document.forms.registration
.password1.value equals equals

932
00:39:42,956 --> 00:39:45,166
something, let me scroll
over a little further,

933
00:39:45,566 --> 00:39:46,476
this is a mouthful,

934
00:39:46,476 --> 00:39:51,216
but in English what is
this else if doing for me?

935
00:39:52,126 --> 00:39:52,486
Axle?

936
00:39:53,056 --> 00:39:58,626
>> If the first password field
is empty as well it's going

937
00:39:58,666 --> 00:40:00,486
to do everything
inside the else if.

938
00:40:02,366 --> 00:40:02,956
It's going to alert [inaudible]

939
00:40:02,956 --> 00:40:06,436
and then return false
to the submit.

940
00:40:06,566 --> 00:40:07,086
>> Exactly.

941
00:40:07,126 --> 00:40:10,566
So just like before if the
user has this field blank,

942
00:40:10,566 --> 00:40:12,246
in this case the
field is password1,

943
00:40:12,466 --> 00:40:14,206
and its value is quote unquote,

944
00:40:14,206 --> 00:40:16,396
that is they typed nothing
there, then I'm going to yell

945
00:40:16,396 --> 00:40:17,756
at them, "You must
provide a password,"

946
00:40:17,756 --> 00:40:19,326
and also return false.

947
00:40:19,646 --> 00:40:23,526
Now realize if the user had
not left it completely blank

948
00:40:24,066 --> 00:40:27,376
but they typed in a
space bar character,

949
00:40:28,036 --> 00:40:30,026
would this return
false at this point?

950
00:40:30,026 --> 00:40:31,216
Yes or no?

951
00:40:31,666 --> 00:40:31,876
Jack?

952
00:40:31,986 --> 00:40:33,466
>> No because it's
not [inaudible].

953
00:40:34,406 --> 00:40:34,906
>> Exactly.

954
00:40:34,956 --> 00:40:37,926
Because obviously a space is
not equal to quote unquote

955
00:40:37,926 --> 00:40:39,186
with nothing between the quotes.

956
00:40:39,186 --> 00:40:40,606
Its quote space unquote..

957
00:40:40,946 --> 00:40:43,366
This if condition
would not catch that

958
00:40:43,686 --> 00:40:46,966
and so we would not declare the
user's input as invalid yet.

959
00:40:47,166 --> 00:40:49,616
So already hopefully you should
be thinking, well there's ways

960
00:40:49,616 --> 00:40:50,446
of making this better.

961
00:40:50,706 --> 00:40:53,256
Right? If the user hits space or
space, space, space, or space,

962
00:40:53,256 --> 00:40:56,806
space, space just to circumvent
my form validation I should

963
00:40:56,806 --> 00:40:59,416
certainly be able to
detect that too and it turns

964
00:40:59,416 --> 00:41:00,786
out there's functions
in JavaScript

965
00:41:00,786 --> 00:41:02,316
or I could write a
function in JavaScript

966
00:41:02,316 --> 00:41:04,046
that lets me trim
the user's input.

967
00:41:04,256 --> 00:41:05,746
I could trip leading
white space,

968
00:41:05,746 --> 00:41:07,266
I could trim trailing
white space,

969
00:41:07,266 --> 00:41:09,376
and that just means throw
it away so that even

970
00:41:09,376 --> 00:41:11,146
if the user's trying to
be difficult or annoying

971
00:41:11,146 --> 00:41:12,376
by just hitting the
spacebar to get

972
00:41:12,376 --> 00:41:14,526
through my stupid
prompts I can still catch

973
00:41:14,526 --> 00:41:15,906
at least those scenarios.

974
00:41:16,226 --> 00:41:17,836
To be clear though,
I'm not doing anything

975
00:41:17,836 --> 00:41:19,466
like checking the
length of the password,

976
00:41:19,826 --> 00:41:23,836
I'm not checking whether it has
enough alphabetical characters,

977
00:41:23,836 --> 00:41:25,476
numeric characters,
punctuation characters.

978
00:41:25,476 --> 00:41:27,486
There's no like security
checking here

979
00:41:27,486 --> 00:41:28,796
of the quality of the password.

980
00:41:29,006 --> 00:41:31,696
We're just seeing if the user
gave us anything whatsoever.

981
00:41:31,966 --> 00:41:33,606
What about the third
branch here.

982
00:41:33,606 --> 00:41:34,336
So else

983
00:41:34,336 --> 00:41:39,446
if document.forms.registration
.password1.value !

984
00:41:39,766 --> 00:41:44,366
equals ""document.forms
.registration.password2 .value

985
00:41:44,366 --> 00:41:46,246
then yell at the user as well.

986
00:41:46,536 --> 00:41:48,096
And before I spoil the answer,

987
00:41:49,076 --> 00:41:51,776
in English what should the
error message probably be?

988
00:41:51,916 --> 00:41:54,016
What have they failed
to do properly here?

989
00:41:54,016 --> 00:41:54,083
Yeah?

990
00:41:54,083 --> 00:41:57,676
>> You need to enter
the same password twice.

991
00:41:57,856 --> 00:41:58,306
>> Exactly.

992
00:41:58,306 --> 00:41:59,506
We need to yell something like,

993
00:41:59,506 --> 00:42:01,346
"You need to enter the
same password twice."

994
00:42:01,346 --> 00:42:04,586
Because the logic I just checked
was did password one's value

995
00:42:04,626 --> 00:42:06,016
equal password two's value?

996
00:42:06,016 --> 00:42:07,456
If not, they screwed up again

997
00:42:07,696 --> 00:42:09,156
and they typed the
wrong thing twice.

998
00:42:09,696 --> 00:42:11,916
So, if you've ever been on
a website that does exactly

999
00:42:11,916 --> 00:42:13,926
that kind of check this
is similar to the kind

1000
00:42:13,926 --> 00:42:15,096
of code that they're writing.

1001
00:42:15,346 --> 00:42:16,696
Theirs is probably a
little more compact,

1002
00:42:16,896 --> 00:42:19,356
we're doing it the very
pedantic way just for now,

1003
00:42:19,826 --> 00:42:22,216
but the functionality
is the same

1004
00:42:22,216 --> 00:42:24,146
as you would find on
a typical website.

1005
00:42:24,376 --> 00:42:25,716
What's this last block doing?

1006
00:42:25,716 --> 00:42:27,526
"You must agree to our
terms and conditions."

1007
00:42:27,996 --> 00:42:29,116
Why does the code in that --

1008
00:42:29,366 --> 00:42:31,206
how does the code in that
branch work apparently?

1009
00:42:31,346 --> 00:42:31,436
Yeah?

1010
00:42:32,026 --> 00:42:35,326
>> Well it looks for a
dot checked on agreement,

1011
00:42:36,176 --> 00:42:37,536
which is probably
the checked box.

1012
00:42:37,536 --> 00:42:38,186
>> Good.

1013
00:42:38,596 --> 00:42:42,566
>> And the exclamation mark
in the beginning of it says

1014
00:42:42,566 --> 00:42:45,966
if it's not checked, so
then you run the alert.

1015
00:42:45,966 --> 00:42:46,576
>> Exactly.

1016
00:42:46,576 --> 00:42:48,876
It turns out, and this is
where DOM again is useful,

1017
00:42:48,876 --> 00:42:50,736
there's different types
of nodes, different types

1018
00:42:50,736 --> 00:42:53,696
of objects when you
parse a big HTML file

1019
00:42:54,006 --> 00:42:55,986
and an input type whose --

1020
00:42:55,986 --> 00:42:59,306
an input tag whose
type is text has things

1021
00:42:59,306 --> 00:43:00,676
like a dot value property.

1022
00:43:00,896 --> 00:43:04,226
By contrast, something like a
checkbox is generally useful

1023
00:43:04,226 --> 00:43:07,226
because it has a dot
checked property that is true

1024
00:43:07,226 --> 00:43:09,106
if it's checked, that's
false if it's not.

1025
00:43:09,346 --> 00:43:12,596
So by saying if !document.forms
.registration.agreement

1026
00:43:12,596 --> 00:43:16,516
.checked, by saying that syntax
I'm saying if it is not checked,

1027
00:43:17,166 --> 00:43:18,916
by inverting the
Boolean value then yell

1028
00:43:18,916 --> 00:43:20,406
at the user accordingly as well.

1029
00:43:20,736 --> 00:43:23,316
But if they pass the first,
and the second, and the third,

1030
00:43:23,316 --> 00:43:26,176
and the fourth if
condition successfully

1031
00:43:26,176 --> 00:43:28,766
and we have not yelled
nor returned false yet,

1032
00:43:28,766 --> 00:43:29,836
what do I do by default?

1033
00:43:29,836 --> 00:43:32,166
I return true at the
very bottom of the code

1034
00:43:32,166 --> 00:43:33,426
because they didn't screw up,

1035
00:43:33,706 --> 00:43:35,916
they typed in everything
I wanted them to.

1036
00:43:36,176 --> 00:43:38,426
Now they didn't necessarily
give me a valid email address,

1037
00:43:38,426 --> 00:43:40,796
they didn't necessarily give me
a password that's anything more

1038
00:43:40,796 --> 00:43:44,126
than a spacebar character, but
we've at least raised the bar

1039
00:43:44,126 --> 00:43:45,796
to just the user
rapidly clicking submit

1040
00:43:45,936 --> 00:43:47,336
and wasting the server's time.

1041
00:43:47,636 --> 00:43:50,696
We could start to make these
more sophisticated and we will

1042
00:43:50,926 --> 00:43:52,306
but for now that is one

1043
00:43:52,306 --> 00:43:55,126
of the easiest mechanisms
whereby we can introduce some

1044
00:43:55,126 --> 00:43:56,436
JavaScript code to the site

1045
00:43:56,976 --> 00:43:59,946
and do something useful
for the user's sake.

1046
00:44:01,036 --> 00:44:05,846
All right, any questions,
syntactically or otherwise?

1047
00:44:05,846 --> 00:44:10,956
No? All right, well let's take
a quick look at form3.html.

1048
00:44:11,336 --> 00:44:15,846
Actually, let's skip form3
that one's kind of boring.

1049
00:44:16,566 --> 00:44:18,656
No, we can show it, just
not that interesting.

1050
00:44:18,926 --> 00:44:20,806
So in form3 it turns out
there's this key [inaudible]

1051
00:44:20,806 --> 00:44:23,116
in JavaScript which actually
isn't used all that often

1052
00:44:23,116 --> 00:44:25,376
because there's cleaner
ways still to do this.

1053
00:44:25,676 --> 00:44:29,246
But realize the [inaudible]
keyword simply says assume the

1054
00:44:29,246 --> 00:44:32,846
following prefix for any
variables in the block

1055
00:44:32,846 --> 00:44:35,996
of code that's to follow so
that I can just say something

1056
00:44:35,996 --> 00:44:39,306
like email.value,
password1.value, and so forth.

1057
00:44:39,536 --> 00:44:41,266
But again this is not
an oft used feature

1058
00:44:41,266 --> 00:44:44,206
but it's one step toward making
what are right now fairly

1059
00:44:44,206 --> 00:44:47,866
ridiculously long expressions
a little more manageable.

1060
00:44:48,306 --> 00:44:49,796
So just FYI there.

1061
00:44:50,536 --> 00:44:53,826
All right, but let's
look at form4,

1062
00:44:54,586 --> 00:44:56,696
which looks a little
something like this.

1063
00:44:56,696 --> 00:45:01,056
I seem to have a fundamentally
different approach here,

1064
00:45:02,256 --> 00:45:08,706
and before we dive in what is
different about this function,

1065
00:45:09,026 --> 00:45:10,006
this version of validate?

1066
00:45:10,056 --> 00:45:10,166
Yeah?

1067
00:45:10,596 --> 00:45:12,626
>> It takes the argument
that you call f,

1068
00:45:13,186 --> 00:45:16,616
which is probably going to be
everything before like .command,

1069
00:45:16,616 --> 00:45:17,356
.form, and everything.

1070
00:45:17,686 --> 00:45:18,486
>> Okay, excellent.

1071
00:45:18,486 --> 00:45:21,646
So it looks like this version of
validate takes an argument first

1072
00:45:21,646 --> 00:45:23,506
of all, and that argument's
apparently called f,

1073
00:45:23,866 --> 00:45:25,306
because it's in parentheses
there.

1074
00:45:25,436 --> 00:45:27,846
And I seem to be using
f subsequently further

1075
00:45:27,846 --> 00:45:31,296
to simplify my syntax and more
generally because what I'm going

1076
00:45:31,296 --> 00:45:35,416
to do in this version as we'll
see after a short break is

1077
00:45:35,416 --> 00:45:39,956
that I can pass around even
forms themselves as arguments

1078
00:45:39,956 --> 00:45:44,276
because a form in a
webpage, once it's read

1079
00:45:44,276 --> 00:45:47,406
in by the browser, is
represented as a node in a tree,

1080
00:45:47,606 --> 00:45:49,176
as one of those rectangles

1081
00:45:49,206 --> 00:45:51,476
that we might have drawn
a couple of lectures ago.

1082
00:45:51,666 --> 00:45:55,626
And so I can pass around a
reference to that DOM node,

1083
00:45:55,776 --> 00:45:58,816
that form node, and indeed
this case we'll soon see

1084
00:45:58,816 --> 00:46:01,686
that the variable f, the
local variable f is going

1085
00:46:01,686 --> 00:46:03,256
to be of type node.

1086
00:46:03,416 --> 00:46:05,176
It's going to be a form element

1087
00:46:05,176 --> 00:46:06,686
that was passed
programmatically.

1088
00:46:07,026 --> 00:46:08,926
Why don't we go ahead here
and take our five minute break

1089
00:46:08,926 --> 00:46:11,186
and when we return we'll
see exactly how we did this

1090
00:46:11,186 --> 00:46:13,476
and what more we can do
with objects from DOM's.

1091
00:46:14,336 --> 00:46:20,486
All right, so the most recent
cliffhanger was how does this

1092
00:46:20,486 --> 00:46:21,826
version four actually work.

1093
00:46:21,826 --> 00:46:24,216
We're passing this thing called
f around, so let's first look

1094
00:46:24,216 --> 00:46:25,566
at how this function
is being called.

1095
00:46:25,566 --> 00:46:27,216
And notice at the
bottom of the form

1096
00:46:27,606 --> 00:46:29,666
that our html is almost the same

1097
00:46:29,666 --> 00:46:33,286
as last time except one
attribute's value has changed,

1098
00:46:33,286 --> 00:46:35,506
which is obviously what?

1099
00:46:36,606 --> 00:46:37,206
Yeah, Axle?

1100
00:46:37,766 --> 00:46:40,446
>> Well, the [inaudible]
function is

1101
00:46:42,056 --> 00:46:47,156
which probably refers back to
that particular node is the DOM.

1102
00:46:47,256 --> 00:46:48,156
>> Yeah, exactly.

1103
00:46:48,156 --> 00:46:50,516
So in a lot of programming
languages, for instance PHP,

1104
00:46:50,516 --> 00:46:52,966
and Java, and also JavaScript,

1105
00:46:52,966 --> 00:46:54,886
there is this special
variable called this,

1106
00:46:55,416 --> 00:46:57,236
which is rather
self-referential,

1107
00:46:57,296 --> 00:46:59,626
whereby if you are in
the context of an object

1108
00:46:59,866 --> 00:47:01,046
or in this case in the context

1109
00:47:01,046 --> 00:47:04,066
of an HTML element
you can specify this

1110
00:47:04,066 --> 00:47:06,526
and that refers to that context.

1111
00:47:06,696 --> 00:47:09,656
So the keyword this, in
this case, is referring

1112
00:47:09,656 --> 00:47:11,976
to the element in which
we've mentioned this,

1113
00:47:11,976 --> 00:47:14,586
and if I scroll back to the
left what is the tag name

1114
00:47:14,586 --> 00:47:15,256
in question here?

1115
00:47:16,336 --> 00:47:21,086
This is the form tag, open
bracket, form, action, method,

1116
00:47:21,426 --> 00:47:25,346
and name, and onsubmit, and
there's the beginning of this.

1117
00:47:25,796 --> 00:47:29,556
So we have this way now in code
to refer to the HTML element

1118
00:47:29,796 --> 00:47:32,396
that we know eventually
will be accessible via

1119
00:47:32,396 --> 00:47:35,706
that DOM object,
that document object.

1120
00:47:36,006 --> 00:47:37,906
All right, so return
validate this.

1121
00:47:37,906 --> 00:47:40,526
Now let's look at what
the implication is

1122
00:47:40,526 --> 00:47:41,616
of this calling convention.

1123
00:47:41,616 --> 00:47:43,296
So if I scroll back
up to the top

1124
00:47:43,586 --> 00:47:45,886
where my validate function
is defined, recall this is

1125
00:47:45,886 --> 00:47:47,236
where we left off a moment ago,

1126
00:47:47,446 --> 00:47:49,596
and the validate function
takes an argument f,

1127
00:47:50,096 --> 00:47:52,396
arbitrarily called f, I could
have called it foo, bar, or baz.

1128
00:47:52,726 --> 00:47:55,846
But thereafter I can
specify f.email.value,

1129
00:47:55,846 --> 00:47:57,886
f.password1.value, and so forth.

1130
00:47:57,886 --> 00:48:00,866
So one, my syntax has gotten a
little simpler, which is nice.

1131
00:48:01,236 --> 00:48:04,586
Two, I now have the beginnings
of more reusable code.

1132
00:48:04,586 --> 00:48:06,156
I now have a validate function

1133
00:48:06,156 --> 00:48:09,126
that in theory could
validate any form object

1134
00:48:09,126 --> 00:48:13,366
that has these particular fields
of the email, and password1,

1135
00:48:13,366 --> 00:48:16,156
and password2, so I've begun
to at least start factoring

1136
00:48:16,156 --> 00:48:18,286
out what could be some
common functionality.

1137
00:48:18,486 --> 00:48:20,916
And three, it really
demonstrates, hopefully,

1138
00:48:20,916 --> 00:48:26,056
that via the this keyword we now
can bridge the gap between HTML,

1139
00:48:26,056 --> 00:48:28,816
which is really just
markup, and programming code.

1140
00:48:28,816 --> 00:48:31,426
And the middleman between
those two worlds is this DOM,

1141
00:48:31,426 --> 00:48:35,316
because the DOM is the result
of having parsed an HTML file

1142
00:48:35,486 --> 00:48:38,946
and built up in memory, in
RAM, this tree structure,

1143
00:48:38,986 --> 00:48:41,136
which JavaScript
can then traverse.

1144
00:48:41,516 --> 00:48:44,286
All right, so the rest of
this code is identical,

1145
00:48:44,716 --> 00:48:48,126
but any questions on this
or the passing thereof?

1146
00:48:48,386 --> 00:48:54,106
All right, so let's take a
look at version five here,

1147
00:48:54,316 --> 00:48:57,306
which is now starting to give
us some more interesting UI.

1148
00:48:57,306 --> 00:49:01,366
Let me zoom in on the
left portion of this form,

1149
00:49:01,726 --> 00:49:02,976
and does anything look new here?

1150
00:49:10,046 --> 00:49:10,166
Isaac?

1151
00:49:10,546 --> 00:49:12,176
>> Well, there's disabled.

1152
00:49:12,176 --> 00:49:14,506
>> Yeah, so disabled is
something that's a little new

1153
00:49:14,506 --> 00:49:16,426
here and there's a couple
of ways of writing this.

1154
00:49:16,426 --> 00:49:19,736
The way I've written it looks a
little silly these days but was

1155
00:49:19,736 --> 00:49:23,156
in vogue when XHTML
was being popularized.

1156
00:49:23,386 --> 00:49:25,536
Could just say disabled
with HTML five,

1157
00:49:25,536 --> 00:49:29,036
but disabled equals disabled
[inaudible] that this element,

1158
00:49:29,166 --> 00:49:31,236
as you might have guessed,
should be disabled.

1159
00:49:31,236 --> 00:49:31,303
[ Inaudible Speaker ]

1160
00:49:31,303 --> 00:49:35,666
So what's the implication

1161
00:49:35,726 --> 00:49:39,986
of disabling something
like a button?

1162
00:49:39,986 --> 00:49:44,796
What is this actually
going to do?

1163
00:49:44,796 --> 00:49:45,386
Yeah, Axle?

1164
00:49:46,516 --> 00:49:49,726
[ Inaudible Speaker ]

1165
00:49:50,226 --> 00:49:50,846
Okay, good.

1166
00:49:50,846 --> 00:49:53,556
So, when you check this, let me
go up to this in a browser now.

1167
00:49:53,556 --> 00:49:58,546
So this is now form5, notice
that it's a little subtle here,

1168
00:49:59,366 --> 00:50:02,126
but notice that now that submit
button is a little grayer

1169
00:50:02,126 --> 00:50:02,856
than usual.

1170
00:50:03,046 --> 00:50:06,536
All right, well maybe that's
just a CSS thing, but let's try

1171
00:50:06,536 --> 00:50:09,476
to click it and be a difficult
user and not fill out anything.

1172
00:50:10,126 --> 00:50:12,176
I'm clicking, nothing's
actually happening

1173
00:50:12,176 --> 00:50:13,746
because that is in
fact disabled.

1174
00:50:13,996 --> 00:50:15,086
So why is it disabled?

1175
00:50:15,086 --> 00:50:16,756
Well, this was just a
design decision I made

1176
00:50:16,756 --> 00:50:19,256
in this version whereby I
only want the user to be able

1177
00:50:19,256 --> 00:50:23,856
to submit this form if they have
minimally given me what I wanted

1178
00:50:23,856 --> 00:50:26,206
or at least minimally
checked that box.

1179
00:50:26,606 --> 00:50:30,896
So let me go over to that
checkbox and see what happens.

1180
00:50:30,926 --> 00:50:34,466
Checking now, and notice the
difference at bottom left.

1181
00:50:34,916 --> 00:50:36,376
Every time I check or uncheck

1182
00:50:36,376 --> 00:50:39,266
that box the submit
button changes state

1183
00:50:39,266 --> 00:50:42,876
and once it is black
like this it seems

1184
00:50:42,876 --> 00:50:44,366
to let me click it again,

1185
00:50:44,366 --> 00:50:46,396
I'm not actually letting
the form be submitted

1186
00:50:46,396 --> 00:50:48,246
but if I clicked it
it would go through.

1187
00:50:48,246 --> 00:50:50,636
Thankfully I now have some error
checking still in place but more

1188
00:50:50,636 --> 00:50:51,796
on that in just a moment.

1189
00:50:52,186 --> 00:50:53,976
So how are we actually
doing this?

1190
00:50:53,976 --> 00:50:59,206
Well, if you were writing the
code yourself and you want

1191
00:50:59,206 --> 00:51:02,076
to tie that button
somehow to the checkbox,

1192
00:51:02,366 --> 00:51:05,666
what was the property on the
checkbox element that we want

1193
00:51:05,666 --> 00:51:07,696
to be checking in
order to decide whether

1194
00:51:07,696 --> 00:51:09,896
or not the submit button
should be enabled or disabled?

1195
00:51:10,316 --> 00:51:10,416
Yeah?

1196
00:51:10,556 --> 00:51:11,016
>> Dot checked.

1197
00:51:11,276 --> 00:51:11,676
>> Dot checked.

1198
00:51:12,166 --> 00:51:13,456
So it turns out in addition

1199
00:51:13,456 --> 00:51:17,456
to dot checked some elements
can have a dot disabled property

1200
00:51:17,686 --> 00:51:20,496
which literally says should the
browser let the user click it

1201
00:51:20,496 --> 00:51:23,186
or not, is it disabled
or not, true or false?

1202
00:51:23,456 --> 00:51:26,996
So if we go back to version
five of this code, let's scroll

1203
00:51:26,996 --> 00:51:30,046
up here to the very
top, or rather,

1204
00:51:30,046 --> 00:51:31,026
let's first look at this.

1205
00:51:31,276 --> 00:51:33,816
Notice that on the
right hand side here,

1206
00:51:34,316 --> 00:51:36,166
I agree to these
terms and conditions,

1207
00:51:36,386 --> 00:51:38,906
then I have input name
equals "agreement" as before,

1208
00:51:39,216 --> 00:51:41,436
and now I have another
event handler.

1209
00:51:41,926 --> 00:51:43,806
So I've done something
a little different here.

1210
00:51:43,906 --> 00:51:47,326
I'm not using onsubmit
because I don't want this form

1211
00:51:47,326 --> 00:51:49,886
to change states when
I submit the form

1212
00:51:49,886 --> 00:51:52,166
because that's too late;
I want it to change state

1213
00:51:52,166 --> 00:51:54,646
when I click on this checkbox.

1214
00:51:55,166 --> 00:52:00,406
So in English, what does
onclick equals "toggle ;

1215
00:52:01,106 --> 00:52:04,546
mean, or do, do you think?

1216
00:52:05,196 --> 00:52:07,116
Yeah, Ben?

1217
00:52:07,116 --> 00:52:07,336
[ Inaudible Speaker ]

1218
00:52:07,336 --> 00:52:08,446
Exactly, simple as that.

1219
00:52:08,446 --> 00:52:11,596
Anytime you click this checkbox
call the toggle function.

1220
00:52:11,796 --> 00:52:13,576
There's no arguments
passed in, but as the name

1221
00:52:13,576 --> 00:52:17,276
of the function suggests there
should probably toggle the state

1222
00:52:17,276 --> 00:52:17,606
of what?

1223
00:52:17,606 --> 00:52:19,316
The checkbox or of
the submit button?

1224
00:52:20,876 --> 00:52:22,106
The submit button
hopefully, right?

1225
00:52:22,106 --> 00:52:23,906
The checkbox you get for free,
you just have to check it,

1226
00:52:23,906 --> 00:52:25,146
the browser will
do that for you.

1227
00:52:25,486 --> 00:52:27,016
So let's scroll up
because it sounds

1228
00:52:27,016 --> 00:52:29,466
like either there's a
built-in toggle function

1229
00:52:29,466 --> 00:52:31,526
or it's something I myself wrote

1230
00:52:31,616 --> 00:52:33,816
and indeed it's the
latter in this case.

1231
00:52:33,936 --> 00:52:35,276
Here's my toggle function.

1232
00:52:35,906 --> 00:52:38,146
Pretty straightforward,
albeit verbose,

1233
00:52:39,146 --> 00:52:42,746
if document.forms
.registration.button .disabled

1234
00:52:43,406 --> 00:52:46,096
then set that same
property equal to false,

1235
00:52:46,806 --> 00:52:50,316
else if document.forms
.registration.button.disabled --

1236
00:52:50,706 --> 00:52:53,846
rather, sorry, else
set it equal to true.

1237
00:52:54,146 --> 00:52:54,966
That was not a condition.

1238
00:52:55,516 --> 00:52:59,716
So in other words if it is
disabled, make it not disabled,

1239
00:53:00,296 --> 00:53:01,816
else make it disabled.

1240
00:53:01,846 --> 00:53:03,896
So really I'm just
toggling the state of that.

1241
00:53:04,126 --> 00:53:06,806
I could actually do this
a little more elegantly

1242
00:53:07,226 --> 00:53:08,086
if you prefer.

1243
00:53:08,266 --> 00:53:12,286
I could just do something
like this.

1244
00:53:12,496 --> 00:53:17,856
I could say document.forms
.registration.button .disabled

1245
00:53:18,046 --> 00:53:21,116
equals that.

1246
00:53:22,486 --> 00:53:25,006
That's a slightly more
elegant way of doing it.

1247
00:53:25,446 --> 00:53:27,046
Right? I don't really
need the if condition,

1248
00:53:27,396 --> 00:53:28,866
but it's also still
a little verbose.

1249
00:53:28,866 --> 00:53:30,616
But again, we'll clean
that up next time.

1250
00:53:31,266 --> 00:53:32,966
All right, so that's
the toggle function,

1251
00:53:33,216 --> 00:53:34,406
simply toggles the state.

1252
00:53:34,606 --> 00:53:36,366
What is the validate
function doing this time?

1253
00:53:36,576 --> 00:53:39,056
Well, it's pretty much identical
to the very first version.

1254
00:53:39,106 --> 00:53:41,706
There's no fundamental
relationship between validation

1255
00:53:41,996 --> 00:53:43,466
and the submitting of this form,

1256
00:53:43,686 --> 00:53:46,476
all I've added this time
is this onclick handle --

1257
00:53:46,816 --> 00:53:50,356
handler and implemented
the toggle function myself.

1258
00:53:50,926 --> 00:53:53,506
So in terms of user
experience now,

1259
00:53:54,276 --> 00:53:57,146
is this a good enhancement,
bad enhancement?

1260
00:53:57,586 --> 00:53:59,356
The fact that there's
this relationship now

1261
00:53:59,356 --> 00:54:01,686
between the checkbox and the
ability to submit the form?

1262
00:54:01,686 --> 00:54:01,806
Thoughts?

1263
00:54:13,936 --> 00:54:14,056
Yeah?

1264
00:54:15,146 --> 00:54:18,496
>> I really don't see
anything wrong here

1265
00:54:18,496 --> 00:54:21,506
but I would alert the
user and say you have

1266
00:54:21,506 --> 00:54:23,376
to click this box [inaudible]
nothing's going to happen.

1267
00:54:23,376 --> 00:54:24,376
>> Okay. Good.

1268
00:54:24,376 --> 00:54:28,546
So, feels okay in your
mind but you should

1269
00:54:28,546 --> 00:54:30,316
at least be more
explicit with the user

1270
00:54:30,316 --> 00:54:33,316
as to you must click this box
in order for anything to happen.

1271
00:54:33,646 --> 00:54:34,436
And I would agree.

1272
00:54:34,436 --> 00:54:36,866
Like I think it's okay to
sort of really get in the way

1273
00:54:36,866 --> 00:54:39,856
of the user submitting the form,
but frankly I can think of a lot

1274
00:54:39,856 --> 00:54:41,476
of family friends of mine

1275
00:54:41,476 --> 00:54:43,436
who would not know what
the heck is going on here

1276
00:54:43,436 --> 00:54:45,576
because it's not obvious
that there's this linkage

1277
00:54:45,576 --> 00:54:47,766
between that checkbox
and the submit button.

1278
00:54:47,996 --> 00:54:50,036
Right? Frankly it might
be reasonable instead

1279
00:54:50,226 --> 00:54:53,936
to just let the button always
be enabled but allow the user

1280
00:54:53,936 --> 00:54:56,706
to click it and then be
yelled at, informing them

1281
00:54:56,706 --> 00:54:59,036
at that point, you must agree
to the terms and conditions,

1282
00:54:59,036 --> 00:55:00,616
especially in terms
of accessibility,

1283
00:55:00,856 --> 00:55:02,596
folks who might have to
use screen-readers or the

1284
00:55:02,596 --> 00:55:06,646
like for reasons of
blindness, like disabling things

1285
00:55:06,646 --> 00:55:09,876
on a webpage that a user,
whether blind of not blind,

1286
00:55:09,876 --> 00:55:13,666
expects to work, is generally
not the best practice even

1287
00:55:13,666 --> 00:55:15,776
though this is not
an uncommon paradigm.

1288
00:55:15,776 --> 00:55:18,276
So in short, at least some
more explicitness would go a

1289
00:55:18,276 --> 00:55:18,866
long way.

1290
00:55:18,916 --> 00:55:19,016
Yeah?

1291
00:55:19,296 --> 00:55:29,236
>> If you don't even want to
enable it can you put some sort

1292
00:55:29,236 --> 00:55:31,736
of onclick thing so
that if it's disabled

1293
00:55:31,736 --> 00:55:34,256
and someone clicks it
[inaudible] check off?

1294
00:55:34,256 --> 00:55:35,166
>> So absolutely.

1295
00:55:35,166 --> 00:55:37,746
We could still listen
for clicks.

1296
00:55:37,926 --> 00:55:39,026
So that's a good question.

1297
00:55:39,026 --> 00:55:40,976
Let's try this because
I feel like one

1298
00:55:40,976 --> 00:55:43,426
or more browsers might
actually disable event handlers

1299
00:55:43,426 --> 00:55:44,166
if it's disabled.

1300
00:55:44,546 --> 00:55:45,346
But let's see.

1301
00:55:45,346 --> 00:55:46,366
Let's try this.

1302
00:55:46,366 --> 00:55:49,056
So, let's go ahead in here
and add -- I'll zoom in --

1303
00:55:49,056 --> 00:55:54,216
onclick equals "alert
'testing 1 2 3';

1304
00:55:55,666 --> 00:55:57,326
so let's just add
this just to see

1305
00:55:57,326 --> 00:55:59,366
if when it's disabled
Jack's idea works.

1306
00:55:59,366 --> 00:56:00,596
So let me reload the page,

1307
00:56:00,596 --> 00:56:04,716
and as ever before anytime
you make changes to code now

1308
00:56:04,716 --> 00:56:06,476
that involves JavaScript
code you obviously need

1309
00:56:06,476 --> 00:56:09,036
to reload the page, just like if
you make HTML changes you need

1310
00:56:09,036 --> 00:56:09,436
to see it.

1311
00:56:09,646 --> 00:56:10,956
And also beware especially

1312
00:56:10,956 --> 00:56:15,726
when you are including .js files
via the script source syntax

1313
00:56:15,726 --> 00:56:16,566
that we saw earlier.

1314
00:56:16,856 --> 00:56:19,656
Be sure also sometimes to
hold down the shift key

1315
00:56:19,656 --> 00:56:22,566
and hit reload or even more
dramatically clear your

1316
00:56:22,566 --> 00:56:25,816
browser's entire cache
just because as with CSS,

1317
00:56:25,816 --> 00:56:29,026
as with other included
files, it tends to get cached

1318
00:56:29,026 --> 00:56:31,786
by the browser and so you might
make some change on the server

1319
00:56:31,786 --> 00:56:34,226
in your JavaScript file, but
the browser might not see it

1320
00:56:34,226 --> 00:56:36,136
because it doesn't
realize it's been changed.

1321
00:56:36,136 --> 00:56:39,326
So, in general a
hold-shift reload minimally

1322
00:56:39,426 --> 00:56:41,586
when reloading files that
are included like that.

1323
00:56:41,756 --> 00:56:43,816
All right, so now, yeah,

1324
00:56:43,816 --> 00:56:46,856
unfortunately I'm clicking
right now on the submit button

1325
00:56:47,046 --> 00:56:48,226
and it's not even listening.

1326
00:56:48,326 --> 00:56:53,986
So it seems to be the
case here -- there we go.

1327
00:56:54,456 --> 00:56:56,776
So unfortunately Jack's
idea does not work,

1328
00:56:56,776 --> 00:56:58,506
at least in this
version of Chrome,

1329
00:56:58,506 --> 00:57:01,966
because when a form element
is disabled via its disabled

1330
00:57:01,966 --> 00:57:04,056
property or the disabled
attribute in HTML,

1331
00:57:04,386 --> 00:57:07,886
it doesn't even transmit other
event handlers like click.

1332
00:57:08,146 --> 00:57:15,356
>> Now while I don't want
to go this deeply into it,

1333
00:57:15,356 --> 00:57:16,946
could you put it inside a DIV
and then have a DIV [inaudible].

1334
00:57:16,946 --> 00:57:17,756
>> Yes. Good question.

1335
00:57:17,756 --> 00:57:19,226
So those of you quite
comfortable with CSS,

1336
00:57:19,226 --> 00:57:21,486
you could for instance
put that button in a DIV,

1337
00:57:21,486 --> 00:57:23,986
or even overlay a DIV
[inaudible] absolute positioning

1338
00:57:23,986 --> 00:57:26,746
or the like, give it a higher Z
index and then listen for that.

1339
00:57:27,006 --> 00:57:28,796
I would agree let's not
ever go down that road.

1340
00:57:30,386 --> 00:57:31,336
That just feels messy.

1341
00:57:31,816 --> 00:57:31,936
Yeah?

1342
00:57:32,206 --> 00:57:33,996
>> If you don't want
to go down that road,

1343
00:57:34,226 --> 00:57:39,866
you could also do it all in
JavaScript, don't disable it

1344
00:57:40,196 --> 00:57:43,816
by doing .disabled, do a
check in the validate function

1345
00:57:43,946 --> 00:57:46,936
that checks the state of the
thing and then alert the user.

1346
00:57:46,996 --> 00:57:47,446
>> I agree.

1347
00:57:47,446 --> 00:57:48,256
Yeah, let's go that road.

1348
00:57:48,256 --> 00:57:51,206
So instead, leave the button
enabled but just add a check

1349
00:57:51,206 --> 00:57:53,376
to the validate function or
some other function that's

1350
00:57:53,376 --> 00:57:55,346
at least still checking
for that error

1351
00:57:55,346 --> 00:57:56,836
and handling however it wants,

1352
00:57:57,246 --> 00:57:59,806
but not by just thwarting
entire form submission.

1353
00:58:00,006 --> 00:58:04,356
As an aside, nothing we do
today unfortunately is going

1354
00:58:04,356 --> 00:58:06,246
to make your life
easier on the server.

1355
00:58:06,526 --> 00:58:09,456
And by that I mean just
because we are doing client side

1356
00:58:09,456 --> 00:58:11,256
validation today with JavaScript

1357
00:58:11,256 --> 00:58:12,926
and therefore catching
errors client side,

1358
00:58:13,396 --> 00:58:16,866
all of these measures are
circumventable by a user

1359
00:58:16,866 --> 00:58:20,206
or more generally an adversary
who's trying to circumvent them.

1360
00:58:20,546 --> 00:58:23,466
In other words, we
absolutely still have

1361
00:58:23,466 --> 00:58:27,626
to do server side form
validation, we cannot trust

1362
00:58:27,756 --> 00:58:31,416
that the data that's
coming from a client just

1363
00:58:31,416 --> 00:58:33,146
because it had client
side validation

1364
00:58:33,146 --> 00:58:35,616
in JavaScript is actually
going to be legitimate.

1365
00:58:36,156 --> 00:58:36,676
Why is that?

1366
00:58:36,676 --> 00:58:38,896
How could I circumvent these
kinds of form protections?

1367
00:58:38,896 --> 00:58:39,006
Yeah?

1368
00:58:39,386 --> 00:58:42,906
>> If you bring up the
inspect element thing,

1369
00:58:42,906 --> 00:58:44,646
you get the developer
[inaudible], you could go

1370
00:58:44,646 --> 00:58:47,896
on the console and then you
could inject JavaScript,

1371
00:58:47,896 --> 00:58:52,126
and then you could essentially
just manually submit whatever

1372
00:58:52,126 --> 00:58:53,806
you want to the PHP.

1373
00:58:53,806 --> 00:58:54,336
>> Exactly.

1374
00:58:54,436 --> 00:58:57,516
Anyone who knows how to access
more sophisticated tools

1375
00:58:57,516 --> 00:59:00,566
like the console here could
actually execute JavaScript

1376
00:59:00,566 --> 00:59:02,676
manually or I can even
do something like this.

1377
00:59:02,676 --> 00:59:04,606
If I go into the
HTML of this page,

1378
00:59:05,066 --> 00:59:08,206
let me zoom in and
expand the form.

1379
00:59:08,706 --> 00:59:09,666
You know what I can do?

1380
00:59:09,816 --> 00:59:13,256
Why don't I just go in
here and just disable --

1381
00:59:13,256 --> 00:59:16,486
delete this, enter, zoom
out, well there you have it.

1382
00:59:16,486 --> 00:59:18,436
Now my form button
is re-enabled.

1383
00:59:18,436 --> 00:59:20,066
Right? So you don't even
have to be a good hacker

1384
00:59:20,066 --> 00:59:22,806
to circumvent protections
like a disabled property,

1385
00:59:23,136 --> 00:59:25,396
you can just change it
right there in that fashion.

1386
00:59:25,626 --> 00:59:28,056
Or frankly, we can be
really sophisticated here

1387
00:59:28,486 --> 00:59:31,856
and if you really want to be a
geek we could do something like,

1388
00:59:31,856 --> 00:59:35,366
well, if I want to telnet to
the server I can telnet --

1389
00:59:35,366 --> 00:59:38,886
rather, if I want to fake a
request, recall we can go back

1390
00:59:38,886 --> 00:59:40,976
to lecture zero in
our HTP request

1391
00:59:40,976 --> 00:59:42,126
and mimic them ourselves.

1392
00:59:42,126 --> 00:59:44,366
So telnet is a program
that allows you to collect

1393
00:59:44,366 --> 00:59:47,596
from a client to a server on
any TCP port in this case.

1394
00:59:47,736 --> 00:59:49,826
I'm going to connect to
port 80 of the appliance.

1395
00:59:49,826 --> 00:59:53,376
Now notice I've connected
to 127.0.0.1,

1396
00:59:53,376 --> 00:59:55,536
and indeed that's
the loopback address.

1397
00:59:55,816 --> 00:59:57,106
However I could do
this to Google,

1398
00:59:57,346 --> 00:59:58,646
but rather I'm going to do this.

1399
00:59:58,646 --> 01:00:02,346
So I'm going to say,
rather, POST to --

1400
01:00:02,346 --> 01:00:02,976
oh no, we're using get today.

1401
01:00:03,046 --> 01:00:08,466
So we're going to use GET
/process.php HTTP/1.1.

1402
01:00:08,466 --> 01:00:12,376
I'm going to say my
host is the appliance.

1403
01:00:12,736 --> 01:00:16,096
And then -- woops, notice I
already got back my results.

1404
01:00:16,436 --> 01:00:17,876
Oh, [inaudible], yep.

1405
01:00:18,466 --> 01:00:21,676
So below that, I won't do
the whole example here,

1406
01:00:22,606 --> 01:00:25,986
what I could continue doing here
is the equivalent of passing

1407
01:00:25,986 --> 01:00:27,606
in -- well let's do it.

1408
01:00:27,816 --> 01:00:31,526
GET /process.php?

1409
01:00:31,786 --> 01:00:41,766
email-malan&password1 equals
asasas&password2 equals z

1410
01:00:42,106 --> 01:00:48,016
HTTP/1.1, so this is
definitely the geekier way

1411
01:00:48,016 --> 01:00:50,046
of circumventing
client side protections.

1412
01:00:50,116 --> 01:00:51,606
I goofed somehow.

1413
01:00:52,236 --> 01:00:57,076
Client site php, bad
request, ampersand.

1414
01:00:58,096 --> 01:00:58,876
What did I do wrong?

1415
01:01:04,356 --> 01:01:10,036
Password. GET /process.php?email
equals malan HTTP/1.1.

1416
01:01:10,036 --> 01:01:14,256
I'm doing something wrong.

1417
01:01:14,556 --> 01:01:16,266
Okay, anyhow, someone smarter

1418
01:01:16,266 --> 01:01:18,716
than me could actually
just mimic the HTP request

1419
01:01:19,176 --> 01:01:22,216
to send them from a command line
client or from a browser client

1420
01:01:22,486 --> 01:01:24,486
and actually trick --
oh, that's what it was.

1421
01:01:24,726 --> 01:01:27,056
Okay. Wait, I can
recover from this.

1422
01:01:27,216 --> 01:01:27,916
Okay, telnet,

1423
01:01:28,316 --> 01:01:36,356
GET /process.php?email
equals malan&password1 equals

1424
01:01:36,356 --> 01:01:43,946
asasas&password2 equals z
HTTP/1.1, host: appliance,

1425
01:01:44,136 --> 01:01:46,346
I forgot that header,
enter, enter.

1426
01:01:46,526 --> 01:01:48,986
Okay, now I got back
a 200 and now look

1427
01:01:48,986 --> 01:01:50,076
at what I sent to the server.

1428
01:01:50,296 --> 01:01:53,216
So in other words, if your
client doesn't even support

1429
01:01:53,216 --> 01:01:56,126
JavaScript as my black
and white window does not,

1430
01:01:56,566 --> 01:01:59,706
well then you can completely
circumvent those protections

1431
01:01:59,866 --> 01:02:00,836
as well anyway.

1432
01:02:01,376 --> 01:02:08,716
All right, so in short,
JavaScript good, useful,

1433
01:02:08,786 --> 01:02:10,606
but it is not a security
mechanism.

1434
01:02:10,866 --> 01:02:12,706
It is really about
user experience

1435
01:02:12,836 --> 01:02:15,646
and decreasing server
load at best.

1436
01:02:16,276 --> 01:02:19,966
All right, so what other
kinds of functionality

1437
01:02:19,966 --> 01:02:23,156
and event handlers do
we have access to here?

1438
01:02:23,376 --> 01:02:25,106
Well, so recall that we had --

1439
01:02:25,106 --> 01:02:27,406
whoops, recall that
we started here.

1440
01:02:27,406 --> 01:02:29,056
It turns out that we
can do a little better

1441
01:02:29,106 --> 01:02:30,676
in terms of functionality.

1442
01:02:30,676 --> 01:02:31,836
So it turns out that like PHP,

1443
01:02:31,836 --> 01:02:35,286
JavaScript supports a feature
called regular expressions via

1444
01:02:35,286 --> 01:02:36,806
an object called RegEx.

1445
01:02:37,116 --> 01:02:39,086
So there's some more
documentation here,

1446
01:02:39,226 --> 01:02:41,686
but this is representative
of a type of object

1447
01:02:41,686 --> 01:02:43,186
that comes built
into JavaScript.

1448
01:02:43,186 --> 01:02:45,296
We talked briefly about
one already, arrays,

1449
01:02:45,786 --> 01:02:49,506
and we'll see others,
strings, we've used thus far,

1450
01:02:49,506 --> 01:02:54,426
but regular expression as
well is a class in JavaScript

1451
01:02:54,426 --> 01:02:56,956
or rather an object in
JavaScript that allows us

1452
01:02:57,546 --> 01:03:05,636
to pattern match
on various strings.

1453
01:03:05,786 --> 01:03:10,626
So for instance, thus far
we've just been assuming

1454
01:03:10,626 --> 01:03:11,766
that if you give me anything

1455
01:03:11,766 --> 01:03:13,626
for an email address
it's an email address,

1456
01:03:13,626 --> 01:03:16,486
but case in point, malan
is not an email address,

1457
01:03:16,486 --> 01:03:18,676
it's missing the @ sign,
it's missing a domain name,

1458
01:03:18,676 --> 01:03:21,156
it's missing a .tld,
top level domain.

1459
01:03:21,366 --> 01:03:23,116
It's just syntactically
not an email address.

1460
01:03:23,116 --> 01:03:25,366
But with a regular
expression we could check

1461
01:03:25,866 --> 01:03:26,786
for that sort of thing.

1462
01:03:26,786 --> 01:03:28,156
And so we'll do that
in just a bit.

1463
01:03:28,156 --> 01:03:29,446
We'll come back and
actually say,

1464
01:03:29,716 --> 01:03:32,706
you have to give me not
just something for an email,

1465
01:03:32,756 --> 01:03:34,096
you have to give me
something that looks

1466
01:03:34,096 --> 01:03:37,506
like
username@domainname.something.

1467
01:03:38,006 --> 01:03:40,626
So a regular expression
again involves pattern.

1468
01:03:40,626 --> 01:03:42,116
So we'll see that
in just a moment.

1469
01:03:42,396 --> 01:03:44,966
Strings too have
actual properties

1470
01:03:44,966 --> 01:03:47,976
and methods associated
with them and we'll see

1471
01:03:47,976 --> 01:03:49,486
that functionality before long.

1472
01:03:49,956 --> 01:03:52,536
And just to give you a sense of
the global objects that exist

1473
01:03:52,536 --> 01:03:56,326
in JavaScript, we have again,
arrays, but there's also dates,

1474
01:03:56,456 --> 01:03:57,866
functions that we've
started to use.

1475
01:03:57,866 --> 01:04:00,776
There's actually a math object
that has things like rounding

1476
01:04:00,776 --> 01:04:02,216
and ceiling and floor

1477
01:04:02,216 --> 01:04:04,656
and related functionality that's
just generally useful to have.

1478
01:04:05,096 --> 01:04:07,856
Numbers and strings
themselves are objects.

1479
01:04:08,156 --> 01:04:11,016
So in short JavaScript is
very much about this paradigm

1480
01:04:11,016 --> 01:04:15,466
of objects having properties and
methods as we've begun to see.

1481
01:04:15,756 --> 01:04:17,586
In terms of objects,
what is an object?

1482
01:04:17,936 --> 01:04:21,906
An object is just a
container for key value pairs.

1483
01:04:22,086 --> 01:04:24,546
It really boils down to
something as simple as that.

1484
01:04:24,756 --> 01:04:26,396
You can think of
it as a hash table.

1485
01:04:26,496 --> 01:04:27,976
You can think of
it as a hash map.

1486
01:04:28,056 --> 01:04:29,906
You can think of it as
an associate of array.

1487
01:04:30,196 --> 01:04:32,416
These all have slight
differences in terms

1488
01:04:32,416 --> 01:04:35,196
of implementation but the
end result is that an object

1489
01:04:35,196 --> 01:04:37,946
in JavaScript is a
collection of key value pairs;

1490
01:04:38,046 --> 01:04:40,276
they're generally separated
by colons as we'll see

1491
01:04:40,276 --> 01:04:43,326
in just a moment, but that's
just a syntactic detail.

1492
01:04:43,656 --> 01:04:46,796
So how do you create an object
in JavaScript, it's as easy

1493
01:04:46,796 --> 01:04:47,996
as creating an array
in JavaScript.

1494
01:04:47,996 --> 01:04:51,046
In this case I have a variable
called obj, to connote object,

1495
01:04:51,476 --> 01:04:55,966
and equals, open curly brace,
closed curly brace, semicolon.

1496
01:04:56,166 --> 01:04:58,556
That gives me an empty
collection of key value pairs.

1497
01:04:58,556 --> 01:05:00,256
So there's no keys,
there's no values yet.

1498
01:05:00,426 --> 01:05:01,916
It's like an empty super global;

1499
01:05:01,916 --> 01:05:03,846
it's like an empty
associative array in PHP.

1500
01:05:03,846 --> 01:05:07,506
How do you assign
things to an object?

1501
01:05:07,736 --> 01:05:09,556
You have two syntaxes
available to you.

1502
01:05:09,766 --> 01:05:12,476
You can say object.key -

1503
01:05:12,476 --> 01:05:15,266
value and that will
create a key called key,

1504
01:05:15,356 --> 01:05:16,816
and a value of value.

1505
01:05:17,166 --> 01:05:21,176
Or you can PHP style
notation using square brackets

1506
01:05:21,176 --> 01:05:25,326
and quotes whereby you index
into the object at that key,

1507
01:05:25,326 --> 01:05:28,636
K-E-Y in this arbitrary case,
and then assign it a value.

1508
01:05:28,976 --> 01:05:32,556
So the upside of
the first approach,

1509
01:05:32,606 --> 01:05:34,506
object.key, is simplicity.

1510
01:05:34,696 --> 01:05:37,566
It's just very readable and
we've been using it all day long

1511
01:05:37,566 --> 01:05:42,036
so far, document.forms
.registration.email1.value.

1512
01:05:42,256 --> 01:05:43,356
Been doing that the whole time.

1513
01:05:43,586 --> 01:05:45,986
However, we could've used the
square bracket notation it just

1514
01:05:45,986 --> 01:05:48,246
wouldn't have read as
cleanly, and moreover

1515
01:05:48,246 --> 01:05:51,056
if you ever have keys that
have funky characters in them,

1516
01:05:51,056 --> 01:05:55,546
like spaces or the like,
using the quoted notation

1517
01:05:55,546 --> 01:05:58,146
with square brackets allows
you to access those keys.

1518
01:05:58,266 --> 01:06:02,246
You can't use the dot notation
for more complex looking keys.

1519
01:06:02,566 --> 01:06:03,626
In general though
it's probably best

1520
01:06:03,626 --> 01:06:06,296
to avoid anything
complex in terms of a key.

1521
01:06:06,646 --> 01:06:08,486
How can you create an object

1522
01:06:08,486 --> 01:06:10,476
and assign key value
pairs to it all at once?

1523
01:06:10,786 --> 01:06:12,626
The very last line
here is representative.

1524
01:06:12,626 --> 01:06:15,016
So if you know in advance that
you want to create an object

1525
01:06:15,126 --> 01:06:18,176
and you know in advance what
your keys and your values are,

1526
01:06:18,386 --> 01:06:20,826
you can simply say,
var obj equals brackets

1527
01:06:20,886 --> 01:06:23,396
and then brackets
key: value bracket;

1528
01:06:23,826 --> 01:06:27,806
and if you want multiple key
value pairs just put a comma

1529
01:06:27,956 --> 01:06:31,706
after the value and do
another key: value, key: value,

1530
01:06:32,016 --> 01:06:34,566
so it's a way of creating
an object on the fly

1531
01:06:34,956 --> 01:06:36,896
with multiple properties.

1532
01:06:37,756 --> 01:06:41,816
So we'll see why this
becomes so useful.

1533
01:06:42,166 --> 01:06:43,496
How about event handlers?

1534
01:06:43,496 --> 01:06:45,046
We've seen a couple, onclick.

1535
01:06:45,546 --> 01:06:46,656
We saw another.

1536
01:06:46,656 --> 01:06:48,186
What was the other one?

1537
01:06:49,116 --> 01:06:49,486
>> Onsubmit.

1538
01:06:49,486 --> 01:06:51,476
>> Onsubmit we've used
a whole bunch of times.

1539
01:06:51,476 --> 01:06:52,986
It turns out there's a
whole bunch of others.

1540
01:06:52,986 --> 01:06:57,586
Onchange, onfocus, onkeydown,
onkeyup, onload, onmousedown,

1541
01:06:57,586 --> 01:07:01,166
onmouseup, onmouseout,
onmouseover, and so forth.

1542
01:07:01,646 --> 01:07:04,116
Just to infer based
on past experiences,

1543
01:07:04,616 --> 01:07:09,656
when or why is something like
onmouseover generally used?

1544
01:07:09,716 --> 01:07:11,916
Even if you've never heard
the phrase until today,

1545
01:07:12,286 --> 01:07:14,056
when might that be
used to detect

1546
01:07:14,056 --> 01:07:15,946
when the mouse is
over something?

1547
01:07:16,656 --> 01:07:19,306
>> When you hover with the
mouse over a [inaudible] field.

1548
01:07:19,776 --> 01:07:21,086
>> Okay, so when you
hover over a mouse

1549
01:07:21,086 --> 01:07:22,486
with an input field what
do you want to happen?

1550
01:07:22,666 --> 01:07:25,556
>> Well, I really wouldn't
want anything to happen,

1551
01:07:25,616 --> 01:07:28,966
but if you [inaudible]
or something you could --

1552
01:07:29,936 --> 01:07:32,796
>> So you want to hover
over a form field?

1553
01:07:33,866 --> 01:07:34,606
Be more concrete here.

1554
01:07:34,606 --> 01:07:36,316
We can recover from this.

1555
01:07:36,586 --> 01:07:40,816
>> You can -- maybe you want
to display some kind of info

1556
01:07:40,816 --> 01:07:42,206
on something you
have on your site,

1557
01:07:42,256 --> 01:07:44,366
like an image, or a file thing.

1558
01:07:44,566 --> 01:07:48,666
So if you have say a website
that lets people download files

1559
01:07:48,666 --> 01:07:51,436
and if they hover over the
icon for the file [inaudible]

1560
01:07:51,436 --> 01:07:55,006
like the file format and
the size and [inaudible].

1561
01:07:55,636 --> 01:07:56,096
>> Perfect.

1562
01:07:56,096 --> 01:07:59,146
Okay. So in contexts where you
want to enable the user to hover

1563
01:07:59,146 --> 01:08:03,206
over something like an image
or maybe even a text field,

1564
01:08:03,206 --> 01:08:04,496
and then you want
to provide them

1565
01:08:04,496 --> 01:08:07,006
with additional information,
or additional functionality,

1566
01:08:07,356 --> 01:08:10,136
then you can use the
onmouseover even handler

1567
01:08:10,256 --> 01:08:13,926
to reveal additional buttons,
or to give them the equivalent

1568
01:08:13,926 --> 01:08:16,956
of a tool tip, a little DIV or
something that suddenly appears

1569
01:08:16,956 --> 01:08:17,866
like a cartoon bubble

1570
01:08:17,866 --> 01:08:19,726
that explains what it is
they're hovering over.

1571
01:08:19,856 --> 01:08:21,206
And these are omnipresent
on the web.

1572
01:08:21,206 --> 01:08:23,146
If you go to YouTube I think
you can hover over most

1573
01:08:23,146 --> 01:08:25,176
of the HTML5 controls
on a player

1574
01:08:25,396 --> 01:08:27,196
and see what those
symbols represent.

1575
01:08:27,436 --> 01:08:30,176
If you go to Netflix you can
hover over a movie posters

1576
01:08:30,176 --> 01:08:31,386
and then a little window opens

1577
01:08:31,386 --> 01:08:33,786
and you can see more
details about that movie.

1578
01:08:34,046 --> 01:08:35,466
Facebook does this
a lot, if you hover

1579
01:08:35,466 --> 01:08:37,286
over a friend's name
a little popup opens

1580
01:08:37,286 --> 01:08:39,146
up where you see
some photos of them

1581
01:08:39,146 --> 01:08:40,816
or their related
friends and whatnot.

1582
01:08:41,086 --> 01:08:44,206
So, being able to detect
when the mouse is hovering

1583
01:08:44,206 --> 01:08:46,786
over something, hugely
useful, at least in terms

1584
01:08:46,786 --> 01:08:48,256
of user experience these days.

1585
01:08:48,256 --> 01:08:49,576
So how do you use that?

1586
01:08:49,866 --> 01:08:52,166
Very similar, if you have an
element, whether it's an image

1587
01:08:52,166 --> 01:08:54,186
or a DIV, or whatnot,
that you want to listen

1588
01:08:54,226 --> 01:08:55,736
for the user's hovering

1589
01:08:55,736 --> 01:08:59,706
over it's just onmouseover
equals "something".

1590
01:09:00,306 --> 01:09:02,746
And we'll eventually
see too, there are ways

1591
01:09:02,746 --> 01:09:04,726
of registering event handlers.

1592
01:09:04,766 --> 01:09:07,636
That is, telling the
browser to call this function

1593
01:09:07,816 --> 01:09:11,026
when the user does this,
using pure JavaScript syntax.

1594
01:09:11,026 --> 01:09:14,956
You don't have to put any
JavaScript code in your HTML

1595
01:09:14,956 --> 01:09:16,886
in order to achieve
this functionality.

1596
01:09:17,106 --> 01:09:19,446
For now though, we're just
using the HTML attributes

1597
01:09:19,446 --> 01:09:21,676
to keep things simple and
to make clear the linkage

1598
01:09:21,676 --> 01:09:24,246
between HTML and
the JavaScript code.

1599
01:09:24,566 --> 01:09:27,276
How about onkeydown, or keyup,

1600
01:09:27,276 --> 01:09:29,396
or onkeypress, which
is yet another?

1601
01:09:29,966 --> 01:09:31,736
When might that be useful?

1602
01:09:32,356 --> 01:09:32,796
Someone else?

1603
01:09:34,166 --> 01:09:38,076
Why might it be useful to
listen for key presses?

1604
01:09:38,816 --> 01:09:41,426
Whether the key is
going down or going up?

1605
01:09:43,376 --> 01:09:43,846
Scott?

1606
01:09:43,846 --> 01:09:46,576
>> [Inaudible] how
many times [inaudible].

1607
01:09:46,706 --> 01:09:47,206
>> Okay, good.

1608
01:09:47,206 --> 01:09:49,586
So recording how many times
the user types something.

1609
01:09:49,586 --> 01:09:52,116
Maybe you could use
that metric for forms

1610
01:09:52,196 --> 01:09:55,226
that have only 100
characters or 140, like a tweet

1611
01:09:55,226 --> 01:09:55,976
or something like that.

1612
01:09:55,976 --> 01:09:58,176
It might be useful to count how
many times the user has typed.

1613
01:09:58,416 --> 01:10:00,766
Alternatively you could check
string length in the value

1614
01:10:00,766 --> 01:10:01,976
of a field, but counting
might be reasonable.

1615
01:10:02,166 --> 01:10:02,726
What else?

1616
01:10:03,156 --> 01:10:05,846
>> I've only ever used it
once, but when I used it I had

1617
01:10:05,846 --> 01:10:09,226
like input field and
when users typed anything

1618
01:10:09,476 --> 01:10:12,306
in input field it
updated [inaudible].

1619
01:10:12,456 --> 01:10:13,636
>> Okay.

1620
01:10:14,166 --> 01:10:16,566
>> On the page -- well,
yeah, on the [inaudible].

1621
01:10:16,566 --> 01:10:17,016
>> Okay, good.

1622
01:10:17,166 --> 01:10:20,006
So if you have a form field
where you want to give the user

1623
01:10:20,006 --> 01:10:22,496
like some kind of automatic
preview of it, so they're typing

1624
01:10:22,496 --> 01:10:24,546
over here but you want them
to see what they're typing

1625
01:10:24,546 --> 01:10:26,966
over here because they're
filling out, I don't know,

1626
01:10:26,966 --> 01:10:28,896
like an e-card or something
like that where you want

1627
01:10:28,896 --> 01:10:31,146
to see a preview on the fly
of what they're typing in,

1628
01:10:31,326 --> 01:10:32,186
well you can use this.

1629
01:10:32,186 --> 01:10:34,596
Every time they type a
character you grab the value

1630
01:10:34,596 --> 01:10:37,656
of the text field and then
you update some DIV element

1631
01:10:37,656 --> 01:10:40,796
elsewhere, and we'll see how
you can update some other DIV

1632
01:10:40,796 --> 01:10:42,746
or portion of the page
using JavaScript as well,

1633
01:10:42,746 --> 01:10:43,676
but it's certainly possible

1634
01:10:43,676 --> 01:10:45,896
because you've probably
seen websites that do this.

1635
01:10:45,996 --> 01:10:48,496
Key presses can also
be used, for instance,

1636
01:10:48,496 --> 01:10:51,376
if you want to prevent the user
from typing certain characters.

1637
01:10:51,376 --> 01:10:53,546
If you don't want any
spaces in a field,

1638
01:10:53,546 --> 01:10:58,546
if you want to make
sure that they have --

1639
01:10:58,546 --> 01:11:01,746
if you don't want them to type
in certain characters at all,

1640
01:11:01,856 --> 01:11:03,206
or maybe it's a numeric field,

1641
01:11:03,206 --> 01:11:05,296
you don't want them typing
letters for whatever reason,

1642
01:11:05,596 --> 01:11:08,416
you can use onkeydown
because what you get

1643
01:11:08,416 --> 01:11:11,286
with this particular event,
you're not just informed

1644
01:11:11,286 --> 01:11:12,696
that the event happened,

1645
01:11:12,896 --> 01:11:15,456
you're informed what
key the user has typed.

1646
01:11:15,916 --> 01:11:18,376
So if you detect, wait a
minute, that's the letter A,

1647
01:11:18,586 --> 01:11:20,096
but this is a numeric
field, you're supposed

1648
01:11:20,096 --> 01:11:21,616
to be telling me
your account number,

1649
01:11:21,896 --> 01:11:24,936
you can just return false
effectively and say,

1650
01:11:25,206 --> 01:11:27,926
ignore that particular
A the user typed in.

1651
01:11:28,346 --> 01:11:32,316
So some websites do this too
to prevent you from pasting.

1652
01:11:32,316 --> 01:11:35,056
For instance, Amtrak.com,
absolutely hate their website

1653
01:11:35,336 --> 01:11:38,626
because my email address
is in my Amtrak profile

1654
01:11:38,866 --> 01:11:40,706
and they have this stupid
feature where you have

1655
01:11:40,706 --> 01:11:42,786
to confirm your email
address, once and twice.

1656
01:11:42,786 --> 01:11:45,216
And I'm okay with the principle
of confirming your email address

1657
01:11:45,276 --> 01:11:47,996
because a lot of people,
myself included, make mistakes

1658
01:11:47,996 --> 01:11:51,266
when typing it, but their
damn website prevents you

1659
01:11:51,266 --> 01:11:53,296
from hitting command
or control-V.

1660
01:11:53,296 --> 01:11:56,136
Which means you can't paste your
email address into the field,

1661
01:11:56,406 --> 01:11:58,806
even if you are absolutely
certain that it is correct

1662
01:11:58,806 --> 01:12:02,176
from the previous field, and
that sort of drives me nuts.

1663
01:12:02,176 --> 01:12:06,476
Other objections I have to
people's websites include --

1664
01:12:06,476 --> 01:12:08,426
actually there's an
unnamed website at Harvard

1665
01:12:08,426 --> 01:12:08,916
that when you're trying

1666
01:12:08,916 --> 01:12:11,686
to buy something they want
a 33-digit billing code,

1667
01:12:11,686 --> 01:12:13,316
those of you who work at Harvard
might know of these things.

1668
01:12:13,316 --> 01:12:16,116
It's god-awful; I have never
memorized a single 33-digit

1669
01:12:16,116 --> 01:12:16,516
billing code.

1670
01:12:16,516 --> 01:12:17,346
I copy and paste it.

1671
01:12:17,566 --> 01:12:20,546
Their website doesn't let
you copy/paste a billing code

1672
01:12:20,836 --> 01:12:22,606
so you have to manually
type it out,

1673
01:12:22,606 --> 01:12:24,936
which I daresay is far more
vulnerable to mistakes.

1674
01:12:25,396 --> 01:12:28,366
But anyhow, what's the
pedagogical value of this rant?

1675
01:12:28,736 --> 01:12:31,526
This is how you would implement
such annoying features as those.

1676
01:12:31,756 --> 01:12:33,456
There are better
of uses of this.

1677
01:12:33,456 --> 01:12:35,216
Right? If you're a Gmail
user you might use some

1678
01:12:35,216 --> 01:12:37,556
of the keyboard shortcuts,
C for compose,

1679
01:12:37,556 --> 01:12:39,076
A for archive, or the like.

1680
01:12:39,076 --> 01:12:41,686
How does Google listen
for those keystrokes?

1681
01:12:41,906 --> 01:12:45,246
Well they're listening for
A, they're listening for C,

1682
01:12:45,416 --> 01:12:47,396
they're listening for
other keystrokes as well,

1683
01:12:47,396 --> 01:12:49,986
and they're not rejecting
those keystrokes per se,

1684
01:12:50,126 --> 01:12:52,076
they're actually doing
something useful based on them,

1685
01:12:52,236 --> 01:12:55,716
and that's all because the
web browser world is very much

1686
01:12:55,786 --> 01:12:56,706
event driven.

1687
01:12:56,876 --> 01:12:59,486
Stuff happens, you hover,
you click, you type,

1688
01:12:59,576 --> 01:13:01,496
and you can listen for
all of these events,

1689
01:13:01,496 --> 01:13:03,366
and this is how you make
all the more dynamic

1690
01:13:03,366 --> 01:13:04,446
of a website these days.

1691
01:13:04,896 --> 01:13:06,796
How about something
like onfocus?

1692
01:13:07,076 --> 01:13:10,436
What does focus mean in
the context of a webpage?

1693
01:13:10,486 --> 01:13:10,586
Yeah?

1694
01:13:10,986 --> 01:13:13,496
>> Well if you have an
input field and you click it

1695
01:13:13,496 --> 01:13:15,936
or you tab to it it's going
to be focused and that's

1696
01:13:15,936 --> 01:13:18,046
when you essentially
edit the value of it

1697
01:13:18,216 --> 01:13:19,316
or type something into it.

1698
01:13:19,316 --> 01:13:19,806
>> Exactly.

1699
01:13:19,906 --> 01:13:23,286
So in the context of a webpage
only one element ever has a

1700
01:13:23,286 --> 01:13:25,416
focus at even given time.

1701
01:13:25,416 --> 01:13:27,546
When, by focus you can
think of it very concretely

1702
01:13:27,546 --> 01:13:29,306
as you've said, like
a text area.

1703
01:13:29,306 --> 01:13:31,486
When you put your cursor
in a text area indeed

1704
01:13:31,486 --> 01:13:34,226
in some browsers it kind
of gets highlighted in blue

1705
01:13:34,226 --> 01:13:36,056
or at least your cursor
starts blinking there.

1706
01:13:36,446 --> 01:13:38,846
That means that form
element has focus.

1707
01:13:38,846 --> 01:13:40,076
If you hit the tab key

1708
01:13:40,336 --> 01:13:42,556
on a webpage you'll
generally see a little blue

1709
01:13:42,556 --> 01:13:44,976
or whatnot outline
move from element

1710
01:13:44,976 --> 01:13:46,376
to element in the webpage.

1711
01:13:46,376 --> 01:13:48,496
That means that element
has focus

1712
01:13:48,496 --> 01:13:51,136
and it's just a visual indicator
for accessibility purposes

1713
01:13:51,386 --> 01:13:53,336
as to what you're
actually hovering over,

1714
01:13:53,336 --> 01:13:55,486
because generally you can
hit enter or the spacebar

1715
01:13:55,486 --> 01:13:58,176
at that point to activate
whatever it is you're hovering

1716
01:13:58,176 --> 01:14:00,976
over, or rather, whatever
it is that has focus.

1717
01:14:01,276 --> 01:14:02,476
Blur is the opposite.

1718
01:14:02,876 --> 01:14:04,656
So when might you care

1719
01:14:04,956 --> 01:14:09,716
that a user has blurred
some form element?

1720
01:14:09,716 --> 01:14:12,126
In other words, blurring
means it's no longer focused,

1721
01:14:12,126 --> 01:14:13,986
it doesn't mean it gets
blurry or anything like that.

1722
01:14:14,466 --> 01:14:14,586
Isaac?

1723
01:14:15,556 --> 01:14:16,756
>> Well you can do
form validation

1724
01:14:16,756 --> 01:14:20,806
after they click
another element.

1725
01:14:20,806 --> 01:14:22,426
>> Yeah. Exactly.

1726
01:14:22,426 --> 01:14:24,646
It might be annoying and
it might not be necessary

1727
01:14:24,646 --> 01:14:28,156
to check a form for validity
with every keystroke, right?

1728
01:14:28,156 --> 01:14:30,576
And obviously when I start
typing my email address it's not

1729
01:14:30,576 --> 01:14:32,456
going to be valid the first
few characters, right?

1730
01:14:32,456 --> 01:14:33,486
You got to give me some time.

1731
01:14:33,796 --> 01:14:35,556
So maybe we could instead wait

1732
01:14:35,556 --> 01:14:38,186
until that form field
has blurred in order

1733
01:14:38,186 --> 01:14:40,216
to check whether or not
it's a valid email address.

1734
01:14:40,246 --> 01:14:42,486
Or we could wait even longer
and wait until onsubmit,

1735
01:14:42,796 --> 01:14:45,216
but onblur gives
me that capability.

1736
01:14:46,456 --> 01:14:48,356
And others, onresize?

1737
01:14:48,396 --> 01:14:50,206
Onresize is actually
a powerful one.

1738
01:14:50,206 --> 01:14:51,286
If you're building a website

1739
01:14:51,566 --> 01:14:54,966
that really has some
predetermined size and you want

1740
01:14:54,966 --> 01:14:58,106
that size to grow when the user
changes the webpage around,

1741
01:14:58,406 --> 01:15:00,886
potentially you need
to listen for onresize

1742
01:15:00,886 --> 01:15:02,816
so that you can do some
math on your own webpage

1743
01:15:02,816 --> 01:15:05,216
and make things wider
or taller or shorter.

1744
01:15:05,506 --> 01:15:08,106
But generally, you get
that functionality for free

1745
01:15:08,106 --> 01:15:09,576
in a browser, but not --

1746
01:15:09,676 --> 01:15:12,106
that's not the case with
various JavaScript widgets.

1747
01:15:12,176 --> 01:15:13,896
For instance, if you
embed a video player,

1748
01:15:14,096 --> 01:15:15,976
it's generally going to have
a fixed width and height.

1749
01:15:16,186 --> 01:15:18,236
So if you want it
to grow over time,

1750
01:15:18,236 --> 01:15:19,596
if the user resizes the page,

1751
01:15:19,916 --> 01:15:21,746
you have to listen
for a resize event.

1752
01:15:21,746 --> 01:15:23,926
And then ask the browser,
"What's you new height

1753
01:15:24,186 --> 01:15:25,576
and width, for instance?"

1754
01:15:26,176 --> 01:15:29,206
All right, so in short, a lot of
power there and really the fun

1755
01:15:29,206 --> 01:15:31,876
in JavaScript client [inaudible]
programming tends to derive

1756
01:15:31,876 --> 01:15:33,786
from an ability to
listen to these things.

1757
01:15:34,046 --> 01:15:36,096
What kinds of things can
you do with JavaScript?

1758
01:15:36,526 --> 01:15:39,976
Well, you can even make
CSS manipulations as well.

1759
01:15:39,976 --> 01:15:43,406
You don't just have to error
check and submit HTTP requests.

1760
01:15:43,746 --> 01:15:45,276
We can do some more
aesthetic things.

1761
01:15:45,276 --> 01:15:50,056
So for instance, in CSS you have
things like borders and colors

1762
01:15:50,056 --> 01:15:51,376
and underlining and the like.

1763
01:15:51,756 --> 01:15:55,046
In JavaScript, you can
programmatically change the

1764
01:15:55,136 --> 01:15:56,656
style of a webpage even

1765
01:15:56,966 --> 01:16:00,086
after your CSS has been
downloaded from the server.

1766
01:16:00,326 --> 01:16:01,846
So for instance,
if you think of --

1767
01:16:01,846 --> 01:16:04,406
try to think of a website
where you filled out a form

1768
01:16:04,606 --> 01:16:06,866
and not only have you gotten
some kind of error message

1769
01:16:06,866 --> 01:16:08,196
if you filled it
out incorrectly,

1770
01:16:08,446 --> 01:16:11,056
sometimes the website
will highlight in red all

1771
01:16:11,056 --> 01:16:13,736
of the form fields that
you got wrong, or green all

1772
01:16:13,736 --> 01:16:14,926
of the ones that you got right.

1773
01:16:15,196 --> 01:16:16,566
That's actually using CSS,

1774
01:16:16,806 --> 01:16:19,286
and what that websites
JavaScript code is doing,

1775
01:16:19,596 --> 01:16:22,796
is if it determines that
this form field was inputted

1776
01:16:22,796 --> 01:16:25,056
incorrectly, it essentially
adds a class --

1777
01:16:25,886 --> 01:16:28,516
a CSS class to that
input element

1778
01:16:28,886 --> 01:16:30,046
that gives it a red border,

1779
01:16:30,276 --> 01:16:32,996
or it literally updates
the style attribute

1780
01:16:33,066 --> 01:16:34,506
of that input element and says,

1781
01:16:34,506 --> 01:16:38,926
border colon one pixel red
solid, something like that

1782
01:16:38,926 --> 01:16:40,056
if you're familiar with CSS.

1783
01:16:40,576 --> 01:16:42,986
So we have this ability
in CSS to do this,

1784
01:16:43,356 --> 01:16:45,976
the one downside
is what's in it --

1785
01:16:45,976 --> 01:16:48,126
what are some examples
of CSS properties

1786
01:16:48,126 --> 01:16:49,306
that relate to Aesthetics?

1787
01:16:49,816 --> 01:16:52,006
Went right off of you, yeah?

1788
01:16:52,786 --> 01:16:53,576
>> Border style.

1789
01:16:53,576 --> 01:16:55,246
>> Border style -- border-style.

1790
01:16:55,246 --> 01:16:55,546
What else?

1791
01:16:56,856 --> 01:16:59,836
That's actually a
really good one.

1792
01:16:59,836 --> 01:17:00,136
Yeah?

1793
01:17:00,646 --> 01:17:00,876
>> Radius [inaudible].

1794
01:17:01,016 --> 01:17:04,176
>> Okay, radius for like
curves around edges, sure.

1795
01:17:04,546 --> 01:17:04,636
Yeah?

1796
01:17:04,916 --> 01:17:05,226
>> Color.

1797
01:17:05,466 --> 01:17:06,196
>> Color, good.

1798
01:17:06,276 --> 01:17:09,766
Give me some multiple word
ones, like border style.

1799
01:17:10,356 --> 01:17:10,436
Yeah?

1800
01:17:12,456 --> 01:17:16,296
>> This doesn't have to do with
border, but text decoration.

1801
01:17:16,346 --> 01:17:20,126
>> Good, text decoration,
font family, line height --

1802
01:17:20,186 --> 01:17:21,686
there's a whole bunch
of properties in CSS

1803
01:17:21,686 --> 01:17:24,036
that have hyphens because
they're multiple words.

1804
01:17:24,256 --> 01:17:25,766
Well, guess what a
hyphen represents

1805
01:17:25,766 --> 01:17:27,226
in a programming
language like JavaScript?

1806
01:17:27,226 --> 01:17:27,316
Yeah?

1807
01:17:27,736 --> 01:17:34,606
>> It might be the same
thing as doing [inaudible].

1808
01:17:34,906 --> 01:17:36,456
>> Not quite the
same as the dot,

1809
01:17:36,536 --> 01:17:38,386
it's actually more
mundane than that.

1810
01:17:38,506 --> 01:17:41,066
The -- the hyphen
represents subtraction,

1811
01:17:41,226 --> 01:17:42,026
like the minus sing.

1812
01:17:42,026 --> 01:17:43,106
Like subtract this variable

1813
01:17:43,106 --> 01:17:44,666
from this variable,
line minus height.

1814
01:17:44,666 --> 01:17:46,576
So the whole world
gets screwed up now

1815
01:17:46,576 --> 01:17:49,296
that no one really thought this
through when they invented CSS.

1816
01:17:49,746 --> 01:17:53,196
So, the reason for this
funky looking URL is

1817
01:17:53,196 --> 01:17:58,516
that there is a mapping
between CSS properties

1818
01:17:58,516 --> 01:18:00,376
and JavaScript properties.

1819
01:18:00,646 --> 01:18:03,116
So that, for instance, border
-- what would you say --

1820
01:18:03,116 --> 01:18:05,456
border style, border-style

1821
01:18:05,456 --> 01:18:10,266
in CSS becomes border
S style in CSS.

1822
01:18:10,386 --> 01:18:12,916
So you eliminate the
hyphen and you capitalize,

1823
01:18:12,976 --> 01:18:15,206
you camel case the rest of
the words in the string.

1824
01:18:15,626 --> 01:18:18,876
So this URL has a whole list
of those mappings, but again,

1825
01:18:18,876 --> 01:18:20,396
the heuristic is
as simple as that.

1826
01:18:20,656 --> 01:18:23,266
Remove the hyphen and capitalize
each of the subsequent,

1827
01:18:23,266 --> 01:18:24,406
but not the first words.

1828
01:18:24,676 --> 01:18:25,876
So what's the implication
of this?

1829
01:18:26,086 --> 01:18:29,906
Well, I argue that some of
you are too young to remember,

1830
01:18:29,906 --> 01:18:34,066
but years ago there was a blink
tag in HTML, and the blink tag

1831
01:18:34,066 --> 01:18:36,046
in HTML did exactly that.

1832
01:18:36,046 --> 01:18:38,896
It was one of the most annoying
features of like, HTML 1.0

1833
01:18:38,896 --> 01:18:42,406
or 2.0, whatever it was and you
put a blink tag around a word,

1834
01:18:42,406 --> 01:18:43,366
and it just does this.

1835
01:18:43,876 --> 01:18:46,916
Even worse, was the marquee tag,
which had text going like this

1836
01:18:46,976 --> 01:18:49,076
across your webpage like
a movie banner, right.

1837
01:18:49,076 --> 01:18:50,666
The web looked awful
in the '90s.

1838
01:18:51,056 --> 01:18:53,656
And we can bring that
functionality back thanks

1839
01:18:53,656 --> 01:18:55,726
to JavaScript now and piece
these things together.

1840
01:18:55,966 --> 01:18:59,446
So, I argue that this function
resurrects the blink tag,

1841
01:18:59,446 --> 01:19:00,506
which it's actually
kind of funny.

1842
01:19:00,506 --> 01:19:02,646
The various browser
manufacturers like Microsoft

1843
01:19:02,646 --> 01:19:06,156
and Mozilla and Apple and the
like, like consciously decided

1844
01:19:06,156 --> 01:19:09,406
to kill that tag and the
marquee tag altogether.

1845
01:19:09,586 --> 01:19:11,126
Few tags have been
killed, but those have.

1846
01:19:11,736 --> 01:19:14,236
But that's okay, we can
override their wishes.

1847
01:19:14,296 --> 01:19:17,866
So here's a function called
blinker that's supposed to go

1848
01:19:17,866 --> 01:19:22,656
through a webpage and any
element that has a tag

1849
01:19:22,656 --> 01:19:24,476
around any text that has a tag

1850
01:19:24,476 --> 01:19:26,926
around it called blink
will have its CSS

1851
01:19:27,086 --> 01:19:28,696
manipulated programmatically.

1852
01:19:28,696 --> 01:19:31,016
So we can kind of tie a
lot of ideas together here.

1853
01:19:31,336 --> 01:19:35,456
So var blinks equals
document.getElementsByID

1854
01:19:35,636 --> 01:19:36,446
"blink."

1855
01:19:36,706 --> 01:19:39,216
So there's a few new pieces of
syntax and functionality here

1856
01:19:39,216 --> 01:19:41,196
that are representative
of very common paradigms.

1857
01:19:41,196 --> 01:19:43,996
So var blinks represents
a variable called blinks.

1858
01:19:44,316 --> 01:19:47,766
The right hand side is
document, that's our DOM object.

1859
01:19:47,996 --> 01:19:49,496
And recall that I
promised earlier

1860
01:19:49,496 --> 01:19:52,556
that the objects can have not
only properties, but methods,

1861
01:19:52,556 --> 01:19:53,636
well here's one such method.

1862
01:19:54,166 --> 01:19:55,606
It turns out that in JavaScript,

1863
01:19:55,876 --> 01:19:59,556
the document object has a method
called get elements by name.

1864
01:19:59,556 --> 01:19:59,966
What does it do?

1865
01:20:00,746 --> 01:20:04,206
It does that, it gets elements
by name, it returns an array

1866
01:20:04,246 --> 01:20:07,236
of all of the elements, that
is all of the tags in a webpage

1867
01:20:07,376 --> 01:20:10,116
that match the arguments
-- the quoted argument.

1868
01:20:10,406 --> 01:20:12,776
So this will literally
return an array of all

1869
01:20:12,776 --> 01:20:14,836
of the blink elements
in the page.

1870
01:20:15,236 --> 01:20:16,486
So what does that mean?

1871
01:20:16,486 --> 01:20:18,966
Well again, think back to
DOM, when we draw a DOM

1872
01:20:18,966 --> 01:20:20,866
on the screen, it looks
like a tree with like,

1873
01:20:20,866 --> 01:20:22,906
rectangular nodes, even
though that's an arbitrary

1874
01:20:22,906 --> 01:20:24,466
artist's interpretation.

1875
01:20:24,896 --> 01:20:28,066
So, the array you get back is
an array of those rectangles.

1876
01:20:28,066 --> 01:20:30,856
They represent all of the
blink elements in the DOM.

1877
01:20:31,286 --> 01:20:34,526
So at this point in the story,
blinks is an array of zero

1878
01:20:34,526 --> 01:20:35,616
or more of those tags.

1879
01:20:35,926 --> 01:20:36,606
What comes next?

1880
01:20:36,606 --> 01:20:37,446
Well, we have a variable.

1881
01:20:37,446 --> 01:20:40,336
Notice that you can declare
variables inside of a for loop,

1882
01:20:40,336 --> 01:20:41,896
just like you can
in some languages.

1883
01:20:42,436 --> 01:20:44,786
So var -- for var i equals zero,

1884
01:20:45,086 --> 01:20:47,386
i is less than blinks.length
i plus plus.

1885
01:20:47,646 --> 01:20:49,806
Well, we have a new feature
here of arrays it seems.

1886
01:20:50,136 --> 01:20:52,436
Blinks.length obviously
represents the length

1887
01:20:52,436 --> 01:20:56,026
of the array, but
what is length really?

1888
01:20:56,026 --> 01:20:56,926
Well, it's a property.

1889
01:20:57,056 --> 01:21:00,026
Again, objects have properties
and array is an object,

1890
01:21:00,166 --> 01:21:03,396
so blinks.length is
the length property

1891
01:21:03,396 --> 01:21:05,966
of the blinks array object.

1892
01:21:06,216 --> 01:21:06,926
All right?

1893
01:21:07,246 --> 01:21:08,856
So what comes next
inside of this loop?

1894
01:21:08,856 --> 01:21:10,996
Well one, I'm iterating
over all of the blink tags

1895
01:21:10,996 --> 01:21:12,556
in the page, and what do I do?

1896
01:21:12,776 --> 01:21:17,886
If blinks [i].style.visibility
equals equals visible,

1897
01:21:18,086 --> 01:21:19,196
then change it to hidden.

1898
01:21:19,196 --> 01:21:20,606
So, this is actually
a CSS thing.

1899
01:21:20,606 --> 01:21:24,936
If unfamiliar, a element on
a webpage can be "visible"

1900
01:21:24,936 --> 01:21:28,986
or it can be hidden and those
CSS properties do exactly that.

1901
01:21:29,066 --> 01:21:31,096
So by default, all
elements are visible.

1902
01:21:31,496 --> 01:21:36,306
So this is saying, if the ith
blink element has a visibility

1903
01:21:36,306 --> 01:21:39,266
style of visible, what am
I obviously doing to it?

1904
01:21:39,786 --> 01:21:39,906
What's --

1905
01:21:43,636 --> 01:21:44,686
>> In the if statement?

1906
01:21:44,686 --> 01:21:45,756
>> In the if statement.

1907
01:21:45,756 --> 01:21:47,556
>> Checking whether
it's visible.

1908
01:21:47,556 --> 01:21:48,806
>> Okay, so I'm checking
if it's visible.

1909
01:21:48,806 --> 01:21:52,446
And if it is visible,
what do I do?

1910
01:21:52,446 --> 01:21:53,746
>> You -- you hit [inaudible]
you make not visible.

1911
01:21:54,106 --> 01:21:54,986
>> I make it not visible.

1912
01:21:54,986 --> 01:21:57,826
I change that same
property to hidden.

1913
01:21:58,176 --> 01:22:00,126
So, what is this exposing to us?

1914
01:22:00,126 --> 01:22:04,316
So it turns out in JavaScript,
any time you have an object

1915
01:22:04,756 --> 01:22:06,386
that happens to be
an HTML element --

1916
01:22:06,746 --> 01:22:09,366
and a blink tag is
an HTML element,

1917
01:22:09,936 --> 01:22:11,386
it has a style property.

1918
01:22:11,386 --> 01:22:12,916
That's one of the
things you get for free.

1919
01:22:13,226 --> 01:22:17,036
So if you're accessing elements
in a DOM, like a blink element,

1920
01:22:17,186 --> 01:22:19,846
that blink element has
automatically a dot

1921
01:22:19,846 --> 01:22:20,886
style property.

1922
01:22:21,206 --> 01:22:23,886
That dot style property
is essentially equivalent

1923
01:22:23,886 --> 01:22:26,906
to the style equals "attribute"

1924
01:22:27,056 --> 01:22:28,766
that we could have
put in the HTML.

1925
01:22:29,076 --> 01:22:31,156
So it's the CSS stylization
for that element.

1926
01:22:32,006 --> 01:22:35,956
We can now say change
the visibility attribute

1927
01:22:36,236 --> 01:22:39,816
to be hidden instead of
visible, else, do the opposite,

1928
01:22:40,146 --> 01:22:41,306
that's all we're
saying in the else.

1929
01:22:41,846 --> 01:22:43,376
So just to be clear
here, let me bring

1930
01:22:43,376 --> 01:22:46,056
up a little scratchpad
for a moment.

1931
01:22:46,496 --> 01:22:52,016
Just to be clear, if I had
done this in my style sheet

1932
01:22:52,106 --> 01:22:54,986
or in my style tag, I might
have something like this.

1933
01:22:55,176 --> 01:23:02,116
Blink -- this is CSS now, I
might say visibility visible,

1934
01:23:03,286 --> 01:23:06,096
so that's the default, so it
would be kind of silly for me

1935
01:23:06,096 --> 01:23:08,586
to put this in a style sheet,
but that's what I've just done.

1936
01:23:08,836 --> 01:23:11,926
What the if condition is
doing is it's changing this

1937
01:23:11,926 --> 01:23:16,376
effectively to this
-- on off, on off.

1938
01:23:16,676 --> 01:23:17,806
So what's the aesthetic effect?

1939
01:23:17,806 --> 01:23:18,606
Well, let's take a look.

1940
01:23:18,606 --> 01:23:22,436
Let's go back to the browser
and let's pull up this one,

1941
01:23:22,436 --> 01:23:28,746
which is in a form example,
this one here is the blink.HTML

1942
01:23:29,276 --> 01:23:30,956
and you can see what it's doing.

1943
01:23:30,956 --> 01:23:33,716
Right. Hideous tag, you know,
it's not all that annoying here,

1944
01:23:33,716 --> 01:23:35,856
but if you see -- actually you
can still see remnants of this

1945
01:23:35,856 --> 01:23:38,336
on the web, like really crazy
looking websites that are trying

1946
01:23:38,336 --> 01:23:39,866
to use the blink tag,
but it just didn't work.

1947
01:23:40,256 --> 01:23:43,086
So let me scroll up here
because this is actually kind

1948
01:23:43,086 --> 01:23:43,736
of interesting.

1949
01:23:43,736 --> 01:23:47,886
Let me zoom in over here
and you can see thanks

1950
01:23:47,956 --> 01:23:50,236
to Chrome exactly
what I'm doing.

1951
01:23:50,236 --> 01:23:55,586
>> I have a question.

1952
01:23:55,586 --> 01:23:55,766
>> Uh-huh.

1953
01:23:56,256 --> 01:23:58,326
>> Is -- are -- on this page,

1954
01:23:58,386 --> 01:24:01,306
are you using the same
script you had in the PDF?

1955
01:24:01,746 --> 01:24:02,506
>> Same -- yes.

1956
01:24:02,696 --> 01:24:07,206
>> Because in the PDF, it
iterated over the number

1957
01:24:07,206 --> 01:24:09,076
of blink elements, which
in this case is just one.

1958
01:24:09,206 --> 01:24:13,946
So wouldn't that be one -- one
iteration, just [inaudible]?

1959
01:24:13,946 --> 01:24:14,476
>> Ah, correct.

1960
01:24:14,476 --> 01:24:16,106
So, I'm using the
same blinker function,

1961
01:24:16,686 --> 01:24:19,176
but I'm calling the blinker
function a little differently.

1962
01:24:19,416 --> 01:24:20,486
So let me open that up.

1963
01:24:20,486 --> 01:24:25,596
Let me go into blink.HTML,
here's my blink function,

1964
01:24:25,886 --> 01:24:28,476
but there's one additional line
of code that's necessary here.

1965
01:24:28,916 --> 01:24:30,976
What is this very
last line of code

1966
01:24:30,976 --> 01:24:33,076
in my script tag
doing apparently.

1967
01:24:34,376 --> 01:24:34,706
Jack?

1968
01:24:34,826 --> 01:24:37,466
>> It makes sure that it
won't [inaudible] again until,

1969
01:24:37,466 --> 01:24:40,706
I guess [inaudible].

1970
01:24:40,926 --> 01:24:42,286
>> Good, although let's
not put it that way

1971
01:24:42,286 --> 01:24:44,956
because it doesn't really make
sure that it won't call it,

1972
01:24:44,956 --> 01:24:46,066
because it's only
going to call it --

1973
01:24:46,066 --> 01:24:48,716
it's not going to call it at all
based on the code I have here.

1974
01:24:48,716 --> 01:24:50,376
>> It makes it call it
once in [inaudible].

1975
01:24:50,956 --> 01:24:54,036
>> Good. So, window.setInterval
is a method

1976
01:24:54,306 --> 01:24:56,876
of the window object, which
we've not seen before,

1977
01:24:56,876 --> 01:24:59,176
but it's another one of these
special top level objects.

1978
01:24:59,176 --> 01:25:00,286
Just like you have document,

1979
01:25:00,496 --> 01:25:01,986
which represents
your actual document,

1980
01:25:02,206 --> 01:25:04,976
window is a different object
that represents like a chrome

1981
01:25:04,976 --> 01:25:06,916
on the screen, it
lets you do things

1982
01:25:06,916 --> 01:25:09,226
like window size
redetection and so forth.

1983
01:25:09,376 --> 01:25:12,046
So window has nothing to do
with the HTML, really has to do

1984
01:25:12,046 --> 01:25:14,236
with the browder --
the browser, the --

1985
01:25:14,236 --> 01:25:16,586
the rectangle that is
your browser window.

1986
01:25:16,866 --> 01:25:18,676
So window.setInterval does that.

1987
01:25:18,676 --> 01:25:22,186
It sets an interval, which means
call the following function

1988
01:25:22,186 --> 01:25:24,456
again and again, every some
number of milliseconds.

1989
01:25:24,826 --> 01:25:26,666
So blinker is the
name of my function,

1990
01:25:26,976 --> 01:25:30,186
500 means 500 milliseconds or
as Jack said, half a second.

1991
01:25:30,456 --> 01:25:32,836
So that line is simply
saying, set an interval

1992
01:25:32,836 --> 01:25:36,046
of 500 milliseconds
whereby every time

1993
01:25:36,046 --> 01:25:38,516
that interval happens,
every 500 milliseconds,

1994
01:25:38,746 --> 01:25:40,686
call the function
called blinker.

1995
01:25:41,256 --> 01:25:43,096
Now notice one key detail.

1996
01:25:43,476 --> 01:25:47,126
I have not written
blinker as a function call,

1997
01:25:47,326 --> 01:25:49,556
I have written it
as a function name.

1998
01:25:49,556 --> 01:25:51,956
So it let me go here.

1999
01:25:52,486 --> 01:25:53,606
This is wrong.

2000
01:25:54,046 --> 01:25:58,316
I've just added to parenthesis,
open paren and closed paren,

2001
01:25:58,686 --> 01:26:00,656
that is wrong, but why?

2002
01:26:01,246 --> 01:26:03,966
What's the difference?

2003
01:26:04,776 --> 01:26:08,336
Or what would happen
in this case here?

2004
01:26:08,336 --> 01:26:08,426
Jack?

2005
01:26:08,956 --> 01:26:13,446
>> It would try to
see if blinker --

2006
01:26:13,636 --> 01:26:21,296
it would actually call
blinker right there and see

2007
01:26:21,296 --> 01:26:23,446
if blinker has a return value

2008
01:26:23,446 --> 01:26:24,556
that might be [inaudible]
what it wants.

2009
01:26:24,556 --> 01:26:24,886
>> Exactly.

2010
01:26:24,886 --> 01:26:26,646
So in this case,
just like in all

2011
01:26:26,726 --> 01:26:30,026
of the examples we've done
this far, blinker open paren

2012
01:26:30,026 --> 01:26:32,256
and closed paren means
call blinker, right.

2013
01:26:32,256 --> 01:26:33,066
There's nothing fancy there.

2014
01:26:33,066 --> 01:26:35,876
The problem with that
is that as [inaudible]

2015
01:26:35,966 --> 01:26:40,626
that will effectively call
blinker once and that's it.

2016
01:26:41,046 --> 01:26:42,516
But what you're trying

2017
01:26:43,456 --> 01:26:48,046
to do here is apparently set
the interval of 500 milliseconds

2018
01:26:48,126 --> 01:26:51,296
to call whatever the
first argument is.

2019
01:26:51,296 --> 01:26:54,136
Now does blinker
return anything?

2020
01:26:54,136 --> 01:26:56,696
It actually doesn't
return anything at all,

2021
01:26:56,696 --> 01:26:58,236
which means you have
nothing to call.

2022
01:26:58,236 --> 01:27:01,336
When it returns, it's
not returning function,

2023
01:27:01,336 --> 01:27:04,846
so nothing's actually going to
happen on subsequent passes.

2024
01:27:05,046 --> 01:27:06,666
So this is actually incorrect.

2025
01:27:06,666 --> 01:27:10,636
By contrast, if I just say
blinker without the parenthesis,

2026
01:27:10,636 --> 01:27:13,216
that means pass in a
function pointer, so to speak,

2027
01:27:13,216 --> 01:27:14,976
pass in a reference
to this function

2028
01:27:14,976 --> 01:27:20,636
because what the
window.setInterval timer will do

2029
01:27:20,636 --> 01:27:24,456
is add the parenthesis
effectively itself to call

2030
01:27:24,456 --> 01:27:26,716
that function every few seconds.

2031
01:27:26,716 --> 01:27:30,566
So we can do something
with this.

2032
01:27:30,596 --> 01:27:36,916
Here's how you make a
really annoying webpage.

2033
01:27:37,326 --> 01:27:39,776
But just [inaudible] here,
let's hammer this home.

2034
01:27:40,916 --> 01:27:44,906
So, let me go ahead and do this.

2035
01:27:44,906 --> 01:27:48,036
Let me delete my blinker
function and let me do --

2036
01:27:48,036 --> 01:27:50,136
create another function,
let's call it annoy.

2037
01:27:50,136 --> 01:27:54,426
And we're going to have the
annoy function say alert hi.

2038
01:27:55,026 --> 01:27:57,376
All right, so if
I do this here --

2039
01:27:57,376 --> 01:28:00,646
500 milliseconds will drive
us nuts, so let's actually

2040
01:28:00,646 --> 01:28:05,976
to like 2000 milliseconds, so
2000 seconds, let's do annoy --

2041
01:28:05,976 --> 01:28:10,506
actually let's do it five,
otherwise we'll really go nuts.

2042
01:28:11,996 --> 01:28:12,606
All right.

2043
01:28:13,056 --> 01:28:19,756
So this is effectively
going to do the same thing,

2044
01:28:19,946 --> 01:28:23,376
but we'll demonstrate an example
this way of another feature

2045
01:28:23,376 --> 01:28:25,276
in JavaScript that I
alluded to earlier.

2046
01:28:25,456 --> 01:28:28,996
So now I'm going to reload
this page, the blink's going

2047
01:28:28,996 --> 01:28:31,476
to go away because
we deleted that.

2048
01:28:31,476 --> 01:28:34,156
And here we have hi, okay good.

2049
01:28:34,156 --> 01:28:36,366
I'm going to click okay.

2050
01:28:36,366 --> 01:28:38,446
Hi, okay. I'm going
to click okay.

2051
01:28:38,636 --> 01:28:42,596
All right, we don't have
to go through this forever,

2052
01:28:42,596 --> 01:28:48,606
but this will go on
forever, so that's fine.

2053
01:28:48,606 --> 01:28:51,616
Actually be careful of
doing things like this

2054
01:28:51,766 --> 01:28:54,906
because if you do
it too fast you have

2055
01:28:54,906 --> 01:28:57,736
to like force quit
the whole browser

2056
01:28:57,736 --> 01:29:01,356
because you can't actually stop.

2057
01:29:01,356 --> 01:29:09,046
Anyhow, let's go and rewrite
this slightly differently.

2058
01:29:09,266 --> 01:29:11,786
So, this -- oh, my
God, all right.

2059
01:29:11,786 --> 01:29:13,026
So here, we can fix this.

2060
01:29:13,026 --> 01:29:17,366
Let's comment this out, let's
go back here, reload, okay.

2061
01:29:17,366 --> 01:29:19,236
So now we've -- now
that should stop.

2062
01:29:19,236 --> 01:29:23,386
All right, so what
don't I like about this?

2063
01:29:23,386 --> 01:29:28,366
Well one, the functionality
is kind of annoying, but two,

2064
01:29:29,016 --> 01:29:31,686
it's kind of stupid that
I defined a function only

2065
01:29:31,686 --> 01:29:33,986
so that I could reference
it the next line down.

2066
01:29:33,986 --> 01:29:39,336
Right. This is kind of a waste
of your name space, so to speak.

2067
01:29:39,336 --> 01:29:44,736
In other words, if you're only
going to write a function once,

2068
01:29:44,736 --> 01:29:48,836
and then call it in one place,

2069
01:29:48,956 --> 01:29:52,626
it's not really fundamentally
necessary

2070
01:29:52,956 --> 01:29:54,486
to give it a name, right.

2071
01:29:54,486 --> 01:29:59,426
The only reason it has a name
at the moment is because I want

2072
01:29:59,746 --> 01:30:03,216
to define it up there and
then call it down there.

2073
01:30:03,216 --> 01:30:05,506
But what if I could do
both of those at once,

2074
01:30:05,506 --> 01:30:09,656
especially if this is a throw
away function that doesn't need

2075
01:30:09,806 --> 01:30:15,056
to be called by anyone else
or even by me anywhere else?

2076
01:30:15,676 --> 01:30:16,766
So what if I instead do this?

2077
01:30:16,766 --> 01:30:24,026
And the syntax is going to look
a little weird for a moment.

2078
01:30:24,446 --> 01:30:27,186
Let me do this.

2079
01:30:27,186 --> 01:30:32,746
Instead of defining a function
that way, let me get rid

2080
01:30:32,746 --> 01:30:37,836
of its name, and let
me say var annoy equals

2081
01:30:37,966 --> 01:30:39,566
function semi-colon.

2082
01:30:39,566 --> 01:30:43,066
So what have I done
here fundamentally?

2083
01:30:43,256 --> 01:30:49,546
So the functionality
now is still identical,

2084
01:30:50,616 --> 01:30:51,986
it's just that now rather

2085
01:30:51,986 --> 01:30:53,056
than have defined the
function called annoy

2086
01:30:53,086 --> 01:30:54,196
with the previous syntax,
this time I've said,

2087
01:30:54,226 --> 01:30:55,426
give me a variable called
annoy coincidentally,

2088
01:30:55,456 --> 01:30:56,326
and set it equal to a function.

2089
01:30:56,356 --> 01:30:57,946
So this is where JavaScript
starts to get a little powerful

2090
01:30:57,976 --> 01:30:59,116
and a little different
from some languages.

2091
01:30:59,146 --> 01:31:00,616
You can have what are called
anonymous functions whereby you

2092
01:31:00,646 --> 01:31:01,846
define a function, but
you don't give it a name,

2093
01:31:01,876 --> 01:31:03,106
but you can assign that
function to a variable

2094
01:31:03,136 --> 01:31:03,886
so that you can still call it.

2095
01:31:03,916 --> 01:31:05,596
So at the end of the day, this
is identical to what I just did,

2096
01:31:05,626 --> 01:31:06,196
but the takeaway now is

2097
01:31:06,226 --> 01:31:07,756
that JavaScript has a function
called function who's return

2098
01:31:07,786 --> 01:31:08,866
value is, if you will,
a pointer to itself,

2099
01:31:08,896 --> 01:31:09,556
is a reference to itself.

2100
01:31:09,586 --> 01:31:10,846
More concretely, it's the
address in memory of where

2101
01:31:10,876 --> 01:31:12,286
that function lives, though
that's kind of an overstatement.

2102
01:31:12,316 --> 01:31:13,366
But in other words,
it's some return value

2103
01:31:13,396 --> 01:31:13,996
that will subsequently --

2104
01:31:14,026 --> 01:31:15,376
subsequently let you call
that function or pass it

2105
01:31:15,406 --> 01:31:16,006
around to be later called.

2106
01:31:16,036 --> 01:31:17,566
So in other words, variable is
still called annoy, but the type

2107
01:31:17,596 --> 01:31:18,916
of that variable is not
an int, it's not a float,

2108
01:31:18,946 --> 01:31:19,936
it's not a string,
it's a type function.

2109
01:31:19,966 --> 01:31:21,196
So functions are, as they
say, first class objects

2110
01:31:21,226 --> 01:31:22,336
in JavaScript, which
means you can pass them

2111
01:31:22,366 --> 01:31:23,476
around in memory just like
you could [inaudible] typical

2112
01:31:23,506 --> 01:31:25,066
variable like an int, a char,
a float, a string and so forth.

2113
01:31:25,096 --> 01:31:25,846
So, what's the next step here?

2114
01:31:25,876 --> 01:31:27,196
Well, that would work, but
this is still kind of silly.

2115
01:31:27,226 --> 01:31:28,756
Now I have a variable called
annoy that I'm only using once,

2116
01:31:28,786 --> 01:31:29,746
feels like I can do
better and I can.

2117
01:31:29,776 --> 01:31:31,426
Let me adopt this same idea and
rewrite setInterval as follows.

2118
01:31:31,456 --> 01:31:32,866
I want to define an interval
whereby every some number

2119
01:31:32,896 --> 01:31:33,976
of seconds, the following
function is called.

2120
01:31:41,656 --> 01:31:46,046
Done. So this is an
incredibly common technique

2121
01:31:46,046 --> 01:31:50,666
in JavaScript whereby now I
have truly defined an anonymous

2122
01:31:50,666 --> 01:31:52,336
function, but that's fine

2123
01:31:52,676 --> 01:31:56,486
because I have informed
setInterval of the address

2124
01:31:56,486 --> 01:31:57,966
of that function, all right.

2125
01:31:57,966 --> 01:31:59,246
Because the function function --

2126
01:31:59,356 --> 01:32:00,606
sorry that that's
a little confusing,

2127
01:32:00,756 --> 01:32:04,226
but the function function
returns effectively the address

2128
01:32:04,596 --> 01:32:06,176
of the function that
was just created.

2129
01:32:06,426 --> 01:32:08,706
Doesn't have a name,
but that doesn't matter

2130
01:32:08,706 --> 01:32:11,486
because setInterval doesn't care
what its name is, it only cares

2131
01:32:11,486 --> 01:32:14,006
about that reference that
can be passed around.

2132
01:32:14,346 --> 01:32:16,616
Now this is a little cryptic,
it would have been nice

2133
01:32:16,616 --> 01:32:19,126
if the interval -- if the
number came first frankly,

2134
01:32:19,126 --> 01:32:21,306
but whatever, someone chose
to put the number second.

2135
01:32:21,306 --> 01:32:22,326
So I still need the comma,

2136
01:32:22,706 --> 01:32:25,656
but notice how I wrote
this all on one line.

2137
01:32:25,786 --> 01:32:27,436
I don't even have
to be that anal,

2138
01:32:27,436 --> 01:32:31,416
I can instead put
this over here.

2139
01:32:31,696 --> 01:32:32,646
I can indent it.

2140
01:32:32,926 --> 01:32:35,416
I can then put the curly
brace on the previous line,

2141
01:32:35,416 --> 01:32:37,636
so this is actually a very
common way of seeing a function.

2142
01:32:37,636 --> 01:32:39,466
If I really want, I
could put this down here,

2143
01:32:39,566 --> 01:32:41,376
but it's actually very
common in JavaScript

2144
01:32:41,566 --> 01:32:44,456
to put the curly braces on
the same line as the function.

2145
01:32:44,776 --> 01:32:47,066
So this actually looks
a little cryptic,

2146
01:32:47,466 --> 01:32:49,236
but it's just the
natural progression

2147
01:32:49,236 --> 01:32:52,176
of the various examples
we did leading up to it.

2148
01:32:52,286 --> 01:32:52,976
So in English,

2149
01:32:53,236 --> 01:32:55,096
window.setInterval
takes two arguments,

2150
01:32:55,206 --> 01:32:56,846
one is the address
of a function.

2151
01:32:57,276 --> 01:33:00,166
The other is number
of milliseconds.

2152
01:33:00,886 --> 01:33:05,016
Doesn't matter how we pass
in that alert function,

2153
01:33:05,486 --> 01:33:09,066
we can still pass it in -- we
can pass it in anonymously.

2154
01:33:09,346 --> 01:33:11,406
So what we've just done is
used an anonymous function

2155
01:33:11,406 --> 01:33:14,636
or something more fancily
called a lambda function,

2156
01:33:15,046 --> 01:33:18,156
which is simply in this case
a function that has no name.

2157
01:33:18,446 --> 01:33:20,006
But it will still work,
so let's try this.

2158
01:33:20,696 --> 01:33:23,176
Let me go back, save this file.

2159
01:33:24,026 --> 01:33:25,096
Go back to the browser.

2160
01:33:25,726 --> 01:33:26,936
And actually let's do it,

2161
01:33:26,936 --> 01:33:28,936
instead of every five
seconds, let's do every two.

2162
01:33:29,736 --> 01:33:33,296
So the story gets told
a little more quickly.

2163
01:33:34,896 --> 01:33:40,246
Hi, hi, hi, browsers
thankfully have gotten smarter,

2164
01:33:40,246 --> 01:33:41,406
so let's ignore this one.

2165
01:33:41,986 --> 01:33:46,596
Back in the day, you would've
gotten another hi, another hi,

2166
01:33:46,596 --> 01:33:48,586
another hi, another
hi, another hi,

2167
01:33:48,726 --> 01:33:51,206
at which point you
realize you should --

2168
01:33:51,206 --> 01:33:52,586
really shouldn't have
visited that website.

2169
01:33:53,116 --> 01:33:54,426
Java -- Chrome at least,

2170
01:33:54,426 --> 01:33:56,366
is better about managing
duplication,

2171
01:33:56,366 --> 01:33:58,346
but that is not necessarily
a given.

2172
01:33:58,456 --> 01:34:03,586
All right, so any questions
on anonymous functions?

2173
01:34:06,756 --> 01:34:09,136
No. If you really want
your mind to be blown,

2174
01:34:09,236 --> 01:34:11,466
let me do one other thing.

2175
01:34:11,556 --> 01:34:13,836
This is really just to show
off and to get you thinking

2176
01:34:13,836 --> 01:34:15,666
about more sophisticated syntax.

2177
01:34:16,046 --> 01:34:17,656
Let me go ahead and
get rid of the interval

2178
01:34:17,876 --> 01:34:20,116
and just do var f gets function

2179
01:34:20,596 --> 01:34:22,646
and we'll do the
alert thing like this.

2180
01:34:23,256 --> 01:34:24,606
So this is similar to before.

2181
01:34:24,606 --> 01:34:28,396
I'm not called f yet, but if I
wanted to, I could do this --

2182
01:34:29,006 --> 01:34:31,936
f open bracket, all right.

2183
01:34:31,936 --> 01:34:33,076
So let me go ahead here.

2184
01:34:33,796 --> 01:34:37,286
Go to my appliance, reload
-- whoops, okay, reload.

2185
01:34:37,886 --> 01:34:38,506
Oh, there it is.

2186
01:34:38,506 --> 01:34:39,696
It happens immediately this time

2187
01:34:39,696 --> 01:34:41,036
because there's no
interval, there it is.

2188
01:34:41,036 --> 01:34:43,026
Every time I reload, it starts.

2189
01:34:43,136 --> 01:34:44,696
Hi, but it just happens once.

2190
01:34:45,176 --> 01:34:46,116
So that's interesting.

2191
01:34:46,316 --> 01:34:49,806
And if I really want to be
fancy here, I can do this,

2192
01:34:49,806 --> 01:34:52,266
just so you've seen this syntax
because again, you'll see it

2193
01:34:52,266 --> 01:34:54,066
in online tutorials perhaps.

2194
01:34:54,066 --> 01:34:59,926
If you have a function like
this, you can actually wrap it

2195
01:34:59,926 --> 01:35:03,596
in parenthesis and then put the
trailing parenthesis like this.

2196
01:35:04,446 --> 01:35:07,336
So what is this going to do?

2197
01:35:07,516 --> 01:35:09,586
And let's change the text
just so you believe me

2198
01:35:09,586 --> 01:35:11,386
that we're actually
making some changes here.

2199
01:35:12,766 --> 01:35:15,256
This is crazy looking syntax
and this is not representative

2200
01:35:15,256 --> 01:35:16,666
of like JavaScript coding.

2201
01:35:16,666 --> 01:35:18,846
Don't -- don't take
this too much to heart,

2202
01:35:18,846 --> 01:35:19,786
but what's this going
to do Axle?

2203
01:35:20,116 --> 01:35:23,196
>> I think it's going
to call itself.

2204
01:35:23,196 --> 01:35:25,256
>> Good. Yeah, it will
call itself in this sense.

2205
01:35:25,256 --> 01:35:27,706
Not so much recursively, it
just means that the thing

2206
01:35:27,706 --> 01:35:29,676
between the first set
of parenthesis from here

2207
01:35:29,676 --> 01:35:32,226
to here is a function reference.

2208
01:35:32,516 --> 01:35:34,836
The fact that I'm putting
parenthesis at the end means

2209
01:35:34,836 --> 01:35:37,276
that I'm actually going to
call it and indeed, yes,

2210
01:35:37,736 --> 01:35:39,036
I did just call that function.

2211
01:35:39,266 --> 01:35:40,046
So what's the takeaway?

2212
01:35:40,046 --> 01:35:41,966
Again, it's not meant to,
[inaudible] sort of overwhelm

2213
01:35:42,106 --> 01:35:44,606
with the very syntax,
but it's just to suggest

2214
01:35:44,656 --> 01:35:47,146
that functions are really no
different than any other types

2215
01:35:47,146 --> 01:35:48,286
of variable that you can define.

2216
01:35:48,286 --> 01:35:49,386
You can pass them around.

2217
01:35:49,666 --> 01:35:52,596
You can invoke them by using the
parenthesis and this is going

2218
01:35:52,596 --> 01:35:56,026
to be incredibly common in
various JavaScript libraries

2219
01:35:56,026 --> 01:35:58,916
that you'll use whereby you'll
need to tell a library like,

2220
01:35:58,996 --> 01:36:01,956
jQuery, which is a
popular JavaScript library,

2221
01:36:02,196 --> 01:36:05,496
what function to call when an
event happens, like blinking

2222
01:36:05,496 --> 01:36:09,406
or rather like blurring or focus
or on mouse over, or the like.

2223
01:36:09,406 --> 01:36:11,746
And indeed you can
create these functions

2224
01:36:11,746 --> 01:36:13,846
on the fly as we just did.

2225
01:36:14,336 --> 01:36:18,396
So what other features will we
be able to have access to here?

2226
01:36:18,786 --> 01:36:21,606
So the blink example was just
really meant to give us a sense

2227
01:36:21,606 --> 01:36:25,876
of how we can override CSS and
nonetheless, navigate a DOM,

2228
01:36:26,266 --> 01:36:27,896
but libraries give us a range

2229
01:36:27,896 --> 01:36:30,516
of much sexier functionality
than the blink tag.

2230
01:36:30,516 --> 01:36:33,436
So here just a few of the most
popular JavaScript libraries

2231
01:36:33,436 --> 01:36:37,136
out there today, jQuery is
probably the most JavaScript --

2232
01:36:37,236 --> 01:36:39,536
the most popular
JavaScript library.

2233
01:36:39,846 --> 01:36:42,736
And frankly, most people these
days almost [inaudible] the two.

2234
01:36:42,736 --> 01:36:44,396
If you are a JavaScript
programmer,

2235
01:36:44,396 --> 01:36:46,936
you minimally know
jQuery, and indeed a lot

2236
01:36:46,936 --> 01:36:50,106
of the syntax we use
today is sort of date

2237
01:36:50,246 --> 01:36:54,276
in that you don't have to type
out document.forms.registration.

2238
01:36:54,276 --> 01:36:57,426
I mean, even I was getting
bored saying [inaudible] phrases

2239
01:36:57,426 --> 01:37:00,026
that were that long, so
libraries like jQuery

2240
01:37:00,026 --> 01:37:03,296
as we'll see will dramatically
simplify the type of code

2241
01:37:03,296 --> 01:37:04,896
that we need to write.

2242
01:37:04,896 --> 01:37:08,076
Bootstrap is a very popular
library that Twitter developed

2243
01:37:08,236 --> 01:37:12,276
that makes it much easier to do
things like icons and tool tips

2244
01:37:12,276 --> 01:37:14,156
and buttons and menus,
and the like.

2245
01:37:14,156 --> 01:37:15,366
I'll pull that up
in just a moment,

2246
01:37:15,646 --> 01:37:18,956
Ext JS also similarly has
widgets and the like, MooTools

2247
01:37:18,956 --> 01:37:20,696
and YUI have the same.

2248
01:37:20,696 --> 01:37:21,636
So what do I mean by this?

2249
01:37:22,446 --> 01:37:27,326
Well, if we go to bootstrap, so
let me search for bootstrap CSS.

2250
01:37:27,326 --> 01:37:29,946
Go to the first link
there from Twitter.

2251
01:37:30,126 --> 01:37:31,886
It's incredibly common
these days

2252
01:37:31,886 --> 01:37:34,156
to not reinvent the
wheel yourself

2253
01:37:34,156 --> 01:37:36,786
and implement every single
little feature of your website.

2254
01:37:37,086 --> 01:37:39,506
Implementing buttons is not
a very interesting problem.

2255
01:37:39,506 --> 01:37:42,326
It might have been once, but not
to do it for every darn project

2256
01:37:42,326 --> 01:37:44,186
that you write or
menus or tooltips,

2257
01:37:44,186 --> 01:37:45,766
or these things I
rattled off earlier.

2258
01:37:46,106 --> 01:37:50,346
So just to give you a sense
of what bootstrap comes with,

2259
01:37:50,586 --> 01:37:52,136
you get a whole bunch
of features.

2260
01:37:52,136 --> 01:37:54,886
For instance, in
bootstrap simply

2261
01:37:54,886 --> 01:37:57,766
by downloading their JavaScript
code, which is open source

2262
01:37:57,856 --> 01:38:02,196
and available, you can for
instance, create a modal.

2263
01:38:02,196 --> 01:38:04,856
A modal window is a blocking
window that prevents the user

2264
01:38:04,856 --> 01:38:06,616
from doing other
stuff while it's open.

2265
01:38:06,996 --> 01:38:09,606
Let me click demo modal,
something like this

2266
01:38:09,886 --> 01:38:13,166
where something drops down and
then grays out the background.

2267
01:38:13,196 --> 01:38:16,726
Notice here that I have a
window over it, that's a modal.

2268
01:38:16,956 --> 01:38:20,226
Well, I can open a modal
in bootstrap literally

2269
01:38:20,226 --> 01:38:22,856
by just calling one
line of code like this.

2270
01:38:23,556 --> 01:38:25,936
We'll see more on this
kind of syntax before long,

2271
01:38:25,936 --> 01:38:29,176
but dollar sign tends
to represent jQuery

2272
01:38:29,766 --> 01:38:33,256
and .modal here is
a method associated

2273
01:38:33,256 --> 01:38:38,346
with a div who's ID is myModal,
but more on that to come.

2274
01:38:38,456 --> 01:38:40,556
What else can you do
with a library like this?

2275
01:38:40,556 --> 01:38:41,716
And again, this is
representative

2276
01:38:41,716 --> 01:38:42,706
of all sorts of things.

2277
01:38:43,396 --> 01:38:45,796
Let's scroll down
to the next example.

2278
01:38:45,796 --> 01:38:48,366
So things like this,
little menus

2279
01:38:48,366 --> 01:38:49,716
that you might want
to hover over.

2280
01:38:50,106 --> 01:38:52,306
This is all very doable
using a combination

2281
01:38:52,306 --> 01:38:53,756
of JavaScript and CSS.

2282
01:38:53,756 --> 01:38:57,846
In fact, our simple blink
example was a step toward using

2283
01:38:57,846 --> 01:39:01,886
code to manipulate CSS and open
things like menus and the like,

2284
01:39:02,276 --> 01:39:04,936
but all of this can be done
with a JavaScript library.

2285
01:39:04,936 --> 01:39:07,856
So knowing how to call these
functions gives you a whole

2286
01:39:07,856 --> 01:39:09,006
bunch of functionality.

2287
01:39:09,366 --> 01:39:12,736
Let me scroll down
to -- oh, let's see.

2288
01:39:12,806 --> 01:39:15,666
Tabs are very common,
so let me zoom in here,

2289
01:39:16,066 --> 01:39:19,606
implementing something like
this is very easy with one

2290
01:39:19,606 --> 01:39:21,656
of these JavaScript
libraries, you simply have

2291
01:39:21,696 --> 01:39:25,826
to configure it using code like
this here in red and black.

2292
01:39:25,826 --> 01:39:28,226
Let me scroll down further --

2293
01:39:28,746 --> 01:39:32,146
tooltips, so I alluded to
these earlier, like in Netflix.

2294
01:39:32,536 --> 01:39:36,526
Which event is this
feature apparently using?

2295
01:39:36,526 --> 01:39:37,096
[ Inaudible Speaker ]

2296
01:39:37,096 --> 01:39:42,156
Yeah, so this is probably the
on mouse over event, right.

2297
01:39:42,156 --> 01:39:43,606
Because as soon as
I move my mouse

2298
01:39:43,606 --> 01:39:46,446
over what's probably span
tag or an anchor tag,

2299
01:39:46,796 --> 01:39:48,726
something else is
popping up on the screen.

2300
01:39:48,726 --> 01:39:50,026
So that's possible here.

2301
01:39:50,316 --> 01:39:52,886
This is another similar one
where I get an even bigger box.

2302
01:39:52,886 --> 01:39:54,656
This is even more Netflix style,

2303
01:39:54,656 --> 01:39:55,916
where it's a whole
window of text.

2304
01:39:56,356 --> 01:39:57,526
In this case, it's
a little boring,

2305
01:39:57,526 --> 01:39:59,846
but it's [inaudible] just black
and white, but that's possible.

2306
01:40:00,226 --> 01:40:02,876
Alerts, we don't have to
use the browser based alert,

2307
01:40:02,876 --> 01:40:04,576
indeed the JavaScript
alert function,

2308
01:40:04,576 --> 01:40:05,586
generally don't use it.

2309
01:40:05,846 --> 01:40:09,826
One, it looks different on all
different browsers and two,

2310
01:40:09,826 --> 01:40:12,116
it usually says something
stupid like, "The webpage

2311
01:40:12,116 --> 01:40:16,606
at CNN.com says," like it's just
not very professional typically

2312
01:40:16,606 --> 01:40:19,836
using the built in one, so it's
fine for class and debugging

2313
01:40:20,126 --> 01:40:23,506
and diagnostics, but something
like this is a little --

2314
01:40:23,556 --> 01:40:27,056
let's see, is a little
more compelling.

2315
01:40:27,056 --> 01:40:30,256
Popover -- oh, not
popover, alert --

2316
01:40:30,926 --> 01:40:34,766
oh, this example is not working.

2317
01:40:35,466 --> 01:40:37,386
That button should
be clicking --

2318
01:40:37,386 --> 01:40:42,236
oh, maybe it's because I already
clicked it, no, let's see.

2319
01:40:42,296 --> 01:40:45,166
Okay, not working as I expected
there, for just a moment.

2320
01:40:45,396 --> 01:40:46,936
And then you have
these kinds of toggles.

2321
01:40:47,176 --> 01:40:50,376
So in short, by understanding
how you can manipulate things

2322
01:40:50,376 --> 01:40:53,136
like objects and pass
functions around and the like,

2323
01:40:53,136 --> 01:40:56,386
it gives you access to such a
broader range of functionality

2324
01:40:56,386 --> 01:40:57,906
so that really your project one

2325
01:40:57,906 --> 01:41:01,196
or project two can be all
the more engaging as a result

2326
01:41:01,196 --> 01:41:04,116
of being able to tie these
various widgets together.

2327
01:41:05,516 --> 01:41:10,426
All right, any questions
on objects

2328
01:41:10,426 --> 01:41:11,816
and libraries and the like.

2329
01:41:12,026 --> 01:41:13,496
And again, we'll
come back to things

2330
01:41:13,496 --> 01:41:16,116
like that in the next project.

2331
01:41:17,306 --> 01:41:19,706
All right, so then a word
on some other features

2332
01:41:19,706 --> 01:41:21,746
of JavaScript, especially
as you look ahead

2333
01:41:22,196 --> 01:41:23,456
to the remaining projects.

2334
01:41:23,456 --> 01:41:24,906
So there's this notion
programming

2335
01:41:24,906 --> 01:41:27,286
of static code analysis,
a fancy way of saying,

2336
01:41:27,566 --> 01:41:29,076
checking your code
for correctness

2337
01:41:29,166 --> 01:41:32,636
for some tactic validity and
consistency with certain rules.

2338
01:41:32,636 --> 01:41:35,506
When it comes time to actually
write your own JavaScript code,

2339
01:41:35,506 --> 01:41:37,996
realize that -- and the
emphasis to be clear of,

2340
01:41:37,996 --> 01:41:40,626
project two will
be on JavaScript,

2341
01:41:40,626 --> 01:41:43,546
realize that you can go to a
website like this, jslint.com,

2342
01:41:43,546 --> 01:41:45,386
paste in your JavaScript
code and it will look

2343
01:41:45,386 --> 01:41:47,726
for common mistakes in your
actual JavaScript code,

2344
01:41:47,976 --> 01:41:51,556
much like the W3C's validator
can do the same for HTML.

2345
01:41:51,876 --> 01:41:54,516
So do take advantage ultimately
of something like that.

2346
01:41:54,836 --> 01:41:58,336
But I've eluded to this
concept a couple of times

2347
01:41:58,336 --> 01:42:01,236
and it's an interesting one
when it comes to security.

2348
01:42:01,576 --> 01:42:03,106
You've probably gone
to a website

2349
01:42:03,106 --> 01:42:05,516
and seen crazy looking
JavaScript code

2350
01:42:05,516 --> 01:42:07,736
that frankly we can't
read ourselves tonight,

2351
01:42:08,006 --> 01:42:10,976
even though you pretty much
have seen the basic syntax

2352
01:42:10,976 --> 01:42:12,286
and fundamentals of JavaScript.

2353
01:42:12,286 --> 01:42:14,006
Case and point, let's
go to Google.com,

2354
01:42:14,446 --> 01:42:16,106
let me view the page source here

2355
01:42:17,246 --> 01:42:21,936
and what does this
now look like?

2356
01:42:21,936 --> 01:42:24,106
We pulled this up a
few weeks ago now.

2357
01:42:24,626 --> 01:42:28,366
This is all JavaScript
code, right.

2358
01:42:28,496 --> 01:42:31,176
But frankly, you know, I can't
really make heads or tails

2359
01:42:31,176 --> 01:42:32,576
of most of that code, why?

2360
01:42:32,916 --> 01:42:35,906
Well, Google has compressed
it or minified it as tends

2361
01:42:35,906 --> 01:42:38,316
to be the buzzword, which means
they eliminated white space

2362
01:42:38,356 --> 01:42:39,406
that doesn't need to be there.

2363
01:42:39,666 --> 01:42:42,836
They have shortened variable
names from something like foo

2364
01:42:42,836 --> 01:42:46,126
to just f. In other words,
they trim function names

2365
01:42:46,526 --> 01:42:48,256
and a whole bunch of
other transformations.

2366
01:42:48,256 --> 01:42:50,266
Why? Like why has Google chosen

2367
01:42:50,966 --> 01:42:52,446
to make their code
so unreadable?

2368
01:42:52,446 --> 01:42:54,046
>> Well, the typical user
is never going to be looking

2369
01:42:57,596 --> 01:43:00,446
into finding out why the
Google page works like it does.

2370
01:43:00,446 --> 01:43:03,626
And on Google's end, this
is less that it has to send

2371
01:43:03,676 --> 01:43:05,976
out to every user that
[inaudible] page --

2372
01:43:05,976 --> 01:43:06,086
>> Good.

2373
01:43:06,086 --> 01:43:07,756
>> -- Google [inaudible] site,
they need to [inaudible].

2374
01:43:07,996 --> 01:43:09,386
>> Yeah, so a couple of reasons.

2375
01:43:09,416 --> 01:43:11,876
Like one, like you know, normal
humans like us, we don't need

2376
01:43:11,876 --> 01:43:13,866
to see this, so it doesn't
need to be pretty printed

2377
01:43:13,866 --> 01:43:15,666
or well formatted with
good variable names.

2378
01:43:15,666 --> 01:43:17,866
It needs to be designed
well underneath the hood,

2379
01:43:18,016 --> 01:43:19,346
but aesthetically doesn't matter

2380
01:43:19,346 --> 01:43:21,326
to us what it --
what it looks like.

2381
01:43:21,586 --> 01:43:24,076
And then performance, as Jack
says, if you think about --

2382
01:43:24,256 --> 01:43:25,016
it's kind of remarkable.

2383
01:43:25,016 --> 01:43:27,566
If Google gets maybe a billion
hits per day on their homepage,

2384
01:43:27,786 --> 01:43:31,226
imagine if a programmer simply
accidentally hit the spacebar

2385
01:43:31,226 --> 01:43:34,416
at the end of the file leaving a
single character of white space,

2386
01:43:34,416 --> 01:43:35,616
not a big deal, right.

2387
01:43:35,616 --> 01:43:36,356
We've all done it.

2388
01:43:36,356 --> 01:43:38,326
We all do it quite
often probably.

2389
01:43:38,866 --> 01:43:40,096
But if a billion
people are going

2390
01:43:40,096 --> 01:43:42,076
to download index.HTML today

2391
01:43:42,076 --> 01:43:46,026
and this programmer hit the
spacebar, how many more bytes

2392
01:43:46,166 --> 01:43:48,696
of traffic is that for
Google to transfer.

2393
01:43:48,736 --> 01:43:48,906
Yeah.

2394
01:43:49,206 --> 01:43:49,486
>> Gigabyte.

2395
01:43:49,926 --> 01:43:52,356
>> It's a gigabyte, right,
like a single space character

2396
01:43:52,356 --> 01:43:54,296
for someone as big
and popular as Google,

2397
01:43:54,436 --> 01:43:55,126
it means they're going to have

2398
01:43:55,126 --> 01:43:57,256
to transfer an additional
gigabyte

2399
01:43:57,566 --> 01:43:59,486
of information for
no good reason.

2400
01:43:59,486 --> 01:44:01,166
My God, what if he hit
the spacebar twice,

2401
01:44:01,296 --> 01:44:03,846
that's two gigabytes, 10
times, that's 10 gigabytes.

2402
01:44:04,176 --> 01:44:06,436
So there's very real
world implication,

2403
01:44:06,436 --> 01:44:08,466
certainly for the Google's
and Facebook's of the world.

2404
01:44:08,696 --> 01:44:09,836
But even for your own website,

2405
01:44:09,836 --> 01:44:12,236
like why bother wasting
bandwidth on things like that

2406
01:44:12,426 --> 01:44:15,696
when you can compress it once,
still keep an original copy

2407
01:44:15,696 --> 01:44:18,336
for your developer so that
humans can actually read it

2408
01:44:18,336 --> 01:44:21,316
and update it later, but the
browser doesn't actually care.

2409
01:44:21,316 --> 01:44:24,116
So this is a very common
technique for that reason.

2410
01:44:24,206 --> 01:44:26,216
And what's a third
potential reason for wanting

2411
01:44:26,216 --> 01:44:27,816
to make your code
look more like this?

2412
01:44:27,816 --> 01:44:27,906
Jack?

2413
01:44:27,906 --> 01:44:32,226
>> If you want to kind of deter
competitors from trying to find

2414
01:44:32,356 --> 01:44:33,596
out how and why your code works.

2415
01:44:35,796 --> 01:44:38,346
>> Good. So if you want to
deter competitors from how

2416
01:44:38,346 --> 01:44:39,676
and why their code works,

2417
01:44:39,976 --> 01:44:42,016
you can try to make
it look a little more

2418
01:44:42,016 --> 01:44:43,276
like this, very easily.

2419
01:44:43,406 --> 01:44:46,206
Now realize that the smartest
of people, the smartest

2420
01:44:46,206 --> 01:44:47,996
of adversaries, the
smartest of competitors,

2421
01:44:48,326 --> 01:44:50,276
they can still figure out
what your code is doing.

2422
01:44:50,276 --> 01:44:52,346
In fact, there exist
tools that do kind

2423
01:44:52,346 --> 01:44:53,876
of the opposite of
compressing it.

2424
01:44:53,876 --> 01:44:55,256
They will make it
much more readable.

2425
01:44:55,466 --> 01:44:57,496
It can't obviously
recover variable names.

2426
01:44:57,496 --> 01:45:01,836
If you have changed the
variable from foo to f, these --

2427
01:45:01,836 --> 01:45:04,946
these decompilers as we might
call them, are not going

2428
01:45:04,946 --> 01:45:06,966
to be able to resurrect
information that's been thrown

2429
01:45:06,966 --> 01:45:09,676
away, but we could absolutely
with, you know, a few minutes

2430
01:45:09,676 --> 01:45:11,686
or in a couple hours
time figure out how most

2431
01:45:11,686 --> 01:45:13,006
of this is actually working.

2432
01:45:13,256 --> 01:45:15,366
So all you're really
doing is raising the bar.

2433
01:45:15,366 --> 01:45:16,536
But that's probably
enough, right.

2434
01:45:16,536 --> 01:45:18,566
Because if your -- you're
worrying about your competitor,

2435
01:45:18,836 --> 01:45:20,276
and your competitor
is smart enough

2436
01:45:20,276 --> 01:45:23,066
to decompile your minified
JavaScript code and figure

2437
01:45:23,066 --> 01:45:25,716
out how your code works, frankly
the person is probably smart

2438
01:45:25,716 --> 01:45:27,256
enough to just go
implement it from scratch

2439
01:45:27,256 --> 01:45:29,256
without wasting time
figuring out how yours works.

2440
01:45:29,256 --> 01:45:31,436
So, all your trying
to do is raise the bar

2441
01:45:31,436 --> 01:45:32,806
to adversarial attacks
like this.

2442
01:45:33,216 --> 01:45:35,676
So to be clear with something
like JavaScript, with something

2443
01:45:35,676 --> 01:45:38,756
like CSS, with something like
HTML -- you cannot, cannot,

2444
01:45:38,756 --> 01:45:41,276
cannot, cannot encrypt it

2445
01:45:41,406 --> 01:45:43,386
or prevent other
people from seeing it.

2446
01:45:43,496 --> 01:45:45,066
That's just not the
way the web works.

2447
01:45:45,096 --> 01:45:48,446
There exists tools that claim to
do this, and there exist tools

2448
01:45:48,446 --> 01:45:50,136
that do actually do this.

2449
01:45:50,626 --> 01:45:56,216
These are a few that do indeed
minify or compress your code,

2450
01:45:56,636 --> 01:46:00,076
but they do not fundamentally
change anything

2451
01:46:00,376 --> 01:46:02,146
because even something
like the middle one,

2452
01:46:02,146 --> 01:46:03,546
which effectively
compresses your --

2453
01:46:03,656 --> 01:46:06,956
rather encrypts your code,
the thing about encryption is

2454
01:46:06,956 --> 01:46:10,056
that if you have a secret key
with which to encrypt code,

2455
01:46:10,356 --> 01:46:15,426
what do you need to decrypt it?

2456
01:46:15,426 --> 01:46:15,696
[ Inaudible Speaker ]

2457
01:46:15,696 --> 01:46:17,766
Oh, yeah, well maybe not
generally the public key,

2458
01:46:17,766 --> 01:46:19,786
but the private key, but if
we were using what's called

2459
01:46:19,786 --> 01:46:23,616
symmetric -- symmetric key
cryptography, the same key.

2460
01:46:23,876 --> 01:46:26,506
So how do some of these
products that literally can --

2461
01:46:26,506 --> 01:46:29,746
or you can find being sold
online to encrypt JavaScript.

2462
01:46:29,746 --> 01:46:30,386
How do they work?

2463
01:46:30,626 --> 01:46:33,066
Yes, they do encrypt
your JavaScript code,

2464
01:46:33,166 --> 01:46:35,966
but they also include in the
encrypted file, guess what?

2465
01:46:36,826 --> 01:46:37,946
The key, right.

2466
01:46:37,946 --> 01:46:39,316
So it's idiotic, right.

2467
01:46:39,316 --> 01:46:42,156
It's not fooling anyone who
is sufficiently advanced,

2468
01:46:42,156 --> 01:46:44,606
so just realize that the
short answer protecting your

2469
01:46:44,606 --> 01:46:47,546
intellectual property when it
comes to JavaScript, HTML, CSS,

2470
01:46:47,826 --> 01:46:50,316
all you can do is raise
the bar to people figuring

2471
01:46:50,316 --> 01:46:51,036
out what you're doing.

2472
01:46:51,406 --> 01:46:53,126
But that should be
okay in theory, right.

2473
01:46:53,126 --> 01:46:55,776
If the value of your
company or your product is

2474
01:46:55,776 --> 01:46:58,246
that you have users and
you can't just steal those

2475
01:46:58,246 --> 01:47:02,316
by viewing source, or you
have actual databases and data

2476
01:47:02,526 --> 01:47:05,266
and interesting stuff going on
server side, that tends to be

2477
01:47:05,266 --> 01:47:07,156
where some of the real
intellectual property is,

2478
01:47:07,156 --> 01:47:09,606
more server side
than client side.

2479
01:47:09,606 --> 01:47:11,126
So don't be misled into thinking

2480
01:47:11,126 --> 01:47:12,856
that these will keep
your code safe,

2481
01:47:12,856 --> 01:47:15,136
all it will do is save you
bytes and raise the bar,

2482
01:47:15,356 --> 01:47:19,596
which those of themselves are
certainly still valid endeavors.

2483
01:47:19,986 --> 01:47:21,446
So let's actually
try one of these.

2484
01:47:21,596 --> 01:47:23,846
Let me go to this one here.

2485
01:47:25,256 --> 01:47:27,606
This is just a smart guy
who's put this together.

2486
01:47:27,606 --> 01:47:29,906
So these are actually reputable
ones, the ones I put up.

2487
01:47:29,906 --> 01:47:31,876
If you're trying to
be sold any such tool,

2488
01:47:31,876 --> 01:47:33,376
I wouldn't pay for it.

2489
01:47:33,376 --> 01:47:38,716
Let me go into one of tonight's
files so that we can dig up,

2490
01:47:38,716 --> 01:47:47,906
let's see -- let's
go into tonight --

2491
01:47:48,426 --> 01:47:54,976
whoops, let me pull up,
let's see, will that work?

2492
01:47:55,186 --> 01:47:56,896
All right, let's just try it,

2493
01:47:57,016 --> 01:47:59,186
we don't need a whole
example, we can do it by hand.

2494
01:47:59,266 --> 01:48:05,296
So let's see -- var
annoy gets function,

2495
01:48:06,006 --> 01:48:06,926
let's see if this works --

2496
01:48:07,836 --> 01:48:13,566
alert hello closed
brace semicolon, okay.

2497
01:48:13,766 --> 01:48:14,276
So here we go.

2498
01:48:14,276 --> 01:48:16,876
We're on this packer site,
I'm going to click pack.

2499
01:48:16,876 --> 01:48:19,496
Okay, so here's what I've
just done to minify my code.

2500
01:48:19,496 --> 01:48:21,546
You know, it's still
quite readable frankly,

2501
01:48:21,546 --> 01:48:22,376
we could all probably figure

2502
01:48:22,376 --> 01:48:23,696
out what this piece
of code now does.

2503
01:48:23,696 --> 01:48:24,926
But what did it obviously
remove?

2504
01:48:24,926 --> 01:48:26,166
[ Inaudible Speaker ]

2505
01:48:26,166 --> 01:48:27,716
Okay, so white space
is all it removed.

2506
01:48:27,716 --> 01:48:29,516
I think this site has
a few options here just

2507
01:48:29,516 --> 01:48:31,076
to make this a little
more interesting.

2508
01:48:31,306 --> 01:48:33,596
We can shrink variables, so
I've just check the box at right

2509
01:48:33,596 --> 01:48:34,636
that says shrink variables.

2510
01:48:35,006 --> 01:48:35,956
Let's pack this again.

2511
01:48:36,766 --> 01:48:38,166
Now that really didn't
do anything this time.

2512
01:48:38,296 --> 01:48:44,036
So let's do base62
encode, what does this do?

2513
01:48:44,266 --> 01:48:45,836
Okay, so this is what
these sites tend to do

2514
01:48:45,836 --> 01:48:47,806
when they claim their
encrypting your code.

2515
01:48:47,806 --> 01:48:49,856
So this is the same thing.

2516
01:48:50,406 --> 01:48:52,246
What is that doing?

2517
01:48:52,416 --> 01:48:53,386
What does that program do?

2518
01:48:53,386 --> 01:48:53,936
[ Inaudible Speaker ]

2519
01:48:53,936 --> 01:48:57,566
It prints hello, right.

2520
01:48:57,596 --> 01:48:58,416
That's all it does.

2521
01:48:58,706 --> 01:49:02,076
Now, all of this though can
be reconstructed and frankly,

2522
01:49:02,076 --> 01:49:03,786
this just, it's kind of a
cute little [inaudible].

2523
01:49:04,076 --> 01:49:06,676
So notice this guy has
define an anonymous function

2524
01:49:06,996 --> 01:49:11,556
with the function keyword that
takes six arguments, p, a, c, k,

2525
01:49:11,556 --> 01:49:13,616
e, r just because he's
being clever with his name.

2526
01:49:14,026 --> 01:49:15,376
What is he passing in?

2527
01:49:15,376 --> 01:49:16,786
Well, if we actually
parse the cell,

2528
01:49:17,016 --> 01:49:19,326
one of these arguments is
apparently this variable

2529
01:49:19,326 --> 01:49:22,746
expression e equals string,
the next is this if condition,

2530
01:49:22,746 --> 01:49:24,376
one of them is this split here

2531
01:49:24,376 --> 01:49:26,686
where clearly this is
relevant to the original code.

2532
01:49:27,046 --> 01:49:29,746
Again, all we have done
is obfuscated the code,

2533
01:49:29,746 --> 01:49:32,466
made it look complex, but
at the end of the day,

2534
01:49:32,996 --> 01:49:35,686
a smart adversary could
just execute this function

2535
01:49:35,686 --> 01:49:38,096
and see what the result is
and piece it back together.

2536
01:49:40,476 --> 01:49:41,396
Any questions?

2537
01:49:42,796 --> 01:49:43,256
Whoops, sorry.

2538
01:49:43,826 --> 01:49:45,546
Whoops, sorry.

2539
01:49:45,666 --> 01:49:46,356
Questions?

2540
01:49:46,966 --> 01:49:54,236
All right, so let's go
ahead and wrap there.

2541
01:49:54,336 --> 01:49:57,016
Myers here for section,
which will dive a bit deeper

2542
01:49:57,016 --> 01:50:00,056
into JavaScript, Monday too, we
will introduce the server side

2543
01:50:00,356 --> 01:50:03,096
of JavaScript, whereby we
will actually have the ability

2544
01:50:03,376 --> 01:50:06,796
to perform and calls, additional
htp requests that will allow us

2545
01:50:06,796 --> 01:50:08,296
to get more data from the server

2546
01:50:08,296 --> 01:50:10,676
and do all the fancier things
while still using the same

2547
01:50:10,676 --> 01:50:12,756
client side technique
to actually update

2548
01:50:12,756 --> 01:50:15,606
and not just reverse the
DOM and the local webpage.

2549
01:50:15,606 --> 01:50:16,666
So more on that to come.

2550
01:50:16,666 --> 01:50:17,976
I'll stick around for
one on one questions.

