Search code examples
javascriptangularjsformsangularjs-ng-repeatangular-validation

Angular js validations for a form in ng-repeat is not working as expected


I have a table, in which I have repeated the <tr> tag by using ng-repeat="cancellationPercentData in cancellationPercent"

Inside this tr tag I have a form with name and id set by using $index

Take a look at my code below :

<tbody>
    <tr  ng-repeat="cancellationPercentData in cancellationPercent">
        <form name="{{ $index }}editPercentageForm" id="{{ $index }}editPercentageForm" novalidate>
        <td class="form-group">
            <input type="number" name="{{ $index }}editFromHours" ng-model="cancellationPercentData.fromHours" class="form-control" ng-disabled="disableField" id="{{ $index }}fromHours" required/>
            <p ng-show="{{ $index }}editPercentageForm.{{ $index }}editFromHours.$touched && {{ $index }}editPercentageForm.{{ $index }}editFromHours.$invalid" class="text-danger">This field is required</p>
        <td class="form-group">
            <input type="number" name="{{ $index }}edittoHours" ng-model="cancellationPercentData.toHours" class="form-control" ng-disabled="disableField" id="{{ $index }}toHours" required/>
            <p ng-show="{{ $index }}editPercentageForm.{{ $index }}edittoHours.$touched && {{ $index }}editPercentageForm.{{ $index }}edittoHours.$invalid">This field is required</p>
            <p ng-show="{{ $index }}edittoHours>={{ $index }}editFromHours" class="text-danger">To Hours should not be more than to Hours</p>
         </td>
        <td class="form-group">
            <input type="text" name="{{ $index }}editPer" ng-model="cancellationPercentData.percentage" class="form-control" ng-disabled="disableField" id="{{ $index }}percentage" required/>
            <p ng-show="{{ $index }}editPercentageForm.{{ $index }}editPer.$touched && {{ $index }}editPercentageForm.{{ $index }}editPer.$invalid">This field is required</p>
        </td>
        <td class="form-group">
            <button class="btn btn-success col-xs-12" type="button" ng-click="disableField = false" ng-show="disableField" style="margin-bottom: 1%;">Edit</button>
            <button class="btn btn-success col-xs-12" type="submit" style="margin-bottom: 1%;"  ng-disabled="{{ $index }}editPercentageForm.$invalid" ng-click="updateCancellations(cancellationPercentData, $index+'fromHours', $index+'toHours', $index+'percentage')" ng-show="disableField == false">Update</button>
            <button class="btn btn-primary col-xs-12" type="button" ng-click="deleteCancellations(cancellationPercentData)" style="margin-bottom: 1%;">Delete</button>
        </td>
        </form>
    </tr>
    </tbody>

tr is repeating correctly but the form inside the tr should start immediately after the tr tag and should end exactly before the tr close tag.

But when I open the above code in the browser and inspect, it is showing differently, the form tag is opened and closed without td tags inside it. Once the form is closed then the tg tags are started .

This is how it is getting changes in my browser when I inspect it :

