Scrolling in KnockoutJS

Scrolling in KnockoutJS

by JBrooks 7. January 2015 05:51

I have a KnockoutJS site (SupplyChaser.com ) where the user can change the order of the products by clicking an up or down arrow image when the product’s row is selected. See below.

image

The problem was getting the scrolling right if the move made the row go above or below the viewing area. If in the example above the user clicked the down arrow, the row would be move so it would be under the menu. So need a little code to scroll it back into view. Since it took way longer than it should have I thought I would post the code I ended up with.

First, KnockoutJS does the binding to the click event for us:

<td class="ControlTD"> <div data-bind="visible: AmISelected()"> <button data-bind="click: $root.editProduct">Edit</button> &nbsp;&nbsp; <img src="/Images/Site/Up.png" data-bind="click: $root.moveProductUp" /> Move <img src="/Images/Site/Down.png" data-bind="click: $root.moveProductDown" /> &nbsp;&nbsp; <img src="/Images/Site/Remove.png" data-bind="click: $root.removeProduct" /> </div> </td>
In my KnockoutJS model I have the functions that we bind to. Notice the first parameter passed to us is the object that is bound to the table row. The second parameter contains a property called “event.target” that will have a reference to the image that was just clicked.

 

self.moveProductDown = function (Product, event) { /*.... code to reorder the array here .... */ scrollIntoView(event.target);

And now the function I had to play with to get right. Obviously this uses JQuery. The hard coded values are based on how big my top and bottom menu’s are. This works better than I expected because the animate shows the page scrolling to the new position.

function scrollIntoView(element) { var elemTop = $(element).offset().top if (elemTop == 0) return; var windowTop = $(window).scrollTop(); var windowBottom = windowTop + $(window).height(); if (elemTop < windowTop + 190) { elemTop -= 190; } else if (elemTop > windowBottom - 220) { elemTop = elemTop - $(window).height() + 220; } else return; $('html, body').animate({ scrollTop: elemTop }); }

Tags: