Search code examples
angularjsangularjs-ng-repeatangular-directive

angular repeat form directive not working editStoryForm is not defined


I have a directive that creates a form with a set of inputs. The directive is repeated multiple times on a page. When my submit function is triggered, I'm unable to run validations on the form because editStoryForm is undefined. How can fix this?

Most of the questions I've found on here deal with validations on repeating form inputs not repeating forms. Additionally, I've tried injecting $element into my directive so that I can access my form object that way, as this answer suggests, however when I inject $element it is undefined.

Here is my directive:

app.directive('story', ['$http', 'modal', function($http, modal) {
    return {
        replace: true,
        templateUrl: '/assets/story.html',
        transclude: false,
        scope: {
            story: '=',
            token: '@'
        },
        controller: ['$scope', '$http', 'modal', function($scope, $http, modal) {
            $scope.editStory = {
                token: $scope.token,
                id: $scope.story.id,
                title: $scope.story.title,
                published: $scope.story.published,
                file: undefined,
                questions_attributes: $scope.story.questions
            };

            $scope.submit = function(result) {
                debugger;
                if (result && $scope.editStoryForm.$valid) {
                    $http.put('/stories/' + result.id + '.json', {
                        workplace_story: result
                    }).progress(function(){
                        $scope.progress = true;
                    }).success(function(data, status, headers, config) {
                        $scope.progress = false;
                    });
                };
            };
        }]
    }
}]);

Template

<form accept-charset="UTF-8" name="editStoryForm" ng-submit="submit(editStory);" multipart="true" novalidate>
<div class="row">
    <div class="col-lg-8" style="height: 285px;overflow:hidden;overflow-y:scroll;">
        <input name="authenticity_token" type="hidden" ng-model="editStory.token">

        <div class="form-group">
            <label>Title</label>
            <input ng-disabled="story.responses.length > 0" type="text" class="form-control" name="title" ng-model="editStory.title" required>
        </div>

        <div class="form-group">
            <label>Questions</label>
            <div ng-repeat="q in editStory.questions_attributes">
                <div ng-hide="question._destroy" class="row form-group">
                    <div class="col-lg-10">
                        <input ng-disabled="story.responses.length > 0" type="text" class="form-control" ng-model="editStory.questions_attributes[$index]['question']" placeholder="What is the meaning of life, the universe, and everything?"/>
                    </div>
                    <div class="col-lg-2">
                        <a ng-if="!story.responses.length > 0" ng-click="removeQuestion($index)" class="btn btn-xs btn-danger">X</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
</form>

Solution

  • $scope.editStoryForm in not define in your controller. if you check your form is valid or not so pass form name in ng-submit method. like:

    in Controller:

                    $scope.submit = function(editStoryForm, result) {
                    debugger;
                    if (result && editStoryForm.$valid) {
                        $http.put('/stories/' + result.id + '.json', {
                            workplace_story: result
                        }).progress(function(){
                            $scope.progress = true;
                        }).success(function(data, status, headers, config) {
                            $scope.progress = false;
                        });
                    };
                };
    

    in HTML :

    <form accept-charset="UTF-8" name="editStoryForm" ng-submit="submit(editStoryForm, editStory);" multipart="true" novalidate>