This week on our "Kendo UI DevChat" series on web development, we built dashboards with Angular and Bootstrap 4. If you missed it, check out the replay as we answer questions we couldn't get to live.
The fun never ends with the Kendo UI DevChat webinar series! This time we covered how to build responsive dashboards with Angular and Bootstrap 4. The session was jam-packed with content and we had a very active group of attendees! As promised during the webinar I wanted to follow-up with the recording, sample project, some helpful links, and of course an extended Q&A section!
If you were unable to join in or if you want to watch the webinar for a second, third, fourth, maybe or even fifth time (😉) then you can find the recording on our YouTube channel.
You can also find the completed GitHub project right here.
As mentioned I wanted to add in a few resources for everyone to read to understand more about the changes in Bootstrap for v4. Here's a quick list that should help you get up to speed pretty quickly.
Throughout the webinar we had quite a few questions come through about Bootstrap, Angular, and Kendo UI! So, I tried to organize the questions below to have them be grouped together a bit logically.
Isn't Bootstrap v4 still in alpha? How safe is it to use it in production-type projects?
Actually, as of the day after this webinar the beta of Bootstrap v4 was released! So, the team keeps on trucking with releasing new versions. Yes, Bootstrap v4 was in alpha 6 during the webinar, but with the recent switch to beta we are getting closer and closer to the actual release. According to this issue on Bootstrap's GitHub repo the team has stopped work on Bootstrap v3 in order to get Bootstrap v4 out there and this beta release continues the march towards the initial release.
Would it make sense to organise widgets/components in a subfolder of the "app" folder, or is there a preferred folder structure you've worked with?
For the sake of brevity during the webinar I was just adding in components and widgets in to the app folder, but making sub-folders are definitely a good idea. I recommend looking at the official Angular styleguide for help on how to structure applications.
What is the unit of width? Is it number of pixel?
The main CSS unit has switched from px (used in v3 and lower) to rem. So, whenever we talk about a unit of measurement we are referring to rem. If you're interested in what rem is versus em, something you may be more familiar with, then I recommend reading this blog post. Also, for more information on what is new you can refer to the Bootstrap v4 migration guide.
What is "my-3" that you add on your classes?
So, with Bootstrap the team has set up some spacing utilities that one can use on any Bootstrap element (and it should work with other elements as well). This documentation section goes into more detail, but what "my-3" specifically does is apply a margin (hence the "m") on the y-axis (adding in "y") and we're using "3" here which is tied to the $spacer variable (not "3 units" as I mentioned in the webinar - my bad!).
Is Bootstrap v4 backward compatible?
While there are many familiar aspects of Bootstrap v4 compared to other versions, due to this being a major rewrite of the project I wouldn't call it a safe backwards compatibility. There are things like browser support (IE10+ and iOS 7+ for Bootstrap v4) and other items that add to this as well, not just new conventions. So, for now I would treat this as something that needs migration and rework in your projects. Luckily this Migrating to v4 document is helpful and continues to be updated to help with this process.
Is there a built in support for breadcrumb nav?
Yes indeed! This Bootstrap component called "Breadcrumb" should help with this requirement. You may need some more advanced routing set up in Angular, but the same idea of using routerLinks and routerLinkActive should work with this component as well.
What is the main advantage to migrate from Bootstrap 3.x.x to Bootstrap v4?
I discussed this a bit during the webinar as well, but overall I think the main advantage of upgrading to Bootstrap v4 is to keep up with the latest and greatest. Under the hood you have things like dropping support for older browsers (read: getting rid of superfluous code) and using newer CSS features (generally performance and productivity enhancers), but also streamlining features like the new Card (replacing many components from Boostrap v3). You also get to start using Sass rather than Less, which is where the CSS community is trending.
Could you show the Kendo UI Charts integraded as widget?
You're in luck! The GitHub project actually has a chart added, I just didn't have time during the webinar. Download it and try it out!
Is media attribute for the Grid available with the Kendo UI Default theme?
Yes indeed it is! However, when you're not working with the Bootstrap theme (which I was using in the webinar) you have to work with the matchMedia browser API like we do in this sample. The benefit of working with our Bootstrap theme is that you can use the breakpoint conventions from Bootstrap. The good news is that if you don't want to stick with the same set of colors as we offer out-of-the-box you can use our Sass Theme Builder to customize the Bootstrap theme colors with ease!
Is Kendo UI using only Bootstrap's CSS rules or does it carry its own?
With the Bootstrap theme we tend to use Bootstrap's CSS rules, but of course one can tweak and customize this from both a Bootstrap and Kendo UI point of view. If you're using the Default theme then you could also work with the matchMedia setting like I mentioned above.
Why do you set height like [height]="410" instead of height="410"?
So, setting the height like height="410" will work just fine as well. However, when you start doing down routes like binding this to an object or anything but a static height like this you'll have to start using [height]="x", so I tend to just stay on the safe side and work with the brackets here.
Is there a "fluid" component that will allow the grid to resize vertically as the windows resizes vertically?
This is a bit trickier than dealing with the width. While I do not have a great sample of this using Angular, we do touch upon the topic and how it can be addressed in this documentation article for the jQuery and AngularJS (1.x.x) version of the Kendo UI Grid. The tl;dr is that it's not as easy as setting a height of the Grid as a percentage due to how the web requires elements to work. I recommend reading the article I just linked to get a deeper understanding of how this can be implemented.
Prefer to read a transcript than watch the video? We have you covered. Check out the full transcript below:
00:04 Carl Bergenhem: Hello, everybody. This is your webinar host here, just making sure that we have a couple more minutes, well, about one minute before we're officially starting. But people tend to roll in a little bit afterwards, so I'll give them about a minute or so before we go ahead and kick things off. But this is about the volume that I'm going to have throughout the webinar. So adjust your headsets or headphones or whatever it is that you're listening to, speakers, maybe you're in a movie theatre even watching this, and we'll be able to kick things off in just a couple of minutes.
01:14 CB: Lots of people are pouring in here right at the start of the hour. I'm going to just wait a minute or so before I go ahead and kick things off. We do have a pretty full schedule. I'm gonna try to make sure that I can fit everything into the webinar here today that I planned but just to give everybody the same kind of start, let's go ahead and wait just a minute or so before we go ahead and get things started.
02:01 CB: Alright, that is that minute that I've been talking about, so let's go ahead and kick things off. So welcome everybody to the fourth installment of the Kendo UI DevChat, where we're going to be talking about building responsive dashboards with Angular and Bootstrap 4, so very exciting topic. Hopefully, I'll be able to teach you guys some things about both Angular and Bootstrap, especially if you haven't taken a look at the latest version of Bootstrap with v4. But just, before I go ahead and kick things off, just as a quick little introduction so you know who is talking to you throughout this webinar. My name is Carl Bergenhem and I am the Kendo UI Product Manager. And I wanted to take the time today, of course, to not only share some love about Bootstrap and Angular, but also here and there maybe chitchat a little bit about Kendo UI and where that fits in. But you can find me on Twitter tweeting @carlbergenhem. And for everybody that's already asking, probably, you can feel assured that we will be recording this webinar, we'll be posting it on YouTube so you'll be able to go ahead and view that in your leisure afterwards. Also, I'll be posting a follow up blog post, answering questions, etcetera, and providing some internal links, so feel free to watch out for that. We'll have both in the Telerik Blogs and I'll, of course, tweet about it, as well.
03:17 CB: But that's really it. I always promise with these things that I want to go ahead and jump into the actual presentation as quickly as possible, so we'll go ahead and do so. Now, one thing that I do want to mention before I start slinging too much code is that, I think that after this, the best thing for you to do, if you're interested in Bootstrap, if you haven't taken a look at Bootstrap v4 yet, is to check out the online documentation that they have. So, just Google Bootstrap v4 and this page will pop up. You'll see here they have the v4 alpha prefix here. And they have done a great job with not only, of course, the getting started experience for how you can include it, added with the CDN or through installing it with npm, but they also dive well into, not only the layout but also the various components that they have to offer. So, what I'm talking about here today is just the tip of the iceberg. This will allow you to be able to really dive into things quite a bit more.
04:16 CB: Now that being said, let me go ahead and bring up two things on the main screen here. And these are going to be the two main views that you have today as we go ahead and code through this application. And now, as you can see on the left hand side, this is just a regular Angular Bootstrap application that I have through the CLI. And I've done a couple of quick modifications to it, that I'll go through in a second. But before I do that, I just want to do a quick highlight of a couple of things we will be covering today, and also, just what's new in Bootstrap v4, and this is the quick version. There are a lot of resources out there, and I'll be adding that to the blog post as a follow up, that covers specifically what's new. But just as a quick highlight, Sass is being used instead of LESS, the panel thumbnail and well classes are now removed and the card replaces them. So we'll be talking about that today quite a bit. They now are using flexbox by default. The font size has gone up from 14 to 16 pixels, I know that's a huge deal, and instead of working with pixels as their main unit of measure, except for media queries and things like that, they're now using REM. That's a quick little digest there. But as I mentioned, there's a lot of other things that's new, of course, you can cover either in a follow up blog post or, of course, diving into the source code and diving into the documentation that they have on the official Bootstrap page.
07:03 CB: Now one thing that you'll notice is that when I actually work with the angular-cli.json, if I inspect these elements here and I pop over into the elements tag, we'll see or tab I should say, we'll see here that Bootstrap actually gets included on the page. And this is very similar to how things get... You can set this up to include all your own styles as well because they do also include styles.css, which right now is empty, but if I scroll down, we'll see here that that's also added here at the top. So this just gives us a quick and easy way to include Bootstrap on the page and already these fonts are looking pretty and, of course, that gives us some flexibility of using all the Bootstrap features just right out of the gate.
07:49 CB: So, just go ahead and actually start off somewhere. So in my "app.component.html", and I'm just going to start there for now, I don't want to have anything that we have here. I want to think about what I would do in a scenario where I want to be able to build up some sort of dashboard, because that's kind of what we're talking about today. The first thing that I want to be able to do of course is, I probably want some sort of navigation at the top of my page because that tends to be what a lot of folks do in the dashboard applications and this can simply be done by including a nav element which of course is nice from the semantics point of view, but we'll just give that a class of nav and then for each element, so if I want to do an anchor, we can do a class of navlink and then we'll just do... Let's do an href just for best practices. So we can do that. And if I save this, we'll go ahead and refresh the application on the left and we'll see now that we have a link up here. I can continue to do this if I wanted to throughout the application. So if I throw in three of these links, we'll see this refreshes and we have something at the top here and we can see that it already kind of falls just from left to right with some padding and margins and everything like that, which is nice.
09:15 CB: Now I do see as we're going through here, by the way, that people are asking questions and I should have mentioned in the beginning that I'll have a dedicated Q&A session at the end and we'll be able to walk through things and answer some of the questions there. Now you can do things in here, like for example also adding active and we can setup disabled if we want to. And now we can see that we have this disabled area and the active one doesn't necessarily look any different right now, but that's just based on the quick and simple navigation that we have here. So I could continue with this if I wanted to; however, I do want to maybe make this a little bit more advanced because I don't just want to have a navbar like this that's a white on white. I want to be able to dive a little bit deeper into that and what I can do is if I just go back to this navbar here, instead of doing nav, I can actually call it a navbar in the class and then we have a couple of quick things that we need to add in order to be able to get a full navigation bar at the top there.
10:21 CB: We do navbar, toggleable which is a mouthful, md, and I'll go into a little bit of what that means in a bit, I'll do bg-primary and then navbar-inverse. So if I go ahead and save that, we'll see that the application changes a little bit here, but we just get a blue bar at the top here. And if I add some additional pieces in here, so I'll just add a blank div for now. I'll go into why in a second. I'll work with an unordered list for this, navbar nav. So that gives us an indication on what classes to use for the unordered list to give it a full navbar kind of feel. Then we'll do an LI with a class of nav-item, one.LI right here, and then we'll do another anchor element here and we'll do, I'll just say Bootstrap for this one. Alright. So if I save this, we'll see now that the application should refresh for us. Of course, I could have also messed up some code here, which I did. That's the beauty of live coding. So let me just quickly snag the code that I have saved over here in a snippet which really is what we're building towards anyways, where I just added this anchor element and then [11:54] ____ two more tabs, Bootstrap, widgets and about.
11:57 CB: What we'll see now is that this menu, first of all, looks a little bit prettier than what I had before. It gives us a solid background. If I don't have a smaller screen as I do here, I will see that the menu is laid out nicely for us here. But if I go ahead and make the small there, we'll see that it kind of automatically... There's some sort of response in this, it listed from top to bottom. Not necessarily ideal for where I want to be, but it still gives us something. Now just to mention what we have here. So navbar-toggleable-md, this is just something that's required to setup and say okay, I want this navigation bar to be something that we can toggle in order to be able to work with responsiveness and have maybe an item that allows me to open and close the menu. Bg-primary actually works with navbar-inverse. So by default, Bootstrap v4, everything is kind of a light gray kind of a theme on the background, you've probably seen that in a lot of Bootstrap application, and navbar-inverse is just for dark backgrounds so black, blue in this case or anything that might require white text on top. And bg-primary, this is just for background colors and primary just ends up being this nice blue color, so that's what I've added in here.
13:12 CB: Now, if we wanted to be able to take this one step further and actually instead of having this kind of menu when we have a smaller screen [13:21] ____ of real estate and we want to actually be able to have something that can toggle, what we can do is we can first of all, take this div right here that I add in and we'll do "class=navbar-collapse" and then collapse. So this might be a little bit confusing, but I'll explain this in a bit and then I'll just call this "mynavbar". There we go. So if I refresh this now, we'll see that the menu actually disappears and goes back to this little thin piece and that's because when we have "navbar-collapse" collapse like this, that just means that this is the element that will... The parent element and everything inside of it will disappear after we've gone ahead and actually hit this md, the medium break point that we have within Bootstrap. So if I want to have something that's responsible for toggling this, I can add in a button, give it a class.
14:14 CB: So we see a lot of classes here right. "Navbar toggler" and we do "navbartogglerright". So that just means it appears on the right-hand side and then I'll define this as type button. And I'll go ahead and also add in a span, give that class of navbar toggler icon, which simply just adds an icon that looks like a hamburger menu. The last thing that I'll do here within the button is I'll actually go through and do a "datatoggle=collapse", and then "datatarget=" and I'll give this the ID that I have down here so "#mynavbar". So this is just required to ensure that when we click on the button, something happens and the menu opens and closes. Now you probably can't see this because it's kinda tiny right now and you can see that this kinda doesn't cover it, but there is a little menu icon here for a Hamburger menu that we can open and close. Not necessarily constantly there, so what I want to do is there's a couple different ways that we can fix this, but what I like to do is there's also the idea of what we call a brand so we can just add a href, there's that class=navbar-brand, and navbar, there we go.
15:44 CB: And then we'll just call this a Bootstrap webinar. Alright, go ahead and save that. So now, we'll see that we get a full menu here that pops open. And we have the Bootstrap webinar. So this can be a logo, this can be of course the name of the application, whatever might this be. Dashboards usually have some sort of branding. Dashboards usually have some sort of indication of who made it or something fun that you named it internally, and we now have this whole toggle [16:10] ____ looking up. Alright, perfect. So now that we have the navbar, let's go ahead and add in some of the Bootstrap elements that we want to be able to work with. So let's just go here and I'll make this a little bit smaller again. So under my navigation here, I'll just do div of class=container-fluid. And container-fluid, there's supposed to container and container-fluid. Container, what that will do is it'll have a fixed width for all the various sizes that we have within Bootstrap, so extra small, small, medium, large and now they have also extra large available to us. So that actually has some fixed width assigned to it.
16:57 CB: Container-fluid allows us to be able to take up the entire width and everything that's available to us. Add in a row so this is all very, something that you're probably used to quite a bit now already within Bootstrap. I'll add a column to it. And now I want to be able to start introducing the card class we were talking about or component, I should say. I'll give this a class of card and then within this, I'll do another div, I'll say card watch. Alright, and then awesome text is awesome. Alright, go ahead and save that. And we'll now see that this refreshes and we get this little block of text that picks up essentially the entire width that we provided to it and gives us a little bit of an indication of an area that it's isolated and had some sort of structure around it.
17:55 CB: Now, the next thing that we might want to do is maybe just let's add another block in here. And so, what I can do is, I can add another column for us. And then, just for the sake of time, what I'm going to do here is that I am going to throw in the HTML here from something that I have saved already. Go ahead and just refresh this and we'll see now that we get another kind of... Not necessarily a panel; this is, again, the card that's looking to replace the panel, and the thumbnail and everything like that. But we have these concepts now of working with the card title, we have card subtitle. You can also even throw in text-muted, so it gives this nice little gray feeling to it. And these are all, just again, to replace some of those features that you might've seen in Bootstrap v3 and started to use already. So everything just falls into this card block area.
19:05 CB: Now, of course, this right now we don't have any padding for the top of the row or anything like that. So it can start looking a little bit weird. So what I want to do, is I want to throw in a "my-3". And what "my-3" does for the row, is it actually adds some margin into this row that we have here. So the M here stands for margin, Y stands for the y-axis, and then "-3", that's just the size, how many units that we want to be able to provide of space. So this can actually be tackled on to just about any container within a component within Bootstrap, which is pretty nice, but we can, of course, also still work with the traditional things that we have within Bootstrap. So we can set this to an "sm-3". And then we can do, set the column to an sm, for example, five if we wanted to.
20:00 CB: Now, the last thing that I wanted to cover within cards, and I'll throw in a full column here for us, again, just for the sake of time. I want to make sure that we can get through everything that I covered today. And when I refresh the application, we can now see that... Let me actually expand this a little bit because I haven't set up anything with the button, we have a card now that has a header, that gives us a unique little header to work with with this particular content area. We can still work with titles, we can add in subtitles, we can have links, we can have buttons, we can have just about anything in here. If we did a little bit more of styling on the button, we can also make sure that it works when it's a little bit smaller like this on the screen, of course. But for this particular case, the main idea really is to give you an idea of what these cards look like. And these are some of the most common scenarios that I've seen of our clients working with Bootstrap v3. And I just wanted to give you an indication of, "Okay, what can I do instead of the panel, or what can I do instead of some of these other components that we've already been working with."
21:12 CB: Alright. So now we have some Bootstrap elements to work with in the application, but honestly, we have a menu that doesn't really do anything. So I want to go ahead and add some routing into my application. So now we're going to be spending a little bit more time within the actual Angular project here. So let me expand this, and give us access to all of the things we have here within my actual Angular project. So let me open up the application here, go into "app.module.ts". And we'll see that I went ahead and I went with the router module and the routes, I've already included those, and that comes from at Angular router so you can start using that within the application.
23:00 CB: Now, if I want to be able to set up some basic routes, let's say I wanted to be able to add in and isolate these widgets that I have over here in a new component, I can go ahead and just have some variable that I can define to be my routes. Every dashboard needs to have some sort of navigation. And then for each one of these routes that I want to be able to define, I can set up a path. I can just call this Bootstrap. And for some reason, I always write Bootstrap, so I'm glad that it actually writes out Bootstrap this time. Alright, component, and we can pass in, for now, Bootstrap component. Now, Angular's gonna yell at us for this, because we do not have an official Bootstrap component. So we can go ahead and add that. But before I do that, the way that I can assure that these routes will later work is if I go ahead...
23:03 CB: Oh! Let's see here. Can everybody still hear me? I believe you still can. Perfect, perfect. Alright, something just happened on the audio on my side, so I wanted to make sure that everybody can go ahead and still hear me. Oh, it seems like we might have actually lost some sound, so let me just go ahead and double check that I am indeed still logged in. Alright, perfect. A lot of you are now saying we can hear you. Alright, sorry about that folks. I just saw some complaints about losing audio and I heard some weird glitch on my side, so sorry about that.
23:45 CB: Anyways, Angular's complaining, right? We don't have this Bootstrap component yet, but before I go ahead and do anything else, I want to remember that in my import statement, I'll throw in the router module, do a four route. And then I'll pass in this app roots right here. Alright, go ahead and hit save. Still going to yell at us though. So let's go ahead and quickly add in the Bootstrap component. So I'll just go ahead into my app folder and do "bootstrap.component.html" first and then I'll also do new file of "bootstrap.component". That's a yes. See, here we go, I already started calling things bootstrap so let me just make sure that's correct. Alright. And, of course, just to give us some quick component bootstrapping, again, I'll be using that word a lot. Not just in the sense of [chuckle] bootstrap the framework but also of course what we're doing in here. I'll jump over to "app.modules" and then here, of course, I'll go ahead and import this from "bootstrap.component" and I'll also throw this in here. There we go. So it'll stop yelling at us, I believe. Yes, perfect. Alright. But now, of course, if you go to "/bootstrap," nothing will really happen because we haven't set this up quite yet and the bootstrap component currently is completely blank.
25:33 CB: So what I'll do is that I'll actually take everything that we have in here, except the navigation because we want to be able to keep that, go ahead and save that, pop over to my bootstrap component, save this here. And the last thing that we want to do is that we want to throw in what's called the router outlet. So this gives us a kind of the placeholder for where we want all the routing to be able to show up. So wherever you place this is where all the routing will show. So now we have the app, component has a navigation which helps the course and then we can just work with the router outlet and throw components in there. One thing that I also want to mention is right here on the "index.html" page, the page you have this base with an href and just a slash and this is required to just give the router an idea of where is the root of the application. Where does it start from. So that usually is actually already included if you use the Angular CLI, but that's just something to be aware when you start working with the Angular router that you need to include that. Alright, so now we see that when we go to "/bootstrap" we get this beautiful page and that's perfect.
26:49 CB: What I also want to do is, I want to go through and actually define a route that automatically goes to bootstrap when we just do a regular localhost and just a quick slash. And the way that we can do that is that we can define a route, give it a path of just something empty, and then we pass in a redirect to or define I should say, I'll do "/bootstrap" and then we'll do also what's called path match. I'll set that to [27:20] ____ full. So now this gives me the flexibility of when this application refreshes, when I go to localhost we'll automatically go to /bootstrap and bring up this page here. Alright. So that's pretty nice and easy, right? So now that we have that, let's add another widget. So what I'll go ahead and do is I'll do a new file here and I'll just call it actually "widgets.component.ts" and I'll throw in, of course, the HTML file so "widget.component.html". Okay, perfect. Now within that I'll go ahead and quickly go into my TS file here, I'll add just a quick bootstrapping of that widget, of course. And for now within this html here, I'm just gonna define an H1. I'll just say widgets. Alright. So now that we have that, let me just close down some of these other tabs here.
28:29 CB: I'll just actually close all tabs. I'll pop back in here into app.module. Import the widget we just made so Angular doesn't yell at us first. [chuckle] Maybe this time we can be a little bit ahead of the yelling game, right. So we'll import that from "./widgets.component". Perfect and then oh... It's still managed to yell at me because I forgot the dot. Alright, let's go ahead and also import that there in the declarations before I forget. And if we want to navigate to this now, what we can do is we can define another path or just say that this is going to be widgets and then we'll pass in a component. There we go. Let me just make sure that I spelled everything correctly. "Widgets.component.html" cannot be found. Interesting. Interesting. Let me just rename this. Hopefully that helps. There we go. Of course, that's the beauty of the live demo, right? Again, me sassing with things here and there.
29:55 CB: Alright. So if you go into that module we see here that we now have widgets. So if I do "/widgets", we'll see now that whoo! We get the H1. It says "widgets" and everybody's super-happy. Now that we have these two pages, what we notice though is that I can just navigate to them, of course, with the roots, but I can't navigate to it with these menu options that I have up here. Let's change that. Let's close these out, go into "app.component.html" and let's start tweaking things a little bit in here. What we can start doing is that these anchor elements that we have here, what we can say is that we can add attributes to them in order to be able to work with Angular. We have the concept of what's called the "router link", and as the name gives it away. This links to the router, or as a link for the router, that allows us to be able to take advantage of the Angular router. So I'll just do "/bootstrap" for this one, and then within this next one I'll do "routerlink=/widgets". I'll leave the third one alone for now. That's kind of more about the finished project that I have on GitHub.
31:16 CB: But let me go ahead and jump into the application here. And we'll now see that when I click on "widgets" we go to widgets, when I click on "bootstrap" we go to bootstrap. This gives me some flexibility around being able to take the router that I have, just add attributes to the HTML elements that are responsible for navigating back and forth, and all I need to do is throw in the router link. I don't really need to do anything else. We know that the router's there. Of course, this is... We don't necessarily have child routes or anything like that set up currently, but it's still super easy to just add this attribute into my existing HTML and work with Bootstrap to be able to set up that navigation. And one thing that I don't like about this is that I don't know which is my main... The currently selected item in my menu. I want to be able to see that a little bit. And luckily for us, we have something within Angular called "router link active", so let me say that: "router link active". Again, something we can just add to the element here. And I'll just pass in and say "active" and I'll copy and paste this. There we go.
32:31 CB: And let me now expand this a little bit more so we see that now, "widgets", when I navigate to "widgets", is actually highlighted here. And if I go to "bootstrap" we'll see now that that turns into this nice little white color. The reason that this works is that "router link active", that I have over here, what this allows me to do is just say, "Okay, when this router is active, so when this has been clicked, then apply this particular class to the element." Now what's nice about that is that we can just pass an "active" which is, first of all, pretty intuitive, but also is what we need from Angular in order to be able to add that class that exists already within Bootstrap onto these elements. By just adding "router link" and "router link active" into my navigation, I now have the full navbar from Bootstrap that also works alongside with the routing of Angular in order to be able to have this nice little navigation.
33:30 CB: I don't know about you guys, but I have spent a lot of time developing a lot of applications where I'm maintaining [33:36] ____ state, where I'm working with when I'm navigating to or from a component, and updating CSS here or there, or whatever it might be, doing a lot of passing of information back-and-forth. And to just be able to take the navigation bar, add two attributes to it, and just automatically work with what I've set up on the TypeScript side of things, that makes my life that much easier. And again, we're just taking advantage of Bootstrap and the nice-looking theme that we get from it. Okay, now what I want to be able to do quickly here now is that let's go ahead and actually add in some components onto the widget page. Dashboards need something a little bit extra. Now what I'm going to first do is I'm going add a new file, and I'm just going to call this "products.ts". And I'm going to pull in some data into here just in a bit. But within my "widgets.component", I can also go ahead and just import this.
34:47 CB: Products from... And I'll just do "./products". Alright, perfect. We'll see now that there's nothing in here; it's not a module or anything like that, and my handy-dandy copy and paste is actually missing. So just give me one second to actually pop that out for us here. And we still have some time, which is nice, so we don't have to worry too much about this adding on too much time.
35:34 CB: Alright, just let me go into "products.ts". There we go. This is just a local array that I'll be working with, just for the sake of having data within my application. Now we should see that the page refreshes. It should, at least. Alright, still not a module it says.
36:00 CB: Let me just double check what's going on here. Just for the sake of that. All right, let me, just actually behind the scenes here, do a quick renewal of "ng serve". Sometimes that kind of fails on us a little bit on the back end there. But while that's happening, I'm also going to update this and just say that I'll make a private variable here called "grid data". I'll eventually be using a grid so I'll do "any=products" so once Angular realizes that this is indeed a module that we can work with we'll be able to be off to the races here. So I'll just quickly take a look at a sample item here within "products.ts". Ah, there we go, it kicked things off. So we see that we have product ID, product name, we have some sub items, and everything like that. So it gives us a little bit of more real data that we can potentially work with and we have the grid... I called it gird data, grid data, there we go. We have that available within my widgets. But now if you go to the widgets page nothing really happens, so let me just make this a little bit smaller and actually fix that.
37:15 CB: So, when we pop over into the "widgets.component" here, I'll remove this H1 and actually start building some things out, so I'll do another div right, and we'll still work with Bootstrap, so we'll do "container-fluid-div". And then I'll do a row and I'll add that "my-3" because I just think that gives a nice enough little margin for us to get some space and make things look easy. Now I do want to just quickly throw in a couple of Kendo UI buttons in here, and you'll see why in a second. And for those of you that haven't worked with Kendo UI before in the Angular sense, we have Kendo UI for Angular, which are a set of native components for Angular that work in a very angular way and, of course, built from the ground up specifically for Angular. And all I'm doing now is I'm attaching [38:14] ____ Kendo button and on one of them I'm also defining the Kendo button here to be a primary, which gives me this nice little color, blue there. What I'm going to also do before I forget is give this a column as well, kind of forgot that.
38:33 CB: There we go. All right, perfect. Go ahead and save that. The reason that I did this is that I wanted to just give you an idea of... Of course we have buttons coming from Angular, so buttons may not be the most exciting piece of technology to add on to a page immediately, but we see here that just by adding the Kendo UI buttons onto the page and I've included the Kendo UI Bootstrap theme, so this actually integrates directly with Bootstrap v4, and we see that this font right here is already picked up by the components. We see this nice primary blue color is the exact same color that we have up here so when I did BG-Primary, right, that is the same link that we have here for these buttons. So if I went ahead and did a custom Bootstrap theme, for example, that I overwrote some of these colors or what primary might be. But that can also be picked up by the Kendo UI components, so we can kind of not have to worry about changing the color scheme in a bunch of different places thanks to the power of Sass, we can do that through variables and then there we go.
39:39 CB: We have a nice little compiled CSS file that has these styles for us. I could also start adding in, let's say, another widget, so if I wanted to throw in another row here, I'll do "my-3", I'll do another div, throw in another column, just for sake of consistency and then, we can start adding in things like what I want it to do here is just add a Kendo grid, we'll give it the "data=grid data". I'm going to give it a height as well, [40:19] ____, set that to 410. And if I do it "/Kendogrid" we'll be able to see what happens on that page over here. So now we get a full list, a grid that, yes, it kind of works and is responsive in a way but all the information is here, all the columns, everything that is defined within my product's object is available here.
40:46 CB: So I don't necessarily want to do that. Instead, what I can do then is define each column, one at a time, the one that I want to be able to include by just setting the field, that the equal to product id, give this a title and then I'll give this a width as well of 40. There we go. Right into your "/Kendogrid" column. So if I say this when I see that we have a single ID column here that takes up the entire width because we are within container-fluid so that's something that's nice about these components, especially something big as the grid. It can stretch and fit in with the parent container and because I set up to be fluid, we'll see that it takes up the entire width of the parent element. Now, I can continue to go through and do this for a couple of more fields, so I can do product name, and I can do, just say name here. We can also do, for example, "category.categoryname" so we can access items within fields and the subfields of those.
42:02 CB: And I can continue to do that for a couple different columns here so we'll see now that these get added. I am going to do a quick copy and paste job just for the sake of time, for what we have here and all that this does, is that it adds the same columns that I just had, however, what I also have is down here at the bottom, I have a discontinued field that actually uses an Angular template. So this is something that I just wanted to highlight from the grid's perspective that you can actually just use regular Angular templates within any one of the columns or a lot of places within Kendo UI components. Oh, and I definitely went back but now you can see here that we have a discontinued column that actually has an checkbox that we can work with that is bound to the data item that's [42:47] ____ passed, so the discontinued data item, whether that's true or false. However now, when we're all talking about responsive, right? When I go back and I make this smaller, we'll see here that we just [42:58] ____ this both horizontal and vertical scroll bar that we can work with.
43:04 CB: But this might not necessarily be what I want to do in the case of this Bootstrap Project. I want to actually be able to start using things from Bootstrap to define what gets displayed and what doesn't get displayed. And what you can do is within each individual column, you can actually define the media attribute and you can then pass in the sizes that we deal with on the Bootstrap side of things to be able to use those as the same break points within the column. So for example I can set up large here for media, for the product ID and then media here, for example, can be small. And we'll see now that the ID column isn't even there, the ID column doesn't appear until I hit the large breakpoint and we see how that pops in nice and easy there for us, at the same time, as the menu goes from being available to us to collapsing. So we're working, again, with bootstrap here and at any point in time I can just go through and do the same thing, for example, here. And if I do it for every single column... I want it to do in stock and maybe for this last one right here, why not just say no. Out with it when we're below large.
44:29 CB: We can now see that every single column is now driven by what's available from the media attribute here and then as it gets a little bit smaller, we'll see that we can also take advantage of wrapping or we get these scroll bars again. The height will remain the same because I did explicitly set a height but you could of course also have a little bit of variable height if you wanted too as well. But the reason that I wanted to throw this into the application is that every dashboard generally needs some sort of widget that displays data so the grid, we have charts and everything like that but it also works with responsiveness and this is extremely important just from the sake of what we were doing with Bootstrap throughout the webinar is that I'm not doing anything kind of magic-y or anything on a very specific Angular way in order to be able to modify bootstrap. Or I'm not doing anything within Angular to account for Bootstrap and on the Kendo UI side, I'm not doing anything for really either library that makes it feel the Kendo UI way. We're just taking things from Bootstrap, from Angular, just making it all the way that we approach development with the components and that's how we take things.
45:40 CB: Now, we've been here for about 45 minutes and I know that, "Hey maybe this isn't a full fledged dashboard application where we're passing a ton of information back and forth and it's updating live with the back end that I have available, but we did only have an hour and I wanted to take some time for some Q&A as well. But this gives you a good introduction to some of the changes that have happened within Bootstrap v4, it gives you an indication of how you can start working with Bootstrap v4 and Angular in a very easy way. You can just throw in Bootstrap into your application. If you add it to the "angular-cli.json" that already starts making things prettier and then you can start taking advantage of these various classes that we have available. We can see here how we have the new card system is set up to be able to replace almost everything that we've done with panel, thumbnail and wells. So card is kind of the end-all be-all within Bootstrap v4 and we've also seen how maybe some of the more advanced widgets out there can also integrate into your application pretty easily.
46:44 CB: And now, what I will say is that part of my follow-up blog post, I will also have the source code to what we walked through here with a couple more widgets and just with a couple more things added to it. So that will be posted on GitHub, so you can take advantage of that and be able to tinker around with it and, of course, it's hard to follow along here. But with that, I did want to go ahead and kick things over into the questions. So you guys have been asking a lot of questions, if you haven't already and if you don't know where you can see those questions, you'll be able to look on the right hand side or depending on where you put your go to meeting window or go to webinar, I should say, but we do have a little questions box there you can feel free to type away.
47:34 CB: So somebody asked if it would make sense to organize widgets in a sub folder of the app folder or if there's any better way than just throwing everything into the app folder. Yes, you can definitely throw it into sub folders and make it a little bit easier. If we look at my project right now, with the app folder open, this can kind of quickly become annoying to look through. So it definitely makes sense to create other folders and to be able to architect things that way. I'm just doing this just explicitly for time. It really is what it is. You can also take the routes for example and define that outside of "app.module.ts". In fact, I would encourage that, but trying to go through the scripts for today and then trying to make sure that we had enough time, some of those little bit of best practices here and there we had to take out. So, some people said that there were some audio issues. I've seen that and I apologize and a lot of you said, "Hey, I can hear you, it's great." So hopefully for the folks that had audio issues, we'll see that everything... It lines up by the end of recording or hopefully they fixed themselves as you were going through.
48:47 CB: I know that I paused for a second because I just wanted to make sure that if I was talking into nothing for a couple of minutes, that would be a very disappointing webinar for everybody here. But I think that the majority of you heard and were able to follow along so we'll see. There still is some delay here, again, I apologize for that. And I'm on a landline to try to help make things better, but we'll see here what kind of outcome we will get at the end of the webinar. Now someone asked what is the unit of width. Is it number of pixels? So when I was talking about a unit of width of the margin that I was setting within my columns and everything like that and within my rows, that's actually set to REM. So that is just the basic unit that they replaced from pixels, which it used to be in Bootstrap v3 and now we're working with REM units instead. So when I say that it was three units, it's just three REM units there.
50:00 CB: Now, also somebody asked, "Isn't Bootstrap 4 still in alpha? How safe is it to use in production type environments?" That's a great question. I could have highlighted that a little bit earlier as well, so I apologize for not mentioning that. Yes it is. It's currently in the 6th iteration of the alpha. But from my understanding, the Bootstrap team has stopped development on Bootstrap v3 so that means that Bootstrap 4 is going to be taking a lot more focus from the team and they can really dive into it and make sure that something can get released. I don't know anybody on the team. I just happen to use Bootstrap v4, but if it's ready for production-type projects? I personally think so specially if you have people that prefer to use Sass and if you want to start to kinda get ahead of things. It all depends, of course, but looking over the issues list that I see on GitHub and everything like that, it seems like it's at a fairly stable point. So I personally use it although I'm not necessarily writing banking apps or apps that a ton of users might be using, but at the same time I feel it's probably ready to start using.
51:09 CB: And I'm trying to also get to the Bootstrap kind of questions here before I jump into specifically some kind of UI questions. What are the main advantages of migrating from Bootstrap 3 to Bootstrap 4? I think that really with the fact that Bootstrap picked up Sass as their main way of developing within CSS, I think that allows us to see the writing on the wall. And actually one of my colleagues wrote about this in a blog post and it means that Sass won the war, so to speak, that existed between LESS and Sass. So from my perspective although I'm not a designer and I don't necessarily work with a ton of CSS all the time, but for me, it's just ensuring okay, I'm on the latest and greatest technology and I'm working with Sass rather than LESS. I've worked with a lot of LESS in my time, especially because the original themes for the JQuery edition of Kendo UI is based on LESS so I've done a lot of that. But now Sass is the favorite technology there.
52:19 CB: On top of that, they have done a ton of improvements and I think reducing things down, for example, having that card element and not having well, panel and everything else that contain items, I think that's an important piece to streamline that a little bit and not necessarily have a ton of different other classes that are out there.
52:46 CB: Now some folks are asking if Bootstrap v4 is backwards compatible. A lot of what we saw within the classes there, so the rows and the columns, that's fairly consistent with what you already have within Bootstrap v3. So the break points for example, all the same. They only big difference is that they now have extra large. I think it might just be Excel. Off the top of my head I just forget now for the Q&A here. But, so you can in terms of the overall layout, there should be a lot of similarities, but they don't contain the same classes, again, for streamlining. So you would have to do some modifications of your classes that you've used, especially if you're using panel and well and everything like that. I haven't seen or read too many things about this specific migration path unfortunately, but I'll see if I can find something and maybe link to that in the follow-up blog post.
53:49 CB: Alright, then we have a couple different questions around the Kendo UI widget. So I'll just answer those quickly. First of all, yes, I did include the Kendo UI libraries ahead of time. I said that in the beginning that I cheated a little bit and I've done a couple of npm installs just for the sake of, first of all, trying and download things from npm live could potentially be a bad idea. I didn't want everybody to sit here and wait for that. And I just included the Kendo UI widgets and made sure that if I had the time, I could go through and add them into the widgets page. Now, there's a lot of other questions, for example, "Does Kendo UI need its own specific responsive code in order to be able to work with Bootstrap?" And the answer really is no. What you've seen when I've been moving the screen around, or resizing the browser, I should say. And as I added the media tags and everything like that, it just works with whatever the constraints are by the parent elements. So the grid doesn't need an extra CSS specifically implemented by you, the buttons or anything like that, they don't need that. It's all just available for you to be able to use, just to drop it in. So very easy to be able to work without necessarily having to work with a lot of custom CSS on your side.
55:21 CB: Oh yeah. Some people are asking why I set a height to the grid. And honestly, it's just for some consistency, so I don't have to scroll through all the data in the browser. If I didn't set the height, all the items would just be displayed without implementing paging, so I [55:36] ____ to a pager here. It just gives me an easy way to be able to constrain all the items, so we can scroll through them if need be. But you don't need to set a height. You can feel free to leave it without a height. The reason also that you might want to do something like that is, later, I could, for example, forego the height but then have a pager and then have five or 10 items are displayed at once. There's some flexibility there. I just did that for the demo sake.
56:09 CB: A lot of you very recently asked the source code. Yes, I will include the source code. It's all gonna be on GitHub, should be easy to install. You just need the angular-cli, you need Node installed, and that's really it. Then you can just go ahead and do a quick npm install, and you'll be off to the races. So, I'll include that. And there's a couple of other specific questions. But what I'll do here folks is that I'll take everything that I have here in terms of questions, even the ones that I just answered. I'll write out some answers too in that follow-up blogpost. I'll include a couple more links, so you can do some more research into Bootstrap v4. And also, of course, we'll have a recording of this session, so if you want to take your time and walk through it, and pause and see what I'm doing, etcetera.
56:56 CB: I know I did a couple of copy and paste jobs here to cut down on time, but hopefully it wasn't too confusing to follow. So, everybody has been very attentive, I see that most of you have stuck around, actually, this entire time. So I appreciate that. But we have about... I can give you four minutes, or if I continue to ramble maybe me three minutes back of your day. So I appreciate your time today folks. And feel free to look out on the blogs at Telerik.com as well as following me on @carlbergenhem. And I'll be able to post as soon as the blogpost is up and running. So catch me on some tweeting there. Alright everybody, have a good rest of your day. And I appreciate you joining the webinar. Bye-bye.