Skip to main content

Price Summary
New

This template shows how to build a responsive price summary pattern. Please note that the example below does not represent a real use case.

Hint: Press F on your keyboard to view both templates and components in fullscreen and ESC to exit the fullscreen mode. You can also open the template in a new browser window.


Open in new window
<!DOCTYPE html>
<html class="duet-bg-gradient duet-sticky-footer" lang="fi">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title>LähiTapiola</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@duetds/fonts@1.3.12/lib/localtapiola.css" integrity="sha384-5JYmtSD7nykpUvSmTW1CHMoBDkBZUpUmG0vuh+NUVtZag3F75Kr7+/JU3J7JV6Wq" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@duetds/css@1.4.6/lib/duet.min.css" integrity="sha384-pCjsyofCzuxv5DPuTf+kg3QNWqVN0ZwRTCgvvNWCkI38A42MtkN2EK2I2e28j+wB" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@duetds/tokens@2.0.30/lib/tokens.custom-properties.css" integrity="sha384-arb0dRY7eabL9qYMLabGqlrgO9p75pZ9lvaqh3xpLpNUUW6KBtRjKqkSwBv3HyLp" crossorigin="anonymous" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@duetds/components@4.2.6/lib/duet/duet.esm.js" integrity="sha384-ytNH4bICrleu6OXiFr0GctdjoojY5a4B3/H3+Z0wTQOB9eUcbh6i7GbP2QykjM4k" crossorigin="anonymous"></script>
<script nomodule src="https://cdn.jsdelivr.net/npm/@duetds/components@4.2.6/lib/duet/duet.js" integrity="sha384-j/SZhqGHRSMeQPpiO0sIu1NANTpsXU23YSk3+nfvGaUM9SvRrOaN15rhsFO4k6L4" crossorigin="anonymous"></script>
</head>
<body>
<style>
.campaign {
transition: 500ms ease;
max-height: 0;
opacity: 0;
padding: 0 4px 1px 1px;
visibility: hidden;
overflow: hidden;
}
.campaign.active {
max-height: 250px;
opacity: 1;
visibility: visible;
}
.alert {
transition: 300ms ease;
visibility: hidden;
transform: scale(0.9);
height: 0;
opacity: 0;
}
.alert.active {
opacity: 1;
transform: scale(1);
visibility: visible;
height: auto;
}
</style>

<duet-header
language="fi"
skip-to-id="#content"
contact="Ota yhteyttä"
current-href="/vakuutukset/"
items='[
{ "label": "Etusivu","href": "/" },
{ "label": "Vakuutukset", "href": "/vakuutukset/" },
{ "label": "Vahinkoasiat", "href": "#" },
{ "label": "Säästöt ja sijoitukset", "href": "#" },
{ "label": "Laskut", "href": "#", "badge": "true" },
{ "label": "Viestit", "href": "#" }
]'

language-items='[
{ "label": "Suomeksi", "country": "fi", "href": "/?lang=fi" },
{ "label": "På Svenska", "country": "sv", "href": "/?lang=sv" },
{ "label": "In English", "country": "en", "href": "/?lang=en" }
]'

contact-items='[
{ "label": "Lähetä viesti", "href": "/viestit/laheta" },
{ "label": "Avaa chat", "href": "/chat/" },
{ "label": "Yhteystiedot", "href": "/yhteystiedot/" }
]'

session='{ "label": "Kirjaudu ulos", "href": "/?logout", "type": "logout" }'
user='{ "label": "Elina", "href": "/?userId=elina" }'>

</duet-header>
<duet-layout id="content">
<div slot="main">
<duet-card heading="Hinta ja maksaminen" heading-level="h1" padding="large">
<duet-grid responsive breakpoint="medium" alignment="stretch">
<duet-grid-item margin="none" max-width="33.333%">
<duet-choice-group
value="1"
label="Haluan maksaa laskuni"
direction="vertical"
name="group">

