I'm building a local WPF application that uses kendo grids. The application needs to work offline so I'm referencing the kendo css and js files in local directory within my application. Everything is working fine except the icons for filtering and paging aren't appearing within the grid. I've attached a small sample project to show my problem.
If you uncomment line 45 in MainWindow.xaml.cs to reference the remote copy of kendo.common.css everything works fine, but when referencing the local copy of that file, the images don't appear properly.
I'd like to block this event (group closing)..
it must not be clickable (attachment file)
<
div
id
=
"mt"
data-role
=
"grid"
data-groupable
=
"true"
data-pageable
=
'{ "pageSize": 10}'
data-reorderable
=
"true"
data-resizable
=
"true"
data-sortable
=
"true"
data-columns="[
{ 'field': 'nome','title':'Nome'}
]"
data-bind
=
"source: Product"
></
div
>
Hello there,
Please write me a suggestion to my problem:
My _Layout.cshtml file looks like this:
<html>
<head>
<link href="@Url.Content("~/Content/bootstrap.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/kendo/2017.3.1018/kendo.common.min.css")" rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/kendo/2017.3.1018/kendo.moonlight.min.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/kendo/2017.3.1018/jquery.min.js")"></script>
<script src="@Url.Content("~/Scripts/kendo/2017.3.1018/kendo.all.min.js")"></script>
<script src="@Url.Content("~/Scripts/kendo/2017.3.1018/kendo.aspnetmvc.min.js")"></script>
<script src="@Url.Content("~/Scripts/kendo/2017.3.1018/cultures/kendo.culture.hu-HU.min.js")"></script>
<script type="text/javascript">
function refreshPartialView(e) {
var selected = this.dataItem($(e.item));
var id = selected.Id;
var result = $.ajax({
url: '@Url.Action("GetSiteInfoSearchResult", "SiteInfo")',
method: 'GET',
data: { id: id },
dataType: 'text',
async: false,
success: function (response) {
$('#tabStripPartial').html(response);//show the tabstrip
$('#gridSerialSearchResult').html('');//and clear the other partial... :(
}
});
}
function refreshSerialGrid(e) {
var selected = this.dataItem($(e.item));
var result = $.ajax({
url: '@Url.Action("GetSerialSearchResult", "Jegyzokonyv")',
method: 'GET',
data: { id: selected },
dataType: 'text',
async: false,
success: function (response) {
$('#gridSerialSearchResult').html(response);//show the gridview
$('#tabStripPartial').html('');//and hide the other partial view
}
});
}
</script>
<script>
$(document).ready(function () {
$("#searchBox").kendoAutoComplete({
dataSource: {
transport: {
read: {
url: "/SiteInfo/GetSiteInfos"
}
}
},
dataTextField: "Nev",
placeholder: "Search site...",
autoWidth: true,
select: refreshPartialView
});
});
$(document).ready(function () {
$("#searchSerial").kendoAutoComplete({
dataSource: {
transport: {
read: {
url: "/Jegyzokonyv/GetSerials"
}
}
},
placeholder: "Search serial...",
autoWidth: true,
filter: "contains",
select: refreshSerialGrid
});
});
</script>
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<p class="site-title">@Html.ActionLink("Home", "Index", "Home")</p>
</div>
<div class="float-right">
@(Html.Kendo().Menu().Name("navmenu").Items(i =>
{
if (Request.IsAuthenticated)
{
i.Add().Text("Search").Content("<input id='searchBox'/>");
i.Add().Text("Tools").Items(children =>
{
children.Add().Text("Reports").Items(children2 =>
{
children2.Add().Text("Report 1");
children2.Add().Text("Report 2");
children2.Add().Text("Report 3");
});
children.Add().Text("Search serial").Content("<input id='searchSerial'/>");
children.Add().Text("Account");//The problem is here, if I add Action("Index","Manage")
children.Add().HtmlAttributes(new { @class = "k-separator" });
children.Add().Text("Logout").HtmlAttributes(new { onClick = "javascript:document.getElementById('logoutForm').submit()" });
});
}
else
{
i.Add().Text("Login").Action("Login", "Account");
}
i.Add().Text("Contact").Action("Contact", "Home");
}))
</div>
</div>
@using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" }))
{
@Html.AntiForgeryToken()
}
</header>
<div id="body" class="container">
@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix" id="mainBody">
@RenderBody()
@if (Request.IsAuthenticated)
{
@Html.Partial("_TabStripPartial")
@Html.Partial("_SerialKeresoPartial")
//or this???
//@RenderPage("_TabStripPartial.cshtml")
//@RenderPage("_SerialKeresoPartial.cshtml")
}
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
<p>© 2015-@DateTime.Now.Year</p>
</div>
</div>
</footer>
</body>
</html>
Now as you can see, the site has a menu when user is not logged in with Login and Contact buttons only. After successful login
the user get the additional menu items. The 'Featured' section is still there.
I want to get the 2 serach result partial view and the account manage page to be shown on the same place. It's working when I only enable those 2 search partial view: at Javascript I fill one of them and clear the other. I hate this solution, do you have any other suggestion?
The _TabStripPartial view contains @Html.Kendo().TabStrip() element and the _SerialKeresoPartial view contains a @Html.Kendo().Grid(Model) grid with local data binding. Both works.
My questions:
1 - is it possible to get independent pages (depending on the menu selection) to body with removing the Featured section (I only want to see this section when the user hasn't made any interaction yet)
2 - is it possible to embed AutoComplete in Menu without that Javascript solution?
3 - after selecting item in either the first Autocomplete or in the other, how can I show those partial view in body and only the selected partial view, not both.
4 - if I add this Action("Index","Manage") after the account menu item, the site crashes at the first @Html.Partial part because of invalid operation (account management uses different model that this tabstrip partial view). How can I create more pages (including this account management) and show them on the same place in body?
Thanks
Attila
I have a line chart that shows hours when they fit, otherwise days. Currently I have the category title text set to Time. How do I make the category title text dynamically display hours or days depending on which one the chart dynamically displays? Thank you.
k-category-axis="{
title: {
text: 'Time',
font: '12px Segoe UI,Tahoma,Geneva,sans-serif'
},
type: 'date',
baseUnit: 'fit',
maxDateGroups: 24,
autoBaseUnitSteps: {
hours: [1],
days: [1]
},
labels: {
rotation: -45,
dateFormats: {
hours: 'HH mm',
days: 'MM/dd'
}
}
}"
How to hide tab of tabstrip with MVVM?
<
div
id
=
"file"
>
<
ul
>
<
li
class
=
"k-state-active"
data-bind
=
"visible: checkEmpty"
>
Images
</
li
>
</
ul
>
</
div
>
Visible does't work!
Hi all. I got a kendo grid that holds candidates.
I got a external textbox, and for every character typed there's a 0.5 second debouce before the datasource.filter happens with the textbox value.(search as you type functionality).
I want to manual filter the grid without a read request occuring on every input. I changed ServerOperation to FALSE, but now datasource.filter just won't work. Nothing happens. When I put ServerOperation to TRUE, all works fine.
How can I make the manual filter work? Here's my code;
@(Html.Kendo().Grid<CandidatesGridViewModel>()
.Name("grid")
.HtmlAttributes(new { @class = "kendoHover" })
.ToolBar(t =>
{
t.Template(@Html.KendoGridToolbar(true, true).ToHtmlString());
})
.Columns(columns =>
{
columns.Bound(c => c.FullName).Title(Resources.Candidates);
columns.Bound(c => c.StatusId).Title(Resources.Status)
.ClientTemplate("# if(StatusDescription == undefined) { # Geen status # } else { # #=StatusDescription# # } # ")
.EditorTemplateName("CandidateStatusEditor")
.Filterable(filterable => filterable.UI("statusFilter"));
columns.Bound(c => c.FirstName).Visible(false);
columns.Bound(c => c.LastName).Visible(false);
columns.Bound(c => c.PrimaryPhone).Title(Resources.PrimaryPhone);
columns.Bound(c => c.Email).Title(Resources.EmailAdress);
columns.Bound(c => c.LastActionDescription).Title(Resources.LatestActions);
columns.Bound(c => c.LastExecutedByEmail).Title(Resources.LastCreationUser);
columns.Bound(c => c.Vacancy).Title(Resources.Vacancy);
columns.Command(commands => commands.Edit().CancelText(Resources.Cancel).UpdateText(Resources.Update).Text(Resources.Edit));
})
.Scrollable()
.Sortable()
.Filterable(filterable => filterable
.Extra(false)
.Operators(operators => operators
.ForString(str => str.Clear()
.Contains(@Resources.Contains)
.StartsWith(@Resources.StartsWith)
.EndsWith(@Resources.EndsWith)
.IsEqualTo(@Resources.IsEqualTo)
.IsNotEqualTo(@Resources.IsNotEqualTo)
))
)
.Groupable()
.Events(events => events
.SaveChanges("onSaveChangesCandidatesGrid")
.Save("onSaveChangesCandidatesGrid")
.ExcelExport("excelExport"))
.Editable(editable => editable.Mode(GridEditMode.InLine))
.Selectable().Events(e => e.DataBound("onDataBound"))
.AutoBind(false)
.Resizable(resize => resize.Columns(true))
.Excel(excel => excel
.FileName("Candidates.xlsx")
).Pdf(pdf => pdf
.FileName("Candidates.pdf")
.AvoidLinks(true)
)
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(new List<object> { 10, 20, 50, "All" })
.ButtonCount(5))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Model(model =>
{
model.Id(p => p.Id);
model.Field(p => p.Id).Editable(false);
model.Field(p => p.FullName).Editable(false);
model.Field(p => p.StatusDescription).Editable(false);
model.Field(p => p.PrimaryPhone).Editable(false);
model.Field(p => p.Email).Editable(false);
model.Field(p => p.LastActionDescription).Editable(false);
model.Field(p => p.LastExecutedByEmail).Editable(false);
model.Field(p => p.Vacancy).Editable(false);
})
.Read(read => read.Action("Candidates_Read", "Candidates").Data("candidatesReadData"))
.Update(update => update.Action("Candidates_Update", "Candidates"))
.PageSize(10))
.NoRecords(x => x.Template("<div class='noSearchResults'>" + Resources.NoCandidatesFound + "</div>")))
External input: keyup => triggers filterGrid()
$(function () {
//dynamic search
var searchBox = $(".search [name=keyword]");
$(searchBox).keyup($.debounce(500, function (ev) {
filterGrid();
}));
$(".search [name=statusFilter]").change(filterGrid());
$(".candidateInfoClick").on('click', function (r) {
console.log($(this).attr('class').split(/\s+/)[2].substr(10));
window.location.href = "@Url.Action("ViewCandidate", "Candidates")?candidateId=" + $(this).attr('class').split(/\s+/)[2].substr(10);
});
});
FilterGrid() :
function filterGrid() {
var keywordUpper = $(".search [name=keyword]").val();
var keyword = keywordUpper.toLowerCase().trim();
var status = $("#statusFilter option:selected").text();
console.log(keyword);
//Setting the filter of the Grid
$("#grid").data("kendoGrid").dataSource.filter
({
filters: [
{
field: "FullName",
operator: "contains",
value: keyword
},{
field: "StatusDescription",
operator: "contains",
value: status
}
]
});
}
I am using Kendo Treelist ie: Load on Demand in our application. I'm using the 2017.1.223 version for kendo. Applied server side filtering for my treelist.
When I try to apply filter to my columns, the result shows me duplicate records. Posting my code below:
Controller method
------------------------------------------------
public async Task<JsonResult> GetAssetTreeListBasedOnPermissions([DataSourceRequest] DataSourceRequest request, AssetColumnFilters assetcolumnFilters,int? id)
{
try
{
string searchExpression = string.Empty;
AssetColumnFilters columnFilters = new AssetColumnFilters();
if (!string.IsNullOrEmpty(assetcolumnFilters.AssetId))
{
var assetIds = assetcolumnFilters.AssetId.ToString().Split(',');
var i = 0;
var assetString = "";
foreach (var assetId in assetIds)
{
if (i == 0)
{
assetString += " (A.AssetId=" + assetId + ") ";
}
else if (i > 0)
{
assetString += " OR (A.AssetId=" + assetId + ") ";
}
i++;
}
searchExpression = assetString;
}
string searchExp = searchExpression;
AssetFiltersModel filters = new AssetFiltersModel();
long? companyId = SiteSession.CurrentSession.CompanyId;
long userId = SiteSession.CurrentSession.UserId;
//FIRST TIME LOAD
if (id==null && request.Filters.Count==0)
searchExp = string.IsNullOrEmpty(searchExp) ? " (SA.ParentAssetId=" + 0 + " AND A.CompanyId=" + SiteSession.CurrentSession.CompanyId + ")" : "(SA.ParentAssetId=" + 0 + " AND A.CompanyId=" + SiteSession.CurrentSession.CompanyId + ") and " + searchExp;
else if(id==null&& request.Filters.Count>0)
searchExp = string.IsNullOrEmpty(searchExp) ? " (A.CompanyId=" + SiteSession.CurrentSession.CompanyId + ")" : "(A.CompanyId=" + SiteSession.CurrentSession.CompanyId + ") and " + searchExp;
else
searchExp = string.IsNullOrEmpty(searchExp) ? " (SA.ParentAssetId=" + id + " AND A.CompanyId=" + SiteSession.CurrentSession.CompanyId + ")" : "(SA.ParentAssetId=" + id + " AND A.CompanyId=" + SiteSession.CurrentSession.CompanyId + ") and " + searchExp;
filters.SearchExpression = searchExp;
filters.SortExpression = (request.Sorts.Count > 0) ? request.Sorts.FirstOrDefault().Member : string.Empty;
filters.SortDirection = (request.Sorts.Count > 0) ? (request.Sorts.FirstOrDefault().SortDirection == ListSortDirection.Ascending ? " asc" : " Desc") : string.Empty;
filters.StartIndex = Helper.GetCurrentPage(request.Page, request.PageSize);
filters.PageSize = request.PageSize;
filters.UserId = userId;
var assetGridList = await aladdinRestClient.PostAsync<AssetFiltersModel, AssetListModel>(Constant.GETASSETLISTBASEDONUSER, filters, false);
var list= assetGridList.AssetList.AsQueryable();
var result = list
.Select(e => new AssetModel
{
AssetId = e.AssetId,
ParentAssetId = e.ParentAssetId,
AssetName = e.AssetName,
AssetIdEncrypt = e.AssetIdEncrypt,
hasChildren = e.IsParent == 1 ? true : false,
AssetNo = e.AssetNo,
Model = e.Model,
SerialNumber = e.SerialNumber,
Category1Name = e.Category1Name,
Category2Name = e.Category2Name,
Category3Name = e.Category3Name,
Category4Name = e.Category4Name,
LocationLevel1Name = e.LocationLevel1Name,
LocationLevel2Name = e.LocationLevel2Name,
LocationLevel3Name = e.LocationLevel3Name,
LocationLevel4Name = e.LocationLevel4Name,
StatusName = e.StatusName,
IsAttachmentsExist = e.IsAttachmentsExist
}).ToTreeDataSourceResult(request,
e => e.AssetId,
e => e.ParentAssetId
);
var jsonResult = Json(result, JsonRequestBehavior.AllowGet);
jsonResult.MaxJsonLength = Int32.MaxValue;
return jsonResult;
}
catch (Exception ex)
{
throw ex;
}
}
View
---------------------------------------------------------------------------
@(Html.Kendo().TreeList<AssetModel>()
.Name("assetTreeList")
.Columns(columns =>
{
columns.Add().Field(a => a.AssetId).Hidden(true);
columns.Add().Field(a => a.AssetIdEncrypt).Hidden(true);
//.Template("#if(IsAttachmentsExist == true) {#" + "<a class='k-button' href='javascript:void(0);' onclick='EditAsset(#:AssetId#,true);'><span class='k-i-attachment-45 k-i-clip-45'></span>#= AssetName# </a>" + "#}else {#" + "<a class='inline-link' href='javascript:void(0);' onclick='EditAsset(#:AssetId#,true);' style='margin-right:5px;'>#= AssetName# </a>" + "#} #").Width(290);
columns.Add().Field(a => a.AssetName).TemplateId("attachment-template").Width(290)/*.HeaderTemplateId("expandAll-template")*/;
columns.Add().Field(a => a.AssetNo).Title(AssetDetailResource.AssetNumber).Width(250).Hidden((bool)ViewData["AssetNumber"]);
columns.Add().Field(a => a.Model).Title(AssetDetailResource.Model).Width(120).Hidden((bool)ViewData["Model"]);
columns.Add().Field(a => a.SerialNumber).Title(AssetDetailResource.SerialNumber).Width(150).Hidden((bool)ViewData["SerialNumber"]);
columns.Add().Field(a => a.LocationLevel1Name).Title(AssetDetailResource.LocationLevel1Name).Width(180).Hidden((bool)ViewData["LocationLevel1"]);
columns.Add().Field(a => a.LocationLevel2Name).Title(AssetDetailResource.LocationLevel2Name).Width(180).Hidden((bool)ViewData["LocationLevel2"]);
columns.Add().Field(a => a.LocationLevel3Name).Title(AssetDetailResource.LocationLevel3Name).Width(180).Hidden((bool)ViewData["LocationLevel3"]);
columns.Add().Field(a => a.LocationLevel4Name).Title(AssetDetailResource.LocationLevel4Name).Width(180).Hidden((bool)ViewData["LocationLevel4"]);
columns.Add().Field(a => a.Category1Name).Title(AssetDetailResource.Category1).Width(180).Hidden((bool)ViewData["CategoryLevel1"]);
columns.Add().Field(a => a.Category2Name).Title(AssetDetailResource.Category2).Width(180).Hidden((bool)ViewData["CategoryLevel2"]);
columns.Add().Field(a => a.Category3Name).Title(AssetDetailResource.Category3).Width(180).Hidden((bool)ViewData["CategoryLevel3"]);
columns.Add().Field(a => a.Category4Name).Title(AssetDetailResource.Category4).Width(180).Hidden((bool)ViewData["CategoryLevel4"]);
columns.Add().Field(a => a.StatusName).Title(@SGE.Aladdin.Resources.SGEAdmin.AdminResources.Status).Width(120).Hidden((bool)ViewData["Status"]);
//if (IsAdd)
//{
// columns.Add().Template("<a href='javascript:void(0);' onclick='CloneAsset(#:AssetId#);' class='duplicate-ico' title='" + string.Format(CommonResources.CloneTooltip, CommonResources.Assets) + "'>" + "</a>").Title(CommonResources.Clone).Width(50);
//}
if (IsDelete)
{
columns.Add().Template("<a href='javascript:void(0);' onclick='DeleteAsset(#:AssetId#);' class='delete-ico' title='" + string.Format(CommonResources.DeleteTooltip, CommonResources.Assets) + "'>" + "</a>").Title(CommonResources.Delete).Width(50);
}
})
.Sortable()
.Events(ev => ev.DataBound("onTreeListDataBound"))
.Events(ev => ev.FilterMenuInit("filterMenuInit"))
.DataSource(dataSource => dataSource
.Read(read => read.Action("GetAssetTreeListBasedOnPermissions", "Asset"))
.ServerOperation(true)
.Model(m =>
{
m.Id(e => e.AssetId);
m.ParentId(e => e.ParentAssetId);
m.Field(e => e.AssetName);
})
)
.Filterable(true)
.Reorderable(true)
.Resizable(true)
.Scrollable(true)
.Sortable(true)
)
In the above code, when a column filter is applied, I am getting the entire data in 'list' variable. When this list of data is converted to treedatasourceresult, the filter will get applied to the data. In the result variable, I can see the filtered results with duplicates. Please see the attached image. Based on the filter, the result should return asset 05, ASSET 01=>ASSET 008. But now its showing as in the attached image, which is incorrect. Could you please help me? Your help will be much appreciated.
Hi Team,
We are exploring to use Kendo UI for one of our project.There are few below requirements which I couldn't find in Demo or not very clear.
1) Add Column on button click.
There will be a add column button in UI which should allow to add new column in the grid.
Case 1
Add New Col[Button] Copy from Existing[Button]
Col 1 [Checkbox]
Group A
Value 1
Value 2
Group B
Value 3
Value 4
When click on add Button it should add new column as shown below:
Add New Col[Button] Copy from Existing[Button]
Col 1 [Checkbox] Col 2[Checkbox]
Group A
Value 1 1
Value 2 2
Group B
Value 3 3
Value 4 4
2) Copy Column on button click using existing Column.
User has filled the value for col 1 and added new col 2 and Col 3 copied from existing Col1. as shown below:
Add New Col[Button] Copy from Existing[Button]
Col 1 [Checkbox] Col 2 [Checkbox] Col 3 [Checkbox]
Group A
Value1 1 5 1
Value2 2 6 2
Group B
Value3 3 7 3
Value4 4 8 4
3) Add section/group capability.
Case 3 Add Group or delete group:
Value 5 and Value 6 added in the Group B.
Add New Col[Button] Copy from Existing[Button]
Col 1 [Checkbox] Col 2 [Checkbox]
Group A
Value 1 1 5
Value 2 2 6
Group B
Value 3 3 10
Value 4 4 11
Value 5
Value 6
I have searched for point 1 and 2 and couldnt find any proper solution. Please confirm if above points has been supported by Kendo grid. If not is there any way to achive above by any tweak or customization?
Thanks in advance.
Mahendra
I'd like to have a listing of validation exceptions, warning and errors, held in a separate control or widget. I mean generic validation message, not necessarily those raised by the validator - they would replace popups and be something like notifications but stored in a separate area.
What widgets do you think should be used used for the message itself (containing the link UID, message type, text) and which one to contain the message list (grid, listbox, other?). The list should scroll like the console, most recent at top. Individually they could be cleared or the entire group could be cleared.
It sounds something like notifications that are stored in a grid - not sure if that's possible or if there is an existing solution.
Curious about your thinking on this...
Thanks,
Larry
Hi,
I have seen some example of the Grid ui for serer paging and sorting. It did show the property for server paging and sorting but didn't give much detail how it is going to use on the data source.
For example if i have 1000 recrods and I only want to show 20 on each page. I dont want to bring the whole lot and want to do the cutom paging. So I will se tthe custom paging on by saying Serverpaging=true.
Now when I clik on the next page , what message will go to my stored procedure so it returns the next 20. I saw an articla in telerik that your datasoure should be able to handle skip and top. Well but from where I am getting the skip and top?
I seen many examples but none showing what is sent to the data source from the code.
i am going to use the webapi to bind as a datasoruce and use the stored procedure or EF to access the data.
Can you show m some examples please so i can be certain how to pass sort, top, skip from the code. I know how to make change on the webapi to accomodat any parameter and all the way to database. .