Search code examples
jquery-uiknockout.jsknockout-sortable

Custom template binding on sortable elements based on condition (Knockout.js Sortable)


I have an observable array of items which are made draggable/droppable using the Knockout sortable plugin. I am able to apply a custom template binding on the elements as per the doc using following piece of code.

<div style="border-width:0;" data-bind="sortable: {template: 'customTemplate', data: observableArray}">

My requirement is to use different templates for different items in the array based on certain condition applied to the item property. For example, if we have a property called 'status' for each item in the observable array, I want to bind 'template1' if status is true else 'template2'.

I am able to achieve the same for arrays which can be traversed using foreach loop in ko, but unable to do the same for sortable array since it does not allow to use foreach. Can someone suggest a solution/workaround to the same?

UPDATE: I was able to apply custom binding in the same template based on condition but it lead to a strange error where the element gets cloned in the parent container while dragging and dropping it into a target container. Demo can be seen here: jsFiddle

I have applied different style to students based on name but on dropping the student to a table, it gets cloned in the parent table as well. What can be the possible issue?

Note: I do not want to bind conditional css to my elements, I want to differentiate the way elements render, based on condition. Example - Going by the table seating example, if I have properties name, age and class for students object, I just want to show name for few students while all 3 properties for some as can be seen in the example fiddle.


Solution

  • we can fix the issue using conditional css binding

    View :

    <script type="text/html" id="customTmpl">
            <div  data-bind="css:{'one': name() === 'Bobby' ? true : false ,'two': name() != 'Bobby' ? true : false } ">
                <p data-bind="text: name"></p>
            </div>
    </script>
    

    Instead of going for a conditional containerless if we can simply avoid it and do it with conditional css binding .

    Working fiddler here

    Documentation on css available here