This is a migrated thread and some comments may be shown as answers.

Multi-Select with Checkboxes Plugin

56 Answers 4189 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Kasey
Top achievements
Rank 1
Kasey asked on 04 Dec 2012, 05:11 PM
I hacked together a Kendo plugin that uses the drop down UI (and associated styling), does multi select using checkboxes, and is bindable against a Kendo MVVM view model. A multiselect drop-down is a huge gap in the Kendo Web toolkit, so I figured it might be useful to others as well.

Fiddle is here: http://jsfiddle.net/bDvkQ/

The reason for using check boxes is so that the user may select many items in one pass. The default behavior of other types of multi-select drop-downs (e.g. Chosen) requires 2*n clicks for n selections; one click to open the drop down, and a second click to make a selection, then the popup closes again. This is fine for infrequently used forms, but when the user hits the same form dozens of times a day, minimizing user clicks is important. This drop-down requires n+2 clicks for n selections.

This could benefit from Select All and Clear actions as well, but I ran out of time. Feel free to hack on this further to suit your needs. As-is, no warranties, and all that.

Kasey

56 Answers, 1 is accepted

Sort by
0
Accepted
Georgi Krustev
Telerik team
answered on 05 Dec 2012, 09:26 AM
Hello Kasey,

 
Thank you for the sharing. The implementation looks very well and the widget can be very helpful for those who need multi-select component. I updated your Telerik points, because of the sharing.

As a side note, I just want to mention that the "multi-select" widget is planned for the next (Q1 2013) release of KendoUI.

Regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Kasey
Top achievements
Rank 1
answered on 05 Dec 2012, 03:45 PM
Thanks for the points!

I'd much rather have the official Kendo control, and I'll be looking forward to its release.

:-)
0
Kevin
Top achievements
Rank 1
answered on 19 Dec 2012, 05:10 PM
Whoops, posted this to the wrong thread.  Can you delete this post..?
0
Sumith Jayasuriya
Top achievements
Rank 1
answered on 19 Dec 2012, 05:49 PM
How or where can I add an optionLabel for this workaround? 

Thanks
0
Kasey
Top achievements
Rank 1
answered on 19 Dec 2012, 06:20 PM

Here is a fork with the option label.

http://jsfiddle.net/xgVpX/

However, there are still a lot of things missing from this example.

  • Select/Clear All buttons
  • Clicking text should also toggle the text box
  • Auto-resize when data-bound (still a mystery why the drop-down list does not do this)
  • Change icon to differentiate between this and a normal drop-down
  • Accessor should return an observable array, otherwise Kendo framework converts array with single value to (non-array) plain value in bound view model
  • value function should set checkbox values even when input array is empty (equivalent to clearing all checkboxes)
  • when value is changed (through value function or popup close event), this should trigger the change event on kendo control (to update MVVM model) and it's original element (in case any other event listeners are attached to the input element)
0
Sumith Jayasuriya
Top achievements
Rank 1
answered on 19 Dec 2012, 06:29 PM
Kasey,

Thanks for the quick reply it worked, but the only issue I have is that the optionLabel is being added to the list of selection options.  Is there a way to not include it in the selectlist?

Other than that great work around!
0
Kasey
Top achievements
Rank 1
answered on 19 Dec 2012, 06:45 PM
Ok, the drop-down list makes a new LI element for the option label, which is not desired for multi-select. Try this instead.

http://jsfiddle.net/MNqaT/

I can't really devote any more time to this, so good luck with future changes.

Kasey
0
Sumith Jayasuriya
Top achievements
Rank 1
answered on 19 Dec 2012, 06:54 PM
Kasey,

Works perfect.  Thanks for taking the time, but like you I'm hoping Telerik comes out with this functionality soon.  I would think its a very common scenario.

Thanks again!
0
Ron DeFreitas
Top achievements
Rank 2
answered on 02 Feb 2013, 08:13 PM
Found something useful missing from this example, and that setting the value of the underlying input field for those using form submission.

This version includes the fix:
http://jsfiddle.net/MNqaT/19/

0
Tim Harker
Top achievements
Rank 2
answered on 20 Feb 2013, 02:49 AM
Georgi Krustev (Telerik team) -

When is the official release happening for Q1 2013?  Do you have a date?

Thanks!
0
Sebastian
Telerik team
answered on 20 Feb 2013, 08:06 AM
Hello guys,

The official release is slated for the second half of March, while a public Beta release (including the new Kendo UI Web widgets) is due in the middle of next week. I encourage you to try it out and share your feedback with us, which will help us polish the multi-select widget for the formal release in March.

Best regards,
Sebastian
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Ron DeFreitas
Top achievements
Rank 2
answered on 25 Feb 2013, 02:58 PM
Hi Sebastian.

Where will the Beta be announced?
0
Sebastian
Telerik team
answered on 25 Feb 2013, 05:07 PM
The Beta will be announced by the end of the day tomorrow, Ron.

