Joseph Sjoblom
Joseph Sjoblom

Reputation: 171

AngularJS Matching ng-model for Select and Radio not Syncing

I'm having an issue with my models when attempting to sync similar functionality using a select with ng-options and a radio using ng-repeat. The models and details are all the same, but they're not syncing properly and I'm not sure why. I tried to add $parent to radio, based on similar posts on Stack, and that didn't work either.

Basically what I'm trying to do is based on the top-level selection (categories), show the child options (descriptions) based on the parent selected. You can see once you choose a radio option the model will fail.

Here's a plunker to illustrate the issue: https://plnkr.co/edit/oP0LUEk5u70kLVsM?preview

Here's my controller:

$scope.selection = {};

$scope.tagCategories = [
    {
        id: 1,
        tagCategoryName: "Payor Issues"
    }, {
        id: 2,
        tagCategoryName: "Technical Issues"
    }, {
        id: 3,
        tagCategoryName: "Special Project Tags"
    }
];

$scope.tagDescriptions = [
    {
        id: 1,
        tagDescriptionName: "Payor Issue 1",
        tagCategoryId: 1
    }, 
    {
        id: 2,
        tagDescriptionName: "Payor Issue 2",
        tagCategoryId: 1
    }, 
    {
        id: 3,
        tagDescriptionName: "Technical Issue 1",
        tagCategoryId: 2
    },
    {
        id: 4,
        tagDescriptionName: "Technical Issue 2",
        tagCategoryId: 2
    }, 
    {
        id: 5,
        tagDescriptionName: "Special Project 1",
        tagCategoryId: 3
    }
];

$scope.selection.category = $scope.tagCategories[1];
$scope.categories = $scope.tagCategories;

$scope.descriptionsForCategory = function(category) {
    if (category) {
        return $scope.tagDescriptions.filter(function (s) {
            return s.tagCategoryId == category.id;
        });
    }
    return [];
};

Associated HTML:

<div class="form-group">
                <label class="control-label">Category</label>
                <!-- NG-MODEL USING SELECT OPTION -->
                <select name='category' class="form-control" ng-model="selection.category" ng-options="category as category.tagCategoryName for category in categories"
                 required>
            <option value="" disabled>Select</option>
        </select>
                    <ul>
                        <!-- NG-MODEL USING NG-REPEAT RADIOS -->
                        <li ng-repeat="category in categories">
                            <div class="radio">

                                <input type="radio" name='category' ng-model="selection.category" id="category{{category.id}}" ng-value="category.tagCategoryName">
                                <label for="category{{category.id}}">{{category.tagCategoryName}}</label>
                            </div>

                        </li>
                    </ul>
            </div>
            <div class="form-group">
                <label for="description" class="control-label">Description</label>
                <select name='description' required id="description" class="form-control" ng-disabled="descriptions.length == 0" ng-model="selection.description" ng-options="description as description.tagDescriptionName for description in descriptionsForCategory(selection.category)">
            <option value="" disabled>Select</option>
        </select>
                    <ul>
                        <li ng-repeat="description in descriptionsForCategory(selection.category)" ng-model="selection.description">
                            {{description.tagDescriptionName}}
                        </li>
                    </ul>

            </div>

I'm hoping it's something minor I'm overlooking. Any insight on what's causing the issue would be greatly appreciated.

thank you

Upvotes: 0

Views: 223

Answers (1)

Michael Kucinski
Michael Kucinski

Reputation: 473

Your issue is that your <select/> is storing the category Object while your <input type="radio"> is storing the category.tagCategoryName String:

<select name='category' class="form-control" ng-model="selection.category" ng-options="category as category.tagCategoryName for category in categories"
             required>
        <option value="" disabled>Select</option>
</select>

<input type="radio" name='category' ng-model="selection.category" id="category{{category.id}}" ng-value="category.tagCategoryName">

In ng-options, you have category as category.tagCategoryName for category in categories, which says "Store the category object on my scope, and use the tagCategoryName as the display name for each category in categories"

For your radios, you have the ng-value set to be the category.tagCategoryName string, so that's what get's bound to your scope. So, the select used the object, the radio used the string. I fixed this by updating the radio to simply use the category as the value:

<input type="radio" name='category' ng-model="selection.category" id="category{{category.id}}" ng-value="category">

Here's the working plunkr.

Upvotes: 2

Related Questions