<tbody>
    <!-- ngRepeat: cancellationPercentData in cancellationPercent --><tr ng-repeat="cancellationPercentData in cancellationPercent" class="ng-scope">
        <form name="0editPercentageForm" id="0editPercentageForm" novalidate="" class="ng-pristine ng-valid"></form>
        <td class="form-group">
            <input type="number" name="0editFromHours" ng-model="cancellationPercentData.fromHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="0fromHours" required="" disabled="disabled">
            <p ng-show="0editPercentageForm.0editFromHours.$touched &amp;&amp; 0editPercentageForm.0editFromHours.$invalid" class="text-danger">This field is required</p>
        </td><td class="form-group">
            <input type="number" name="0edittoHours" ng-model="cancellationPercentData.toHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="0toHours" required="" disabled="disabled">
            <p ng-show="0editPercentageForm.0edittoHours.$touched &amp;&amp; 0editPercentageForm.0edittoHours.$invalid">This field is required</p>
            <p ng-show="0edittoHours>=0editFromHours" class="text-danger">To Hours should not be more than to Hours</p>
         </td>
        <td class="form-group">
            <input type="text" name="0editPer" ng-model="cancellationPercentData.percentage" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="0percentage" required="" disabled="disabled">
            <p ng-show="0editPercentageForm.0editPer.$touched &amp;&amp; 0editPercentageForm.0editPer.$invalid">This field is required</p>
        </td>
        <td class="form-group">
            <button class="btn btn-success col-xs-12" type="button" ng-click="disableField = false" ng-show="disableField" style="margin-bottom: 1%;">Edit</button>
            <button class="btn btn-success col-xs-12 ng-hide" type="submit" style="margin-bottom: 1%;" ng-disabled="0editPercentageForm.$invalid" ng-click="updateCancellations(cancellationPercentData, $index+'fromHours', $index+'toHours', $index+'percentage')" ng-show="disableField == false">Update</button>
            <button class="btn btn-primary col-xs-12" type="button" ng-click="deleteCancellations(cancellationPercentData)" style="margin-bottom: 1%;">Delete</button>
        </td>

    </tr><!-- end ngRepeat: cancellationPercentData in cancellationPercent --><tr ng-repeat="cancellationPercentData in cancellationPercent" class="ng-scope">
        <form name="1editPercentageForm" id="1editPercentageForm" novalidate="" class="ng-pristine ng-valid"></form>
        <td class="form-group">
            <input type="number" name="1editFromHours" ng-model="cancellationPercentData.fromHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="1fromHours" required="" disabled="disabled">
            <p ng-show="1editPercentageForm.1editFromHours.$touched &amp;&amp; 1editPercentageForm.1editFromHours.$invalid" class="text-danger">This field is required</p>
        </td><td class="form-group">
            <input type="number" name="1edittoHours" ng-model="cancellationPercentData.toHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="1toHours" required="" disabled="disabled">
            <p ng-show="1editPercentageForm.1edittoHours.$touched &amp;&amp; 1editPercentageForm.1edittoHours.$invalid">This field is required</p>
            <p ng-show="1edittoHours>=1editFromHours" class="text-danger">To Hours should not be more than to Hours</p>
         </td>
        <td class="form-group">
            <input type="text" name="1editPer" ng-model="cancellationPercentData.percentage" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="1percentage" required="" disabled="disabled">
            <p ng-show="1editPercentageForm.1editPer.$touched &amp;&amp; 1editPercentageForm.1editPer.$invalid">This field is required</p>
        </td>
        <td class="form-group">
            <button class="btn btn-success col-xs-12" type="button" ng-click="disableField = false" ng-show="disableField" style="margin-bottom: 1%;">Edit</button>
            <button class="btn btn-success col-xs-12 ng-hide" type="submit" style="margin-bottom: 1%;" ng-disabled="1editPercentageForm.$invalid" ng-click="updateCancellations(cancellationPercentData, $index+'fromHours', $index+'toHours', $index+'percentage')" ng-show="disableField == false">Update</button>
            <button class="btn btn-primary col-xs-12" type="button" ng-click="deleteCancellations(cancellationPercentData)" style="margin-bottom: 1%;">Delete</button>
        </td>

    </tr><!-- end ngRepeat: cancellationPercentData in cancellationPercent --><tr ng-repeat="cancellationPercentData in cancellationPercent" class="ng-scope">
        <form name="2editPercentageForm" id="2editPercentageForm" novalidate="" class="ng-pristine ng-valid"></form>
        <td class="form-group">
            <input type="number" name="2editFromHours" ng-model="cancellationPercentData.fromHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="2fromHours" required="" disabled="disabled">
            <p ng-show="2editPercentageForm.2editFromHours.$touched &amp;&amp; 2editPercentageForm.2editFromHours.$invalid" class="text-danger">This field is required</p>
        </td><td class="form-group">
            <input type="number" name="2edittoHours" ng-model="cancellationPercentData.toHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="2toHours" required="" disabled="disabled">
            <p ng-show="2editPercentageForm.2edittoHours.$touched &amp;&amp; 2editPercentageForm.2edittoHours.$invalid">This field is required</p>
            <p ng-show="2edittoHours>=2editFromHours" class="text-danger">To Hours should not be more than to Hours</p>
         </td>
        <td class="form-group">
            <input type="text" name="2editPer" ng-model="cancellationPercentData.percentage" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="2percentage" required="" disabled="disabled">
            <p ng-show="2editPercentageForm.2editPer.$touched &amp;&amp; 2editPercentageForm.2editPer.$invalid">This field is required</p>
        </td>
        <td class="form-group">
            <button class="btn btn-success col-xs-12" type="button" ng-click="disableField = false" ng-show="disableField" style="margin-bottom: 1%;">Edit</button>
            <button class="btn btn-success col-xs-12 ng-hide" type="submit" style="margin-bottom: 1%;" ng-disabled="2editPercentageForm.$invalid" ng-click="updateCancellations(cancellationPercentData, $index+'fromHours', $index+'toHours', $index+'percentage')" ng-show="disableField == false">Update</button>
            <button class="btn btn-primary col-xs-12" type="button" ng-click="deleteCancellations(cancellationPercentData)" style="margin-bottom: 1%;">Delete</button>
        </td>

    </tr><!-- end ngRepeat: cancellationPercentData in cancellationPercent --><tr ng-repeat="cancellationPercentData in cancellationPercent" class="ng-scope">
        <form name="3editPercentageForm" id="3editPercentageForm" novalidate="" class="ng-pristine ng-valid"></form>
        <td class="form-group">
            <input type="number" name="3editFromHours" ng-model="cancellationPercentData.fromHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="3fromHours" required="" disabled="disabled">
            <p ng-show="3editPercentageForm.3editFromHours.$touched &amp;&amp; 3editPercentageForm.3editFromHours.$invalid" class="text-danger">This field is required</p>
        </td><td class="form-group">
            <input type="number" name="3edittoHours" ng-model="cancellationPercentData.toHours" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="3toHours" required="" disabled="disabled">
            <p ng-show="3editPercentageForm.3edittoHours.$touched &amp;&amp; 3editPercentageForm.3edittoHours.$invalid">This field is required</p>
            <p ng-show="3edittoHours>=3editFromHours" class="text-danger">To Hours should not be more than to Hours</p>
         </td>
        <td class="form-group">
            <input type="text" name="3editPer" ng-model="cancellationPercentData.percentage" class="form-control ng-pristine ng-untouched ng-valid ng-valid-required" ng-disabled="disableField" id="3percentage" required="" disabled="disabled">
            <p ng-show="3editPercentageForm.3editPer.$touched &amp;&amp; 3editPercentageForm.3editPer.$invalid">This field is required</p>
        </td>
        <td class="form-group">
            <button class="btn btn-success col-xs-12" type="button" ng-click="disableField = false" ng-show="disableField" style="margin-bottom: 1%;">Edit</button>
            <button class="btn btn-success col-xs-12 ng-hide" type="submit" style="margin-bottom: 1%;" ng-disabled="3editPercentageForm.$invalid" ng-click="updateCancellations(cancellationPercentData, $index+'fromHours', $index+'toHours', $index+'percentage')" ng-show="disableField == false">Update</button>
            <button class="btn btn-primary col-xs-12" type="button" ng-click="deleteCancellations(cancellationPercentData)" style="margin-bottom: 1%;">Delete</button>
        </td>

    </tr><!-- end ngRepeat: cancellationPercentData in cancellationPercent -->
    </tbody>

Why is getting changed in the browser?

Because of this the validations are not working properly.

Please help, thanks in advance :)


Solution

  • You can't have other than table tag inside table, if you try to do that it will make your html invalid & that content will thrown out from table. here you should consider using ng-form inspite of form tag.

    <tbody>
        <tr ng-repeat="cancellationPercentData in cancellationPercent" ng-form="{{ $index}}editPercentageForm">
    
        </tr>
    </tbody>
    

    Also ng-show don't need {{}}(interpolation) directive, you can form complex expression by concatenating string as key of object

    ng-show="this.[$index+ 'editPercentageForm'][$index+'editFromHours'].$touched && 
             this.[$index+ 'editPercentageForm'][$index+'editFromHours'].$invalid"
    

    Likewise correct your all other expression.

    See Also Angular form not working in a table