Best regards,
Sebastian
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Ron DeFreitas
Top achievements
Rank 2
answered on 25 Feb 2013, 05:26 PM
Thanks for the update Sebastian.

I'm looking forward to trying it out.
0
Robert
Top achievements
Rank 1
answered on 26 Feb 2013, 02:47 PM
I have not looked at the beta being released but I had however created my own extension.
It is based on my own requirments and built on 2012.3.1114  which I know needs a tweak for the latest version of 2012.3.1315.
This has taken quite some time to implement and I hope that the Telerik devs can take some of the ideas forward as I would love to have simlar functionality built into the new multi-select for Kendo.  Meaning I can then delete mine :)

http://jsfiddle.net/draunkin/kfQDg/14/

Let me know what you think or any questions you have
0
Georgi Krustev
Telerik team
answered on 28 Feb 2013, 09:05 AM
Hello Robert,

 
Thank you for your input and for the jsFiddle demo. We decided to take a different approach where selected values are shown as tags. Thus the end user is able to see what is selected and modified it with ease. Hence the widget will not use checkboxes as the suggested demo. The MultiSelect widget uses <select multiple> element and it also allows to filter the list.

Kind regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Ron DeFreitas
Top achievements
Rank 2
answered on 28 Feb 2013, 02:51 PM
Georgi,

I'm really happy with the implementation direction you guys went with.

There is, however, one issue I noticed in the download...   when constructing the float wrapper div, the BETA download uses the class floatWrap instead of k-floatwrap

This occurs in both the kendo.all.min.js and the kendo.multiselect.min.js
0
Georgi Krustev
Telerik team
answered on 28 Feb 2013, 03:41 PM
Hello Ron,

 
I am glad to hear that you are happy with the chosen direction.

This is a known issue, which we addressed and the widget will use the correct css class for the official release of Kendo UI. Thank you for the involvement.

Regards,
Georgi Krustev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
fretje
Top achievements
Rank 1
answered on 31 May 2013, 04:26 PM
I made 2 more changes to the last version from Ron DeFreitas:

  1.  You can now select a checkbox by clicking on the label as well.
  2.  The control now works on a <select multiple="multiple"> to be consistent with the official kendo ui multiselect.
Here's the fiddle.

I still think there's a need here for a control like this, as the official multiselect doesn't play very well on mobile (for one thing). Because you can also type something in the control, the keyboard on mobile comes in front of the select list so you can't easily select anything anymore (try it and you'll understand what I mean).
Also what Kasey said in the first post: this control with checkboxes works faster as you only have to click n+2 times in stead of 2*n times in the official one.

I hope telerik will include this as well in the official release one day, either as a separate control, or as an option on the existing multiselect.

0
fretje
Top achievements
Rank 1
answered on 11 Jun 2013, 03:28 PM
I updated to the latest version of KendoUI (2013.1.514) but now there's a bug in my latest update of the multiselectbox.
I have a multiselectbox on a form with an optionlabel specified. When the form is posted back, the first option is sent back as selected option for that input, in stead of an empty value.

I'm not sure on how to solve this. Anybody has some more insight. This would be greatly appreciated!
0
Kasey
Top achievements
Rank 1
answered on 11 Jun 2013, 03:59 PM
@fretje,

I also tried to upgrade, but ran into different problems. In my particular case, I figured out that the binding code was changed in a way that breaks this drop-down-list-based multi-select control. Specifically, I was trying to set a view model value to an array of simple ids like [1,2,3] bound to my control. But the new code expects an object array like [{Id: 1}, {Id: 2}, {Id: 3}] and throws. However, it works fine if you set the Kendo multi-select control to an array of simple values. So, it's pretty annoying that they broke this for me but allow it to work in their widget.

I ultimately had to abandon the upgrade until such time that a 1-pass multi-selection is added to the framework, either with checkboxes or Ctrl-clicking multiple items in one pass. This is a requirement for my users which the new Kendo widget does not meet, and therefore I can't use it.

Kasey
0
fretje
Top achievements
Rank 1
answered on 12 Jun 2013, 01:41 PM
Okay, I found a solution. I'm not sure if it's the right way to do this, but my problem is gone.

After some research I found that the value of the select was wrongly set to the first item of the list after the widget was databound, so when catching that event and setting the value again there, the problem was solved.

I added the following code right after the init of the dropdownlist in the MultiSelectBox widget:

    me.bind('dataBound', function() {
        me.element.val(me.value());
    });

Regards,

fretje
0
Kasey
Top achievements
Rank 1
answered on 12 Jun 2013, 02:33 PM
@fretje,

That looks like it might solve my issue too. Thanks.

Kasey
0
Dave
Top achievements
Rank 1
answered on 09 Aug 2013, 04:45 PM
Is it possible to have more than one on a page?

I have the following markup and code and only the first item in the markup is initialized, I can switch the order in the html and the other will show.

