-2

I have this piece of HTML:

:
:
<td ng-if="Curr_State == 'Edit' && This_Page.Data_Changed == false" style="max-width:300px">
    <button type="button"
            class="FD" 
            ng-click="Initiate_Append_to_JobCard()" 
            style="height:80px;width:180px;white-space:normal;background:green;padding:10px">
        <font size="3" class="ng-binding">Append{{All_Labels.Common.Append}}
        </font>
        <font size="2">
            {{This_Page.Append_Get_Number}}
            <table id="Get_Append_Count_an_Execute" ng-if="This_Page.Append_Get_Number == 'Y'">
                <tbody>
                    <tr>
                        <td>
                            <label for="Append_Number"> #:</label>
                        </td>
                        <td>
                            <input string-to-number
                                   id="Append_Number"
                                   type="number" 
                                   class="form-control" 
                                   ng-model="This_Page.Append_Number"
                                   min="0"
                                   step="1"
                                   style="width:70px;margin:0px">
                        </td>
                        <td>
                            <button class="btn btn-success" 
                                    ng-click="Do_Append()" 
                                    title="Proceed with Append"
                                    type="button">
                                <font size="2" color="white">
                                    <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
                                </font>
                         </button>

                        </td>
                        <td>
                            <button class="btn btn-danger" 
                                    ng-click="Cancel_Append()" 
                                    title="Cancel Append request"
                                    type="button">
                                <font size="2" color="white">
                                    <span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
                                </font>
                         </button>

                        </td>
                    </tr>
                </tbody>
            </table>
        </font>
    </button>
</td>
:
:

and the following two functions within the controller:

$scope.Initiate_Append_to_JobCard = function() {
    $scope.This_Page.Append_Get_Number = "Y" ;
}

//////////////////////////////////////////////////////////////////

$scope.Cancel_Append = function() {
    $scope.This_Page.Append_Get_Number = "N"   ;
    $scope.This_Page.Append_Number     = null  ;
}

When the outer button is clicked, $scope.This_Page.Append_Get_Number is set to "Y" and the inner objects are properly shown.

When the Cancel button is clicked, the function $scope.Cancel_Append is invoked, the value of $scope.This_Page.Append_Get_Number is set to "N" (first statement of the function) but this change is not propagated towards the HTML. In fact, I added {{This_Page.Append_Get_Number}} which shows initially N, then Y and it then remains unchanged no matter how many times I click on the cancel button.

halfer
  • 19,824
  • 17
  • 99
  • 186
