Search code examples
asp.net-corerazorblazor

How to collapse/expand Razor components using Blazor syntax?


I'm currently implementing a form to create a new user along with their respective user rights. In this form, I have about 30 different IT systems and if the user account should have the access rights for that specific IT system, I want to provide a panel to the admin where some extra information must be entered regarding that specific IT system. I want to implement this using razor components. What I have so far is the core view for my "new user form" as well as a razor component for the additional information of a specific IT system. By clicking the + button, I want the component to be visible / expand right below the IT system. That's what It looks like so far:

enter image description here

The new user form:

 <div class="row">
                <div class="col-sm-2 font-weight-bold">GOODWILL PKW/Smart</div>
                <div class="col-sm-2">
                    <label>Add</label>
                    <input type="checkbox" />
                </div>
                <div class="col-sm-2">
                    <label>Change</label>
                    <input type="checkbox" />
                </div>
                <div class="col-sm-2">
                    <label>Remove</label>
                    <input type="checkbox" />
                </div>
                <div class="col-sm-4">                    
                    <button @onclick="@collapseGoodwill">+</button>
                </div>

            </div>
            <ModalGoodwillPKW ></ModalGoodwillPKW>

@code {

public void collapseGoodwill() {     


        }

}

The component:

<div class="panel panel-default border">
    <div class="panel-heading alert-primary">
        <h3 class="panel-title">Goodwill PKW/smart</h3>
    </div>

    <div class="panel-body">
        <div class="container-fluid">
            <div class="row">
                <div class="col-sm-2 font-weight-bold">Profile</div>

                <div class="col-sm-5">
                    <input type="checkbox" id="CB_c" />
                    <label>Salesman</label>
                </div>
                <div class="col-sm-5">
                    <input type="checkbox" id="CB_r" />
                    <label>Administrator</label>
                </div>                
            </div>
        </div>
    </div>
</div>

Normally, I would use JQuery in the "collapseGoodwill" method to add a .collapse class to this element. But since I am experimenting with Blazor, I'd like to know if there is a 100% Javascript /JQuery free way of doing this.

Thanks!


Solution

  • Within Blazor, you always follow the pattern:

    change data 
        --> new view rendered
    

    Anytime you want to change the component's UI from outside, you should do it by changing the data (model/state/parameter/context/...).

    As for this scenario, you can add a Collapsed field to indicate whether the panel itself is collapsed now:

    <div class="panel panel-default border @Collapse">
        <div class="panel-heading alert-primary">
            <h3 class="panel-title">Goodwill PKW/smart</h3>
        </div>
    
        <div class="panel-body">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-sm-2 font-weight-bold">Profile</div>
    
                    <div class="col-sm-5">
                        <input type="checkbox" id="CB_c" />
                        <label>Salesman</label>
                    </div>
                    <div class="col-sm-5">
                        <input type="checkbox" id="CB_r" />
                        <label>Administrator</label>
                    </div>                
                </div>
            </div>
        </div>
    </div>
    
    @code{
        [Parameter]
        public string Collapse{get;set;}="collapse"; // hide by default
    }
    

    And whenever you want to collapse it, just set this parameter to collapse:

    <div class="row">
        <div class="col-sm-2 font-weight-bold">GOODWILL PKW/Smart</div>
        <div class="col-sm-2">
            <label>Add</label>
            <input type="checkbox" />
        </div>
        <div class="col-sm-2">
            <label>Change</label>
            <input type="checkbox" />
        </div>
        <div class="col-sm-2">
            <label>Remove</label>
            <input type="checkbox" />
        </div>
        <div class="col-sm-4">                    
            <button @onclick="e => this.Collapsed = !this.Collapsed">
                @( this.Collapsed ? "+" : "-")
            </button>
        </div>
    </div>
    <ModalGoodwillPKW Collapse="@( this.Collapsed ? "collapse": "")" ></ModalGoodwillPKW>
    
    @code {
        private bool Collapsed = true;
    }
    

    Demo:

    enter image description here


    [Edit] : we can even refactor the above code to expose less information by changing the field from string to boolean.

    The ModalGoodwillPKW.razor:

    <div class="panel panel-default border @(Collapsed? "collapse": "" ) ">
        <div class="panel-heading alert-primary">
            <h3 class="panel-title">Goodwill PKW/smart</h3>
        </div>
    
       ...
    
    
    @code{
        [Parameter]
        public bool Collapsed{get;set;}= true; // hide by default
    }
    

    The UserForm.razor:

    <div class="row">
        ...
        <div class="col-sm-4">                 
            <button @onclick="e => this.Collapsed = !this.Collapsed">
                @( this.Collapsed ? "+" : "-")
            </button>
        </div>
    </div>
    <ModalGoodwillPKW Collapsed="@Collapsed" ></ModalGoodwillPKW>
    
    @code {
        private bool Collapsed = true;
    }