0

Binding data into html table using knockout. One of the column has large text 200 length.. and UI just got scroll long. So just want to show, first 20 length chars and click of, ... it should expand or collapse the text. so just created a template below,

 <script type="text/html" id="templateLongText">
        <span data-bind="text: (Comments.length > 20 ? Comments.substring(0, 20) + '<a href=\'#\' data-bind=\'click: toggle(Comments)\'>...</a>' : Comments)"></span>
    </script>

It does not work event, just rendering same text as above.

Edit: How toggle the expand or collapse text(Comments value) on click of ...

dsi
  • 3,199
  • 12
  • 59
  • 102

2 Answers2

2

You can't implement html tag as a text in binding.

 <script type="text/html" id="templateLongText">
    <span data-bind="text: Comments.length > 20 ? Comments.substring(0, 20) : Comments"> </span><a href="#" data-bind="click: function(){ toggle(Comments) }, visible: Comments.length > 20">...</a>
</script>
Gawel1908
  • 138
  • 1
  • 9
  • 1
    How to expand and collapse this comments on `toggle(..) ` – dsi Dec 05 '19 at 15:27
  • You can use two variables and one flag. One with full length comment and next with trimmed comment. On toggle you can change the flag and use `visible` binding to display right variable – Gawel1908 Dec 06 '19 at 08:31
2

You could add a custom binding for this, which you can bind to any simple (observable) string. This custom binding:

  • initially adds two child elements. A span for the (abbreviated) text and an anchor for toggling.
  • on every update (or only once if the text is not observable) sets the abbreviated text in the span and adds an onclick handler for toggling the text. The toggle anchor is hidden for texts having less than 20 characters.

ko.bindingHandlers.expandText = {
  init: function(element, valueAccessor) {
    element.appendChild(document.createElement('span'));
    var toggle = document.createElement('a');
    toggle.appendChild(document.createTextNode("..."));
    toggle.href = "#";
    element.appendChild(toggle);
  },
  update: function(element, valueAccessor) {
    var text = ko.unwrap(valueAccessor());
    var textElement = element.getElementsByTagName('span')[0];
    var toggle = element.getElementsByTagName('a')[0];
    var collapsed = true;
    toggle.onclick = function() {
      collapsed = !collapsed;
      ko.utils.setTextContent(textElement, collapsed ? text.substr(0, 20) : text);
    }
    toggle.style.display = text.length > 20 ? 'inline' : 'none';
    ko.utils.setTextContent(textElement, collapsed ? text.substr(0, 20) : text);
  }
};

ko.applyBindings({
  sample1: '1234567890123456789012345',
  sample2: '123456789012345',
  sample3: '123456789012345678901234567890'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="expandText: sample1"></div>
<div data-bind="expandText: sample2"></div>
<div data-bind="expandText: sample3"></div>
Philip Bijker
  • 4,955
  • 2
  • 36
  • 44
  • 1
    Efficient solution.. it works perfect in my grid customtemplate. Thanks a lot ! – dsi Dec 06 '19 at 17:49