How to edit and load class only for a single element

7

I have the following HTML structure below. However, by clicking on one of the "items" the class (editing) is displayed for both elements. What should I do to make this happen only on the clicked item?

Editing:

Note: ng-click , is within loop ng-repeat="item in items track by $index"

Simulation in JSFiddle: link

<h4>Angular-xeditable Text (Bootstrap 3)</h4>
<form ng-app="app" ng-controller="Ctrl" editable-form name="formulario">

  <!-- Texto I -->
  <a href="#" ng-click="formulario.$show()" ng-show="!formulario.$visible" editable-text="user.name">{{ user.name || 'empty' }}</a>
    <div class="buttons">
      <!-- buttons to submit / cancel form -->
      <span ng-show="formulario.$visible">
        <br/>
        <button type="submit" class="btn btn-primary" ng-disabled="formulario.$waiting">
          Save
        </button>
        <button type="button" class="btn btn-default" ng-disabled="formulario.$waiting" ng-click="formulario.$cancel()">
          Cancel
        </button>
      </span>
    </div>
    <br />

    <!-- Texto II -->
    <a href="#" ng-click="formulario.$show()" ng-show="!formulario.$visible" editable-text="user.name">{{ user.name || 'empty' }}</a>
    <div class="buttons">
      <!-- buttons to submit / cancel form -->
      <span ng-show="formulario.$visible">
        <br/>
        <button type="submit" class="btn btn-primary" ng-disabled="formulario.$waiting">
          Save
        </button>
        <button type="button" class="btn btn-default" ng-disabled="formulario.$waiting" ng-click="formulario.$cancel()">
          Cancel
        </button>
      </span>
    </div>
</form>

JavaScript:

var app = angular.module("app", ["xeditable"]);

app.run(function(editableOptions) {
  editableOptions.theme = 'bs3';
});

app.controller('Ctrl', function($scope) {
  $scope.user = {
    name: 'awesome user'
  };
});
    
asked by anonymous 02.06.2017 / 01:40

3 answers

5
  

What should I do to make this happen only on the clicked item?

You must uniquely identify the item under edit.

  

The ng-click is within the ng-repeat="item in items track by $index" loop

Then you can use $index as the unique identifier of the item under edit.

Modifiedversionofyourcodebelow:

