Card templates allow you to display custom card content. This demo uses a cardTemplate to display car images, car info, and a custom button within cards.
@model IEnumerable<DevExtreme.MVC.Demos.Models.Vehicle>
@(Html.DevExtreme().CardView()
.DataSource(Model, "ID")
.Height(1120)
.CardsPerRow(Mode.Auto)
.CardMinWidth(240)
.Paging(p => p.PageSize(12))
.SearchPanel(sp => sp.Visible(true))
.HeaderFilter(hf => hf.Visible(true))
.Columns(c => {
c.Add()
.DataField("TrademarkName")
.Caption("Trademark");
c.Add()
.DataField("Name")
.Caption("Model");
c.Add().DataField("Price")
.Format("currency")
.HeaderFilter(hf => {
hf.GroupInterval(20000);
});
c.Add()
.DataField("CategoryName")
.Caption("Category");
c.Add().DataField("Modification");
c.Add()
.DataField("BodyStyleName")
.Caption("Body Style");
c.Add().DataField("Horsepower");
})
.CardTemplate(@<text>
<div class="vehicle__card">
<div class="vehicle__img-wrapper">
<img class="vehicle__img"
src="@Url.Content("~/Content/images/vehicles/image_")<%- card.data.ID %>.png"
alt="<%- card.data.TrademarkName %> <%- card.data.Name %>" />
</div>
<div class="vehicle__info">
<div class="vehicle__name" title="<%- card.data.TrademarkName %> <%- card.data.Name %>">
<%- card.data.TrademarkName %> <%- card.data.Name %>
</div>
<div class="vehicle__price">
<%- card.fields.find(f => f?.column?.dataField === 'Price').text %>
</div>
<div class="vehicle__type-container">
<div class="vehicle__type">
<%- card.data.CategoryName %>
</div>
</div>
<div class="vehicle__spec-container">
<div class="vehicle__modification">
<%- card.data.Modification %>
</div>
<div class="vehicle__modification">
<%- card.data.BodyStyleName %>
</div>
<div class="vehicle__modification">
<%- card.data.Horsepower %> h.p.
</div>
</div>
<div class="vehicle__footer-container">
@(Html.DevExtreme().Button()
.Text("Image Info")
.Type(ButtonType.Default)
.Width("100%")
.OnClick("(e) => { button_onClick(e, card.data); }")
)
</div>
</div>
</div>
</text>)
)
@(Html.DevExtreme().Popup()
.ID("vehiclePopup")
.Width(360)
.Height(260)
.Title("Image Info")
.HideOnOutsideClick(true)
.Visible(false)
.DragEnabled(false)
)
<script>
const popupContentTemplate = function(vehicle) {
const sourceLink = `https://${vehicle.Source}`;
return $('<div>').append(
$('<p>')
.append($('<b>').text('Image licensed under: '))
.append($('<span>').text(vehicle.LicenseName)),
$('<p>')
.append($('<b>').text('Author: '))
.append($('<span>').text(vehicle.Author)),
$('<p>')
.append($('<b>').text('Source link: '))
.append(
$('<a>', {
href: sourceLink,
target: '_blank',
})
.text(sourceLink),
),
$('<p>')
.append($('<b>').text('Edits: '))
.append($('<span>').text(vehicle.Edits)),
);
};
function button_onClick(e, vehicle) {
const popup = $("#vehiclePopup").dxPopup("instance");
popup.option('contentTemplate', popupContentTemplate(vehicle));
popup.show();
}
</script>
using DevExtreme.MVC.Demos.Models.CardView.ColumnChooser;
using DevExtreme.MVC.Demos.Models.CardView.ColumnHeaderFilter;
using DevExtreme.MVC.Demos.Models.CardView.ColumnReordering;
using DevExtreme.MVC.Demos.Models.CardView.DataValidation;
using DevExtreme.MVC.Demos.Models.CardView.FilterPanel;
using DevExtreme.MVC.Demos.Models.CardView.Overview;
using DevExtreme.MVC.Demos.Models.CardView.PopupEditing;
using DevExtreme.MVC.Demos.Models.CardView.SearchPanel;
using DevExtreme.MVC.Demos.Models.CardView.Selection;
using DevExtreme.MVC.Demos.Models.CardView.SimpleArray;
using DevExtreme.MVC.Demos.Models.CardView.Sorting;
using DevExtreme.MVC.Demos.Models.SampleData;
using System.Web.Mvc;
namespace DevExtreme.MVC.Demos.Controllers {
public class CardViewController : Controller
{
public ActionResult CardTemplate()
{
return View(SampleData.Vehicles);
}
}
}
.vehicle__img-wrapper {
overflow: hidden;
display: flex;
justify-content: center;
aspect-ratio: 16 / 9;
width: 100%;
background-color: #fff;
}
.vehicle__img {
height: 100%;
width: 100%;
object-fit: scale-down;
}
.vehicle__info {
padding: 12px;
border-top: var(--dx-border-width) solid var(--dx-color-border);
}
.vehicle__name {
font-weight: 700;
font-size: 20px;
line-height: 28px;
height: 28px;
padding-left: 12px;
padding-right: 12px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.vehicle__price {
padding-left: 12px;
padding-right: 12px;
height: 32px;
font-weight: 700;
font-size: 24px;
color: var(--dx-color-primary);
}
.vehicle__type-container {
padding: 12px;
display: inline-block;
}
.vehicle__type {
padding: 2px 6px;
background-color: var(--dx-color-separator);
border-radius: 13px;
}
.vehicle__spec {
padding: 2px 12px;
}
.vehicle__modification {
height: 24px;
padding: 2px 0 2px 12px;
}
.vehicle__footer-container {
padding: 12px;
}
.vehicle__image-licence-caption {
font-weight: 600;
}