dsi
dsi

Reputation: 3359

knockout toggle/expand the text on click of text

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 ...

Upvotes: 0

Views: 334

Answers (2)

Philip Bijker
Philip Bijker

Reputation: 5115

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>

Upvotes: 2

Gawel1908
Gawel1908

Reputation: 138

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>

Upvotes: 2

Related Questions