[MUSIC] In this lecture we will discuss building the subject page tabs and languaging a parent child controller interaction in order to do this. As we get started with this tabs lecture, you'll notice in the baseline that we have a subjects page that has several placeholders for components that we're going to be placing on the page. These components are being expressed by just placeholder dibs, and placed inside fo HTML element tabs. That have no behavior at this point, because we have not yet defined any kind of component, or directive to back them. All right, to get started, we really don't need all our tab groups. So, what I'm going to do is delete everything, I think, but the first tab group. So, that leaves us with a much simpler page. So, the next thing I want to do is create my tabs component. And to be able to manage the information that appears within the open, and close tag. Within the layout, we are going to create a new folder of tabs. And I'll create a tabs component, and to go with the tabs component I need to create a tab HTML file. And before I forget I need to register with our app config. And also while we're doing logistics. Lets include our new tabs component in the job the script manifest. Okay, so back at the tabs HTML I'm just going to do something really simple. I'm just going to display Div. That has a class of tabs pane. So, when I define my SD tabs, and someone declares it. This controller will get instantiated, and the page will get displayed. But that's pretty much it. So, now, when I do a refresh, we fix one more place for tabs template, okay. So, now, when we hit refresh, our place holders go away. The only thing we have to show for is our tabs pane. That isn't displaying anything. What we would like Is all this information that's inside the tabs pane to show up, and just leave tabs to managing it, okay? In order to do that, we need to bring in the concept of a transclude. We definine the transclude in the HTML file, like whatever appears inside the element, place it here. And it's going to be inside of this div. And in the components we need to declare it as well. So, now, we refresh our component place holders are again shown and that's, because that tab's pane now has a transclude define that says, whatever inside of me, put inside of me. Okay, we'll just demonstrate the very simplistic use of transclude. There's a whole lot more we need to do. We're going to be going through this really slow to make sure we make a point as to what constructs are serving what purpose. The next thing we want are these tabs to come alive, to actually be registered within the tabs component. So, in order to do that, the minimum that we have to do is declare a new component. Of tab, tab, tab, and right now we don't yet need a URL we will, and of course we don't have HTML, we don't need transcript. Let's declare controller for our tab, let's declare a place to remember all the tabs that we have In the tabs controller, and also within the tabs controller let's define a method to be able to add a tab to that collection. Let's just add it to the prototype since we won't be calling it from the HTML page. We'll just be calling it from the other controller. Now, really important point. How does the tab controller get a reference to it's tabs controller, it's parent? We make that controller available by adding a require statement. To our SD tab. Looking for the component in one of our parents of SD tabs, and calling whatever its controller is, the tabs controller and having the injected into our controller. And a documentation states that carrot carrot means look into our parent, and tabs is the parent of tab, okay, well, that should work. A single carrot could have been used if there are multiple controllers hanging off of the same element. Now, what's also important is the documentation says we can't just make a call here, when we enter the function, we need to wait until our dollar on in it to be able to make that call. All right, so now when I do a refresh, and I look into the tab controller. It does have a tabs controller, its parent, and that controller, its parent. Has two tabs, okay?, we're getting somewhere. Now, back at our tabs HTML, I want to do something with that list of tabs. So, let's use an un-numbered list to do something with it. And this un-numbered list is going to take advantage of some bootstrap styling that's going to make it look like tabs. And this role property is part of HTML5 for assisted technologies. It helps HTML readers to know why are we having this unnumbered list. Now, that's going to be for, building a tab list. So, within our numbered list we're going to create some list items. And we'll populate them via the tabs list array that's in our controller. And within each list item, let's go ahead and create an anchor tag, let's give it a role of being a tab and then, of course, let's have it display something, some text, a tab label. Well, that will get us going some, but you'll see a problem here. We now have these tabs up here, but they don't say anything. That's, because we have not assigned a value to label. Well, wait a minute, you say, didn't I say label equals things? Label = Images, but we didn't declare that in the component. Well, that's easy to fix. So, let's come back into our component, uncomment bindings and add label. This is a one way binding for, string-like properties. Value. Just expect to read these things. Now, when hit refresh, okay, starting to look like tabs here. We are getting somewhere. All right, but now let's see if we can improve this concept and make one of the tabs know that they are the current tab. And they should come to the forefront. So, lets extend our HTML page as some kind of concept of active. That if the tab says it's selected, let's add the class active to the list item. It should do something special, like highlighting that particular pill, and keep it highlighted, even as we move our mouse away. And so, we need to have a callback for when we click on the tab, to be able to make these annotations. We could set selected here, but we need to deselect the other tabs. So, in our tabs controller, in the tabs component we want to register our call back of select tab. And go ahead and define it in the body of the controller. And as I said, we want reset set the false all the other tabs. And only set the selected one to be true. And then, by default, let's make it a standard that within order, it's the zero with one that's always active. So, whosoever put in first, they are selected true. If we hit refresh at this point, things thinks he's active. And now if we click on images, it thinks it's active. If we open up the tab controller, we'll see that things says, false. And Images say, true, okay? But what we do? Even now if we're selecting a particular tab, we 'll still seeing the body show up here. We need to make our tab a bit more intelligent, so that it only displays the contents of the component. The lower area if it is the current tab. All right, one thing we might be able to do is put an NG high, or show in the subjects page, that might react to something telling it that this tab is hidden or shown. But we can encapsulate this much better in the tabs component. Over in the tabs folder I'm going to add a new HTML file, tab HTML. And whatever I pass in, in the tab element. Here comes ng-transclude again. It's going to show up here, but conditionally. Only if the controller says it's selected. Okay, all right, this is a nice decorator around some HTML that we're passing in, and soon to be a more robust component at some point. Just whatever it is, it's going to have this extra logic applied. Starting to see the power of transclude? So, let me register the tab_html without config, come back in to tab component, and register a template for the tab. We'll call this tab templateURL. It too has transclude. Tabs has no bindings that I know of. And then we just need to doctor this one up, with inject. Okay, if we come back out refresh our page, notice we only have one component showing up, and when we click on images we see the images component. And not the things. Things and not the image. Image and not the thing. Now, we're cooking with gas. This is now starting to work the way you think tabs should, right? And now, if we come back in to our subjects page, and bring back our full tab definition, hit refresh. We'll see our three areas. With independent tabs. Minus a bit of styling tabs are functional. In summary, we build a set of parent and child components namely that are tabs and tab components. With tabs component being the parent is the overall manager of all over tabs, and able to accept content for those tabs. Using ng-transclude. It managed the overall interaction with tabs with selecting and de-selecting. Using the list that was populated when the child component was instantiated. And it displayed a tab bar at the very top of the area that was styled with bootstrap classes that allowed us to select the individual tab. The job of the child tab component was initially to just register with the tab, and was able to locate the parent controller using the require injection. The child component also identified the identity of the tab, using a data binding that allowed the label to be passed in from the HTML page. And then lastly the child component would apply a decorator to the business component that would leverage ng-show, or hide based upon whether the tab was selected. So, we would only get one component showing in the overall tabs area. What's next? Subject page areas. We've shown how to divide individual page areas into tabs. Now, we would like to divide the overall page into areas with behavior like hide and expand.