robk27
robk27

Reputation: 693

Angular toggle not working after submit

I am playing around with Angular and came about an issue. The toggle I have set up on the Edit button works until I either click on the Save or Cancel button. Then it doesn't work anymore.

Here is my Plunker: http://plnkr.co/edit/Vy2WeUkk7jvIjp1z8Sfi

<section ng-controller="ContactController">
<ul class="list-group">
    <li class="list-group-item" ng-repeat="contact in contacts">
        <h3>
            {{ contact.id }}
            <em class="pull-right">{{contact.fname }} {{ contact.lname }} <button ng-click="editing = !editing">Edit</button></em>
            <form ng-show="editing" ng-submit="editing = false" ng-controller="FormController">
                <input type="hidden" ng-model="contact.id">
                <label>First Name:</label>
                <input type="text" ng-model="contact.fname" placeholder="first name" ng-required/>
                <label>Last Name:</label>
                <input type="text" ng-model="contact.lname" placeholder="last name" ng-required/>
                <br/>
                <button class="btn" ng-click="Save();" type="submit">Save</button>
                <button class="btn" ng-click="editing = false">Cancel</button>
              </form>
        </h3>
    </li>
    </ul>
    </section>

Any help would be appreciated.

Upvotes: 0

Views: 256

Answers (1)

lukewestby
lukewestby

Reputation: 1207

The ng-repeat directive creates a new scope for contact element it iterates. Let's call this the contact scope. Because the Edit button is within the contact scope, clicking it will create an editing property on the contact scope.

When you use the ng-controller directive to create a FormController, you are creating a child scope, let's call it the form scope, whose prototype is the contact scope. This is why you can access properties from a parent scope directly from a child scope, and why the ng-show directive initially works in your code.

However, when you click the Cancel button, you are setting the editing property to false directly on the form scope and this overrides the value of editing on the contact scope. Since you are referencing editing on the form scope in your ng-show directive it is never going to show again since the Edit button modifies editing on the contact scope.

The way to fix this is to use the scope's $parent property whenever you are referencing editing in the form scope. This ensures you are watching and modifying editing on the contact scope.

<section ng-controller="ContactController">
<ul class="list-group">
<li class="list-group-item" ng-repeat="contact in contacts">
    <h3>
        {{ contact.id }}
        <em class="pull-right">{{contact.fname }} {{ contact.lname }} <button ng-click="editing = !editing">Edit</button></em>
        <form ng-show="$parent.editing" ng-submit="$parent.editing = false" ng-controller="FormController">
            <input type="hidden" ng-model="contact.id">
            <label>First Name:</label>
            <input type="text" ng-model="contact.fname" placeholder="first name" ng-required/>
            <label>Last Name:</label>
            <input type="text" ng-model="contact.lname" placeholder="last name" ng-required/>
            <br/>
            <button class="btn" ng-click="Save();" type="submit">Save</button>
            <button class="btn" ng-click="$parent.editing = false">Cancel</button>
        </form>
    </h3>
</li>
</ul>
</section>

Upvotes: 1

Related Questions