Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update session card Add/Remove buttons to use JavaScript #99

Open
DamianEdwards opened this issue Jun 18, 2019 · 0 comments
Open

Update session card Add/Remove buttons to use JavaScript #99

DamianEdwards opened this issue Jun 18, 2019 · 0 comments

Comments

@DamianEdwards
Copy link
Contributor

DamianEdwards commented Jun 18, 2019

During the workshop today I added the ability for the session cards on the Home and My Agenda pages to progressively enhance the buttons for adding/removing sessions from the personal agenda to post using JavaScript rather than a normal form submit. It also handles dynamically updating the UI including removing the cards on the My Agenda page.

The JavaScript and modified agenda partial follow. We should consider incorporating this into the workshop.

site.js

"use strict";

// Agenda form functionality
let onMyAgendaPage = document.querySelector("h1[data-myAgenda]") !== null;
let form = document.querySelector("#agendaForm");
if (form) {
    form.addEventListener("submit", async e => {
        e.preventDefault();
        let sessionId = document.activeElement.getAttribute("value"),
            card = document.querySelector("#session-" + sessionId),
            button = card.querySelector("button:not(.template)"),
            template = card.querySelector("button.template"),
            url = button.formAction || form.action,
            formData = new FormData(form);

        formData.append("sessionId", sessionId);

        let response = await fetch(url, {
            method: form.method,
            body: formData
        });

        if (response.status === 200) {
            if (url.indexOf("Remove") > 0 && onMyAgendaPage) {
                let timeSlotDiv = card.closest("div.timeSlot"),
                    agendaDiv = document.querySelector("div.agenda"),
                    dayPill = agendaDiv.querySelector("a.nav-link.active");

                card.remove();

                // Check if this was the last card in this time slot and if so remove the track node
                if (timeSlotDiv.querySelectorAll(".session-card").length === 0) {
                    timeSlotDiv.remove();
                    // Check if this was the last card in the day and if so remove the day pill button
                    if (agendaDiv.querySelectorAll(".session-card").length === 0) {
                        dayPill.remove();
                        // Check if there are more days and if so navigate to the next day, else show the empty message
                        let dayPills = agendaDiv.querySelectorAll("a.nav-link");
                        if (dayPills.length > 0) {
                            document.location.search = "";
                        }
                        else {
                            agendaDiv.querySelector("#agendaMessage").classList.remove("template");
                        }
                    }
                }
            } else {
                button.classList.add("template");
                template.classList.remove("template");
            }            
        }
    });
}

_AgendaPartial.cshtml

@model IndexModel

<div class="agenda">
    <ul class="nav nav-pills mb-3">
        @foreach (var day in Model.DayOffsets)
        {
            <li role="presentation" class="nav-item">
                <a class="nav-link @(Model.CurrentDayOffset == day.Offset ? "active" : null)" asp-route-day="@day.Offset">@day.DayofWeek?.ToString()</a>
            </li>
        }
    </ul>

    @{
        var messageClassName = Model.Sessions.Any() ? "template" : null;
    }
    <p id="agendaMessage" class="@messageClassName">There don't appear to be any sessions here.</p>

    <form authz method="post" id="agendaForm">
        @foreach (var timeSlot in Model.Sessions)
        {
            <div class="timeSlot">
                <h4>@timeSlot.Key?.ToString("HH:mm")</h4>
                <div class="row">
                    @foreach (var session in timeSlot)
                    {
                        <div class="col-md-3 mb-4 session-card" id="session-@session.Id">
                            <div class="card shadow session h-100">
                                <div class="card-header">@session.Track?.Name</div>
                                <div class="card-body">
                                    <h5 class="card-title"><a asp-page="Session" asp-route-id="@session.Id">@session.Title</a></h5>
                                </div>
                                <div class="card-footer">
                                    <ul class="list-inline mb-0">
                                        @foreach (var speaker in session.Speakers)
                                        {
                                            <li class="list-inline-item">
                                                <a asp-page="Speaker" asp-route-id="@speaker.Id">@speaker.Name</a>
                                            </li>
                                        }
                                    </ul>
                                    <p class="mb-0">
                                        <a authz-policy="Admin" asp-page="/Admin/EditSession" asp-route-id="@session.Id" class="btn btn-default btn-xs">Edit</a>
                                        @{
                                            var isInSession = Model.UserSessions.Contains(session.Id);
                                            var removeClassName = isInSession ? "" : "template";
                                            var addClassName = isInSession ? "template" : "";
                                        }
                                        <button type="submit" name="sessionId" value="@session.Id" asp-page-handler="Remove" class="btn btn-default btn-sm bg-transparent @removeClassName" title="Remove from my personal agenda">
                                            <i class="icon ion-md-star" aria-hidden="true"></i>
                                        </button>
                                        <button type="submit" name="sessionId" value="@session.Id" class="btn btn-default btn-sm bg-transparent @addClassName" title="Add to my personal agenda">
                                            <i class="icon ion-md-star-outline" aria-hidden="true"></i>
                                        </button>
                                    </p>
                                </div>
                            </div>
                        </div>
                    }
                </div>
            </div>
        }
    </form>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant