0

Can we dynamically create a simple span to input with ng-model feature only when we click on the span.

I have already gone through the way, where i am creating both span and input and hiding input in the loading by ng-hideand only displaying input when user is clicking on the span. but here the problem is we are binding input directly with the value by ng-model and its causing slowness and hanging problem in browser where we have large list of data (i have tested with 1000 values).

Please help me on this, I want to make all read only data in the loading and when user will click on the span then it should dynamically converted into the input box, when we make any changes on it then it should to save in the list.

Plunkr : http://plnkr.co/hwi1vXQxgaTSMzEdwcf7

HTML

<div ng-controller="myctrl">
  <div ng-repeat="value in list">
    <span ng-click="editThis()" tabindex="0">{{value}}</span>
  </div>
</div>

CONTROLLER

app.controller("myctrl", function($scope){
  $scope.list = [
    "sports", "coverage", "breaking", "news", "live",
    "results", "and", "complete", "sport", "information:",
    "football", "basket", "tennis"
    ];
  $scope.editThis = function(){

  };
});
Praveen Rawat
  • 724
  • 2
  • 12
  • 29
  • See this [answer](https://stackoverflow.com/a/18214735/3455035) , but i think your original approach of having `span\input` and using `ng-if` to interchange would be better, rather than creating custom directive and running it in loop. try to make app faster via `track by` in ng-repeat or avoiding function in `ng-if\ng-show` – anoop May 31 '17 at 14:17

1 Answers1

0

Starting that my suggestion is to avoid to display at the same time thousands of items, and if possible use pagination (for example angular ui bootstrap pagination component is awesome), you can achieve want you want with something like the following:

var app = angular.module('app', []);
app.controller("myctrl", function($scope, $compile, $rootScope, $timeout){
  $scope.list = [
    "sports", "coverage", "breaking", "news", "live",
    "results", "and", "complete", "sport", "information:",
    "football", "basket", "tennis"
    ];

  $scope.editThis = function($event, ind){
    angular.element($event.currentTarget).replaceWith( $compile('<input type="text" ng-model="list['+ind+']" ng-blur="blurThis($event, '+ind+')">')($scope));
  };
  $scope.blurThis = function($event, ind){
    angular.element($event.currentTarget).replaceWith( $compile('<span ng-click="editThis($event, '+ind+')"  tabindex="0">{{list['+ind+']}}</span>')($scope));
  };
});
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-app="app">
      <div ng-controller="myctrl">
          <div ng-repeat="value in list track by $index">
            <span ng-click="editThis($event, $index)" tabindex="0">{{value}}</span>
          </div>
      </div>
  </body>
</html>

Please, use a custom directive in order to keep things clearer and move this logic inside your directive. Then inside your ng-repeat there will be your directive.

I hope it helps.

quirimmo
  • 9,800
  • 3
  • 30
  • 45