4

I would like my form labels to display a red asterisk next to the label when the corresponding form control has a required attribute.

Instead of hard coding the asterisk, I desire a way to append the asterisk to the label dynamically during page load if the label's corresponding input, select or textarea is required (the element the label corresponds to).

I created the directive below, and the directive works. But is there a better, more native way to accomplish my goal? This directive finds all the div.form-group containers and adds a red * character after the label if the corresponding form control inside the div.form-group has a required attribute.

myApp.directive('labelsRequired',function(){
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, elem, attrs){
            elem.find('div.form-group').each(function(i, formGroup){
                var formControls = $(formGroup).find('input, select, textarea');
                console.log(formControls)
                if (0 !== formControls.length && undefined !== $(formControls[0]).attr('required')){
                    jLabel = $(formGroup).find('label');
                    jLabel.html(jLabel.html()+ "<span class='red-color'>*</span>");
                }
            })
        }
    }
});

The directive assumes all inputs, selects, and textareas are inside a div.form-group container.

<div class='form-group'>
  <label>First Name</label><!-- this label gets an asterisk -->
  <input name='fname' required />
</div>
<div class='form-group'>
  <label>Favorite Food</label><!-- this label does not get an asterisk -->
  <input name='favFood'  />
</div>

4 Answers 4

1

You don't need a directive, there are built-in form properties you can use with filters like ng-show, look:

<div ng-app="myApp" ng-controller="myCtrl">
    <form name="userForm" novalidate>
        <div class='form-group'>
          <label>First Name</label>
          <input name='fname' ng-model="fname" required />
          <label ng-show="userForm.fname.$dirty && userForm.fname.$error.required">* Required field</label>
        </div>
        <button type="submit">Submit</button>
    </form>
</div>

If you define an ng-model for the input you can deal with it looking if it is filled or not. You can also check it only after the user "dirty" it with userForm.fname.$dirty, so the label will be shown only after a user try to input something but then clear it. Try playing with it here JSFiddle

Sign up to request clarification or add additional context in comments.

1 Comment

I want to communicate the required to the user before the error occurs. A form should communicate required fields prior to errors happening, in my UX opinion.
1

Building off of Corey's answer:

I just used compile rather than link, as I saw that my required attribute was not being applied to my input elements. I also included a select tag for any dropdowns that I had.

    app.directive('inputRequired', function () {
    return {
        restrict: 'A',
        compile: function (elem) {
            elem.find('label').append("<sup><i class='fa fa-asterisk'></i></sup>");
            elem.find('input').attr('required', 'required');
            elem.find('select').attr('required', 'required');
        }
    };
});

1 Comment

This requires you to include input-required on every field. My solution only requires one directive for the form.
0

If you're not using the built-in Angular validation, you could restructure your directive and attach it to your .form-group element. Like this:

app.directive('inputRequired', function() {
  return {
    restrict: 'A',
    link: function(scope, elem, attr) {
      elem.find('label').append('<span>*</span>');
      elem.find('input').attr('required', 'required');
    }
  };
});

Your HTML would then look like:

<div class="form-group" input-required>
  <label>Name</label>
  <input name="name" />
</div>
<div class="form-group">
  <label>Food</label>
  <input name="food" />
</div>

However, if you haven't looked into the built-in validation with Angular, I would recommend using it.

1 Comment

I am using the angular native form validation. The purpose of the directive is only to put the asterisk on the label in a way which corresponds to the existence or presence of the required attribute. I'll edit to be more clear.
0

This might come too late and it might not be too elegant but it works, if anyone needs it:

<label ng-show="userForm.fname.$validators.hasOwnProperty('required')">* Required field</label>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.