Hotel
Experimental
此示例使用了以下实验性功能: amp-date-picker
amp-lightbox-gallery
. 通过下方按钮启用实验。某些组件需要同时启用 AMP Beta Channel。 Learn more about experimental features.
- AMP VersionPROD BETA
Introduction
This is a sample showing how to implement a hotel page. It features room availability based on date selection and a pet-friendly filter on page data. The room list resizes automatically after filtering and the user is shown a message in case of no results. The user can enlarge photos and swipe rooms by using a gallery.
Setup
We use a few AMP extensions to dynamically render a list of rooms. We use amp-form
to send a filter request to the server.
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
We use amp-mustache
as a template rendering engine for amp-list
.
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
We use amp-list
to dynamically show a list of rooms.
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
We use amp-bind
to filter rooms based on their availability.
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
We use amp-date-picker
to simplify entering dates for checking room availability.
<script async custom-element="amp-date-picker" src="https://cdn.ampproject.org/v0/amp-date-picker-0.1.js"></script>
We use amp-lightbox-gallery
to make it possible enlarge an image upon clicking ans swipe throughout all the images.
<script async custom-element="amp-lightbox-gallery" src="https://cdn.ampproject.org/v0/amp-lightbox-gallery-0.1.js"></script>
We use amp-fit-text
to fit the hotel name to the available space.
<script async custom-element="amp-fit-text" src="https://cdn.ampproject.org/v0/amp-fit-text-0.1.js"></script>
Searching for available rooms
This sample shows how to search for available rooms based on date selection. You can implement an availability search by using the amp-date-picker
as input of a form.
Here we are using type=range
as we need 2 dates: the arriving and leaving date of an hotel reservation. Upon receiving a submit-succes
event from the form response, we set the value of a global variable rooms
to the form response. We are using the variable rooms
throughout the sample to access the response from other AMP components.
<form method="GET" action-xhr="/documentation/examples/e-commerce/hotel/rooms" target="_top" on="submit-success:AMP.setState({
rooms: event.response
})">
<amp-date-picker id="picker" layout="container" type="range" mode="overlay" locale="en" format="YYYY-MM-DD" min="2017-10-26" month-format="MMM" start-input-selector="#arriving" end-input-selector="#leaving">
<input name="start" id="arriving">
<input name="end" id="leaving">
<button on="tap: picker.clear">Clear</button>
</amp-date-picker>
<input type="submit" value="Check Availability">
</form>
Client-side filtering
We want to make it possible for the user to filter rooms by pet friendliness. The filter shouldn't require an additional network request, instead it should work client-side. We implement a filter by adding a checkbox which sets a new variable, filterPetFriendly
, whenever the value changes.
<label>Show only pet friendly rooms:
<input type="checkbox" on="change:AMP.setState({
showPetFriendlyOnly: event.checked
})">
</label>
Filter implementation
We use amp-bind-macro
to implement a function which filters the amp-list
content based on the pet-friendly variable. By using amp-bind-macro
we avoid duplicating the filter expression across the page.
<amp-bind-macro id="filteredRooms" expression="rooms.filter(room => showPetFriendlyOnly ? room.petFriendly : true)">
</amp-bind-macro>
Room list initial state
We are using amp-state
to set the initial value of the variable rooms
to the list of rooms returned by the server.
This is necessary for client-side filtering to work after the initial page load. We are using the variable rooms
throughout the sample to access this list from other AMP components.
Both, amp-list
and amp-state
, use the same endpoint.
<amp-state id="rooms" src="/documentation/examples/e-commerce/hotel/rooms"></amp-state>
Room list
We are using amp-list
to show a list of rooms. We bind the value of the src
variable to the result of the function filterRooms
so that we can show the available rooms based on the user selection.
The user can view an enlarged version of each image by clicking on it. This can be implemented using the amp-lightbox-gallery
by adding the lightbox
attribute to every amp-img
; the alt
parameter content adds also a caption for every image in the lightbox gallery.
amp-list
content takes the entire height on the page from the height
attribute; after filtering, it could take unused space: we are resizing by binding the height
attribute to the result of the height of the image plus the margins multiplied by the length of the list.
<amp-list class="rooms" layout="fixed-height" height="800" src="/documentation/examples/e-commerce/hotel/rooms" [src]="filteredRooms()" items="." [height]="(80 + (16*2)) * filteredRooms().length" binding="refresh">
<template type="amp-mustache">
<amp-img width="108" height="80" src="/static/samples/{{img}}" lightbox alt="{{name}}-{{desc}}"></amp-img>
<div>{{name}} {{#petFriendly}}🐾{{/petFriendly}}</div>
<button>book</button>
</template>
</amp-list>
Handling empty list content
In case no rooms are available, we are showing a message to inform the user. We hide the
message by default and show it when the list is not empty. We are calling filteredRooms()
function
from the amp-bind-macro
to get the list of rooms filtered by user selection.
0" i-amphtml-binding>Sorry, no rooms available
<p hidden [hidden]="filteredRooms().length > 0">Sorry, no rooms available</p>
如果此页面上的说明未能涵盖您的所有问题,欢迎与其他 AMP 用户取得联系,讨论您的具体用例。
前往 Stack Overflow 一项无法解释的功能?AMP 项目强烈鼓励您参与并做出贡献!我们希望您能成为我们开放源代码社区的持续参与者,但我们也欢迎您对所热衷问题做出一次性贡献。
编辑 GitHub 上的示例-
Written by @aghassemi