Kendo multi select component passing placeholder as value - kendo-ui

I have a form with a Kendo UI MultiSelect component for ASP.NET MVC / Razor:
#(Html.Kendo().MultiSelectFor(m => m.Ids)
.Filter(FilterType.Contains)
.AutoBind(true)
.MinLength(3)
.Delay(500)
.DataTextField("Value")
.DataValueField("Key")
.Placeholder("Please fill")
.DataSource(
ds => ds.Read(
r => r.Action("FillMultiSelect", "ReportsController", new { companyId = IdentityManager.CompanyID, search = string.Empty })
).ServerFiltering(true)
)
)
JavaScript for filtering:
var $ids = $("#Ids").data("kendoMultiSelect");
$ids.dataSource.transport.options.read.data = basicFilter($ids);
var basicFilter = function ($element) {
return {
companyId: self.form.getModel().CompanyId,
search: $element.input.val()
}
}
When I type the search text at the "Ids" MultiSelect, the parameter passed to the ASP.NET MVC Action is the value of the placeholder of the element:
What's wrong with my code?

The errors was in retrieving value from MultiSelect component. I should use the filters array from filter object, passed by the data event. Correct JavaScript:
window.global.setDatasourceTransportFilter($("#Ids"), "kendoMultiSelect", basicFilter);
var basicFilter = function (e) {
return {
companyId: self.form.getModel().CompanyId,
search: e.filter && e.filter.filters[0] ? e.filter.filters[0].value : ""
}
}

Related

How to get input field name that value has changed [ Angular 6 ]

I tried reactive form valueChanges but valueChanges method doesn't return input field name which has changed.
I thought code like this. but I think this is not smart way. Because I have to compare every each input field. so I need more smart way.
// get init view data from local storage
this.localstorageService.getPlaceDetail().subscribe(data => {
this.initPlaceDetail = data;
// watch changed value
this.editPlaceForm.valueChanges.subscribe(chengedVal => {
if (chengedVal['ja_name'] !== this.initPlaceDetail.languages.ja.name.text) {
this.changedJA = true;
}
if (chengedVal['ja_romaji'] !== this.initPlaceDetail.languages.ja.name.romaji) {
this.changedJA = true;
}
// ...... I have to check all input fields??
});
});
I'm adding form controls from an array and something like this worked for me. Just reference the item you need instead of expecting the valueChanges observable to pass it to you.
myFields.forEach(item => {
const field = new FormControl("");
field.setValue(item.value);
field.valueChanges.subscribe(v => {
console.log(item.name + " is now " + v);
});
});
This is my way to get changed control in form.
I shared for whom concerned.
Method to get list control changed values
private getChangedProperties(form): any[] {
let changedProperties = [];
Object.keys(form.controls).forEach((name) => {
let currentControl = form.controls[name];
if (currentControl.dirty)
changedProperties.push({ name: name, value: currentControl.value });
});
return changedProperties;
}
If you only want to get latest changed control you can use
var changedProps = this.getChangedProperties(this.ngForm.form);
var latestChanged = changedProps.reduce((acc, item) => {
if (this.changedProps.find(c => c.name == item.name && c.value == item.value) == undefined) {
acc.push(item);
}
return acc;
}, []);
Instead of listening to whole form changes you can listen to value changes event for each form control as shown in below code:
this.myForm.get('ja_name').valueChanges.subscribe(val => {
this.formattedMessage = `My name is ${val}.`;
});

how to insert value into the kendo combo box

If I have a kendo combobox that contains more than 1 value I would like to insert "-ALL- as the DataTextField and "9999" as the DataValueField. Currently, if I have only a single record I use the DataBound event to test for that and if it = 1 then I load a grid based on this value, but if the length > 1 then I would like to add the -All-. I don't understand the insert as described by telerik.
#(Html.Kendo().ComboBox()
.Name("FAList")
.Placeholder("Select Fiscal Agency...")
.DataTextField("Text")
.DataValueField("Value")
.HtmlAttributes(new { style = "width:50%;" })
.Filter("startswith")
.AutoBind(true)
.MinLength(3)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetUserAgencyList", "Entities");
})
.ServerFiltering(true);
})
.Events(e => e
.Change("onFAChange")
.DataBound("onFADataBound")
)
)
and then the function for binding the data
function onFADataBound(e) {
// the agency list dropdown
var combobox = $("#FAList").data("kendoComboBox");
// if there is only a single record then set that in the combobox and load the grid based on that
if (e.sender.dataSource.view().length == 1) {
e.sender.select(0);
var filter = this.value();
$.get('/City/CityGrid_Read', { id: filter }, function (data) {
var grid = $("#FollowUpGrid").data("kendoGrid");
grid.dataSource.read();
})
}
if (e.sender.dataSource.view().length > 1) {
}
}
Answered at: Adding an item dynamically in kendo combobox
Combining that with your code:
if (e.sender.dataSource.view().length > 1) {
$("#FAList").data("kendoComboBox").dataSource.add({ Text: "-All-",
Value: "0" });
}
Something like that! I hope you get this implemented :)
An alternative could be to change the Placeholder text in this event method where length > 1
as per example on: http://www.telerik.com/forums/placeholder-text
$("#FAList").data("kendoComboBox").input.attr("placeholder", "-All-");

How to assign kendo combobox a value