<duet-choice label="1 erässä" type="radio" value="1" expand></duet-choice>
<duet-choice label="2 erässä" type="radio" value="2" expand></duet-choice>
<duet-choice label="6 erässä" type="radio" value="6" expand></duet-choice>
<duet-choice label="12 erässä" type="radio" value="12" expand></duet-choice>
</duet-choice-group>
<duet-button
class="button"
variation="plain"
icon="messaging-discount"
icon-size="large">

Onko sinulle kampanjakoodi?
</duet-button>
<div class="campaign">
<form class="form">
<duet-grid responsive breakpoint="x-large" alignment="bottom">
<duet-input class="code" label="Syötä koodi" placeholder="Kampanjakoodi" expand></duet-input>
<duet-spacer size="small" direction="horizontal"></duet-spacer>
<duet-button style="min-width:8rem" wrapping="none" submit variation="primary" class="use-code">Käytä</duet-button>
</duet-grid>
</form>
<duet-alert class="alert" variation="success">Koodi käytetty onnistuneesti!</duet-alert>
</div>
</duet-grid-item>
<duet-grid-item margin="none">
<duet-spacer size="xxx-large" direction="horizontal"></duet-spacer>
</duet-grid-item>
<duet-grid-item fill margin="none">
<duet-spacer breakpoint="medium" size="xx-large"></duet-spacer>
<duet-card padding="large" variation="border">
<duet-heading level="h2" visual-level="h4">Vakuutuksen hinta</duet-heading>
<duet-table margin="none" variation="plain">
<table>
<thead>
<tr>
<th>Vakuutus</th>
<th class="duet-text-right">Hinta</th>
</tr>
</thead>
<tbody>
<tr>
<td>Omakotitalo</td>
<td class="duet-text-right duet-font-weight-semi-bold">120,00&nbsp;</td>
</tr>
<tr>
<td>Koti-irtaimisto</td>
<td class="duet-text-right duet-font-weight-semi-bold">70,00&nbsp;</td>
</tr>
<tr>
<td>Vastuu</td>
<td class="duet-text-right duet-font-weight-semi-bold">30,00&nbsp;</td>
</tr>
<tr>
<td>Oikeusturva</td>
<td class="duet-text-right duet-font-weight-semi-bold">28,00&nbsp;</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="duet-font-weight-semi-bold">Vuosimaksu yhteensä</td>
<td class="duet-text-right duet-font-weight-semi-bold duet-font-size-x-large">
<span class="total">248,00</span>&nbsp;<sup><a class="duet-color-secondary footnote" style="text-decoration:none" href="#cite">*</a></sup>
</td>
</tr>
</tfoot>
</table>
</duet-table>
<duet-grid responsive breakpoint="medium">
<duet-grid-item fill class="duet-font-weight-semi-bold">
Maksuerä
</duet-grid-item>
<duet-grid-item class="duet-font-size-large duet-font-weight-semi-bold">
<span class="price">41,33</span>&nbsp;€ / <span class="period">6</span>&thinsp;×&thinsp;vuosi
</duet-grid-item>
</duet-grid>
<duet-caption margin="none" size="small" id="cite">
<sup>*</sup> Hinta saattaa muuttua vakuutuskauden vaihtuessa.
</duet-caption>
</duet-card>
<duet-spacer size="large"></duet-spacer>
<form>
<duet-grid direction="horizontal">
<duet-grid-item margin="none">
<duet-checkbox
label="Olen tutustunut vakuutuksen ehtoihin,tuoteselosteeseen ja avaintietoihin"
label-hidden>

