[blazor] BootStrap Tab기능

코찔찔이·2023년 8월 13일
0

blazor강의 따라하기

목록 보기
15/23
  1. bootstrap Tab 기능 구현해 보기.
  2. Tab기능을 C#코드로 구현해 보기.
  3. blazor에서 bootStrap에서 가져온 소스가 Tab기능이 작동 하지 않음.
    일반 .html페이지에서는 구동 되지만 blazor프로젝트에서는 구동 되지 않아
    3번째 소재목 3. scroll기능 해결방법에 해결 방법 기재.

1. google에서 "bootStrap Tab"을 검색 후 소스 복사.

사이트주소


2. 소스 구현(페이지, 네비게이션 설정)

  1. TabDemo.razor 페이지 생성.
  2. 네비게이션에서 호스팅 설정.
  • TabDemo.razor 페이지 생성
  1. hr 테그 상단은 bootStrap에서 그대로 가져온 소스.
  2. 버튼을 눌러도 동작하지 않으며 강의에서는 button테그가 a 테그로 되어 있어
    동일하게 profile만 a테그로 바꾸고 테스트 했을때 profile을 누르면 index 페이지로 이동됨.
  3. hr 테그 아래는 c# 코드를 사용 하여 탭기능 구현. 정상 독장 확인.
@page "/Samples/TabDemo"

<ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item" role="presentation">
        <button class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" type="button" role="tab" aria-controls="home" aria-selected="true">Home</button>
    </li>
    <li class="nav-item" role="presentation">
        <a class="nav-link" id="profile-tab" data-bs-toggle="tab" href="#profile" type="button" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
    </li>
    <li class="nav-item" role="presentation">
        <button class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact" type="button" role="tab" aria-controls="contact" aria-selected="false">Contact</button>
    </li>
</ul>
<div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">tab1</div>
    <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">tab2</div>
    <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">tab3</div>
</div>

<hr />


<ul class="nav nav-tabs" id="myTab2" role="tablist">
    <li class="nav-item" role="presentation">
        <button class="nav-link @tab1Active" @onclick=@(() => Clicked(1) )>Home</button>
    </li>
    <li class="nav-item" role="presentation">
        <button class="nav-link @tab2Active" @onclick=@(() => Clicked(2))>Home</button>
    </li>
    <li class="nav-item" role="presentation">
        <button class="nav-link @tab3Active" @onclick=@(() => Clicked(3))>Contact</button>
    </li>
</ul>
<div class="tab-content" id="myTabContent">
    <div class="tab-pane fade @tabPanle1Active" id="home" role="tabpanel" aria-labelledby="home-tab">tab1</div>
    <div class="tab-pane fade @tabPanle2Active" id="profile" role="tabpanel" aria-labelledby="profile-tab">tab2</div>
    <div class="tab-pane fade @tabPanle3Active" id="contact" role="tabpanel" aria-labelledby="contact-tab">tab3</div>
</div>


@code {
    string tab1Active = "active";
    string tab2Active = "";
    string tab3Active = "";

    string tabPanle1Active = "show active";
    string tabPanle2Active = "";
    string tabPanle3Active = "";

    public void Clicked(int i )
    {
        switch(i)
        {
            case 1:
                tab1Active = "active";
                tab2Active = "";
                tab3Active = "";

                tabPanle1Active = "show active";
                tabPanle2Active = "";
                tabPanle3Active = "";
                break;
            case 2:
                tab1Active = "";
                tab2Active = "active";
                tab3Active = "";

                tabPanle1Active = "";
                tabPanle2Active = "show active";
                tabPanle3Active = "";
                break;
            case 3:
                tab1Active = "";
                tab2Active = "";
                tab3Active = "active";

                tabPanle1Active = "";
                tabPanle2Active = "";
                tabPanle3Active = "show active";
                break;
        }
    }
}
  • 네비게이션 메뉴 설정 _Layout.cshtml

            <!--<div id="collapseDemo" class="collapse" aria-labelledby="headingPages" 에서 id를 변경하지 않고 그대로 사용 하면 기존 메뉴와 동시에 동작됨.-->
            <!-- Nav Item - Pages Collapse Menu -->
            <li class="nav-item">
                <a class="nav-link" href="#" data-toggle="collapse" data-target="#collapseDemo" @* <!--변경--> *@ aria-expanded="true"
                   aria-controls="collapseDemo">
                    @* <!--변경--> *@
                    <i class="fas fa-fw fa-folder"></i>
                    <span>Samples@* <!--변경--> *@</span>
                </a>
                <div id="collapseDemo" @* <!--변경--> *@ class="collapse" aria-labelledby="headingPages"
                     data-parent="#accordionSidebar">
                    <div class="bg-white py-2 collapse-inner rounded">
                        <h6 class="collapse-header">LECTURE SAMPLES:</h6>
                        <a class="collapse-item" href="/Samples/TodoListInMemory">TodoListInMemory</a>@* <!--변경--> *@
                        <a class="collapse-item" href="/Samples/TabDemo">Tab</a>
                        <div class="collapse-divider"></div>
                        <h6 class="collapse-header">Other Pages:</h6>
                        <a class="collapse-item" href="/Samples/Test">404 Page</a>
                        <a class="collapse-item" href="/Pages/BlankPage">Blank Page</a>
                    </div>
                </div>
            </li>

