pnp / sp-dev-solutions

Repository for SharePoint development reusable solutions
Other
496 stars 441 forks source link

Modern Search - Handlebars template for modern events #196

Open sympmarc opened 5 years ago

sympmarc commented 5 years ago

Category

I've been working on a Handlebars template to display modern events. It's still WIP, but I wanted to share it here for discussion. It might make sense to offer some additional templates like this for known Content Types.

There are challenges here with formatting. I've stolen the markup for the Events Web Part as a starting point and layered in the Handlebars magic to handle the variations. I may not have covered all of them.

For this to be standalone, we'll need to replicate the look and feel with custom CSS in the /* Insert your CSS here */ section. All of the transpiled classes below (cardWrapper_0eb586b0 compactCard_0eb586b0 compactCard-258, etc.) need to be replaced with custom CSS, which basically takes us "off brand". This isn't a great approach, so I'm curious what ideas others might have.

Query Template

Could be anything, but in my case, I'm doing something like this (for an example): DepartmentId:{{PageContext.hubSiteId}} ContentType:Event (RefinableCampus:{{User.CustomCampus.Name}} OR RefinableCampus:'All')

Selected Properties

ListItemId,ListId,Title,EventDateOWSDATE,EndDateOWSDATE,IsAllDayEvent,Path

Handlebars template

<style>
    /* Insert your CSS here */
</style>

<div class="template_root">
    <div class="ms-List" role="list">
        <div class="ms-List-surface" role="presentation">
            {{#each items as |item|}}
            <div class="ms-List-page" role="presentation">
                <div role="listitem" class="ms-List-cell" data-list-index="0" data-automationid="ListCell">
                    <div style="margin: 0px 10px 20px;">
                        <div aria-label="{{Title}}"
                            class="cardWrapper root-256 cardWrapper_0eb586b0 compactCard_0eb586b0 compactCard compactCard-258"
                            role="listitem" data-is-focusable="true" data-is-focus-item="true"
                            data-sp-a11y-skipkeys="13" style="width: 382.656px;" tabindex="0">
                            <div tabindex="0" data-is-focusable="false" role="button"
                                class="ms-DocumentCard ms-DocumentCard--actionable ms-DocumentCard--compact compactCard compactCard_0eb586b0 compactCard-271"
                                data-automation-id="compact-card">
                                <div data-automation-id="normal-card-preview">

                                    {{#eq (itemAt (split EventDateOWSDATE "T") 0) (itemAt (split EndDateOWSDATE "T") 0) }}
                                    <div class="box_acf6571e boxIsSingleDay_acf6571e boxIsSmall_acf6571e box dateBox-242 dateBox_0eb586b0"
                                        data-automation-id="singleDayBox">
                                        <div class="month_acf6571e" data-automation-id="singleDayMonthContainer">
                                            {{getDate EventDateOWSDATE "MMM"}}</div>
                                        <div class="day_acf6571e" data-automation-id="singleDayDayContainer">
                                            {{itemAt (split (itemAt (split EventDateOWSDATE "T") 0) "-") 2}}
                                        </div>
                                    </div>
                                    {{/eq}}

                                    {{#isnt (itemAt (split EventDateOWSDATE "T") 0) (itemAt (split EndDateOWSDATE "T") 0) }}
                                    <div class="box_acf6571e boxIsMultipleDays_acf6571e boxIsSmall_acf6571e box dateBox-259 dateBox_0eb586b0"
                                        data-automation-id="multipleDayBox">
                                        <div class="date_acf6571e" data-automation-id="multipleDayStartDateContainer">
                                            {{getDate EventDateOWSDATE "MMM"}}
                                            {{itemAt (split (itemAt (split EventDateOWSDATE "T") 0) "-") 2}}
                                        </div>
                                        <hr class="separator_acf6571e">
                                        <div class="date_acf6571e" data-automation-id="multipleDayEndDateContainer">
                                            {{getDate EndDateOWSDATE "MMM"}}
                                            {{itemAt (split (itemAt (split EndDateOWSDATE "T") 0) "-") 2}}
                                        </div>
                                    </div>
                                    {{/isnt}}

                                </div>
                                <div class="compactCardDetails_0eb586b0">
                                    <div data-automation-id="event-card-title" class="title title-268 title_0eb586b0 underWebLink_0eb586b0">
                                        <a href="{{itemAt (split Path '/Lists') 0}}/_layouts/15/Event.aspx?ListGuid={{ListId}}&ItemId={{ListItemId}}">{{Title}}</a>
                                    </div>
                                    <div class="datetime datetime-267 datetime_0eb586b0">
                                        {{#is IsAllDayEvent "true" }}
                                            {{getDate EventDateOWSDATE "ddd, MMM DD"}}, All Day
                                        {{/is}}
                                        {{#isnt IsAllDayEvent "true" }}
                                            {{getDate EventDateOWSDATE "ddd, MMM DD h:mm A"}}
                                        {{/isnt}}
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            {{/each}}
        </div>
    </div>
</div>

@dcashpeterson

FranckyC commented 5 years ago

Thank you @sympmarc for sharing this! Actually, it is a good timing to speak about this because I was currently thinking about the template feature in this Web Part and how we could improve it. These are my thoughts and it is all about Office UI Fabric ;)

Basically, with the Office UI Fabric evolution (a very good explanation by @AndrewConnell BTW), if you want to use Office UI Fabric to get a nice UI that fit with Office 365 styles, you basically have no other choice than to use React components, which is, for a solution based on Handlebars, pretty much not compatible I would say ;)...To deal with this, you can do what you did, by 'rewriting' the Office UI Fabric CSS to get the same styles or go with a full custom CSS (not even SASS) in the '