1

I am new to Knockout JS, therefore need your help to fix one small issue. I am trying to bind css style with a table row in CSHTML page, based on a condition. I have added 2 rows but displaying only one for each item using 'visible' attribute. Following is my cshtml code:

<table class="listing">
<tbody class="no-wrap" data-bind="foreach: searchResultsListing.pagedItems, select: searchResultsListing">
<tr class="selectable" data-bind="visible: !$root.isMatchedCase($data), css: { selected: $root.searchResultsListing.isSelected($data) }">
<td class="check"><span></span></td>
--
--
<tr/>
<tr class="selectablematch" data-bind="visible: $root.isMatchedCase($data), css: { selected: $root.searchResultsListing.isSelected($data) }">
<td class="check"><span></span></td>
--
--
<tr/>

Underlying Typescript: Inside app.listing.ts File:

isSelected(item: T) {
   return this.selectedItems.indexOf(item) >= 0;
}

As you can see, based on the result of isMatchedCase() method (which returns a boolean), I am displaying either of the tr (selectable or selectablematch). The problem is the css on the tr is getting binded only for the first tr, i.e. with the class selectable, and not getting binded with the selectablematch tr. The method 'isSelected($data)' is not getting called when the checkbox in the first td is clicked for 'selectablematch' tr. Can you guys please let me know what I am missing here?

3
  • Code looks ok... Is there any other binding before selectablematch? Is there any error? Commented Aug 16, 2018 at 9:25
  • @ray - Thats the thing, I do not see any errors in console too :( And there are just bindings in 'visible' and foreach loop before this, as I have already mentioned in the code. Commented Aug 16, 2018 at 9:38
  • Would it be possible to share the rest of your code? Commented Aug 16, 2018 at 16:17

1 Answer 1

2

I am little confused as to why you need to have 2 tr to begin with. What you could do is have a computed which would return the correct class for you and have only one row which will be always visible. Not need to deal with hide/show etc.

Look at this article on the css binding and how it is done. Here is what I am suggesting:

<table class="listing">
  <tbody class="no-wrap" data-bind="foreach: searchResultsListing.pagedItems, select: searchResultsListing">
    <tr data-bind="css: { rowClass($data), selected: $root.searchResultsListing.isSelected($data) }">
      <td class="check"><span></span></td>
    <tr/>
  </tbody>
</table>

And your pureComputed (wrapped in a function so we can pass the $data):

var rowClass = function(data) {
  return ko.pureComputed(function(){
    return isMatchedCase(data) ? 'selectablematch' : 'selectable')
  )}
}

I think that should get you going in the right direction.

Sign up to request clarification or add additional context in comments.

1 Comment

That looks like a much better approach. Thanks @Akiron.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.