Show more and Hide details in an AngularJS modal template

Viewed 145

I am having an AngularJS modal template where I project my response from the scope. The template looks something like this:

<div class="modal-body" id="modal-body">
<uib-accordion close-others="true">
    <div uib-accordion-group class="mt-1" ng-repeat="x in data.details" heading="{{data.displayName}}">
        <pre>{{ x|json:4 }}</pre>
    </div>
</uib-accordion>

I want to display a table with the most important fields of 'x' first then, give a "showMore" field where on button clicked, we would be displayed complete JSON. The Button here works as a toggle to Show important details(table) or the Complete details(Json Response) I am following a less Angular way, but using Javascript and HTML. The following this the implementation:

<div class="modal-body" id="modal-body">
<uib-accordion close-others="true">
    <div uib-accordion-group class="mt-1" ng-repeat="x in data.details" heading="{{data.displayName}}">
        <span id="dots"> <table>..</table> </span>
        <span id="more"> <pre>{{ x|json:4 }}</pre> </span>
        <button onclick="myFunction()" id="myBtn">Read more</button>
    </div>
</uib-accordion>

<script type="text/javascript">
    function myFunction() {
        var dots = document.getElementById("dots");
        var moreText = document.getElementById("more");
        var btnText = document.getElementById("myBtn");

        if (dots.style.display === "none") {
            dots.style.display = "inline";
            btnText.innerHTML = "Read more";
            moreText.style.display = "none";
        } else {
            dots.style.display = "none";
            btnText.innerHTML = "Read less";
            moreText.style.display = "inline";
        }
}
</script>

How could I not use Javascript and make my needs match? I want to implement a more Angular way, I am new to Angular please mind my brevity. Thanks in advance.

1 Answers

You have a few options straight from Angular. The core principle is to use a variable from your component and check it as well as update in/from your template.

First solution, template:

<div uib-accordion-group class="mt-1" ng-repeat="x in data.details" heading="{{data.displayName}}">
    <span id="dots" [hidden]="! showTable"> <table>..</table> </span>
    <span id="more" [hidden]="showTable"> <pre>{{ x|json:4 }}</pre> </span>
    <button (click)="toggleTableVisibility()" id="myBtn">Read more</button>
</div>

And in the component

showTable = true;

function toggleTableVisibility() {
    this.showTable = ! this.showTable;
}

Second solution, using ngIf, only the template changes

<div uib-accordion-group class="mt-1" ng-repeat="x in data.details" heading="{{data.displayName}}">
    <span id="dots" *ngIf="showTable"> <table>..</table> </span>
    <span id="more" *ngIf="! showTable"> <pre>{{ x|json:4 }}</pre> </span>
    <button (click)="toggleTableVisibility()" id="myBtn">Read more</button>
</div>

I did not test this so there might be typos / parsing errors but that's the gist of it. The difference between the two is that with [hidden] the content is hidden with display: none whereas with ngIf the content is simply removed from the DOM.

EDIT: modified my answer to reflect an update to the question adding a toggle button.

Related