<div id="ViewModelModel" class='dealer-filter'>
    <select id="oemFilterItems"  multiple="multiple" data-role="multiselectbox" data-option-label="OEM..." data-text-field="Name" data-value-field="ID" data-bind="source: oemFilterItemSource, value: oemFilterItems" />
    <select id="networkFilterItems"  multiple="multiple" data-role="multiselectbox" data-option-label="Network..." data-text-field="Text" data-value-field="Value" data-bind="source: networkFilterItemSource, value: networkFilterItems" />
</div>
01.<script>
02.    var viewModel = kendo.observable({
03.        networkFilterItems: [],
04.        networkFilterItemSource: new kendo.data.DataSource({
05.            data: [
06.                { Value: 1, Text: "Facebook" },
07.                { Value: 2, Text: "Twitter" },
08.                { Value: 3, Text: "Google" },
09.                { Value: 4, Text: "Blooger" }
10.            ]
11.        }),
12.        oemFilterItems: [],
13.        oemFilterItemSource: new kendo.data.DataSource({
14.            transport: { read: { url: "/Reputation/Reputation/OEMListFiltered", dataType: "json" } },
15.            schema: { data: "Data" }
16.        })
17.    });
18.     
19.    $(function () {
20. 
21.        kendo.bind($("#ViewModelModel"), viewModel);
22.    });
23.</script>
0
Jason Mobley
Top achievements
Rank 1
answered on 03 Oct 2013, 07:09 PM
Hi Robert,

I really like this implementation, it best represents the functionality I've been looking for with built-in Select All functionality and a count of selected items. Implemented as-is I've experienced a couple of issues and I wondered if you could provide any insight into these. First in the latest version of kendo (all) I get the following error: Uncaught TypeError: Object [object Object] has no method '_valueOnFetch'. This seems to happen in the kendo framework itself where it interprets the nodes as numbers and not as li items. The second error, which doesn't throw any kind of exception is that after selecting all/deselect all the checkboxes no longer show checked. The values are selected correctly, but it appears a toggle count may be off by 1. The one difference between my implementation and your JSFiddle example is that my control is loaded dynamically via AJAX. I was wondering if you had encountered either of these issues or could offer some insight as to why they might be happening. Also if you have any recent enhancements I'd love to see them.

Thanks
Jason
0
Robert
Top achievements
Rank 1
answered on 04 Oct 2013, 08:29 AM
Hi Jason Mobley,

Thank you for your feedback, appreciate knowing it suits your needs.
This jsfiddle and my custom extension runs on Kendo 2012.3.1114.  It has not yet been updated to the latest version and I realise when I tested an upgrade that there are breaking changes.  I do intend to spend time to do it as I am running behind on running the latest kendo which is something I'd like to change.  However it has not been my priority to date.  I'll take a quick look at the points you've made. If they prove to take too long to fix I will be parking it until I have time.

Cheers,
Rob.
0
Robert
Top achievements
Rank 1
answered on 21 Oct 2013, 02:01 PM
Hi Jason,

This jsFiddle uses the new version of kendo. I have not tested this extensively, but everything I've seen so far indicates is works as per the previous version I submitted.

http://jsfiddle.net/draunkin/8caNL/2/

Cheers,
Rob.
0
Jason Mobley
Top achievements
Rank 1
answered on 21 Oct 2013, 08:03 PM
Rob,

This is working perfectly. This extension is going to be a big help for our project. Thanks again for your help and insight!

Regards
Jason
0
Landon
Top achievements
Rank 2
answered on 28 Oct 2013, 04:29 PM
Hi Rob,

This is probably a bit of a long-shot, but would you happen to have an example of how to apply this extension to a Razor/CSHTML Kendo Multiselect box?

I'm trying duplicate the functionality of the old RadControls Multiselect and your implementation would work perfectly.

Thanks,
Landon
0
menaheme
Top achievements
Rank 1
answered on 04 Nov 2013, 04:06 PM
Hi Georgi ,

i just found this thread, and i also require a checked list box for our web projects. 
i would rather not resort to copying the code from fiddle, unless i have to.
are there any plans to include such a control as an official part of Kendo UI ?

 Thanks
Menahem

0
Robert
Top achievements
Rank 1
answered on 06 Nov 2013, 02:06 PM
Hi Landon,

This plugin / extension of the kendo dropdownlist will not be supported by the Kendo MVC wrappers, basically because it is my own customisation which the wrappers could not know about.

We have a view model which has a string property that stores the comma separated values used by the value() method of the multiselect.

The data soure comes from another property on our view model which as you can tell is a IDictionary

Essentially you will need to build the multiselect via javascript yourself rather than with the wrappers

Here is a modified snippet of our binding which I have not run, so you may find syntax issues.

@{  
        var fieldName = ViewData.TemplateInfo.GetFullHtmlFieldName("PropertyName");
// clean up property name to use as an element Id
        var fieldId = fieldName.Replace(".", "_");
}

<input id="@(fieldId)" name="@(fieldName)" style="width: 280px" />

