0

I have a problem with .dotdotdot jQuery plugin used with KnockoutJS. I have similar structure:

<div class="dotdotdot">
    <h3 data-bind="text: Text"></h3>
</div>
<input data-bind="value: Text"/>
<button data-bind="click: someThingsThatTriggerDotdotdotFunction"/>    

The problem is that when dotdotdot function is called on html element with class dotdotdot then binding relation gets broken.

$('.dotdotdot').dotdotdot({});

After the above code execution value of h3 is no longer updating after input value change.

I am new to Knockout so I would like to ask for some help with my issue.

krzyhub
  • 6,285
  • 11
  • 42
  • 68
  • 1
    Sounds like there is a conflict. You might need to do a custom binding using knockout. Read this article http://www.knockmeout.net/2011/07/another-look-at-custom-bindings-for.html – Matin Kajabadi Aug 02 '16 at 21:42

2 Answers2

0

I created a custom binding handler to work around the issue:

ko.bindingHandlers.dotDotDot = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        var value = allBindingsAccessor().dotDotDot.Value;

        $(element).html(value());

        var dotdotdot = $(element).parent().truncate(options);

        allBindingsAccessor().dotDotDot.Value.subscribe(function (newValue) {
            $(element).html(newValue);
            dotdotdot.trigger("update.dot");
        });
    }
};
<div class="announcement-container">
    <div data-bind="dotDotDot: { Value: Announcement, height: 80 }"></div>
</div>
combatc2
  • 1,215
  • 10
  • 10
0

As @combatc2 solution doesn't seem to work nowadays, I have created another custom binding for this purpose, adding a show more/less anchor to toggle between truncated and original text (Dotdotdot v5.0.4 (es6), Knockout v3.5.0).

<div data-bind="dotdotdot: myObservable, maxHeight:250, moreLess: true"></div>
ko.bindingHandlers["dotdotdot"] = {
  init: function(element, valueAccessor, allBindingsAccessor) {
    let valueUnwrapped = ko.utils.unwrapObservable(valueAccessor());
    const maxHeight = allBindingsAccessor().maxHeight || 100;
    const moreLess = allBindingsAccessor().moreLess || false; //show more/less anchor

    function addMoreLess(val) {
      if (val != null && moreLess)
        val += '<a class="ddd-toggle d-none ddd-keep" href="#"></a>';
      return val;
    }
    valueUnwrapped = addMoreLess(valueUnwrapped);
    if (valueUnwrapped == null) valueUnwrapped = "";
    var options = {
      height: maxHeight,
      watch: "window", //"window" avoids recalculating  the truncation after adding show more/less anchor.
      keep: ".ddd-keep" // preserve these elements (for show more/less anchor)
    };

    $(element).html(valueUnwrapped);
    var ddd = new Dotdotdot(element, options); //es6 version

    //show more/less anchor handler
    $(element).on("click", ".ddd-toggle", function(e) {
      e.preventDefault();
      if ($(element).hasClass("ddd-truncated")) {
        ddd.restore();
        $(element).addClass("ddd-full-story");
      } else {
        $(element).removeClass("ddd-full-story");
        ddd.truncate();
        ddd.watch();
      }
    });

    //we put the 'update' callback code in a computed here so it gets the 'ddd' Dotdotdot instance)
    ko.computed({
      read: function() {        
        var text = ko.utils.unwrapObservable(valueAccessor());        
        ddd.API.unwatch();
        text = addMoreLess(text);
        $(element).html(text);
        //we need to update the originalContent (no API method here)
        ddd.originalContent = ddd._getOriginalContent();
        ddd.API.truncate();
        ddd.API.watch();
      },
      disposeWhenNodeIsRemoved: element
    });

  }
}

css for anchor "show more/less":

.d-none{display:none;}
.ddd-truncated .ddd-toggle,
.ddd-full-story .ddd-toggle{
    display: inline !important;
}
.ddd-toggle:before {
    content: '[ Show more ]';
}
.ddd-full-story .ddd-toggle:before {
    content: '[ Show less ]';
}

Working example: https://codepen.io/raguchi/pen/VRVwqx

(note that example works with es6 version of Dotdotdot)

raguchi
  • 51
  • 5