StackOverFlow
StackOverFlow

Reputation: 29

Replacing label with input textbox and vice versa by clicking a button in AngularJs

I have a form with label and button Edit, when I click on button, Label should be converted into textbox with the label data as text and when I save it, textbox should be converted as label again.

how can we approach in AngularJs? Could any one provide some information on this?

html:

<form ng-app="testApp" ng-controller="testController">
    <label class="keyColumn">name: </label>
    <label class="valueCoulmn">stackover flow </label>
    <button ng-click="editLabel">Edit</button>
</form>

Controller.js:

(function() {
  angular
    .module("testApp", [])
    .controller('testController', function($scope) {
      $scope.editLabel = function() {}
    });
})();

Upvotes: 1

Views: 7478

Answers (2)

You could use the contenteditable attribute in your label tag.

Check this demo:

(function() {
  "use strict";

  var app = angular.module("app", []);
  app.controller("Controller", ["$scope",
    function($scope) {
      $scope.buttonText = "Edit";

      $scope.editSave = function(evt) {
        var label = evt.target.previousElementSibling; // Get the label tag from your button.
        var labelData = label.innerText; // Get the label text.

        alert(labelData);

        if ($scope.buttonText == "Edit") { // If the current button's text is "Edit"...
          label.setAttribute("contenteditable", true); // Set contenteditable=true to your label.

          /* To make focusable your editable label. */
          label.setAttribute("target", 0);
          label.focus(); // Set the focus in your label.
          $scope.buttonText = "Save"; // Change the button's text to "Save".
        } else {
          label.removeAttribute("contenteditable");
          label.removeAttribute("target");
          $scope.buttonText = "Edit";
        }
      };
    }
  ]);
})();
label {
  padding: 2px;
}
label[contenteditable=true] {
  border: solid 1px #CCCCCC;
  padding: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="app">
  <div data-ng-controller="Controller">
    <form id="form">
      <div>
        <label>Label</label>
        <button data-ng-bind="buttonText" data-ng-click="editSave($event)" type="button"></button>
      </div>
    </form>
  </div>
</div>

This demo works with your last update:

(function() {
  angular
    .module("testApp", [])
    .controller('testController', function($scope) {
      $scope.buttonText = "Edit";

      $scope.editLabel = function(evt) {
        var label = evt.target.previousElementSibling; // Get the label tag from your button.
        var labelData = label.innerText; // Get the label text.

        alert(labelData);

        if ($scope.buttonText == "Edit") { // If the current button's text is "Edit"...
          label.setAttribute("contenteditable", true); // Set contenteditable=true to your label.

          /* To make focusable your editable label. */
          label.setAttribute("target", 0);
          label.focus(); // Set the focus in your label.
          $scope.buttonText = "Save"; // Change the button's text to "Save".
        } else {
          label.removeAttribute("contenteditable");
          label.removeAttribute("target");
          $scope.buttonText = "Edit";
        }
      };
    });
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="testApp" ng-controller="testController">
  <label class="keyColumn">name:</label>
  <label class="valueCoulmn">stackover flow</label>
  <button ng-bind="buttonText" ng-click="editLabel($event)"></button>
</form>

Hope this helps.

Upvotes: 1

T J
T J

Reputation: 43156

You can just show/hide label and inputs using ngshow and ngHide.
Basically the <label> should contain an expression displaying the data and corresponding <input> should contain ngModel pointing to same data. Then use the buttons to simply switch between display modes:

angular.module('test', []).controller('testCtrl', function($scope) {
  $scope.editMode = false;
  $scope.name = "John Doe";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="testCtrl">
  <form>
    <label ng-hide="editMode">{{name}}</label>
    <input ng-show="editMode" ng-model="name">
    <button ng-click="editMode=true">Edit</button>
    <button ng-click="editMode=false">Save</button>
  </form>
</div>

If you think your form is very heavy and don't want to have both the <label> and <input> in DOM at same time, use ngIf instead.

Upvotes: 3

Related Questions