<script type="text/javascript">
$(document).ready(function() {

$('#@(fieldId)').kendoMultiSelectBox({
dataTextField: "Text",
dataValueField: "Value",
dataSource: @Html.Raw(Json.Encode(Model.FieldLookupData.Select(x => new { Value = x.Key, Text = x.Value }))),
emptySelectionLabel: "Please select...",
value: @Html.Raw(Json.Encode(string.Format("{0}", Model.PropertyName).Split(new []{','})))
});
});
</script>

0
yuva
Top achievements
Rank 1
answered on 06 Dec 2013, 09:04 AM
Hello Robert,

   Its working perfect in your updated  js fiddle http://jsfiddle.net/8caNL/10/ if i change jquery version to 1.9.1 but, the same if i tried to copy the code in my local it is not working. Functionality are working fine but when it is chosen it popups like modal window. could you please reply on this. 

 For Your info : I have attached the image .
0
Lynx IT
Top achievements
Rank 1
answered on 13 Dec 2013, 04:36 AM
Hi guys

I took a look at the Kendo official MultiSelect and it didn't quite serve the purpose that we needed. I've used this checkbox MultiSelectBox widget instead and updated it to work within a grid popup, and using MVVM binding. I had to override / implement the _accessor function for that.

Just now, I've updated the Kendo version to 2013.3.1119 and I'm noticing some really strange behaviour. I thought I'd post a fiddle based on the last one that was posted in this thread, you can find it at http://jsfiddle.net/timweightman/vzX8m/4/.

If anyone has some ideas about what might be causing this weird stuff, please don't hesitate to let me know!



0
Lynx IT
Top achievements
Rank 1
answered on 15 Dec 2013, 09:51 PM
Hi again everyone,

I managed to track the issue down to the new _textAccessor function which is in the v2013.3.1119 DropDownList widget.
I've made the necessary changes to preserve the expected functionality from this MultiSelectBox.

See this JsFiddle: http://jsfiddle.net/timweightman/vzX8m/5/
0
menaheme
Top achievements
Rank 1
answered on 07 Jan 2014, 03:49 PM
Hi Joseph,

Thanks so much for the you great efforts on this very much needed widget !
The guys at Telerik should take a page out of your book.

a question: i am trying to post the selected items to the server in a from. but i only get the first item that is selected , rather than all of the selected items.
any idea why that is ? (its all based on the fiddle you posted)
the regular multiselect does post all selections.

Thanks,
Menahem
0
EDGAR JIMENEZ
Top achievements
Rank 1
answered on 04 Feb 2014, 10:46 PM
Hello,

This is a great additional to the basic multiselect functionality. I've been looking for something just like this for some time now.

However the above fiddle does not seem to be working - any chance you could provide an updated link?

Best Regards
0
Sebastian
Telerik team
answered on 05 Feb 2014, 12:55 PM
Hello Edgar,

I tested the jsfiddle linked in the first post of this thread under different browsers and it seems to operate a as expected.

Can you try it on a different machine/device to see whether it works? You may also check whether there are any javascript errors when the page is loaded which prevent the proper functioning of the sample.

Regards,
Sebastian
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Robert
Top achievements
Rank 1
answered on 02 May 2014, 02:37 PM
I recently had to update this control to work with a later version of kendo (2014.1.318).

Here a plunker with the later version included (script.js) 

http://plnkr.co/edit/OVPTCV?p=preview

0
tiffany
Top achievements
Rank 1
answered on 13 Jun 2014, 07:05 PM
Hi Robert,

I found this lately, and I'm trying to use this plugin now, I have a question: how can i clear all selections in javascript?

Thanks a lot
Tiffany
0
Robert
Top achievements
Rank 1
answered on 16 Jun 2014, 10:34 AM
Hi tiffany,

You can send an empty array or value to the .value() function.  This would wipe existing values.

e.g.  $('#elementId').data("kendoMultiSelectBox").value([]);

Cheers,
Rob.
0
tiffany
Top achievements
Rank 1
answered on 18 Jun 2014, 04:23 PM
Hi Rob,

It works for me.
Thank you!
Tiffany
0
Caitlin
Top achievements
Rank 1
answered on 28 Jul 2014, 01:34 PM
Robert,

Thanks so much for putting this extension together, it's almost exactly what I was looking for. I just have 2 questions. How can I set multiple default values? I used the code from your last post and just added values, but only one was recognized and I need to set 2 or 3. Also, I would much prefer the box to show the comma delimited values that are selected as the selected value, than just how many. Is this easily possible? Thank you.
0
Apoorv
Top achievements
Rank 1
answered on 02 Aug 2014, 01:14 PM
THANKS A LOT!

I was using the older version that you had posted before and it started acting weird when I updated Kendo UI libraries. I happened to visit this thread again and was delightfully surprised to see the updated example. This works perfectly even on 2014.2.716.
0
Carey
Top achievements
Rank 1
answered on 05 Aug 2014, 09:57 PM
Robert,

