asp kendo multiselect manualy select items by jquery - kendo-asp.net-mvc

in my form there are asp kendo multiselect ; I want select some items from multiselect per selected value from a asp kendo dropdownlist? how can I do this ?
#(Html.Kendo().DropDownList()
.Name("dropdown")
.Filter("contains")
.DataTextField("Name")
.DataValueField("Id")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("action", "controller" });
});
})
.AutoBind(true)
)
#(Html.Kendo().MultiSelect()
.Name("multiselect")
.Filter("contains")
.HtmlAttributes(new { style = "width:100%" })
.DataTextField("Name")
.DataValueField("Id")
.Filter("contains").Animation(false)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("action", "controller" });
});
})
)

i solved this problem;
first define a function for dropdown_change and in that function get selected value from dropdown and load data by jquery ajax then select items from multiselect :)
$(document).ready(function () {
$('#dropdownName').data("kendoDropDownList").bind("change", drp_change);
});
function drp_change() {
var selected = $('#dropdownName').val();
if (selected > 0) {
//fill multiselect per selected value
var params= { [paramName]: selected };
$.get('/controller/action', params, function (data) {
var multiSelect = $("#multiselectName").data("kendoMultiSelect");
var selected = $.map(data, function (item) {
return item;
});
multiSelect.value(selected);
multiSelect.trigger("change");
})
} else {
$('#multiselectContailner').hide();
}
}

Related

Kendo Multi-select in cascading scenario unable to populate initial values

I'm using Telerik for MVC and trying to get the multi-select to populate with the initial values in an Edit scenario.
<script>
function filterProducts() {
return {
manufacturerId: $("#ServiceBulletinItem_ManufacturerId").val()
};
}
function onManufacturerChange(e) {
var v = e.sender.dataItem().Value;
$.post("#Url.Action("GetCascadeProducts", "Components")", { manufacturerId: v }, function (result) {
var grid = $("#ServiceBulletinItem_ApplicableProducts").data("kendoMultiSelect")
grid.setDataSource(result)
});
}
function InitialPopulate(manId) {
$.post("#Url.Action("GetCascadeProducts", "Components")", { manufacturerId: manId }, function (result) {
var grid = $("#ServiceBulletinItem_ApplicableProducts").data("kendoMultiSelect")
grid.setDataSource(result)
});
}
$(document).ready(function () {
$('.control-datepicker').Zebra_DatePicker();
var m = $("#ServiceBulletinItem_ManufacturerId").val();
InitialPopulate(m);
});
</script>
<div class="form-group">
#Html.LabelFor(m => m.ManufacturerList, "Manufacturer", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#(Html.Kendo().DropDownListFor(m => m.ServiceBulletinItem.ManufacturerId)
.HtmlAttributes(new { #class = "col-md-6 form-control" })
.Filter("contains")
.DataValueField("Value")
.DataTextField("Text")
.BindTo((IEnumerable<SelectListItem>)Model.ManufacturerSelectList)
.HtmlAttributes(new { style = "width:70%;" }).Events(e =>
{
e.Change("onManufacturerChange");
})
)
</div >
</div >
<div class="form-group">
#Html.LabelFor(m => m.ProductList, "Product", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#(Html.Kendo().MultiSelectFor(m => m.ServiceBulletinItem.ApplicableProducts)
.AutoClose(false)
.DataTextField("ProductName")
.DataValueField("ProductId")
.Placeholder("Select products...")
)
</div>
</div>
I'm trying to populate the manufacturer drop down and the Product multiSelect. The ApplicableProducts item is an IEnumerable representing the ProductId's of all those previously selected and I know that when I select the manufacturer and it calls the GetCascadeProducts controller method it will return back a collection of ProductId and ProductName for all the manufacturers products of which those productId is the ApplicableProducts property should exist.
On document.ready I can call the InitialPopulate method with the manufacturerID which will populate the multiSelect items but can't seem to populate the initial values.
I couldnt get the binding working correctly so ended up using
#(Html.Kendo().MultiSelect()
.Name("ServiceBulletinItem_ApplicableProducts")
.AutoClose(false)
.DataTextField("ProductName")
.DataValueField("ProductId")
.Placeholder("Select products 2...")
.AutoBind(false)
)
and then on the using the following code on document ready to make an ajax call to populate the manufacturer and product controls
function PopulateProductsInitial(manId) {
$.post("#Url.Action("GetCascadeProducts", "Components")", { manufacturerId: manId }, function (result) {
var grid = $("#ServiceBulletinItem_ApplicableProducts").data("kendoMultiSelect")
grid.setDataSource(result);
var s = $("#ServiceBulletinItem_Id").val();
$.post("#Url.Action("GetSBProducts", "ServiceBulletins")", { Id: s}, function (result) {
var arr = [];
result.forEach(function (element) {
arr.push(element.ProductId);
});
var grid = $("#ServiceBulletinItem_ApplicableProducts").data("kendoMultiSelect")
grid.value(arr);
});
});
}
}
$(document).ready(function () {
//Populate Initial Values
PopulateProductsInitial($("#ServiceBulletinItem_ManufacturerId").val());
$('#YourButton').click(SendForm);
});
The problem then became sending the selected items back to the controller when the edit was complete which again seemed convoluted because the control was not bound and therefore I had to make an Ajax call to submit the data.
function SendForm() {
var items = $("#ServiceBulletinItem_ApplicableProducts").data("kendoMultiSelect").value();
//Manipulate into ServiceBulletinViewModel for the save
var data = {
Id: $("#ServiceBulletinItem_Id").val(),
ServiceBulletinItem: {
Id: $("#ServiceBulletinItem_Id").val(),
ManufacturerId: $("#ServiceBulletinItem_ManufacturerId").val(),
IssueDate: $('#ServiceBulletinItem_IssueDate').val(),
Heading: $('#ServiceBulletinItem_Heading').val(),
Details: $('#ServiceBulletinItem_Details').val(),
Url: $('#ServiceBulletinItem_Url').val(),
SelectedProducts: items
}
}
$.ajax({
type: 'POST',
url: '/ServiceBulletins/Edit',
contentType: 'application/json',
data: JSON.stringify(data),
success: function (result) {
//Your success code here..
if (result.redirectUrl != null) {
window.location = result.redirectUrl;
}
},
error: function (jqXHR) {
if (jqXHR.status === 200) {
alert("Value Not found");
}
}
});
}
It all seemed a lot more convoluted than any of the demo's that teleriks and I couldnt find any good examples of binding from remote sources which looked similar.
As the binding is convention based I'm wondering if its possible to simplify the ajax calling for the post functionality with the correct naming of the controls so that I can simply get the selected items on the multiselect control or if the ajax post is the way to go.

