FREELessons: 17Length: 2.7 hours

Next lesson playing in 5 seconds

  • Overview
  • Transcript

2.5 New Field Directive: The Directive

Now that we have created the template for our new field directive, we're to go ahead and write the directives JavaScript code. So, we'll open up our public/source/directives.js file, and right down at the bottom, let's go ahead and add a new directive. And we'll call this directive newField. This function here will need to take two parameters. We'll start with $filter, which is a way for us to access angular filters from within our JavaScript code instead of from within our HTML templates. And the other thing, of course, is the fieldTypes, which is this object that we have created up above. As with our other directive, we will return an object here. And let's see. We start with restrict, which is an element or an attribute. We want to give it a templateUrl, and that is gonna be views/new-field.html. We want to set replace to true. And then, we have the scope, just like in our previous directive. The scope will set the record equal to the equals sign, which means it's two-way binding. And we will set live equal to our one-way text binding. And the next property, we're gonna add is one we have not used previously, and that is require. And we're gonna require carrot form. Now the reason we're gonna do this is because we need access to a form value and a carat means its value is a parent of our directive here. So where we created a directive here in new form, we have new fields here and as a parent of it, we have this form element. So, basically, we're getting access to this form element. And the reason we need access to this form element. And so, if we look at new field here, we're creating a new form inside of it, ng form. And we're giving it an actual name this time instead of name inside of curly braces, we're actually calling it new field. To be able to check if this new field form is valid, we need access to our parent form here. Because the way this directive will do it is basically what'll say form.newField. So, when we use an NG form, it basically becomes a child form of the form that is above it. And since this form is entirely different, it's not one of our form fields here, where it is all related to the new contact form. It's kind of something separate that we're just using temporarily and we'll just dispose of when we add this new field to our new contact form here. We need to do it this way. So we require the form like that. And then, in our link function here, where we get our $Scope, and our element, and our attributes, we also get that form as an extra parameter there. We'll start as we did in the previous one, $scope.types = fieldTypes. Recall that's being used down here where we show the user a list of types. Next, we wanna set $scope.field equal to an empty object. Remember, this is used to catch the and the field.value. And also, the field.type, which we'll set in just a second here. Because remember, when the user clicks one of those types in the drop down menu, we have to call the shelf method. So let's go ahead and write that method next. We have $ equals a function that takes a type as it parameter, $scope.field.type equals this type, and then we can set $scope.display equal to true, and when the set, and when display is set equal to true, this div up here with the input elements for the and the field.value will show. Because notice this directive right here, ng-if='display.' So if display is true, that will be displayed. So all that's left now is the add and remove methods. Let's start with remove because it's really simple. So we'll do $scope.remove and what happens is basically the user chose to create a new field, but then they decide not to and so they click remove and get rid of it. And all we need to do in this case is set $scope.field equal to an empty object once again and $scope.display = false. So we'll go ahead and remove this form and clear out our field object here, so it is ready when the user chooses to add a new field once again. So, finally, we have scope dot add, and this will be run when the user has typed in a field name and potentially a field value and has decided to add it to the record that we are working with. So, the first thing we need to do is check to see if the form is valid. So, we can say if form.newField. And this is where we use this form value, basically. Remember, we're calling the parent form dot child form, so if form.field.$valid then we'll say $scope.record, square bracket, and then we can say $scope.field name equals $scope.field.value. Before we move on here, there's a little bit of an issue you might notice. And that is we have our being put right in here. But remember, is the value which comes from this input element right here. Notice it's connected to the NG model field name,, and that could really be a string of any format. Now the problem is when we, you store these in our database, we want to store them in camel case. So lets create a filter that, will basically do the reverse, of our label case. Function it will set them as camelCase. So we'll open up public source filter once again. And underneath labelCase here, let's create another filter. And we're gonna call it camelCase. Basically, what we wanna do is imagine that the user chooses to call their field first name. It's multiple fields, right? Well, what we want to do is convert that to first name in camelCase. Partly because that's the way we like to store it in our database, partly because that is what our label case filter here expects. And later on when we're showing this field name to the user, we're gonna use label case here to convert it back into a user friendly view. So, we wanna convert first name like this into first name like this. And the beauty of it is that first name. This will also work if it is first name in all lowercase or even if the user does first name in all uppercase. All three of these will turn out the same, like this. And this way, all of our labels will be uniformly formatted. So what we will return from this is, we're gonna return input.toLowerCase. And then we're going to do a replace. And we're gonna look for every place where there's a space, and then a word character. So we're looking for multiple words. So w're looking for space and then a word character. And instead of replacing this with a snub of string, we can actually call a function here that will return the string that will get replaced. So the first will be any matches that are made. The second will be any specific capture groups that we have. So the first capture group is any first letter that comes after a space, so that will be this letter parameter here. So, now, we can just return letter dot to uppercase. So, in case you're not entirely clear on what this does, let me spell it out for you. Assume the input is first name, first input is to lowercase so that we get first space name, all lower case, then we search for anything that is a space and then a letter. So, in this case, we would get that right there, the space and then the letter n. And then, we replace both the space and the letter n with just an upper case letter N. And so this will end up being first capital N Name,no space at all. So with that in place, we can come back to our directive here. Notice we prepared to use this by pulling in filter in our function parameters up above. So now down here, we can call dollar sign filter, and we called that camel case. So we'll just pass in that string to the filter function. And now that returns the function, so we will wrap our scope dot field dot name in that function call. And now scope dot filed dot name will be [INAUDIBLE]. Completely formatted as a camel case field name. So now that we've added this field to our record, believe it or not, it will automatically now show up as a form field because it's been added to contact, angular with automatically add a form field directive element for this newly added field. So, after this we want to go ahead and call scope dot remove to reset this directive so that it's ready for when the user wants to go ahead and add another field. The very last step is to go ahead and update it with the server. Because remember, this directive will also be used on our edit user page. So I'm just gonna scroll right up to our blur update function here. And I'm just gonna copy all the guts of our blur update function. So we need to check if live is not equal to false, go ahead and perform the update. So I'm gonna copy that in, and I will paste it right in here, excellent, and that is pretty much all we have to do on our add function. Oh, there is one thing I need to correct, and that is when we set the value of the new field here on record. I set it just as plain value. But, what I really needed to do is put this in an array, right? And the second value of the array should be $scope.field.type. There we go. And that way our form field directive will know what type to display this as excellent. And so now, this sound be working just fine. We've already added it to our new contacts form field here, so let's see it in action. Before we actually look at that, I noticed I have a problem here, to get the drop down to work automatically, we have to set data toggle here to drop down and. I have it set to downdown. So I'm gonna change that to dropdown. And so now when we come to the Contacts/New page, down at the bottom here you can see we have the Add New Field button. And if I click this, we can add, let's add a fun one. Let's add color. I can add a name for this field here. We'll say favorite color. Now, I can go ahead and choose a color with the color picker. There we go. I like that shade of green. I'll choose Add. And now, you can see our new field form has disappeared, but in its place, we have our favorite color attribute added as one of our form field directives. And there you go. So, now let's add a name here. We'll add Sally. Downs. And now I can create this contact. And if we come back to the list, you can see Sally Downs. Now currently, we're not showing color, and currently clicking on our contact doesn't actually do anything. However, we have created a new contact and we've given it a custom field. And that was our goal for the new field directive, and we have accomplished it.

Back to the top