A very valuable custom extension to the drop down list element; I've fairly easily implemented it as the filter UI for one of my kendo grid columns, however it isn't immediately apparent to me how to listen for a change to the element values; I know how to apply changes to the kendo grid filter, once I have access to those values. In your Plunker example, you've just got the standalone element wrapped in a DIV, then you're binding the selectionChanged event to a jQuery listener on that DIV's ID. I thought selecting multiple values in my dropdown, then simply pressing the Filter button, would auto-magically apply the filters, as the out-of-the-box drop down does when you select one item. Nothing is happening, however, so I'm unsure how to proceed.
0
Robert
Top achievements
Rank 1
answered on 06 Aug 2014, 12:30 PM
Hi Caitlin,

To assign multiple default values you just provide an array of the values either in the options object when creating or afterwards using the value() function.  If you look at this example I have 2 values assigned. http://plnkr.co/edit/OVPTCV?p=preview

You can increase the number of items to display before turning into a count by assigning a value to preSummaryCount in your options object when you create the control. For example { preSummaryCount: 999 }

Hope that helps.

0
Robert
Top achievements
Rank 1
answered on 06 Aug 2014, 12:32 PM
Hi Apoorv,

No problem, as I had to update it to work for me I thought it best to share :)

Cheers,
Rob.
0
Robert
Top achievements
Rank 1
answered on 06 Aug 2014, 12:43 PM
Hi Hunter,