<a class="collapse-item" href="/Samples/TabDemo">Tab</a> 코드 추가.


3. scroll기능 해결방법

  1. 아래방법이 최선의 방법인지는 모르겠지만 아래와 같은 방법으로 진행시 해결됨.
  2. 참조사이트
  3. 혹시 사이트가 사라질 경우를 대비 해 해당내용 스크랩.
  • _Layout에 아래 스크립트 추가. scroll기능을 구현함.
<script>
    function BlazorScrollToId(id) {
        const element = document.getElementById(id);
        if (element instanceof HTMLElement) {
            element.scrollIntoView({
                behavior: "smooth",
                block: "start",
                inline: "nearest"
            });
        }
    }
</script>
  • AnchorNavigation.razor
  1. OnLocationChanged을 컴포넌트 인스턴스시 구독을 시킴.
  2. OnLocationChanged은 로케이션 체인지가 될때 발생하는 이벤트.
  3. 페이지 이동이 일어날때 ScrollToFragment메소드를 실행 시켜서 _layout에 추가시킨 BlazorScrollToId 함수를 사용하여 스크롤 기능 구현.
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
@implements IDisposable
@code {
    protected override void OnInitialized()
    {
        NavigationManager.LocationChanged += OnLocationChanged;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await ScrollToFragment();
    }

    public void Dispose()
    {
        NavigationManager.LocationChanged -= OnLocationChanged;
    }

    private async void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        await ScrollToFragment();
    }

    private async Task ScrollToFragment()
    {
        var uri = new Uri(NavigationManager.Uri, UriKind.Absolute);
        var fragment = uri.Fragment;
        if (fragment.StartsWith('#'))
        {
            // Handle text fragment (https://example.org/#test:~:text=foo)
            // https://github.com/WICG/scroll-to-text-fragment/
            var elementId = fragment.Substring(1);
            var index = elementId.IndexOf(":~:", StringComparison.Ordinal);
            if (index > 0)
            {
                elementId = elementId.Substring(0, index);
            }

            if (!string.IsNullOrEmpty(elementId))
            {
                await JSRuntime.InvokeVoidAsync("BlazorScrollToId", elementId);
            }
        }
    }
}
  • demo 페이지
  1. 참조 사이트에서는 GetHref 에서 #만을 앞에 붙여 동작된다고 되어 있지만
    현재 시점으로 테스트 했을때 그럴경우 index페이지로 이동됨.
  2. #앞에 현재 페이지의 라우팅 경로를 넣어주면 정상동작 확인 됨.
@page "/Samples/Test"

<strong>Table of Contents</strong>
<ul>
    @for (int i = 0; i < 10; i++)
    {
        <li><a href="@GetHref(i)">Header @i</a></li>
    }
</ul>

@for (int i = 0; i < 10; i++)
{
    <h1 id="@GetId(i)">Header @i</h1>
    @LoremNET.Lorem.Paragraph(wordCount: 30, sentenceCount: 10)
}

@* 👇 Integrate the component *@
<AnchorNavigation />

@code {
    string routingPath = "/Samples/Test";
    string GetId(int i) => "header-" + i;
    string GetHref(int i) => $"{routingPath}#" + GetId(i);
}

1개의 댓글

comment-user-thumbnail
2023년 8월 13일

유익한 자료 감사합니다.

답글 달기