I am using the 2016.3.914.440 version of kendo and have a question on the ComboBox. If my datasource only returns a single value, how can I assign that to the ComboBox so the user doesn't need to enter a value? I tried the .SelectIndex(0), but that works under all situations, so I thought in the .DataBound I would check for the record count and if = 1 then I wanted to assign to the ComboBox.
The code I have is the following.
#(Html.Kendo().ComboBox()
.Name("FAList")
.Placeholder("Select Fiscal Agency...")
.DataTextField("Text")
.DataValueField("Value")
.HtmlAttributes(new { style = "width:50%;" })
.Filter("startswith")
.AutoBind(true)
.MinLength(3)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetUserAgencyList", "Entities");
})
.ServerFiltering(true);
})
.Events(e => e
.Change("onFAChange")
.DataBound("onFADataBound")
)
)
But I don't know how to finish the onFADataBound event
function onFADataBound(e) {
var dropdown = $("#FAList").data("kendoComboBox");
var count = dropdown.dataSource.data().length
alert('FA Count: ' + count)
}
So how would I find the text and value of the datasource record and assign that to the DataTextField and DataValueField.
You can select the first item via the select method.
function onFADataBound(e) {
if (e.sender.dataSource.view().length == 1) {
e.sender.select(1);
}
}
Note that the selected item's index will be 1 if you have an optionLabel (placeholder) and 0 otherwise.

How to prevent deleting items in KendoUI multiselect?

I use a Kendo.UI MultiSelect in MVC
#(Html.Kendo().MultiSelect()
.Name("ADGroups")
.DataTextField("Name")
.DataValueField("Value")
.MinLength(3)
.Value(Model.SelectedADGroups)
.HtmlAttributes(new { style = "width:auto", id="ADGroupsList" })
.Filter(FilterType.Contains)
.DataSource(source => source.Read(read => read.Action("GetADGroups", "Edit"))
.ServerFiltering(true))
.Events(e => e.Change("onChange").DataBound("onDataBound"))
)
And now I would like to prevent from deleting some Items.
So I save the current values on DataBound-Event
function saveCurrent(multi)
{
multi._savedValues = multi.value().slice(0);
multi._savedItems = multi._dataItems.slice(0);
}
function onDataBound()
{
saveCurrent(this);
}
And OnChange I detect the difference between before and after.
function onChange()
{
var previous = this._savedValues;
var current = this.value();
if (current.length < previous.length)
{
var diff = $(previous).not(current).get(0);
if (confirm('Sure?'))
{
// do nothing value already deleted
}
else
{
// reset
this.value(previous);
}
}
saveCurrent(this);
}
This works perfectly. But If I type a new phrase so the widget calls the Read-Action to add some Items all works fine and NOW when I delete an item and cancel this action, however items will be removed.
What is wrong?

Kendo UI DropDownList as Multi Select with CheckBox

I'm Using Kendo UI MVC wrapper. I need a DropDownList with checkbox for each item to allow me select multiple of items.
I found this jsfiddle doing what I want to achieve, but it is not with MVC wrapper.Would you please show how I can implement the same thing with MVC wrapper?
#(Html.Kendo().DropDownList()
.Name("StructureCompany")
.HtmlAttributes(new { style = "width:180px" })
.OptionLabel("-- Select --")
.DataTextField("Title")
.DataValueField("Id")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeCompany", "Company");
});
}))
Here's a way you can do it:
View
#(Html.Kendo().DropDownList()
.Name("StructureCompany")
.HtmlAttributes(new { style = "width:180px" })
.DataTextField("Title")
.DataValueField("Id")
.Template("<input type='checkbox' name='cb' value='#:data.Title#' /> #:data.Title#")
.Events(e => e.Select("onSelect"))
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetCascadeCompany", "Company");
});
}))
I removed your OptionLabelbecause it doesn't flow well with this style. But I found an alternative as you will see below
Script
//This extendes the base Widget class
(function ($) {
var MultiSelectBox = window.kendo.ui.DropDownList.extend({
_select: function (li) { },//Prevents highlighting
_blur: function () { },//Prevents auto close
});
window.kendo.ui.plugin(MultiSelectBox);
})(jQuery);
//Sets up your optional label
$(document).ready(function () {
$("#StructureCompany").data("kendoDropDownList").text("-- Select --");
})
//Does all the functionality
function onSelect(e) {
var dataItem = this.dataItem(e.item);
var ddl = $("#StructureCompany").data("kendoDropDownList");
var cbs = document.getElementsByName("cb");
var display;
var list = [];
for (var i = 0; i < cbs.length; i++) {
if (cbs[i].checked) {
list.push(cbs[i].value);
}
}
if (list.length == 0) {
display = "-- Select --";
}
else {
display = list.join(", ");
}
ddl.text(display);
}
Here is the tricky part, I'm not a real connoisseur when it comes to javascript so forgive my terminology if it is wrong. The first blob where you have the new scope function allows you to inherit from the kendo.ui namespace so that you are able to change the base level stuff. Such as the auto close and highlighting functionality
That next blob is just my alternative to having your 'OptionLabel'(you can do it however you want)
The last part is the selection which as you can see just creates a comma value then shoves it in as the display in the drop down list via 'ddl.text()' method. You can do this however you want. Hope this helps!

Resources