var app = angular.module("app", ["xeditable"])
.run(function(editableOptions) {
  editableOptions.theme = 'bs3';
})
.controller('Ctrl', function($scope) {
  $scope.targetIndex = -1;
  
  $scope.toggle = function(index){

    // Se o targetIndex atual for o mesmo do selecionado, então apague.
    // Caso contrário, salve o índice selecionado em targetIndex.

    $scope.targetIndex = ($scope.targetIndex == index ? null : index);
  }
  
  $scope.users = [
  {    name: 'awesome user 1'  }, 
  {    name: 'awesome user 2'  }, 
  ];
});
div[ng-app] { margin: 50px; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-sanitize.min.js"></script>
<script src="https://vitalets.github.io/angular-xeditable/dist/js/xeditable.js"></script><h4>Angular-xeditableText(Bootstrap3)</h4><formng-app="app" ng-controller="Ctrl" editable-form name="formulario">
  
  <div ng-repeat="user in users track by $index">
  <a href="#" ng-click="toggle($index)" ng-show="!(targetIndex == $index)" editable-text="user.name">{{ user.name || 'empty' }}</a>
  <input type='text' ng-model="user.name" ng-show="targetIndex == $index"/>
    <div class="buttons">
      <!-- buttons to submit / cancel form -->
      <span ng-show="targetIndex == $index">
        <br/>
        <button type="submit" class="btn btn-primary" ng-disabled="formulario.$waiting" ng-click="toggle($index)">
          Save
        </button>
        <button type="button" class="btn btn-default" ng-disabled="formulario.$waiting" ng-click="toggle($index)">
          Cancel
        </button>
      </span>
    </div>
  <br />
  </div>
</form>
    
07.06.2017 / 17:39
4

The solution to your problem is very simple, you only need to have a boolean property within each user, we will use this property to show or hide the specific user's editing html, see my example:

I created a list of users

$scope.usuarios = [{
    nome: 'João Batista'
  },
  {
    nome: 'Josefa Santos'
  }
];

Note that each user has only one property - nome , however, to control whether each user's div will be displayed or not, we'll need a new property, come on.

Let's use a new property for each user

<div class="col-xs-6 col-xs-offset-3" ng-show="usuario.isEditar">
  <div class="form-group">
    <input type="text" class="form-control" ng-model="usuario.nome">
    <button class="btn btn-primary" ng-click="salvar(usuario)">Salvar</button>
    <button class="btn btn-default" ng-click="usuario.isEditar = !usuario.isEditar">Cancelar</button>
  </div>
</div>

See that I created a div that contains the field that we are going to change and the buttons responsible for "Save" and "Cancel", and I also used the ng-show property of the user isEditar of the user - ng-show="usuario.isEditar"

Note that this property - isEditar - was not declared elsewhere in our controller, ie we are using a undefined property, which to our delight, for ng-show will be considered as false and our div will not be shown.

Now, how do we show the div with the edit fields?

<div class="col-xs-6 col-xs-offset-3" ng-show="!usuario.isEditar">
  {{ usuario.nome }} <a href="javascript:void(0)" ng-click="usuario.isEditar= !usuario.isEditar">Editar</a>
</div>

Simple, we create another div with any input that changes the value of the isEditar property of the user to true . To do this, we set the ng-click to invert the value of the property - ng-click="usuario.isEditar= !usuario.isEditar" - that is, when it is false we will change to true .

Note also that I only show this div when isEditar is false - ng-show="!usuario.isEditar"

See the example below and here for your fiddle with the changes.

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

angular.module('myApp').controller('myCtrl', MyCtrl);

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

function MyCtrl($scope) {
  $scope.usuarios = [{
      nome: 'João Batista'
    },
    {
      nome: 'Josefa Santos'
    }
  ];
  
  $scope.salvar = Salvar;
  
  function Salvar(usuario) {
    console.clear();
    console.log('Objeto usuário selecionado: ' + JSON.stringify(usuario));
    alert('Você salvou o usuário ' + usuario.nome);
    
    usuario.isEditar= !usuario.isEditar;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script><linkhref="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="myApp">
  <div class="container" ng-controller="myCtrl">
    <div class="row" ng-repeat="usuario in usuarios">
      <div class="col-xs-6 col-xs-offset-3" ng-show="!usuario.isEditar">
        {{ usuario.nome }} <a href="javascript:void(0)" ng-click="usuario.isEditar= !usuario.isEditar">Editar</a>
      </div>
      <div class="col-xs-6 col-xs-offset-3" ng-show="usuario.isEditar">
        <div class="form-group">
          <input type="text" class="form-control" ng-model="usuario.nome">
          <button class="btn btn-primary" ng-click="salvar(usuario)">Salvar</button>
          <button class="btn btn-default" ng-click="usuario.isEditar = !usuario.isEditar">Cancelar</button>
        </div>
      </div>
    </div>
  </div>
</div>
    
06.06.2017 / 22:49
3

This happens because forms are managed by the same property, so it is modified in one reflects on the other.

So to solve this question in specific I separate the variables that manage the state of the form.

HTML

<h4>Angular-xeditable Text (Bootstrap 3)</h4>
<form ng-app="app" ng-controller="Ctrl" editable-form name="formulario">

  <!-- Texto I -->
  <a href="#" ng-click="show1()" ng-show="!form1Visible" editable-text="user.name">{{ user.name || 'empty' }}</a>
    <div class="buttons">
      <!-- buttons to submit / cancel form -->
      <span ng-show="form1Visible">
        <br/>
        <button type="submit" class="btn btn-primary" ng-disabled="formulario.$waiting">
          Save
        </button>
        <button type="button" class="btn btn-default" ng-disabled="formulario.$waiting" ng-click="cancel1()">
          Cancel
        </button>
      </span>
    </div>
    <br />

    <!-- Texto II -->
    <a href="#" ng-click="show2()" ng-show="!form2Visible" editable-text="user.name">{{ user.name || 'empty' }}</a>
    <div class="buttons">
      <!-- buttons to submit / cancel form -->
      <span ng-show="form2Visible">
        <br/>
        <button type="submit" class="btn btn-primary" ng-disabled="formulario.$waiting">
          Save
        </button>
        <button type="button" class="btn btn-default" ng-disabled="formulario.$waiting" ng-click="cancel2()">
          Cancel
        </button>
      </span>
    </div>
</form>

JS

var app = angular.module("app", ["xeditable"]);

app.run(function(editableOptions) {
  editableOptions.theme = 'bs3';
});

app.controller('Ctrl', function($scope) {
  $scope.user = {
    name: 'awesome user'
  };
  $scope.form1Visible = false;
  $scope.form2Visible = false;

  $scope.show1 = function () {
    $scope.form1Visible = true;
  } 
  $scope.show2 = function () {
    $scope.form2Visible = true;
  } 
  $scope.cancel1 = function () {
    $scope.form1Visible = false;
  }
  $scope.cancel2 = function () {
    $scope.form2Visible = false;
  }
});

JSFIDDLE: link I hope I have helped

    
05.06.2017 / 16:07