12/08/2018, 14:19

Truncate Text AngularJS Directive

I-Giới thiệu Bài viết này sẽ hướng dẫn cách viết một AngularJS directive để cắt bớt đi một đoạn text dài dòng thành dấu ba chấm và có thêm nút hiển thị ra hết nội dung và ẩn đi lại mà không dùng css. Thông thường AngularJS đã cho một filter có tên limitTo để tạo một array hoặc string chứa một ...

I-Giới thiệu

Bài viết này sẽ hướng dẫn cách viết một AngularJS directive để cắt bớt đi một đoạn text dài dòng thành dấu ba chấm và có thêm nút hiển thị ra hết nội dung và ẩn đi lại mà không dùng css.

Thông thường AngularJS đã cho một filter có tên limitTo để tạo một array hoặc string chứa một số phân tử quy định. các phần tử được lấy từ điểm bắt đầu hoặc kết thúc của nguồn array, string hoặc số được xác định bởi giá trị và dấu(số dương hay số âm) quy định. ví dụ:

  • Có một string vm.longText rồi dùng limitTo để hạn chế độ dài của string.

$scope.longText = "Lorem ipsum dolor sit amet, and a possibly long remaining text.";

  • Trong view
{{longText|limitTo:15}}
-> Lorem ipsum dol
  • Cho thêm một điều kiện nữa để có dấu "..."
{{longText|limitTo:15}}{{longText.length > 15? "..." : ""}}
-> Lorem ipsum dol...

II-Viết directive

Dưới đây sẽ viết một directive dùng để cắt bớt text. Nhưng để tiện cho việc sử dụng ở nhiều chỗ thì sẽ viết thành một module angularJS cho nên việc sử dụng những module khác chỉ cần inject vào dependency là dùng được.

(function() {
  'use strict';
  var truncateTextApp = angular.module("truncateTextApp", []);

  truncateTextApp.factory("truncationService", TruncationService);
  TruncationService.$inject = ["$compile"];
  function TruncationService($compile) {
    return {
      truncationApplies: function($scope, limtchars) {
        return $scope.text.length > limtchars;
      },
      applyTruncation: function(limtchars, $scope, $element) {
        var more_label = "More";
        var less_label = "Less";
        if($scope.useToggling) {
            var el = angular.element("<span>" + $scope.text.substr(0, limtchars) +"<span ng-show='!open'>...</span>" +
              "<span class='btn-link ngTruncateToggleText' " + "ng-click='toggleShow()'" + "ng-show='!open'>" + " " +
              more_label + "</span>" + "<span ng-show='open'>" + $scope.text.substring(limtchars) +
              "<span class='btn-link ngTruncateToggleText'" + "ng-click='toggleShow()'>" +
              " " + less_label + "</span></span></span>" );
            $compile(el)($scope);
            $element.append(el);
        } else {
          $element.text($scope.text.substr(0, limtchars) + "...");
        }
      }
    };
  };

  truncateTextApp.directive("truncateTextDir", TruncateTextDir);
  TruncateTextDir.$inject = ["truncationService"];
  function TruncateTextDir(truncationService) {
    var directive = {
      link: link,
      restrict: "A",
      scope: {
        text: "=truncateTextDir",
        charsLimit: "@charsLimit",
      },
      controller: ["$scope", "$attrs", function($scope, $attrs) {
        $scope.toggleShow = function() {
          $scope.open = !$scope.open;
        };
        $scope.useToggling = $attrs.noToggling === undefined;
      }]
    };
    return directive;

    function link($scope, $element, $attrs) {
      $scope.open = false;
      var CHARS_LIMIT = parseInt($scope.charsLimit);
      $scope.$watch("text", function() {
        $element.empty();
        if(CHARS_LIMIT) {
          if($scope.text && truncationService.truncationApplies($scope, CHARS_LIMIT)) {
            truncationService.applyTruncation(CHARS_LIMIT, $scope, $element);
          } else {
            $element.text($scope.text);
          }
        }
      });
    }
  };
}());
  • Cách dùng:

Chúng ta tạo một app có tên myApp rồi thêm directive vào dependency.

var app = angular.module("myApp", ["truncateTextApp"]);
app.controller("homeCtrl", HomeCtrl);
HomeCtrl.$inject = ["$scope"];
function HomeCtrl($scope) {
  var vm = this;
  vm.data = {
    "title": "Why do we use it?",
    "content":
      "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout."+
      "The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters"+
      "as opposed to using 'Content here, content here', making it look like readable English."+
      "Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text"+
      "and a search for 'lorem ipsum' will uncover many web sites still in their infancy. "+
      "Various versions have evolved over the years, sometimes by accident"+
      "sometimes on purpose (injected humour and the like)."
  };
}
  • Trường hợp chỉ ẩn thị thành ba chấm.
<span truncate-text-dir="vm.data.content" chars-limit="120" no-toggling=true></span>
  • Trường hợp muốn có nút less and more.
<span truncate-text-dir="vm.data.content" chars-limit="120"></span>

III-Kết quả

  • Trước và sau khi chỉ ẩn thị thành ba chấm.

truncate_directive_1.png

  • Trước và sau khi muốn có nút less and more.

truncate_directive_2.png

  • Hiển thị ra tất cả nội dung bị ẩn

truncate_directive_3.png

IV-Kết luận

Sau khi các bạn tham khảo bài viết này sẽ giúp và hỗ trợ việc cắt bớt đi các đoạn text dài mà không cần dùng css và có thể quy định cho hiển thị tùy ý.

0