</duet-checkbox>
</duet-grid-item>
<duet-grid-item fill margin="none">
<duet-paragraph style="margin-top:2px;">
Olen tutustunut <duet-link url="#">vakuutuksen ehtoihin</duet-link>,
<duet-link url="#">tuoteselosteeseen</duet-link> ja
<duet-link url="#">avaintietoihin</duet-link>.
</duet-paragraph>
</duet-grid-item>
</duet-grid>
<duet-checkbox value="confirm" label="Vakuutan että antamani tiedot ovat oikein.">
</duet-checkbox>
<duet-spacer size="large"></duet-spacer>
<duet-button submit variation="primary">Hyväksy ja osta vakuutus</duet-button>
</form>
</duet-grid-item>
</duet-grid>
</duet-card>
</div>
</duet-layout>
<duet-footer
logo-href="#"
language="fi"
items='[
{ "label": "Hae korvausta", "href": "#", "icon": "navigation-make-claim" },
{ "label": "Osta vakuutus", "href": "#", "icon": "action-buy-insurance" },
{ "label": "Yhteystiedot", "href": "#", "icon": "form-tel" }
]'

menu='[
{ "label": "Turvallisuus ja käyttöehdot", "href": "#" },
{ "label": "Evästeet", "href": "#" },
{ "label": "Henkilötietojen käsittely", "href": "#" }
]'
>

</duet-footer>

<script>
// Save references to components we want to adjust below
var group = document.querySelector("duet-choice-group")
var button = document.querySelector(".button")
var useCode = document.querySelector(".use-code")
var code = document.querySelector(".code")
var form = document.querySelector(".form")
var total = 248

// Footnote click handler
document.querySelector(".footnote").addEventListener("click", function(e) {
e.preventDefault()
var el = document.getElementById("cite")
window.scrollTo(0, el.getBoundingClientRect().top + window.scrollY - 80)
})

// Listen for choice changes in the group
group.addEventListener("duetChange", function(e) {
var value = e.detail.value
document.querySelector(".price").innerHTML = (total / value).toFixed(2).replace(".", ",")
document.querySelector(".period").innerHTML = value
})

// Toggle campaign code panel on button click
button.addEventListener("click", function(e) {
e.preventDefault()
var campaign = document.querySelector(".campaign")
campaign.classList.toggle("active")
setTimeout(function() {
if (campaign.classList.contains("active")) {
code.setFocus()
}
}, 300)
})

// When using campaign code, change UI state
form.addEventListener("submit", function(e) {
e.preventDefault()
if (code.value) {
useCode.variation = "loading"
code.disabled = true
total = 198

// This timeout creates a fake loading experience
setTimeout(function() {
useCode.variation = "primary"
useCode.disabled = true
document.querySelector(".alert").classList.add("active")
document.querySelector(".price").innerHTML = (total / group.value).toFixed(2).replace(".", ",")
document.querySelector(".total").innerHTML = total
var markup = "<td class='added-label'>Kampanja-ale</td><td class='added-price duet-text-right duet-font-weight-semi-bold'>-50,00&nbsp;€</td>"
var row = document.createElement("tr")
row.style.backgroundColor = "rgb(242,249,247)"
row.innerHTML = markup
document.querySelector("tbody").appendChild(row)

// Make sure these get added during next tick
setTimeout(function() {
document.querySelector(".added-label").setAttribute("data-heading", "Alennus")
document.querySelector(".added-price").setAttribute("data-heading", "Määrä")
},1)

}, 1000)
} else {
alert("Syötä ensin kampanjakoodi.")
}
})
</script>
</body>
</html>

Integration

To install this template’s dependencies into your project, run:

npm install @duetds/components
npm install @duetds/css
npm install @duetds/fonts

For further guidelines, please see each package’s documentation.



Tutorials

Follow these practical tutorials to learn how to build simple page layouts using Duet’s CSS Framework, Web Components and other features:

Tutorials

Building Layouts

Tutorials

Using CLI Tools

Tutorials

Creating Custom Patterns

Tutorials

Server Side Rendering

Tutorials

Sharing Prototypes

Tutorials

Usage With Markdown


Troubleshooting

If you experience any issues while using a template, please head over to the Support page for more guidelines and help.