<!doctype html>
<html lang="en" ng-app="app">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Angular ngModel Spike</title>

    <!-- Bootstrap core CSS -->
    <link href="https://cdn.jsdelivr.net/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet">
    <link href="css/style.css" rel="stylesheet">
</head>

<body ng-controller="MainController">
<div class="header">

</div>
<div class="container">
  <div class="row">
    <div class="col-sm-12">
        <form novalidate name="form" role="form">
             <custom-input id="foldername"
                            name="foldername"
                            label="Folder Name:"
                            ng-model="folder.name"
                            ng-maxlength="15"
                            ng-required="true">
            </custom-input>
<br />
            <custom-input id="folderpath" name="folderpath" label="Folder Path:"
                          ng-required="true"
                          ng-model="folder.path"
                          ng-minlength="5"
                          ng-maxlength="15" >
            </custom-input><br /><br />
            <button class="btn btn-primary"
                ng-click="submit(form)">submit</button>
        </form> 
        <hr />
        Folder<br />
            -name: {{folder.name}}<br />
            -path: {{folder.path}}
        <hr />
        <br />
            name invalid: <pre>{{form.foldername.$invalid}}</pre>
            name error: <pre>{{form.foldername.$error}}</pre>
        <br />  
            path invalid: <pre>{{form.folderpath.$invalid}}</pre>
            path error: <pre>{{form.folderpath.$error}}</pre>
        <br />
            Form invalid: <pre>{{form.$invalid}}</pre>
            Form error: <pre>{{form.$error | json}}</pre>

    </div>
  </div>
</div> <!-- /container -->

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>

<script src="script.js"></script>
<script src="custom-input.js"></script>

</body>
</html>
// Code goes here

'use strict';

angular.module('app',[])
    .controller('MainController', function($log, $scope){
        $scope.folder = { name: '', path: '' }

        $scope.submit = function(form){
        	$log.debug('submit called');
        }
    });
/* Styles go here */

body {
	padding: 5em;
}
A simple plunk to investigate how a nested input field can be wired with ngModel 
so that ngModel-dependend directives (like ng-required) can be used with the directive.
<span class="custom-input-element">
   <label for="{{elementId}}-input">
        <span class="label-content">
        	<span>{{elementLabel}}</span> 
        	<span class="required-marker" ng-if="elementRequired">*</span>
    	</span>
    </label>
     <input id="{{elementId}}-input" type="text" ng-trim ng-model="elem.value"
            ng-init="focused = false" ng-focus="focused = true" ng-blur="focused = false"/>
</span>
angular.module('app').directive('customInput', function ($log) {
    return {
        templateUrl: 'custom-input.html',
        replace: true,
        require: 'ngModel',
        scope: {
            elementId: '@id',
            elementLabel: '@label',
            elementName: '@name',
        },
        link: function (scope, element, attrs, ngModelCtrl) {
           scope.elem = {};
            if(attrs.ngRequired && attrs.ngRequired === "true"){
                scope.elementRequired = true;
            }

            ngModelCtrl.$render = function() {
                scope.elem.value = ngModelCtrl.$viewValue;
            };

            scope.$watch('elem.value', function() {
                ngModelCtrl.$setViewValue(scope.elem.value);
                ngModelCtrl.$validate();
                return ngModelCtrl;
            });
        }
    };
});