HI,
I am trying to implement same as in the below link. Left side I will have some kind Post. When user clicks on post, a detail description of the post and link to post. How can i achieve that using Kendo UI.
https://www.indeed.com/?vjk=ecee10295b7129db&advn=2889100715288898
Thanks
2 Answers, 1 is accepted
Hi Babu,
I have implemented a behavior similar to the one seen in the link you have shared in this Telerik REPL example.
The example above uses
- on the left side:
- a Selectable ListView with Custom Template and styling to display the items
@(Html.Kendo().ListView<Kendo.Mvc.Examples.Models.ProductViewModel>() .Name("listView") .TagName("div") .ClientTemplateId("leftTemplate") .DataSource(dataSource => dataSource .Ajax() .Read(read => read.Action("Products_Read", "ListView")) .PageSize(4) ) .Pageable() .Selectable(ListViewSelectionMode.Single) )
Template
<script type="text/x-kendo-tmpl" id="leftTemplate">
<div class="product">
<h3>#:ProductName#</h3>
<img src="@Url.Content("~/shared/web/foods/")#:ProductID#.jpg" alt="#:ProductName# image" />
<p> Last Supply: #: kendo.toString(LastSupply, "MM/dd/yyyy")# </p>
<p> Unit Price: #:kendo.toString(UnitPrice, "c")#</p>
<p> Units in stock: #= UnitsInStock # </p>
</div>
</script>
- on the right side:
- a SkeletonContainer that is replaced in the Change Event handler of the ListView by a Card that contains additional information about the item
<div class="selected-item"> @(Html.Kendo().SkeletonContainer() .Name("skeleton") .Animation(SkeletonContainerAnimation.Pulse) .Template("<div class='k-card'>" + "<div class='k-card-header'>" + "<div>" + "<span data-shape-circle class='k-card-image avatar'></span>" + "</div>" + "<div class='user-info' style='width: 100%;'>" + "<span data-shape-text class='k-card-title'></span>" + "<span data-shape-text class='k-card-subtitle' style='width: 35%;'></span>" + "</div>" + "</div>" + "<span data-shape-rectangle style='width: 480px; height: 600px; '></span>" + "<div class='k-card-body'>" + "<span data-shape-text></span>" + "</div>" + "</div>") ) <div class="k-card card"> <div class="k-card-header"> <div style="width:40px; height:40px;"> <img alt="Telerik UI for ASP.NET Core SkeletonContainer avatar" class="k-card-image avatar" src="@Url.Content("~/shared/web/skeleton/avatar.jpg")" /> </div> <div class="user-info"> <h5 class="k-card-title">Tom Smith</h5> <h6 class="k-card-subtitle">5 hours ago</h6> </div> </div> <br> <img alt="Telerik UI for ASP.NET Core SkeletonContainer" class="k-card-image main-image" src="@Url.Content("~/shared/web/skeleton/card-thumbnail.jpg")" /> <div class="k-card-body"> <div class="dynamic"></div> ... </div> </div> <div>
Subcribing to the Change Event
@(Html.Kendo().ListView<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("listView")
...
.Events(e=>e.Change("onChange"))
)
function onChange(e){
var selected = e.sender.select();
var dataItem = e.sender.dataItem(selected[0])
var card = $(".card");
cardBody = card.find(".k-card-body");
cardBody.find(".dynamic").remove();
cardBody.prepend("<div class='dynamic'></div>");
var dynamic = cardBody.find(".dynamic");
dynamic.append(`<h3>${dataItem.ProductName}</h3>`);
dynamic.append(`<p> Last Supply: ${kendo.toString(dataItem.LastSupply, "MM/dd/yyyy")} </p>`);
dynamic.append(`<p> Unit Price: ${kendo.toString(dataItem.UnitPrice, "c")}   Units in stock: ${dataItem.UnitsInStock}</p>`);
dynamic.append(`<h4> Total Amount For Product In Stock: ${kendo.toString(dataItem.UnitsInStock*dataItem.UnitPrice, "c")} </h3>`);
selectedImg = $(selected[0]).find("img");
card.find(".main-image").attr("src",selectedImg.attr("src"));
card.show();
$("#skeleton").hide();
}
CSS
.k-repl-preview-wrapper{
display:flex;
}
.narrow{
width:430px;
}
.narrow>.k-pager{
border-color:transparent;
background-color:rgb(255,255,255);
}
.k-listview{
border-color:transparent;
}
.selected-item{
position:fixed;
margin-left:420px;
padding: 10px 5px;
}
.card {
display:none;
width: 480px;
height: 750px;
}
For the entire code and to review the behavior run the REPL example. Although the REPL runs on ASP.NET Core the required configurations of the ListView and SkeletonContainer as well as the JavaScript and CSS customizations in this example are identical for both Telerik UI for ASP.NET Core and ASP.NET MVC.
Please give this suggestion a try and let me know whether it suits the scenario at hand.
Regards,
Stoyan
Progress Telerik
Stay tuned by visiting our public roadmap and feedback portal pages. If you're new to the Telerik family, be sure to check out our getting started resources, as well as the only REPL playground for creating, saving, running, and sharing server-side code.
Hi Babu,
The Telerik Components' required configuration is identical for the most part in ASP.NET MVC and Core.
However to implement a more dynamic scenario which involves server calls and possibly calls to a database, I recommend sending an AJAX request to the backend.
Then at the server-side you can consume the request and when the needed data is ready return a PartialView to be added to the main View.
I have applied the suggested behavior to the sample project you will find attached to my reply.
Please run the application and let me know how it works on your side.
Regards,
Stoyan.
Stoyan,
functionality is working as expected but i have few design Issues.
Issue 1: In the loading page header is fixed. when I scroll down header is also scrolling. How to make this fixed?
Issue 2: In the Index.cshtml file, if I remove ViewBag.Title = "Home Page" or if I put big text, the left and right boxes alignment is completely going crazy. How to fix this?
Issue 3: I tried to add search box with search button in the index.cshtml file (above the boxes) but it's not displaying properly. Can you help me how to fix this.
I tried very hard to fix all these issues but I am not able to do it. Can you help me in this.
Thanks
Babu
Hello Babu,
I'll be taking over due to Stoyan's absence.
I've examined the given solution's code and have come up with fixes about your concerns for the design issues:
- For the loading page header, it had the CSS rule position: fixed, which for some strange reason made it scrollable, even though that's not the default behavior. To fix this, I've removed the rule and it works as intended.
- About the left/right alignment, I've adjusted some of the <div> elements and made it not go completely crazy, as you've said.
- Finally for the search box, I've added a <form> which has an <input type="search"> element inside it, that will do the job.
You can see the gif file for a visualization, as well as open the attached project to see the changes for yourself.
Kind regards,
Vasko
Progress Telerik
Stay tuned by visiting our public roadmap and feedback portal pages. If you're new to the Telerik family, be sure to check out our getting started resources, as well as the only REPL playground for creating, saving, running, and sharing server-side code.
Vasako
Header is not fixed.
Hi Babu,
To make the navigation bar of the sample project fixed, you can wrap the nav bar and the Menu on the page with a div Html element and then apply the following styles:
<body class="k-content">
<div class="fixed-container">
<!-- nav and Menu configured here -->
</div>
<main>
<div class="container-fluid">
@RenderBody()
</div>
</main>
...
</body>
.fixed-container {
min-height:40px;
position: fixed;
width: 100%;
top:0;
left:0;
z-index: 99;
}
main {
margin-top: 115px;
}
I am attaching the modified project that showcases the behavior to this message.
With that being said, I have to let you know that implementation of custom scenarios runs outside of the product's support scope.
If you need help with additional customizations on the topic I'd like to recommend our Professional Services who specialize in custom implementations.
Additionally, with the R3 2023 increment coming on Wednesday the DockManager Component will be released as noted in our product Roadmap. The component comes with numerous behaviors supported out-of-the-box and it might help you to achieve a custom layout more easily.
I hope the information above is useful.
Regards,
Stoyan
stoyan,
How do I call @(Html.Kendo().ListView<IDOHJobBank.Models.LHDJobHub>() when i click on search button and pass search criteria? I tried like below but didnt workout.
@{
ViewBag.Title = "Search Jobs";
}
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@model IDOHJobBank.Data.Models.UserSearchViewModel
<div>
<form style="padding-bottom: 10px; padding-left:10px; padding-right:10px;">
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-2">
@*@Html.TextBox("txtTitleSearch", "", new { @class = "form-control", style = "width:99.9%; height: 35px;", placeholder = "Job Title" })*@
@Html.TextBoxFor(model => model.JobTitle, new { @class = "form-control", placeholder = "Job Title" })
</div>
<div class="col-md-2">
@*@Html.DropDownList("ddlCounty",
new SelectList(Enum.GetValues(typeof(Util.eCounty))),
"Select County",
new { @class = "form-control", style = "width:99.9%; height: 35px;" })*@
@Html.DropDownListFor(model => model.countyName, new SelectList(
Model.ddlCounties, "Id", "Name", 0), "Select County", new { @class = "form-control" })
</div>
<div class="col-md-2">
@*@Html.DropDownList("ddlJobType",
new SelectList(Enum.GetValues(typeof(Util.eJobType))),
"Select Job Type",
new { @class = "form-control", style = "width:99.9%; height: 35px;" })*@
@Html.DropDownListFor(model => model.jobType, new SelectList(
Model.ddlJobTypes, "Id", "Name", 0), "Select JobType", new { @class = "form-control" })
</div>
<div class="col-md-2">
@*@Html.TextBox("txtPostDateSearch", "", new { @type="date", @class = "form-control datepicker", style = "width:99.9%; height: 35px;", placeholder = "Job Post date" })*@
@Html.TextBoxFor(x => x.PostDate, "{0:yyyy-MM-dd HH:mm:ss}", new { @type = "date", @class = "datepicker form-control", placeholder = "Job Post date", id = "myDate" })
</div>
<div class="col-md-1">
<input type="button" name="Search" value="Search" style="text-align:center;" class="btn btn-info" id="btnSubmit">
</div>
<div class="col-md-1">
</div>
</div>
</form>
</div>
<script type="text/x-kendo-tmpl" id="leftTemplate">
<div class="product">
<h2>#:Title#</h2>
<p> Posted Date : #: kendo.toString(PostDate, "MM/dd/yyyy")# </p>
<p> Positions Available : #= Vacancies # </p>
<hr>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
</div>
</script>
<script>
function onChange(e) {
var selected = e.sender.select();
console.log(selected)
var dataItem = e.sender.dataItem(selected[0])
$.ajax({
type: "GET",
url: "/User/GetCard",
data: { id: dataItem.ID },
success: function (viewHTML) {
$("#skeleton").hide();
$(".selected-item").html(viewHTML);
},
error: function (errorData) { console.log(errorData) }
});
}
function searchCriteria() {
return {
JobTitle: $("#JobTitle").val(),
countyName: $("#countyName").val(),
jobType: $("#jobType").val(),
PostDate: $("#PostDate").val()
};
}
</script>
<div class="parent">
<div class="demo-section narrow">
@(Html.Kendo().ListView<IDOHJobBank.Models.LHDJobHub>()
.Name("listView")
.TagName("div")
.ClientTemplateId("leftTemplate")
.DataSource(dataSource => dataSource
.PageSize(10)
.Model(m =>
{
m.Id(f => f.ID);
}
)
.Read(read => read.Action("Jobs_Read", "User").Data("searchCriteria"))
)
.Pageable()
.Selectable(s=>s.Mode(ListViewSelectionMode.Single))
.Events(e=>e.Change("onChange"))
)
</div>
<div class="selected-item" style="display:block;">
@(Html.Kendo().SkeletonContainer()
.Name("skeleton")
.Animation(SkeletonContainerAnimation.Pulse)
.Template(
"<div class='k-card'>" +
"<div class='k-card-header'>" +
"<div>" +
"<span data-shape-circle class='k-card-image avatar'></span>" +
"</div>" +
"<div class='user-info' style='width: 100%;'>" +
"<span data-shape-text class='k-card-title'></span>" +
"<span data-shape-text class='k-card-subtitle' style='width: 35%;'></span>" +
"</div>" +
"</div>" +
"<span data-shape-rectangle style='width: 800px; height: 480px; '></span>" +
"<div class='k-card-body'>" +
"<span data-shape-text></span>" +
"</div>" +
"</div>"+
"</div>")
)
</div>
</div>
no worries. i got it.
$("#btnSubmit").click(function () {
$("#listView").data("kendoListView").dataSource.read();
});
Additionally, if you need to apply custom filtering to the DataSource on the client-side the Custom Filtering forum thread goes over the approach in more depth.
stoyan,
When data is loaded, how to make first record is automatically selected and display the result in SkeletonContainer? when there is no item to slect it shouldn't throw any kind of error
When data is loaded, how to make first record is automatically selected and display the result in SkeletonContainer? when there is no item to select it shouldn't throw any kind of error
I deployed latest code into Server. When I click on any post result is not displaying in SkeletonContainer. Instead Its showing attached error. below is the code. What si wrong.
@{
ViewBag.Title = "Search Jobs";
}
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@model IDOHJobBank.Data.Models.UserSearchViewModel
<div>
<form style="padding-bottom: 10px; padding-left:10px; padding-right:10px;">
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-2">
@Html.DropDownListFor(model => model.JobTitle, new SelectList(
Model.ddlTitles, "Id", "Name", 0), "Select Title", new { @class = "form-control" })
</div>
<div class="col-md-2">
@Html.DropDownListFor(model => model.countyName, new SelectList(
Model.ddlCounties, "Id", "Name", 0), "Select County", new { @class = "form-control" })
</div>
<div class="col-md-2">
@Html.DropDownListFor(model => model.jobType, new SelectList(
Model.ddlJobTypes, "Id", "Name", 0), "Select JobType", new { @class = "form-control" })
</div>
<div class="col-md-2">
@Html.DropDownListFor(model => model.divName, new SelectList(
Model.ddlDivisions, "Id", "Name", 0), "Select Division", new { @class = "form-control" })
</div>
<div class="col-md-2">
<input type="button" name="Search" value="Search" style="text-align:center;" class="btn btn-info" id="btnSubmit">
<input type="button" name="Clear" value="Clear" style="text-align:center;" class="btn btn-info" id="btnClear">
</div>
@*<div class="col-md-1">
</div>*@
</div>
</form>
</div>
<script type="text/x-kendo-tmpl" id="leftTemplate">
<div class="product">
<P style="font-size:medium; font-weight: bold">#:Title#</P>
<p style="margin: 0px 0px 5px;"> Posted Date : #: kendo.toString(PostDate, "MM/dd/yyyy")# </p>
<p style="margin: 0px 0px 5px;"> Positions Available : #= Vacancies # </p>
<p style="margin: 0px 0px 5px;"> County : #= County # </p>
<hr>
<p>#= JobDesc #</p>
</div>
</script>
<script>
function onChange(e) {
var selected = e.sender.select();
//console.log(selected)
var dataItem = e.sender.dataItem(selected[0])
$.ajax({
type: "GET",
url: "/User/GetCard",
data: { id: dataItem.ID },
success: function (viewHTML) {
$("#skeleton").hide();
$(".selected-item").html(viewHTML);
},
error: function (errorData) { console.log(errorData) }
});
}
function onDataBound(e) {
//var listView = $('#jobsListView').data('kendoListView');
////listView.select(listView.element.children().first());
//listView.select(".k-first");
//var listView = e.sender;
//alert(listView);
//var firstItem = listView.element.children().first();
//listView.select(firstItem);
//// get a reference to the ListView widget
//var listView = $("#jobsListView").data("kendoListView");
//// selects first ListView item
//console.log(listView.content.children().first());
//listView.select(listView.content.children().first());
}
function searchCriteria() {
return {
JobTitle: $("#JobTitle").val(),
countyName: $("#countyName").val(),
jobType: $("#jobType").val(),
divName: $("#divName").val()
};
}
$("#btnSubmit").click(function () {
$("#jobsListView").data("kendoListView").dataSource.read();
});
$("#btnClear").click(function () {
$("#JobTitle").val('');
$("#countyName").val('');
$("#jobType").val('');
$("#divName").val('');
$("#jobsListView").data("kendoListView").dataSource.read();
});
</script>
<div class="parent">
<div class="demo-section narrow">
@(Html.Kendo().ListView<IDOHJobBank.Data.Models.UserJobDetails>()
.Name("jobsListView")
.TagName("div")
.ClientTemplateId("leftTemplate")
.DataSource(dataSource => dataSource
.PageSize(10)
.Model(m =>
{
m.Id(f => f.ID);
}
)
.Read(read => read.Action("Jobs_Read", "User").Data("searchCriteria"))
)
.Scrollable()
.Pageable()
.Selectable(s => s.Mode(ListViewSelectionMode.Single))
.Events(e => { e.Change("onChange"); e.DataBound("onDataBound"); })
)
</div>
<div class="selected-item" style="display:block;">
@(Html.Kendo().SkeletonContainer()
.Name("skeleton")
.Animation(SkeletonContainerAnimation.Pulse)
.Template(
"<div class='k-card'>" +
"<div class='k-card-header'>" +
"<div>" +
"<span data-shape-circle class='k-card-image avatar'></span>" +
"</div>" +
"<div class='user-info' style='width: 100%;'>" +
"<span data-shape-text class='k-card-title'></span>" +
"<span data-shape-text class='k-card-subtitle' style='width: 35%;'></span>" +
"</div>" +
"</div>" +
"<span data-shape-rectangle style='width: 800px; height: 480px; '></span>" +
"<div class='k-card-body'>" +
"<span data-shape-text></span>" +
"</div>" +
"</div>"+
"</div>")
)
</div>
</div>
<style>
.container-fluid {
display: block;
}
.parent {
display: flex;
}
.parent > div {
display: inline-block;
}
.narrow {
width: 35%;
}
.narrow > .k-pager {
border-color: transparent;
background-color: rgb(255,255,255);
}
.k-listview {
border-color: transparent;
}
.selected-item {
padding: 10px 5px;
}
.card {
width: 60%;
height: 480px;
}
#jobsListView {
padding: 10px 5px;
margin-bottom: -1px;
min-height: 510px;
height: auto !important;
/* Avoid cutout if font or line is bigger */
font: inherit;
}
.product {
float: left;
position: relative;
width: 95%;
height: auto !important;
margin: 0 5px;
margin-bottom: 10px;
padding: 5px;
border: 0.5px solid grey;
border-radius: 5px;
}
.product img {
width: 150px;
height: 150px;
}
.product h3 {
margin: 0;
padding: 3px 5px 0 0;
max-width: 96px;
overflow: hidden;
line-height: 1.1em;
font-size: .9em;
font-weight: normal;
text-transform: uppercase;
color: black;
}
.main-image {
width: 180px;
height: 180px;
}
.k-listview:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.scrollable {
overflow-y: auto;
max-height: 400px;
}
.k-card {
border-radius: 6px;
border-width: 1px;
border-style: solid;
box-sizing: border-box;
outline: 0;
font-family: inherit;
font-size: 14px;
line-height: 1.4285714286;
display: flex;
flex-direction: column;
position: fixed;
overflow: hidden;
-webkit-touch-callout: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.k-textbox, .k-textbox > input {
font-size: 100%;
font-family: inherit;
border-style: solid;
border-width: 1px;
-webkit-appearance: none
}
</style>
using IDOHJobBank.Data.Models;
using IDOHJobBank.Data.Services;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace IDOHJobBank.External.UI.Controllers
{
public class UserController : Controller
{
private JobBankExternalService eService;
public UserController()
{
eService = new JobBankExternalService();
}
// GET: User
public ActionResult Jobs()
{
var vm = eService.GetUserDropdownValues();
return View(vm);
}
public ActionResult Jobs_Read([DataSourceRequest] DataSourceRequest request, string JobTitle, string countyName, string jobType, string divName)
{
var usrSearch = new UserSearchViewModel
{
JobTitle = JobTitle,
countyName = countyName,
jobType = jobType,
divName = divName
};
var jobList = eService.GetUserJobDetails(usrSearch);
//var result = GetAll();
return Json(jobList.ToDataSourceResult(request));
}
public ActionResult GetCard(int id)
{
var model = eService.GetUserJobDetailsByID(id);
return PartialView("_Card", model);
}
}
}
Hi Babu,
To ensure a Card is selected by default, I recommend sending an Ajax request to the GetCard Action method with a predetermined id upon initialization. This will ensure that the Card with that id will be selected initially.
Furthermore, I suspect that the error might occur because the browser might interpret the Url in the Ajax's configuration as incomplete.
In ASP.NET it is recommended to utilize the Url.Action method:
$.ajax({
type: "GET",
url: "@Url.Action("GetCard","User")",
data: { id: dataItem.ID },
success: function (viewHTML) {
$("#skeleton").hide();
$(".selected-item").html(viewHTML);
},
error: function (errorData) { console.log(errorData) }
});
With the above in mind, the topic of the current thread is now entirely outside of the support scope of Telerik UI for ASP.NET for MVC. I strongly recommend contacting our Professional Service for more in-depth help on the custom configuration required in the scenario at hand.
Sure. Is there a way to adjust the height based on the screen? If i open in laptop its working fine but in monitor its looking odd.
You can control the responsiveness of any web app with the use of media queries, for examples:
@media only screen and (max-height: 800px) {
.narrow {
height: 320px;
}
.card {
height: 480px;
}
}
P.S.: Very useful suggestions by the Telerik team in this thread!