Coding

Vanilla JavaScript Modal – JavaScript Only!

  • 00:00:01 so in the last part of this video here
  • 00:00:05 we had a mole with all the markup in our
  • 00:00:09 index.html file we had this demo
  • 00:00:11 container where we could open the model
  • 00:00:13 and output some quote and that quote
  • 00:00:15 outputting and the control team modal
  • 00:00:17 would all be handled through JavaScript
  • 00:00:19 well we got access to all the elements
  • 00:00:21 we need to work with and then registered
  • 00:00:23 a bunch of event listeners to open and
  • 00:00:26 close the modal and also to register any
  • 00:00:28 changes to that quote which we loaded a
  • 00:00:31 2d text area in the modal also for
  • 00:00:34 JavaScript and which we den well updated
  • 00:00:37 when we close the modal now my goal is
  • 00:00:39 to not do this by just changing the
  • 00:00:43 display style to non and block anymore
  • 00:00:45 but instead to create this entire markup
  • 00:00:48 here dynamically in our JavaScript code
  • 00:00:52 so let's comment this all out and let's
  • 00:00:56 well add it dynamically and how can we
  • 00:00:59 do that
  • 00:01:02 so let's do that and let's for example
  • 00:01:06 start with the more simple thing let's
  • 00:01:09 add the backdrop up on a click off that
  • 00:01:12 edit value' button so for that I'll have
  • 00:01:16 to do something when we click this
  • 00:01:18 button this is the edit value' button
  • 00:01:20 and I will no longer set my Styles of
  • 00:01:23 modal and backdrop because these no
  • 00:01:25 longer exists I can all remove it up
  • 00:01:28 there and I can also stop getting my
  • 00:01:31 references there because these elements
  • 00:01:34 don't exist in the Dom anymore so we
  • 00:01:35 can't get access to the modal and the
  • 00:01:37 backdrop instead of we'll need to create
  • 00:01:40 it dynamically so when we click on that
  • 00:01:42 button here where we open the modal this
  • 00:01:46 one here will have to create that
  • 00:01:49 backdrop cue added to the dawn' and we
  • 00:01:51 can create HTML elements or dom elements
  • 00:01:55 in JavaScript dynamically this is
  • 00:01:57 possible so in here let's create this
  • 00:02:01 backdrop now and actually I'll still
  • 00:02:03 create this as a global variable here
  • 00:02:06 and I'll do the same for the modal so do
  • 00:02:09 that still but there uninitialized
  • 00:02:11 initially so they're just undefined but
  • 00:02:14 this allows me to then use them from
  • 00:02:16 other places in my app too so now back
  • 00:02:18 into our code here where we have a click
  • 00:02:21 listener on that added value button here
  • 00:02:24 all set backdrop equal to document and
  • 00:02:26 then there's this create element method
  • 00:02:29 which allows us to create a new HTML
  • 00:02:31 element this method simply takes the tag
  • 00:02:35 name as an argument and I'll create a
  • 00:02:38 div here so my backdrop will be a div
  • 00:02:40 with death created I can access it here
  • 00:02:43 on the variable in which I store the
  • 00:02:45 created element and now I just want to
  • 00:02:47 make sure that this has my backdrop CSS
  • 00:02:50 class and for that I can access class
  • 00:02:53 list which allows me to access all a
  • 00:02:55 list of all the CSS classes sitting on
  • 00:02:58 that element and I can call add here to
  • 00:03:01 add backdrop like this now we won't be
  • 00:03:05 able to see this yet because right now
  • 00:03:06 our script wit still crash because here
  • 00:03:09 I got a listener on the backdrop which
  • 00:03:12 essentially will close them all but I
  • 00:03:14 listen to something which is under
  • 00:03:16 initially so this would throw an error
  • 00:03:18 the right place for the listeners of
  • 00:03:20 course after we created it so here in
  • 00:03:23 this function I'll now set up my
  • 00:03:26 listener like that
  • 00:03:27 now one other issue all face is
  • 00:03:29 regarding my buttons this is now not
  • 00:03:32 correct anymore I'm selecting the third
  • 00:03:34 button but if we take a closer look we
  • 00:03:36 not only get one button ear because the
  • 00:03:39 other two buttons which existed in the
  • 00:03:41 last part don't exist anymore so we have
  • 00:03:44 to change this too for the button here I
  • 00:03:47 can actually just say added-value button
  • 00:03:52 and use query selector without all and
  • 00:03:55 select the first button I find which is
  • 00:03:57 the only button I have on the page of
  • 00:03:58 course you could also assign an ID to
  • 00:04:00 the button to have an even clearer way
  • 00:04:02 of selecting this by the way if we later
  • 00:04:05 add buttons this will not cause this to
  • 00:04:08 not work anymore because this script
  • 00:04:10 runs when the page is first loaded and
  • 00:04:12 deadest and the point of time which is
  • 00:04:14 important for selecting buttons if we
  • 00:04:16 later add more buttons programmatically
  • 00:04:18 this will not run again so this query
  • 00:04:21 selector will not run again and will not
  • 00:04:23 select one of the new buttons will
  • 00:04:25 always run this when the page is first
  • 00:04:26 loaded and at this point of time we'll
  • 00:04:28 only have one button so that's the added
  • 00:04:30 value button to which I want to add my
  • 00:04:34 event listener therefore and that of
  • 00:04:36 course means that these scripts here
  • 00:04:38 won't work anymore so let's actually
  • 00:04:40 comment that out the other two buttons
  • 00:04:42 they just don't exist yet text edit will
  • 00:04:45 all do not exist because and that means
  • 00:04:48 we can of course also comment this out
  • 00:04:50 we don't have a modal in which we could
  • 00:04:53 select a text area and that of course
  • 00:04:55 all the means that text added value here
  • 00:04:58 won't work so let's comment this out too
  • 00:05:00 and with all these changes made we
  • 00:05:02 should have working code again there's
  • 00:05:04 one thing which will stop this from
  • 00:05:05 displaying the backdrop though and that
  • 00:05:08 is that we add this backdrop class but
  • 00:05:10 in this Styles we still have displayed
  • 00:05:13 on here as a default now since we now
  • 00:05:15 control the visibility of the backdrop
  • 00:05:17 and the modal differently I'll have to
  • 00:05:19 remove that there because these elements
  • 00:05:21 now won't exist if we don't want to
  • 00:05:23 display them and that means if we do
  • 00:05:25 want to display them well then we should
  • 00:05:27 certainly always
  • 00:05:30 supports this with CSS and not hide them
  • 00:05:32 through CSS so now with this we're
  • 00:05:34 almost done but there's one thing we're
  • 00:05:36 not doing with the backdrop we're
  • 00:05:38 creating it we're not adding it to the
  • 00:05:40 DOM and that is something we shouldn't
  • 00:05:43 forget because this will only create it
  • 00:05:45 in memory to also display something on
  • 00:05:47 the screen I'll have to append it or add
  • 00:05:49 it to my DOM and we can do this by
  • 00:05:52 getting access to our wrapping container
  • 00:05:55 which in my case is simply the whole
  • 00:05:57 body that can therefore just called
  • 00:05:59 document body and then we could append
  • 00:06:04 it at the end or we use insert before to
  • 00:06:08 insert before another element and now I
  • 00:06:11 want to insert my backdrop and the every
  • 00:06:13 element before I want to insert it in my
  • 00:06:15 case it's the demo container so I can
  • 00:06:19 also select that and I have to select it
  • 00:06:21 here so the demo container let's store
  • 00:06:24 it in this variable can be selected with
  • 00:06:26 the query selector by its class which it
  • 00:06:28 has so this is the element before which
  • 00:06:31 I want to add my backdrop so this is the
  • 00:06:34 reference or the variable name I'll use
  • 00:06:36 here in insert before to insert this
  • 00:06:38 backdrop in my body before the demo
  • 00:06:41 container there for demo container of
  • 00:06:44 course has to be a direct child of the
  • 00:06:46 body and with that now if I reload this
  • 00:06:49 neck like added-value we see the
  • 00:06:51 backdrop clicking on the backdrop
  • 00:06:53 doesn't do anything yet though and we of
  • 00:06:54 course also don't see the modal so let's
  • 00:06:57 follow this pattern and let's also
  • 00:06:58 create the modal programmatically this
  • 00:07:01 entire code here is responsible for the
  • 00:07:03 backdrop now we can already add some
  • 00:07:06 code to close the backdrop maybe so we
  • 00:07:09 can reach out to our backdrop here and
  • 00:07:11 add an event listener a click listener
  • 00:07:17 to execute clothes modal just pointing
  • 00:07:22 at it not executing it immediately with
  • 00:07:25 parentheses I just want to pass the
  • 00:07:27 address to that function to this click
  • 00:07:30 listener so that this click listener
  • 00:07:32 will execute close modal whenever a
  • 00:07:34 click occurs and in close modal I now
  • 00:07:37 want to first of all check if my
  • 00:07:39 backdrop exists I can do this with this
  • 00:07:41 if check it will fail of design of
  • 00:07:44 find so if that backdrop exists then I
  • 00:07:46 want to call backdrop and I want to
  • 00:07:49 remove it right and to remove it I can
  • 00:07:51 just call remove on that element notice
  • 00:07:55 will not work in um Internet Explorer 7
  • 00:07:57 for example but it should work fine here
  • 00:07:59 if we reload this opens it this closes
  • 00:08:01 it so this is now working with the
  • 00:08:03 backdrop now let's do the same for the
  • 00:08:05 modal and feel free to practice this on
  • 00:08:07 your own and pause the video at this
  • 00:08:09 point all of course all do together with
  • 00:08:12 you and I'll do it here below the
  • 00:08:14 backdrop I also want to create my modal
  • 00:08:16 don't keep in mind we created a modal
  • 00:08:18 variable already it's just undefined and
  • 00:08:20 we can use that variable to create the
  • 00:08:23 modal and just as before I'll create a
  • 00:08:25 new element with create element document
  • 00:08:28 create element to be precise this will
  • 00:08:30 also be a div and I want to recreate
  • 00:08:32 that markup I used before now unlike the
  • 00:08:36 backdrop this is of course also has our
  • 00:08:38 children so we'll have to create these
  • 00:08:41 two we'll have to create the h1 tag
  • 00:08:43 we'll have to create this div the text
  • 00:08:46 area this div the buttons in there so
  • 00:08:48 that's quite a lot of work obviously and
  • 00:08:50 that also is the reason why you use
  • 00:08:53 frameworks or libraries like react or
  • 00:08:56 view but that's something I'll come back
  • 00:08:58 to in a separate video so well let's go
  • 00:09:01 through all of that I have my modal Dave
  • 00:09:05 here let's also access the class list
  • 00:09:07 and make sure that we add that modal
  • 00:09:09 class which we need to give that the
  • 00:09:12 right styling now the next element is
  • 00:09:15 that h1 tag here so let's create that
  • 00:09:20 modal heading maybe could be document
  • 00:09:23 create element h1 and then all my modal
  • 00:09:28 heading here I will set the text content
  • 00:09:31 to well simply this added your statement
  • 00:09:37 text and we do this not with a function
  • 00:09:39 call but with an equal sign so now it is
  • 00:09:42 created the h1 tag we need to add that
  • 00:09:45 h1 tag to the modal so we can access
  • 00:09:47 modal appendchild since we wanna well
  • 00:09:50 append it inside of the modal we don't
  • 00:09:52 want to insert it before anything it
  • 00:09:53 should just be well the next element in
  • 00:09:55 there
  • 00:09:56 and therefore now I append my modal
  • 00:09:58 heading like this well that was the h1
  • 00:10:02 tag let's repeat it for this death so
  • 00:10:05 let's create another variable and of
  • 00:10:09 course you can certainly write a more
  • 00:10:11 elegant way I'm deliberately doing this
  • 00:10:13 very explicitly to make it clear which
  • 00:10:15 steps were executing so now I'll treat
  • 00:10:18 this div with my modal input class so
  • 00:10:22 let's copy that text edit container
  • 00:10:26 seems to be a fitting name these names
  • 00:10:28 are always up to you let's create an
  • 00:10:30 element this will be a div and the text
  • 00:10:33 edit container there we need to access
  • 00:10:35 the class list and add this modal input
  • 00:10:38 class which it should have
  • 00:10:39 let's now alter append this and the cool
  • 00:10:42 thing is append child always well
  • 00:10:44 appends it at the end of the child list
  • 00:10:47 and therefore this will add it after the
  • 00:10:49 h1 tag so I can't just append text edit
  • 00:10:52 container and make sure it's positioned
  • 00:10:53 correctly in the Dom automatically now
  • 00:10:57 inside the text edit container I need to
  • 00:10:59 add my text area so I'll create text
  • 00:11:04 edit area or however you want to call it
  • 00:11:07 just text area of course document create
  • 00:11:10 element this will be a text area element
  • 00:11:13 now that text area text edit area that
  • 00:11:17 should actually have its rows configured
  • 00:11:20 and for that we can simply access the
  • 00:11:22 rows property and set this to free
  • 00:11:25 important and this has to be have be a
  • 00:11:28 string not a number it's a string and
  • 00:11:30 I'm using free because I used free here
  • 00:11:32 at you and now this text edit area
  • 00:11:34 should be appended not to the model but
  • 00:11:37 to that text edit container of course
  • 00:11:39 so let's access text edit container and
  • 00:11:42 append a child there and that child will
  • 00:11:45 be the text edit area the text area
  • 00:11:48 all's of course will receive some logic
  • 00:11:51 to save whatever the user entered in
  • 00:11:55 there this input listener here to be
  • 00:11:58 precise so we can copy that from down
  • 00:12:02 there and add it on our text edit area
  • 00:12:06 here so text edit area
  • 00:12:10 add eventlistener let's comment this in
  • 00:12:13 here and this will make sure that we now
  • 00:12:15 listen to input events on the text edit
  • 00:12:17 area and that we therefore well save the
  • 00:12:21 value we enter in the edited quote we're
  • 00:12:26 not done yet though we also need to add
  • 00:12:28 this dev with the modal actions so just
  • 00:12:31 as before let's create that in
  • 00:12:34 JavaScript modal actions container will
  • 00:12:39 be document create element there will be
  • 00:12:42 a div and then I'll access Moodle
  • 00:12:45 actions container the class list and add
  • 00:12:47 my whoops modal actions class as a
  • 00:12:50 string like this and in there I need to
  • 00:12:52 add my two buttons now so these two
  • 00:12:55 buttons with type button and button
  • 00:12:58 cancel for that let's first of all
  • 00:13:02 append our container of course so let's
  • 00:13:04 reach out to the modal append a child
  • 00:13:07 and append dad modal actions container
  • 00:13:09 so that we don't forget that but then
  • 00:13:11 let's create the cancel button with
  • 00:13:17 document create element will be a button
  • 00:13:22 now to set that type that actually is a
  • 00:13:25 attribute because it's used by but the
  • 00:13:29 browser padam so to say so here I will
  • 00:13:32 set will call my cancel or reach out to
  • 00:13:34 my cancel button and then set an
  • 00:13:38 attribute with the set attribute method
  • 00:13:40 and then I want to set the type
  • 00:13:42 attribute Q button so that's kind of a
  • 00:13:46 special thing this is not a property of
  • 00:13:48 the button object we handle in
  • 00:13:51 JavaScript this instead is just an
  • 00:13:53 attribute we add to the HTML code to the
  • 00:13:56 Dom so that the browser knows what to do
  • 00:13:59 with the button when it's clicked so it
  • 00:14:02 works a bit different here now I of
  • 00:14:04 course all the want to add my class so
  • 00:14:06 cancel button class list add is what I
  • 00:14:10 want to call and I want to add button
  • 00:14:11 cancel here now this cancel button
  • 00:14:13 should be added to the modal actions
  • 00:14:15 container not to the modal so modal
  • 00:14:17 actions container appendchild cancel
  • 00:14:20 button is what i want to execute here
  • 00:14:23 and I will now copy that code and repeat
  • 00:14:26 it for my confirm button so let's
  • 00:14:29 replace canceled with confirmed down
  • 00:14:33 there although in the class name we're
  • 00:14:36 assigning and this will now add the
  • 00:14:37 confirm button to the model to okay so
  • 00:14:41 now this controls the model it adds all
  • 00:14:44 the elements a lot of code as you can
  • 00:14:46 see let's now add that modal Q our page
  • 00:14:52 and for that I want to insert it before
  • 00:14:55 my demo container right still this will
  • 00:14:58 be after the backdrop but before that
  • 00:15:00 container so I'll just copy that code
  • 00:15:03 from up there where we added the
  • 00:15:04 backdrop and I'll use that same code to
  • 00:15:07 add my modal now let's give this a try
  • 00:15:10 let's reload the page and edit value'
  • 00:15:13 loads to modal now the text the buttons
  • 00:15:15 is missing because I forgot to set it
  • 00:15:17 I'll do this in a second and we don't
  • 00:15:19 see the text in there but besides that
  • 00:15:22 it's working
  • 00:15:23 now clicking on the backdrop doesn't
  • 00:15:24 close the modal yet because we're not
  • 00:15:26 handling this let's fix this
  • 00:15:28 step-by-step first of all let's make
  • 00:15:29 sure that the buttons have a text so the
  • 00:15:32 cancel button text content will be equal
  • 00:15:35 to cancel and the confirmed button text
  • 00:15:41 content will be equal to confirm like
  • 00:15:44 this that's the first important step
  • 00:15:47 the average Portman step is that we set
  • 00:15:50 the text edit value here to our loaded
  • 00:15:52 quote so when I create my text edit area
  • 00:15:55 here I'll set text edit area value equal
  • 00:15:59 to the quote so now this should be
  • 00:16:01 pre-populated too if I now reload the
  • 00:16:03 page yeah that looks better now these
  • 00:16:06 buttons don't do anything and the modal
  • 00:16:08 is never closed so let's also make sure
  • 00:16:10 that this is the case and for that on
  • 00:16:13 these buttons on cancel button for
  • 00:16:16 example I'll add an event listener to
  • 00:16:20 the click event and on the cancel button
  • 00:16:22 I just want to execute the closed modal
  • 00:16:26 functions or pass a reference to it just
  • 00:16:29 as I did for the backdrop now for the
  • 00:16:31 confirmed but that's a bit different the
  • 00:16:33 confirm button will receive an event
  • 00:16:36 listener
  • 00:16:37 it's also listening to a click event but
  • 00:16:41 just as I did it down there I want to do
  • 00:16:44 more than just close the modal so
  • 00:16:46 actually copied that anonymous function
  • 00:16:48 from down there and use that here on the
  • 00:16:51 confirm button event listener make sure
  • 00:16:53 to uncomment it and it will still close
  • 00:16:56 the modal of course but then I also want
  • 00:16:59 to call update paragraph and well store
  • 00:17:02 the editor quote if it is long enough
  • 00:17:05 now with that let's visit close modal
  • 00:17:09 and make sure that we not only remove
  • 00:17:11 the backdrop but although the modal and
  • 00:17:13 for that I'll add another if check check
  • 00:17:18 of the modal exists if it's not
  • 00:17:20 undefined and if that's the case I'll
  • 00:17:22 call remove on it and with that if we
  • 00:17:26 now reload the page click edit value'
  • 00:17:28 this loads it if I click the backdrop
  • 00:17:30 it's removed click it again it's loaded
  • 00:17:32 cancel remove CID confirm remove sit now
  • 00:17:36 let's edit it cancel does not accept the
  • 00:17:39 Edit confirm alls it doesn't and the
  • 00:17:44 reason for dad simply is that in my
  • 00:17:47 event listener on the confirm button I'm
  • 00:17:49 getting the edited quote here this is
  • 00:17:53 what I assigned to quote now edited
  • 00:17:56 quote is also what I change here in the
  • 00:18:01 text edit area but there I'm getting the
  • 00:18:03 value of TextEdit which does not exist
  • 00:18:05 anymore I renamed this to text edit area
  • 00:18:08 so let's fix this here tiny mistake from
  • 00:18:11 my side and with dad if we now reload
  • 00:18:13 should still be able to edit this and
  • 00:18:16 cancel and not take to change but if I
  • 00:18:18 edit it and click confirm this is all's
  • 00:18:22 use there so now we're handling this
  • 00:18:24 modal entirely through JavaScript we
  • 00:18:27 don't do anything in HTML we create and
  • 00:18:30 remove the modal in JavaScript you can't
  • 00:18:32 optimize this code you write this more
  • 00:18:34 elegantly but in general this is the
  • 00:18:36 work you have to do if you want to
  • 00:18:38 create it entirely in JavaScript and
  • 00:18:40 this gives you an idea of why using some
  • 00:18:44 libraries like react or frameworks like
  • 00:18:46 you and angular could be a good idea
  • 00:18:48 because this still is a relatively
  • 00:18:50 simple thing
  • 00:18:51 it's not a super complex one so I hope
  • 00:18:55 this was helpful and helps you a bit
  • 00:18:57 with understanding how to do such things
  • 00:18:59 with vanilla JavaScript which of course
  • 00:19:01 is fine if you like that if you don't
  • 00:19:04 have more complex requirements this is
  • 00:19:06 certainly less to load for your users
  • 00:19:09 then if you pull in an entire framework
  • 00:19:12 but of course you also see the potential
  • 00:19:15 pitfalls or disadvantage is off that so
  • 00:19:18 I hope you like this video let me know
  • 00:19:19 what you think about it in the comment
  • 00:19:21 section subscribe to the channel if you
  • 00:19:23 want to see more and hopefully see you
  • 00:19:25 in future videos bye