Kendo Multiselect data.length undefined in template

This is very simple, I have a Multiselect and when one item is selected, I want the tag to represent the DataTextField. When multiple items are selected, I want one tag to represent the quantity of items selected. Here is my code:
#(Html.Kendo().MultiSelect()
.Placeholder("Select Employees...")
.Name("empSelect")
.DataTextField("Employee")
.DataValueField("PERSONNEL_KEY")
.HtmlAttributes(new { style = "width:100%;font-size:10px;", id = "empSelect" })
.AutoBind(false)
.AutoClose(false)
.Filter(FilterType.Contains)
.TagTemplateId("tagTemplate")
.DataSource(source => {
source.Read(read =>
{
read.Action("GetEmployees", "EmployeeTS");
})
.ServerFiltering(true);}))
and here is the tagTemplate script:
<script id="tagTemplate" type="text/x-kendo-template">
# if (data.length < 2) { #
<span>
#= data.Employee #
</span>
# } else { #
<span>
#= data.length # selected
</span>
# } #
All items come back from my Controller just fine. When I select an item(s), the tag displays "UNDEFINED selected". Apparently "data.length" is undefined, yet I know of no other way to grab the count of items selected.
I am currently on the 2016.3.1118 build of Telerik Kendo MVC.
"data" doesn't have property of length. Because of that, always works "else" and shows undefined.
<script>
function onChange(e) {
var multi = $("#empSelect").data("kendoMultiSelect");
var multi = $("#empSelect").data("kendoMultiSelect");
if (multi.listView._dataItems.length > 1) {
multi.setOptions({
tagMode: 'single'
});
} else {
multi.setOptions({
tagMode: 'multiple'
});
}
multi.refresh();
}
#(Html.Kendo().MultiSelect()
.Placeholder("Select Employees...")
.Name("empSelect")
.DataTextField("TANIM")
.DataValueField("URETIM_YERI")
.AutoBind(false)
.AutoClose(false)
.Filter(FilterType.Contains)
.TagMode(TagMode.Multiple)
.Events(e =>
{
e.Change("onChange");
})
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetFactories", "Factory");
})
.ServerFiltering(true);
}))

ReactJS modify parent state from child component