From what I understand (haven't tried it myself), the built in filter menu will expect a single value and the multi select provides an array.  I don't think the two will be compatible, if kendo supports its own multiselect as a filter ui then perhaps I am wrong. 

You could always try and perform the filtering yourself. You can handle the apply button click on the filter menu and then create filter objects to apply to the datasource.filter function directly. You can even read the existing filters already applied to pre-populate the multiselect next time the menu is shown. Take a look at the datasource api documentation on that one.

Sorry can be of more help, best of luck with it.

Cheers,
Rob.
0
Carey
Top achievements
Rank 1
answered on 11 Aug 2014, 04:56 AM
Thanks! I've taken care of manually applying the selected filters, but there's a few things that I know won't make it past QA; 

Here's my issue: The drop down filter still displays the Kendo "logic" box for selecting "is equal to", which I don't want. I'm not sure how to hide this box without affecting all the other filters in column headers since Kendo (I think) doesn't put an ID on them. Also, the Filter and Cancel buttons get blocked by the drop down when the user clicks in the "---Select Value(s)---" block, which means they have to click their selections, then click back above the drop down to close it, thereby making the buttons visible again.

Best case scenario is I would like to hide the "logic" box, for only this column, and move the submit buttons above the drop down box (in effect, where the logic box was, so they are visible while the dropdown list is open.

Any help would be greatly appreciated!
0
Xinzhou
Top achievements
Rank 1
answered on 23 Oct 2014, 04:07 PM
Hi guys, 

I'm pretty new to telerik and was looking at the custom Multiselect Dropdownlist from Robert which is great and i hope Telerik incorporate this feature in their controls as well.  I am curious on how you add filtering to the custom multiselect.  Can you please share some insight on that. Thanks. 
0
Carey
Top achievements
Rank 1
answered on 23 Oct 2014, 04:29 PM
Xinzhou,

In my case, my custom multi-select widget represents statuses: I call the function applyStatusFilter when the selectionChanged property of my custom element is fired. Here's what my function looks like:

// Apply the status filters from the multi-select drop down
function applyStatusFilter(statusValues) {
    var grid = $("#grid").data("kendoGrid");
    var dataSource = grid.dataSource;
    var filter = dataSource.filter() || { filters:[], logic: "and" };
    var statusFilters = { logic: "or", filters: [] };
    var statusArray = statusValues.split(','); // Convert status selections to array
 
    // Strip out any status related filters so we can rebuild and apply new ones
    removeFiltersForField(filter, "status");
 
    // Only build status filter array if selections were made in the dropdown...
    if (statusArray[0].length > 0) {
        // Spin through all the statuses chosen
        $.each(statusArray, function (key, value) {
            statusFilters.filters.push({
                field: "status",
                operator: "eq",
                value: value
            });
        });
    }
 
    // Add the status filter to the current filters, if we built any
    if (statusFilters.filters.length > 0) {
        filter.filters.push(statusFilters);
    }
 
    // Apply new filters to grid
    dataSource.filter(filter);
}
 
function removeFiltersForField(expression, field) {
    if (expression.filters) {
        expression.filters = $.grep(expression.filters, function(filter) {
            removeFiltersForField(filter, field);
            if (filter.filters) {
                return filter.filters.length;
            } else {
                return filter.field != field;
            }
        });
    }
}

Hopefully this helps with your situation.
0
Xinzhou
Top achievements
Rank 1
answered on 23 Oct 2014, 04:43 PM
Hunter,

I was mistaken, i thought you were adding the filter feature onto the custom multiselect dropdownlist making it similar to the kendo combobox but with multiselect which is what i want to achieve.  Was looking at the script.js file that extends the dropdownlist, do you know if i can do the same with the combobox? 

I'm sure your code to manual filter the grid datasource will come in handy as well. 
0
Xinzhou
Top achievements
Rank 1
answered on 23 Oct 2014, 04:45 PM
I found this other custom multiselect dropdownlist with filtering which might come in handy for you in the future as well. 

http://www.erichynds.com/examples/jquery-ui-multiselect-widget/demos/#filter

I might use this custom control since it incorporates filtering in the dropdownlist. 
0
Carey
Top achievements
Rank 1
answered on 23 Oct 2014, 04:56 PM
I am adding this filtering to my custom multiselect dropdown, as you can see here:

// Create the custom status multi-select dropdwon
var statusDropdown = $('#statusMultiSelect');
statusDropdown.kendoMultiSelectBox({
    dataTextField: 'text',
    dataValueField: 'value',
    dataSource: {
        transport: {
            read: {
                dataType: 'json',
                url: '/home/ajax/getstatuses'
            }
        },
    },
    showSelectAll: false,
    emptySelectionLabel: "Status",
    selectionChanged: function() {
        $("#statusMultiSelect-list").css('display','none'); // Close the dropdown right away
        applyStatusFilter(this.value());
    }
});

And here is the custom extension of Kendo's dropdownlist that I got from one of the previous posts:

//MultiSelect - A user extension of KendoUI DropDownList widget.
(function ($) {
    // shorten references to variables
    var kendo = window.kendo,
        ui = kendo.ui,
        DropDownList = ui.DropDownList,
        keys = kendo.keys,
        SELECT = "select",
        SELECTIONCHANGED = "selectionChanged",
        SELECTED = "k-state-selected",
        HIGHLIGHTED = "k-state-active",
        CHECKBOX = "custom-multiselect-check-item",
        SELECTALLITEM = "custom-multiselect-selectAll-item",
        MULTISELECTPOPUP = "custom-multiselect-popup",
        EMPTYSELECTION = "custom-multiselect-summary-empty";
 
    var lineTemplate = '<input type="checkbox" name="#= {1} #" value="#= {0} #" class="' + CHECKBOX + '" />' +
                    '<span data-value="#= {0} #">#= {1} #</span>';
 
    var MultiSelectBox = DropDownList.extend({
        init: function (element, options) {
            options.template = kendo.template(kendo.format(lineTemplate, options.dataValueField, options.dataTextField));
            // base call to widget initialization
            DropDownList.fn.init.call(this, element, options);
        },
        options: {
            name: "MultiSelectBox",
            index: -1,
            showSelectAll: null,
            preSummaryCount: 1,  // number of items to show before summarising
            emptySelectionLabel: null// what to show when no items are selected
            selectionChanged: null, // provide callback to invoke when selection has changed
        },
        events: [
            SELECTIONCHANGED
        ],
        refresh: function () {
            // base call
            DropDownList.fn.refresh.call(this);
            this._updateSummary();
            $(this.popup.element).addClass(MULTISELECTPOPUP);
        },
        current: function (candidate) {
            return this._current;
        },
        open: function () {
            this._removeSelectAllItem();
            this._addSelectAllItem();
            DropDownList.fn.open.call(this);
            //hook on to popup event because dropdown close does not
            //fire consistently when user clicks on some other elements
            //like a dataviz chart graphic
            this.popup.one('close', $.proxy(this._onPopupClosed, this));
        },
        _onPopupClosed: function () {
            this._removeSelectAllItem();
            this._current = null;
            //this._highlightCurrent();
            this._raiseSelectionChanged();
        },
        _raiseSelectionChanged: function () {
            var currentValue = this.value();
            var currentValues = $.map((currentValue.length > 0 ? currentValue.split(",") : []).sort(), function (item) { return item.toString(); });
            var oldValues = $.map((this._oldValue || []).sort(), function (item) { return item.toString(); });
            // store for next pass
            this._oldValue = $.map(currentValues, function (item) { return item.toString(); });
            var changedArgs = { newValue: currentValues, oldValue: oldValues };
            if (oldValues) {
                var hasChanged = ($(oldValues).not(currentValues).length == 0 && $(currentValues).not(oldValues).length == 0) !== true;
                if (hasChanged) {
                    //if (this.options.selectionChanged)
                    //    this.options.selectionChanged(changedArgs);
                    this.trigger(SELECTIONCHANGED, changedArgs);
                }
            }
            else if (currentValue.length > 0) {
                //if (this.options.selectionChanged)
                //    this.options.selectionChanged(changedArgs);
                this.trigger(SELECTIONCHANGED, changedArgs);
            }
        },
        _addSelectAllItem: function () {
            if (!this.options.showSelectAll) return;
            var firstListItem = this.ul.children('li:first');
            if (firstListItem.length > 0) {
                this.selectAllListItem = $('<li tabindex="-1" role="option" unselectable="on" class="k-item ' + SELECTALLITEM + '"></li>').insertBefore(firstListItem);
                // fake a data object to use for the template binding below
                var selectAllData = {};
                selectAllData[this.options.dataValueField] = '*';
                selectAllData[this.options.dataTextField] = 'All';
                this.selectAllListItem.html(this.options.template(selectAllData));
                this._updateSelectAllItem();
                this._makeUnselectable(); // required for IE8
            }
        },
        _removeSelectAllItem: function () {
            if (this.selectAllListItem) {
                this.selectAllListItem.remove();
            }
            this.selectAllListItem = null;
        },
        _focus: function (li) {
            if (this.popup.visible() && li && this.trigger(SELECT, { item: li })) {
                this.close();
                return;
            }
            this.select(li);
        },
        //_highlightCurrent: function () {
 
        //    $('li', this.ul).removeClass(HIGHLIGHTED);
        //    $(this._current).addClass(HIGHLIGHTED);
        //},
        _keydown: function (e) {
            // currently ignore Home and End keys
            // can be added later
            if (e.keyCode == kendo.keys.HOME ||
                e.keyCode == kendo.keys.END) {
                e.preventDefault();
                return;
            }
            DropDownList.fn._keydown.call(this, e);
        },
        _keypress: function(e) {
            // disable existing function
        },
        _move: function (e) {
            var that = this,
                key = e.keyCode,
                ul = that.ul[0],
                down = key === keys.DOWN,
                pressed;
            if (key === keys.UP || down) {
                if (down) {
                    if (!that.popup.visible()) {
                        that.toggle(down);
                    }
                    if (!that._current) {
                        that._current = ul.firstChild;
                    } else {
                        that._current = ($(that._current)[0].nextSibling || that._current);
                    }
                } else {
                    //up
                    // only if anything is highlighted
                    if (that._current) {
                        that._current = ($(that._current)[0].previousSibling || ul.firstChild);
                    }
                }
                if (that._current) {
                    that._scroll(that._current);
                }
                that._highlightCurrent();
                e.preventDefault();
                pressed = true;
            } else {
                pressed = DropDownList.fn._move.call(this, e);
            }
            return pressed;
        },
        selectAll: function () {
            var unselectedItems = this._getUnselectedListItems();
            this._selectItems(unselectedItems);
            // todo: raise custom event
        },
        unselectAll: function () {
            var selectedItems = this._getSelectedListItems();
            this._selectItems(selectedItems);  // will invert the selection
            // todo: raise custom event
        },
        _selectItems: function (listItems) {
            var that = this;
            $.each(listItems, function (i, item) {
                var idx = ui.List.inArray(item, that.ul[0]);
                that.select(idx);  // select OR unselect
            });
        },
        _selectItem: function () {
            // method override to prevent default selection of first item, done by normal dropdown
            var that = this,
                options = that.options,
                useOptionIndex,
                value;
            useOptionIndex = that._isSelect && !that._initial && !options.value && options.index && !that._bound;
            if (!useOptionIndex) {
                value = that._selectedValue || options.value || that._accessor();
            }
            if (value) {
                that.value(value);
            } else if (that._bound === undefined) {
                that.select(options.index);
            }
        },
        _select: function (li) {
            var that = this,
                value,
                text,
                idx;
            li = that._get(li);
            if (li && li[0]) {
                idx = ui.List.inArray(li[0], that.ul[0]);
                if (idx > -1) {
                    if (li.hasClass(SELECTED)) {
                        li.removeClass(SELECTED);
                        that._uncheckItem(li);
                        if (this.selectAllListItem && li[0] === this.selectAllListItem[0]) {
                            this.unselectAll();
                        }
                    } else {
                        li.addClass(SELECTED);
                        that._checkItem(li);
                        if (this.selectAllListItem && li[0] === this.selectAllListItem[0]) {
                            this.selectAll();
                        }
                    }
                    if (this._open) {
                        that._current(li);
                        that._highlightCurrent();
                    }
                    var selecteditems = this._getSelectedListItems();
                    value = [];
                    text = [];
                    $.each(selecteditems, function (indx, item) {
                        var obj = $(item).children("span").first();
                        value.push(obj.attr("data-value"));
                        text.push(obj.text());
                    });
                    that._updateSummary(text);
                    that._updateSelectAllItem();
                    that._accessor(value, idx);
                    // todo: raise change event (add support for selectedIndex) if required
                }
            }
 
        },
        _getAllValueListItems: function () {
            if (this.selectAllListItem) {
                return this.ul.children("li").not(this.selectAllListItem[0]);
            } else {
                return this.ul.children("li");
            }
        },
        _getSelectedListItems: function () {
            return this._getAllValueListItems().filter("." + SELECTED);
        },
        _getUnselectedListItems: function () {
            return this._getAllValueListItems().filter(":not(." + SELECTED + ")");
        },
        _getSelectedItemsText: function () {
            var text = [];
            var selecteditems = this._getSelectedListItems();
            $.each(selecteditems, function (indx, item) {
                var obj = $(item).children("span").first();
                text.push(obj.text());
            });
            return text;
        },
        _updateSelectAllItem: function () {
            if (!this.selectAllListItem) return;
            // are all items selected?
            if (this._getAllValueListItems().length == this._getSelectedListItems().length) {
                this._checkItem(this.selectAllListItem);
                this.selectAllListItem.addClass(SELECTED);
            }
            else {
                this._uncheckItem(this.selectAllListItem);
                this.selectAllListItem.removeClass(SELECTED);
            }
        },
        _updateSummary: function (itemsText) {
            if (!itemsText) {
                itemsText = this._getSelectedItemsText();
            }
            if (itemsText.length == 0) {
                this._inputWrapper.addClass(EMPTYSELECTION);
                this.text(this.options.emptySelectionLabel);
                return;
            } else {
                this._inputWrapper.removeClass(EMPTYSELECTION);
            }
 
            if (itemsText.length <= this.options.preSummaryCount) {
                this._textAccessor(itemsText.join(", "));
            }
            else {
                this._textAccessor(itemsText.length + ' selected');
            }
        },
        _checkItem: function (itemContainer) {
            if (!itemContainer) return;
            itemContainer.children("input").prop("checked", true);
        },
        _uncheckItem: function (itemContainer) {
            if (!itemContainer) return;
            itemContainer.children("input").removeAttr("checked");
        },
        _isItemChecked: function (itemContainer) {
            return itemContainer.children("input:checked").length > 0;
        },
        value: function (value) {
            var that = this,
                idx,
                valuesList = [];
            if (value !== undefined) {
                if (!$.isArray(value)) {
                    valuesList.push(value);
                    this._oldValue = valuesList; // to allow for selectionChanged event
                }
                else {
                    valuesList = value;
                    this._oldValue = value; // to allow for selectionChanged event
                }
                // clear all selections first
                $(that.ul[0]).children("li").removeClass(SELECTED);
                $("input", that.ul[0]).removeAttr("checked");
                $.each(valuesList, function (indx, item) {
                    var hasValue;
                    if (item !== null) {
                        item = item.toString();
                    }
                    that._selectedValue = item;
                    hasValue = value || (that.options.optionLabel && !that.element[0].disabled && value === "");
                    if (hasValue && that._fetchItems(value)) {
                        return;
                    }
                    idx = that._index(item);
                    if (idx > -1) {
                        that.select(idx);
                    }
                });
                that._updateSummary();
            }
            else {
                var selecteditems = this._getSelectedListItems();
                return $.map(selecteditems, function(item) {
                    var obj = $(item).children("span").first();
                    return obj.attr("data-value");
                }).join();
            }
        },
 
    });
    ui.plugin(MultiSelectBox);
})(jQuery);
0
Carey
Top achievements
Rank 1
answered on 23 Oct 2014, 07:50 PM
I just reread your statement more closely and see you are looking for the multiselect functionality but extended onto the Kendo combobox. I imagine that you could probably do this fairly easily, especially using the js code I posted that shows the Kendo dropdown being extended.
0
Geoff
Top achievements
Rank 1
answered on 05 Dec 2014, 11:24 PM
Can anyone from telerik comment on why the option to use check boxes instead of tags has not been included in the product? 

Any time you need a multi-select with an amount of options that cause the tags to wrap, the control is quite ugly and using checkboxes makes much more sense.
0
Georgi Krustev
Telerik team
answered on 09 Dec 2014, 11:33 AM
Hello guys,

Currently, we do not have any specific plans for providing combobox/dropdownlist widgets with multi-select support including the checkboxes in this case. For now, our solution for  widget providing multiple selection is Kendo UI MultiSelect.

I encourage every interested in this thread to open/comment in our Feedback portal or send us a pull request (Kendo UI Core is an open-source library).

I will close this thread. If any one would like to share his/her implementation, I would suggest Kendo UI Labs.

Regards,
Georgi Krustev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
DropDownList
Asked by
Kasey
Top achievements
Rank 1
Answers by
Georgi Krustev
Telerik team
Kasey
Top achievements
Rank 1
Kevin
Top achievements
Rank 1
Sumith Jayasuriya
Top achievements
Rank 1
Ron DeFreitas
Top achievements
Rank 2
Tim Harker
Top achievements
Rank 2
Sebastian
Telerik team
Robert
Top achievements
Rank 1
fretje
Top achievements
Rank 1
Dave
Top achievements
Rank 1
Jason Mobley
Top achievements
Rank 1
Landon
Top achievements
Rank 2
menaheme
Top achievements
Rank 1
yuva
Top achievements
Rank 1
Lynx IT
Top achievements
Rank 1
EDGAR JIMENEZ
Top achievements
Rank 1
tiffany
Top achievements
Rank 1
Caitlin
Top achievements
Rank 1
Apoorv
Top achievements
Rank 1
Carey
Top achievements
Rank 1
Xinzhou
Top achievements
Rank 1
Geoff
Top achievements
Rank 1
Share this question
or