FDavidov
  • 3,505
  • 6
  • 23
  • 59
  • 1
    You should use $scope.$apply() – Irhad Ljubcic Jun 05 '18 at 10:41
  • 1
    This might be because of `ng-if` creating a new scope. Try `ng-model="$parent.This_Page.Append_Number"` or `ng-show` – Aleksey Solovey Jun 05 '18 at 10:42
  • Set `$scope.This_Page.Append_Number` to `undefined` instead of `null`. – georgeawg Jun 05 '18 at 11:08
  • @IrhadLjubcic, you cannot use the $apply() method while Angular is in the middle of a digest cycle, which is the case when you invoke a `$scope.xyz` function. – FDavidov Jun 05 '18 at 11:23
  • @AlekseySolovey, switched to `ng-show` with no effect. The point is that switching from "N" to "Y" (function `$scope.Initiate_Append_to_JobCard`) works, but from "Y" to "N" (function $scope.Cancel_Append) does not. I set a breakpoint at the line that `$scope.This_Page.Append_Get_Number = "N" ;`, it is executed, but its effect is not seen on the page. – FDavidov Jun 05 '18 at 11:26
  • @georgeawg, `$scope.This_Page.Append_Number` is just a number entered by the user within the input element. The issue is with the model variable that controls showing or not the inner table. – FDavidov Jun 05 '18 at 11:28
  • (you do have multiple `ng-if`s) Can you make a Plunker example? – Aleksey Solovey Jun 05 '18 at 11:28
  • @AlekseySolovey I must **shamefully confess** that I have never done that, so need to learn how to do it. – FDavidov Jun 05 '18 at 11:30
  • Where is the closing `` tag for the append button? – georgeawg Jun 05 '18 at 11:39
  • The closing button tag is at the bottom (after the table). That is the original problem. The closing button tag should be before the table – Prabhu Thomas Jun 05 '18 at 11:55
  • When posting code snippet, please spend some time to make it minimal and nice -- remove styles, classes, titles and rest irrelevant information. – Petr Averyanov Jun 05 '18 at 12:00
  • @PetrAveryanov, point taken. Thanks. – FDavidov Jun 05 '18 at 12:02
  • @georgeawg, the layout is correct (or, that was the intention): There is a button labeled "Append" that, when clicked, three elements are supposed to appear **WITHIN** that very same button: and input element and two additional buttons, OK and Cancel. When either OK or Cancel are clicked, these three first should disappear. I have in many places elements (tables included) that are shown/ hidden using `ng-if` and everywhere it works perfectly, but not here.... – FDavidov Jun 05 '18 at 12:06
  • @PrabhuThomas, see my response to georgeawg. – FDavidov Jun 05 '18 at 12:07
  • @FDavidov, Have updated my answer and also the plunker. Its working with the table inside the button – Prabhu Thomas Jun 05 '18 at 12:16
  • @georgeawg, you marked the question as duplicate, right... I changed the outer button to a clickable div and it is still not working. Moreover, the inner button with `ng-click="Do_Append()"` works perfectly in the sense that it invokes the function (Do_Append) and yields the desired result. So, buttons within buttons DO WORK (at least in my case), but AngularJS binding appears NOT TO WORK. Do you still consider it a duplicate? – FDavidov Jun 05 '18 at 12:55
  • @georgeawg, check Thomas solution. I works perfectly as expected. So much for **duplicate**... :-(. – FDavidov Jun 05 '18 at 13:10
  • **Eliminate any issues that aren't relevant to the problem.** [Validate](https://validator.w3.org/) any HTML or XML. – georgeawg Jun 05 '18 at 13:46
  • @georgeawg, thanks for the link. Quite interesting and I guess helpful. Unfortunately (at least for the current case), the application is not and will never be accessible from the public network (security reasons). The interesting thing is that the addition of the `event` thing (see Thomas' answer) did solve the problem, though I don't quite understand why (asked Thomas for a brief explanation). – FDavidov Jun 06 '18 at 04:22
  • @FDavidov, have added an explanation in my answer – Prabhu Thomas Jun 06 '18 at 10:00

2 Answers2

1
<button type="button"
            class="FD" 
            ng-click="Initiate_Append_to_JobCard()" 
            style="height:80px;width:180px;white-space:normal;background:green;padding:10px">
        <font size="3" class="ng-binding">Append{{All_Labels.Common.Append}}
        </font>
        <font size="2">
            {{This_Page.Append_Get_Number}} </font></button>

<table id="Get_Append_Count_an_Execute" ng-if="This_Page.Append_Get_Number == 'Y'">

If the table should be inside the button itself, then the click event on the Cancel button will bubble up to the Append button, which will close and open again.

You need to add a

event.stopPropagation()

in your cancel function and also pass the $event to that function

Updated Plunker

https://embed.plnkr.co/CEHNggASaVGqkqfamdEx/

Event Bubbling

When you have an element inside another element and an event occurs on the innermost element (the click event here), then the event is processed by that element and then it is passed up the DOM hierarchy to all the ancestor elements that have a listener for that event and processed by each one.

Here you have a button inside a button, with click event listeners on both. When the inner button (Cancel) is clicked, the listener (Cancel_Append) processes the event (changes the value to N) and then passes the click to the parent/outer button where the listener (Initiate_Append_to_JobCard) processes the event and changes the value to Y again.

Since these happen at almost the same time, we cant see the difference. It can be seen by adding a 'console.log($scope.This_Page.Append_Get_Number)' to both the functions.

To prevent the bubbling of the event, we need to cancel the propagation after the event has been handled. So we need to pass the $event object from the HTML and then after the event is processed by the "Cancel_Append", we need to stop propagating the event further up the DOM using the event.stopPropagation().

Take a look at this link for a better understanding of event bubbling

What is event bubbling and capturing?

halfer
  • 19,824
  • 17
  • 99
  • 186
Prabhu Thomas
  • 174
  • 2
  • 9
  • Hey Thomas, I checked the plunker you posted and, for some reason, it does not finish its loading (and hence cannot see how it works). Anyway, I didn't quite see any difference between your posted solution and my code (except for the `event.stopPropagation()` that does not make any difference). – FDavidov Jun 05 '18 at 12:49
  • @FDavidov, did you add the $event when you are calling the cancel function in the HTML ---> ng-click="Cancel_Append($event)" https://run.plnkr.co/W5LgWMF7IsWEsN2e/ – Prabhu Thomas Jun 05 '18 at 12:59
  • Yeap. Same result (not hiding the table). – FDavidov Jun 05 '18 at 13:01
  • Funny, it works fine for me – Prabhu Thomas Jun 05 '18 at 13:01
  • I saw the new link and indeed works!!! – FDavidov Jun 05 '18 at 13:02
  • Did you change anything from my code? – FDavidov Jun 05 '18 at 13:02
  • I added only the $event in the HTML and the event.stopPropagation() – Prabhu Thomas Jun 05 '18 at 13:03
  • BINGO!!!!!!!!!!!!!!!!!!!!!!! It works!!!!! I misunderstood your wording regarding the event. Checked you example, reproduced what you did and EUREKA!!!! Thank you Sir!!!!!!!!!!! (needless to say, you get my vote). – FDavidov Jun 05 '18 at 13:09
  • Thomas, I thought about your solution and would like to ask you for a brief explanation on why the addition of the **event** solved the problem, could you kindly post it? Thanks in advance. – FDavidov Jun 06 '18 at 04:19
  • Thomas, description is crystal clear. I am aware about bubbling but didn't think in that direction. Many thanks for the answer and your time Sir!!! – FDavidov Jun 06 '18 at 11:22
0

make use of ng-show instead of ng-if

<td ng-show="Curr_State == 'Edit' && This_Page.Data_Changed == false" style="max-width:300px">