I'm trying to remove an item from my state array when clicked. At the moment I have an onclick listener which calls a function passed into the props. However I get a warning: bind(): React component methods may only be bound to the component instance. See App... and it does not remove the item.
Thanks for any help regarding this issue! It has pretty much ground my progress to a halt.
(function (React) {
var data = [
'Go to work',
'Play Albion Online',
'Keep learning React'
]
var App = React.createClass({
getInitialState: function () {
return {data: []}
},
componentWillMount: function () {
this.state.data = data;
},
removeItem: function (i) {
console.log(i);
},
render: function () {
return (
<ToDoList onRemoveItem={this.removeItem} tasks={this.state.data} />
)
}
});
var ToDoList = React.createClass({
render: function () {
var scope = this;
var tasks = this.props.tasks.map(function (task, i) {
return <ToDo onClick={scope.props.onRemoveItem.bind(this, i)} key={task} task={task} />
});
return (
<ul>
{tasks}
</ul>
)
}
});
var ToDo = React.createClass({
render: function () {
return (
<li>{this.props.task}</li>
)
}
});
React.render(<App />, document.getElementById('example'));
})(React);
React actually auto-binds methods to the current component:
http://facebook.github.io/react/blog/2013/07/02/react-v0-4-autobind-by-default.html
In the TodoList component, rather than:
scope.props.onRemoveItem.bind(this, i)
Try:
scope.props.onRemoveItem.bind(null, i)
By providing null instead of this you'll allow React to do its own thing. Also you need to actually use the onClick handler:
<li onClick={this.props.onClick}>{this.props.task}</li>

How can I programmatically add/remove models to a controller?

This shouldn't be too hard.
I have a datepicker UI widget, and each time the user clicks on a month, I want to add or remove that month from the MonthsController (an ArrayController). The MonthsController is not associated with a route, so in my ApplicationTemplate I simply have
{{render months}}
A simplified version of my datepicker view is
App.DatepickerView = Ember.View.extend({
click: function(e) {
var id = $(this).datepicker().data('date').replace(" ", "-");
this.get('controller.controllers.months').toggleMonth(id);
}
});
and I handle the event in my MonthsController:
App.MonthsController = Ember.ArrayController.extend({
toggleMonth: function(id) {
var month = App.Month.find(id),
index = this.indexOf(month);
if (index === -1) {
this.pushObject(month);
} else {
this.removeAt(index);
}
}
});
I thought I had this working, but then I realized that month in the last snippet wasn't really an App.Month, it was just (I suppose) an anonymous object.
How can I programmatically add/remove models to a controller?
Your App.Month.find(id) will return a promise. If that month hasn't loaded yet you would also be loading this data from the server. You need to wrap your code in the promise's then.
toggleMonth: function(id) {
var _this = this;
App.Month.find(id).then(function(month) {
var index = _this.indexOf(month);
if (index === -1) {
_this.pushObject(month);
} else {
_this.removeAt(index);
}
});
}

Ember.js bind class change on click

How do i change an elements class on click via ember.js, AKA:
<div class="row" {{bindAttr class="isEnabled:enabled:disabled"}}>
View:
SearchDropdown.SearchResultV = Ember.View.extend(Ember.Metamorph, {
isEnabled: false,
click: function(){
window.alert(true);
this.isEnabled = true;
}
});
The click event works as window alert happens, I just cant get the binding to.
The class is bound correctly, but the isEnabled property should be modified only with a .set call such as this.set('isEnabled', true) and accessed only with this.get('isEnabled'). This is an Ember convention in support of first-class bindings and computed properties.
In your view you will bind to a className. I have the following view in my app:
EurekaJ.TabItemView = Ember.View.extend(Ember.TargetActionSupport, {
content: null,
tagName: 'li',
classNameBindings: "isSelected",
isSelected: function() {
return this.get('controller').get('selectedTab').get('tabId') == this.get('tab').get('tabId');
}.property('controller.selectedTab'),
click: function() {
this.get('controller').set('selectedTab', this.get('tab'));
if (this.get('tab').get('tabState')) {
EurekaJ.router.transitionTo(this.get('tab').get('tabState'));
}
},
template: Ember.Handlebars.compile('<div class="featureTabTop"></div>{{tab.tabName}}')
});
Here, you have bound your className to whatever the "isSelected" property returns. This is only true if the views' controller's selected tab ID is the same as this views' tab ID.
The code will append a CSS class name of "is-selected" when the view is selected.
If you want to see the code in context, the code is on GitHub: https://github.com/joachimhs/EurekaJ/blob/netty-ember/EurekaJ.View/src/main/webapp/js/app/views.js#L100
Good answers, however I went down a different route:
SearchDropdown.SearchResultV = Ember.View.extend(Ember.Metamorph, {
classNameBindings: ['isSelected'],
click: function(){
var content = this.get('content');
SearchDropdown.SelectedSearchController.set('content', content);
var loadcontent = this.get('content');
loadcontent.set("searchRadius", $("select[name=radius]").val());
SearchDropdown.LoadMap.load(content);
},
isSelected: function () {
var selectedItem = SearchDropdown.SelectedSearchController.get('content'),
content = this.get('content');
if (content === selectedItem) {
return true;
}
}.property('SearchDropdown.SelectedSearchController.content')
});
Controller:
SearchDropdown.SelectedSearchController = Ember.Object.create({
content: null,
});
Basically stores the data of the selected view in a controller,