Allen
Allen

Reputation: 41

Conditional Table row in angularJs

I have angular display some tables with data from a JSON file.

<div class="inner">
    <div ng-controller="Picks">
        <element>
        <th><b></b></th>
        </element>
        <table id="myTable" class="tablesorter">
            <thead>

                <tr>
                    <th style="width: 70px">League</th>
                    <th style="width: 150px">Away<br>Home
                    </th>
                    <th style="width: 130px">Score</th>
                    <th style="width: 200px">Game Clock</th>
                    <th style="width: 200px">Wager</th>
                    <th style="width: 100px">Amount</th>
                    <th style="width: 100px">Odds</th>
                    <th style="width: 90px">Result</th>
                    <th style="width: 80px">Net</th>
                    <th style="width: 100px;">Game Date</th>
                </tr>
            </thead>

            <tr><td>&nbsp;</td></tr>
            <tbody ng:repeat="i in picks" style="height: 50px; left: 50px">
                <tr style="border-top: 1px solid #000; text-align:left">
                    <td rowspan="2" style="width: 70px">{{i.league}}</td>
                    <td style="width: 150px">{{i.teamName[0]}}</td>
                    <td style="width: 30px">{{i.teamScore[0]}}</td>
                    <td rowspan="2" style="width: 100px">{{i.quarter}}</td>
                    <td rowspan="2" style="width: 200px"><b>{{i.pick}}</b></td>
                    <td rowspan="2" style="width: 100px">{{i.units}} Unit(s)</td>
                    <td rowspan="2" style="width: 100px">{{i.odds}}</td>
                    <td rowspan="2" style="width: 80px">{{i.result}}</td>
                    <td rowspan="2" style="width: 80px">{{i.net | number}}
                        Unit(s)</td>
                    <td rowspan="2" style="width: 100px; text-align: center">{{i.time}}</td>
                </tr>

                <tr style="text-align:left">
                    <td style="width: 150px">{{i.teamName[1]}}</td>
                    <td style="width: 30px">{{i.teamScore[1]}}</td>
                </tr>


                <tr><td>&nbsp;</td></tr>
            </tbody>
        </table>
    </div>
</div>
function Picks($scope, $http) {
    $http.get('http://xxxxxxxx/Service/picks').
        success(function(data) {
            $scope.picks = data;
        });
}

Now what I want to do is, if there exists a pick2 property in the json, then create another tr and display some information.

How can I create this conditonal HTML row?

The JSON is shown below, sometimes there will be a pick2, and a pick3. When they exist, Id like the units2, odds2, result2, etc associated with that pick to be displayed on my table:

Upvotes: 3

Views: 6101

Answers (3)

Michael Kang
Michael Kang

Reputation: 52847

Demo

If you have a table structure like this:

<table>
    <thead>
        <tr>
           <th>Name</th>
           <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="row in rows">
            <td>{{row.name}}</td>
            <td>{{row.description}}</td>
        </tr>
    </tbody>
</table>

And you want to conditionally display another row depending on whether a property exists on a given iteration of ngRepeat, then I recommend implementing a directive (smartRow) that checks for the property and adds the additional row when the property exists:

<table>
    <thead>
        <tr>
           <th>Name</th>
           <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="row in rows" smart-row="row">
            <td>{{row.name}}</td>
            <td>{{row.description}}</td>
        </tr>
    </tbody>
</table>

Directive

  app.directive('smartRow', function($compile) {
    return  {
      restrict: 'A',
      transclude: 'element',
      link: function(scope, element, attr, ctrls, transcludeFn) {
        var model = scope.$eval(attr.smartRow);
        transcludeFn(function(clone) {
          element.after(clone);
          if (model.hasOwnProperty('price')) {

             var priceRow = angular.element('<tr price-row="' + model.price + '"></tr>');
             clone.after(priceRow);
             $compile(priceRow)(scope);
          }
        })
      }
    }
  });

The example solution was meant to demonstrate concepts that you could use in your own solution:

  1. Using ngRepeat to loop over your array model and output HTML row elements
  2. Using a custom directive to conditionally check for a property, and when it exists, insert another row element after it (the price row in my example). The directive uses 'element' transclusion to achieve this.
  3. Using the $compile service to manually compile the extra row and link it to the child scope created by ngRepeat. In my example, I created a tr row with a priceRow directive, inserted it into the DOM, and then manually compiled it and linked it to the right scope.

Upvotes: 1

Anita
Anita

Reputation: 2400

    <tbody ng:repeat="i in picks" style="height: 50px; left: 50px">
            <tr style="border-top: 1px solid #000; text-align:left">
                ....
            </tr>
             <tr ng-show="i.pick2 !== '' && i.pick2 !== undefined && i.pick2 !== null">
              ...
           </tr>
  </tbody>

This way you can display tr conditionally.

Upvotes: 3

Andy
Andy

Reputation: 5414

One idea to achieve this is use the ngIf directive (see here) to check for the pick2

You create two different set of <tr> one with something like <tr ng-if="pick2"> and another like <tr ng-if="!pick2"> so when you ngRepeat looped, it can decide which <tr> to be generated.

Another way is to create a custom directive where you can treat pick2 as an input parameter for the custom directive to generate the appropriate <tr> markup.

Upvotes: 0

Related Questions