2

I want to hide a div based on a click from a controller :

My HTML :

<div ng-controller ="myctrl">
    <div ng-repeat="emp in emps">
       <div class="myclass">
        <p> {{emp.name}} </p> 
          <span class="testclass" ng-click="showBox='true'" >Show</span><br>

          <div ng-show="showBox">
            <textarea rows="3" cols="50" ng-model="data.sometext"></textarea><br>
            <button ng-click = "testme(sometext)">Submit</button>
          </div>

        </div>
    </div>
</div>

In the controller :

app.controller("myctrl", function($scope){

    $scope.data = {sometext : ""}  //DONT KNOW WHY I HAD TO DO LIKE THIS

    $scope.testme = function(sometext){
        console.log(sometext);
        $scope.data.sometext = "";  //THIS WORKS.
        $scope.showBox = false;     //THIS DOES NOT WORK.
        $scope.showBox = 'false';   //THIS DOES NOT WORK.
        HOW TO HIDE THE DIV  
}    
});

So When I click Show, the textarea is shown. When I click the button, the text area becomes empty. Like I want. But the div is not hidden. I want to hide the div when the button is clicked. Tried to make the ng-show false but its not working.

Thanks.

Somename
  • 3,376
  • 16
  • 42
  • 84

3 Answers3

3

First of all, you shouldn't be using the ngModel directive on your span element.

From the ngModel documentation:

The ngModel directive binds an input, select, textarea (or custom form control) to a property on the scope using NgModelController, which is created and exposed by this directive.

I have changed your code to make it a little clearer to demonstrate. The code now uses the controller as syntax to make it clearer where the data belongs to and the span has been changed to a button. See the AngularJS example of the controller as syntax and the benefits of doing so.

The following demonstrates:

1) When you click the show button, showText property of that emp is set to true.

2) Because the scope has been updated, the $digest cycle is called and the expression within the ngShow directives on your div tags are evaluated. Those with the showText property of the emp set to true will evaluate true and the div element containing your textarea then shows.

3) When you click the "Submit" button your testme function on your controller is called, passing in the binded value from the textarea ngModel directive held in MyCtrl.data.sometext and the emp so we can change it's properties. A text property of the emp is set to the input and the showText property is set back to false so the textarea is then hidden again.

// app.js
(function() {

  'use strict';

  angular.module('app', []);

})();

// my.controller.js
(function() {

  'use strict';

  angular.module('app').controller("MyController", MyController);

  MyController.$inject = ['$scope'];

  function MyController($scope) {

    var vm = this;

    vm.emps = [{
        id: 1,
        name: "John Doe"
      },
      {
        id: 2,
        name: "Jane Smith"
      },
      {
        id: 3,
        name: "Jack Jones"
      }
    ];

    // expose the testme function to the view
    vm.testme = testme;

    function testme(input, emp) {
      
      // get the index of the employee
      var index = vm.emps.indexOf(emp);
      
      // set the employee text to the input
      vm.emps[index].text = input;
      
      // set showText to false
      vm.emps[index].showText = false;

    }

  }

})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="MyController as MyCtrl">

  <div ng-repeat="emp in MyCtrl.emps">

    <div class="myclass">

      <p>{{emp.name}} </p>
      <p>{{emp.text}}</p>
      <p>
        <button ng-click="emp.showText = !emp.showText">{{emp.showText ? 'Hide' : 'Show'}}</button>
      </p>

      <div ng-show="emp.showText">
        <textarea rows="3" cols="50" ng-model="MyCtrl.data.sometext"></textarea><br>
        <button ng-click="MyCtrl.testme(MyCtrl.data.sometext, emp); MyCtrl.data.sometext = ''">Submit</button>
      </div>

    </div>
  </div>

</div>
cnorthfield
  • 3,384
  • 15
  • 22
  • I sincerely apologize. I did not include the `ng-repeat` in my original question. I edited the question. Your solution works perfectly fine with a standalone `span` and `div` but not when nested in a `ng-repeat`. Don't know why. Please have a look at the edits. Once again. I'm sorry. – Somename Mar 18 '17 at 20:48
  • @Somename I have now updated it to use the emp as the driver for showing/hiding the textarea – cnorthfield Mar 18 '17 at 21:07
  • This works perfect! Exactly what Im looking for. Can I try to code this without `vm` and using simple `$scope`? And without using the `index` as i've heard it causes wrong `indexes` when using `filter` in `ng-repeat`? Many thanks. – Somename Mar 18 '17 at 21:24
  • Sure you can, just replace `vm` with `$scope` in your controller and remove the `MyCtrl` prefixes in the view. Have a play around with the code and experiment :) – cnorthfield Mar 18 '17 at 22:05
0

You have some errors in your code, like use ng-model in the span. Here you have a working jsfiddle with some changes

HTML:

<div ng-controller="myCtrl">
  <span class="testclass" ng-click="showBox='true'">Show</span><br>

  <div ng-show="showBox">
    <textarea rows="3" cols="50" ng-model="data.sometext"></textarea><br>
    <button ng-click="testme(sometext)">Submit</button>
  </div>
</div>

JS:

var ang = angular.module('myApp', []);

ang.controller('myCtrl', ['$scope', function($scope) {
  $scope.data = {
    sometext:""
  };

  $scope.testme = function(text){
    $scope.showBox = false;
  }
}]);

https://jsfiddle.net/lonking/qo7bngmq/

  • I sincerely apologize. I did not include the `ng-repeat` in my original question. I edited the question. Please have a look at the edits. Once again. I'm sorry. – Somename Mar 18 '17 at 20:49
  • @Somename Sometimes it happens, dont worry. I saw it too late, but the selected answer works fine, so use it :) –  Mar 20 '17 at 22:14
0

Hi could you try initialising $scope.showBox = false; and also ng-click="showBox=true" and not ng-click="showBox='true'" as it is a string form. Your code is correct to an extent also try hitting control save on your text editor just might work :) .