How to edit and load class only for a single element

Asked

Viewed 1,044 times

7

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

Editing:

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

Simulation in Jsfiddle: http://jsfiddle.net/NfPcH/19444/

<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'
  };
});
  • Lucas, from what I saw in your code the idea is to have a list of users and edit each of them, that’s it?

  • Yes. @Pedrocamarajunior

3 answers

5


What should I do to make it happen only in the clicked item?

You must uniquely identify the item under editing.

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

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

inserir a descrição da imagem aqui

Modified version of your code below:

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>
<script src="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-xeditable Text (Bootstrap 3)</h4>

<form ng-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>

4

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

I created a user list

$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 will need a new property, come on.

We will 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>

Note that I created a div that contains field that we will change and the buttons responsible for "Save" and "Cancel", and also used on ng-show the property isEditar user’s - ng-show="usuario.isEditar"

Note that this property - isEditar - has not been declared in any place in our controller, that is, we are using a property undefined, that for our joy, for the 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 some input that changes the value of the property isEditarfrom the user to true. To do this, we define the ng-click to reverse the property value - ng-click="usuario.isEditar= !usuario.isEditar" - that is, when false we will change to true.

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

See the example below and here 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>
<link href="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>

3

This is because Forms are managed by the same property, so it is modified into one reflected in the other.

So to solve this question in specific I separated 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: http://jsfiddle.net/lucassilvax/NfPcH/19457/ I hope I’ve helped

  • Hello @Lukssys, it would be almost that, but I forgot to mention that this structure is inside the loop ng-repeat="item in items track by $index"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.