0

I have an HTML table that expands or collapse depending if the user clicks on a row, the main record is the "parent" row, if you click it you'll see a child row that displays some records, my issue is that I add a third row that should display by default because the child is hidden until you click on the parent but that third row wont appear and I cant figure out the problem =(

Here's my example in a fiddle and below youll see my directive.

angular
.module('app',[])
.controller('DataCtrl',DataCtrl)
.directive('drillDown',drillDown);

 function DataCtrl($scope) {
  $scope.category = [
            {
                "desc": "CATEGORY 1",
                "LW$": "45",
                "LW": "-4%",
                "L4W": "-15.7%",
                "L13W": "24%",
                "L52W": "-6%"
            }
        ]

        $scope.subcat = [
            {
                "desc": "SUB CATEGORY 1",
                "LW$": "45",
                "LW": "-4%",
                "L4W": "-15.7%",
                "L13W": "24%",
                "L52W": "-9%"
            },
            {
                "desc": "SUB CATEGORY 2",
                "LW$": "15",
                "LW": "4.2%",
                "L4W": "1.7%",
                "L13W": "-2.4%",
                "L52W": "-65%"
            },
            {
                "desc": "SUB CATEGORY 3",
                "LW$": "767",
                "LW": "4.2%",
                "L4W": "9.7%",
                "L13W": "-2.4%",
                "L52W": "-21%"
            },
            {
                "desc": "SUB CATEGORY 4",
                "LW$": "21",
                "LW": "14.2%",
                "L4W": "1.7%",
                "L13W": "-42.4%",
                "L52W": "-34%"
            }
        ];
    }

    function drillDown() {

     var directive = {
     restrict: 'A',
    link: link
    };

    return directive;

    function link(scope,element) {

     var table = $('.categories-table');

     table.each(function() {
        var $table = $(this);
        $table.find('.parent').each(function(){
            if($(this).nextUntil('.parent', ".child").length > 0){
                $(this).children('td:first').html('+');
            }
        });
        $table.find('.child').each(function(){
            if($(this).nextUntil('.child', ".grandson").length > 0){
                $(this).children('td:first').html('+');
            }
        });

        var $childRows = $table.find('tbody tr').not('.parent').hide();
        $table.find('button.hide').click(function() {
            $childRows.hide();

        });
    });
    element.on('click',function(){
        if($(this).parent().hasClass('parent') == true)
        {
            console.log("----Parent");
            if ($(this).text() == "+")
                $(this).text("-")
            else
                $(this).text("+");

            $(this).parent().nextUntil('.parent', ".child").fadeToggle("slow", "linear");
            $(this).parent().nextUntil('.parent', ".grandson").hide("fast");
            $(this).parent().nextUntil('.parent', ".child").each(function(){

                if($(this).children('td:first').text() == '-')
                    $(this).children('td:first').text('+');
            });
        }
        else if($(this).parent().hasClass('child') == true)
        {
            console.log("----Child");
            if ($(this).text() == "+")
                $(this).text("-")
            else
                $(this).text("+");
            $(this).parent().nextUntil('.child',    ".grandson").fadeToggle("slow", "linear");
        }
    });
 }
}

1 Answer 1

1

First of all I recommend you to read this topic: "Thinking in AngularJS" if I have a jQuery background?

Obviously you are using jquery+angular in a wrong way. And there is a logic error in your jQuery code.

If you want to solve problem in angular-way:

One possible solution is to use scope variables or object variables and ng-show directive.

Something like this: https://jsfiddle.net/p7ew017u/4/

<td ng-class="expand" ng-click="d.expanded = !d.expanded">+</td>

And one more thing: tables are not very good for displaying tree structures (like categories, subcategories, subsubcategories, etc). It is better to use lists (ul, ol)

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

4 Comments

Thanks for your time, I know that is not the best way and I'm planning to improve my version but now for time issues I need to solve it... Wich is my logic issue in my jquery? :(
It's here var $childRows = $table.find('tbody tr').not('.parent').hide(); You hide all rows with class not .parent and last row hasnt .parent
One more question, what if I want to add a new level, like sub. sub category according to your example how can I manage that?
The best way is to build tree of categories, i.e. [{title: "Category1", children: [{title: "SubCategory1", children: [...] }, {...}]}, {...}]. And in template use nested <ul> with ng-repeat

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.