Here's what I have today:
<
div
class
=
"span3"
>
@(Html.Kendo().MultiSelect()
.Name("tags")
.Placeholder("No tags selected for this unit")
.BindTo(new SelectList(Model.TagsAvailable))
.Events(e => e
.Select("select")
.Change("change"))
.Value(Model.TagsSelected.ToArray())
)
</
div
>
<
script
>
function select(e) {
var dataItem = this.dataSource.view()[e.item.index()];
var param = dataItem.Text;
var url = '@Url.Content("~/UnitDetails/TagUnit/" + Model.UnitId)';
$.ajax({
url: url,
data: { selectedItem: param },
type: 'GET',
dataType: 'json',
success: function (data) {
},
error: function () {
}
});
};
function change(e) {
var dataItem = this;
var param = dataItem.element.context.innerText;
var url = '@Url.Content("~/UnitDetails/UnTagUnit/" + Model.UnitId)';
$.ajax({
url: url,
data: { selectedItem: param },
type: 'GET',
dataType: 'json',
success: function (data) {
},
error: function () {
}
});
};
</
script
>
11 Answers, 1 is accepted
What is the needed functionality in your scenario? Could you provide a little more detailed information about it? What should happen in the change and in the select event? What happens when using the approach demonstrated in the jsBin? At least when I tested the suggested solution with the wrappers, the add functionality was working as expected. I attached my test project to this thread.
Regards,Daniel
Telerik
My code seems to interfere with the one you suggested, causing the change event not to work properly. As the change event also picks up when "deleting" a tag, I need to do that in the same method.
function
change(e) {
var
changedItem =
this
;
var
param = changedItem.element.context.innerText;
var
url =
'@Url.Content("~/UnitDetails/UnTagUnit/" + Model.ViewUnitContract.Id)'
;
var
value =
this
.value().slice(0);
var
dataitems =
this
.dataSource.data();
var
newtag =
""
;
for
(
var
i = 0; i < dataitems.length; i++) {
var
dataItem = dataitems[i];
if
(dataItem.Text.substring(0,
"Add new tag: "
.length) ===
"Add new tag: "
) {
newtag = dataItem.Text.replace(
"Add new tag: "
,
""
);
this
.dataSource.remove(dataItem);
}
}
this
.dataSource.add({ Value: newtag, Text: newtag });
if
(newtag) {
this
.dataSource.filter({});
if
(
this
.value().length == 1) {
this
.value(newtag);
}
else
{
value.push(newtag);
console.log(value);
this
.value(value);
}
}
$.ajax({
url: url,
data: { selectedItem: param },
type:
'GET'
,
dataType:
'json'
,
success:
function
(data) {
},
error:
function
() {
}
});
}
There does not seem to be anything in the additional code that would interfere with this functionality and when I tested it on my side it was working as expected. I attached the sample project modified to use the provided code. Let me know if it works as expected on your side or if I am missing something.
Regards,Daniel
Telerik
It filters out the already existing items.
It uses another item class (IdNameItem) which fits better with database entries since it offers an Id property for the associated item id Db.
IMPORTANT: Please note that you have to copy in \bin and \script directory of the former MultiSelectAddItem project since I am not alowed to upload more than 2MB...
I've followed Daniels sample code and it works great for a local datasource, but if you use a remote data source it doesn't seem to work.
How would we have to amend the javascript to make this work with a remote datasource?
Could you provide the code that you are currently using so I can check the exact setup?
Regards,
Daniel
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
I'm using the same code as above:
@(Html.Kendo().MultiSelect()
.Name("tags")
.Animation(false)
.Filter(FilterType.Contains)
.DataSource(ds=>ds.Read("ListItemTest", "Test"))
.DataValueField("value")
.DataTextField("text")
.Events(e=> e.Change("change").DataBound("dataBound"))
)
<
script
>
function change() {
var value = this.value().slice(0);
var dataitems = this.dataSource.data();
var newtag = "";
for (var i = 0; i <
dataitems.length
; i++) {
var
dataItem
=
dataitems
[i];
if (dataItem.Text.substring(0, "Add new tag: ".length) === "Add new tag: ") {
newtag
=
dataItem
.Text.replace("Add new tag: ", "");
this.dataSource.remove(dataItem);
}
}
this.dataSource.add({ Value: newtag, Text: newtag });
if (newtag) {
this.dataSource.filter({});
if (this.value().length == 1) {
this.value(newtag);
}
else {
value.push(newtag);
console.log(value);
this.value(value);
}
}
}
var newitemtext;
function dataBound() {
if ((newitemtext || this._prev) && newitemtext != this._prev) {
newitemtext
=
this
._prev;
var
dataitems
=
this
.dataSource.data();
var
isfound
=
false
;
for (var
i
=
0
; i < dataitems.length; i++) {
var
dataItem
=
dataitems
[i];
if (dataItem.Value != dataItem.Text) {
dataItem.Text
=
"Add new tag: "
+ newitemtext;
this.refresh();
isfound
=
true
;
}
}
if (!isfound) {
this.dataSource.add({ Text: "Add new tag: " + newitemtext, Value: newitemtext });
this.refresh();
}
this.search();
this.open();
}
}
</script>
However this object seems to be null:
var dataitems = this.dataSource.data();
And I think that's why it doesn't work. However, if I change to this:
@(Html.Kendo().MultiSelect()
.Name("tags")
.Animation(false)
.Filter(FilterType.Contains)
.BindTo(new List<
SelectListItem
>()
{
new SelectListItem() {
Text = "Tag1", Value ="Tag1"
},
new SelectListItem() {
Text = "Tag2", Value ="Tag2"
},
new SelectListItem() {
Text = "Tag3", Value ="Tag3"
}
})
.Events(e=> e.Change("change").DataBound("dataBound"))
)
It does work. Any ideas how to get this to work with the remote data source?
Thanks.
Loading the data via Ajax should not make a difference but the dataTextField and dataValueField seems to be different
.DataValueField(
"value"
)
.DataTextField(
"text"
)
function
change() {
var
value =
this
.value().slice(0);
var
dataitems =
this
.dataSource.data();
var
newtag =
""
;
for
(
var
i = 0; i < dataitems.length; i++) {
var
dataItem = dataitems[i];
if
(dataItem.text.substring(0,
"Add new tag: "
.length) ===
"Add new tag: "
) {
newtag = dataItem.text.replace(
"Add new tag: "
,
""
);
this
.dataSource.remove(dataItem);
}
}
this
.dataSource.add({ value: newtag, text: newtag });
if
(newtag) {
this
.dataSource.filter({});
if
(
this
.value().length == 1) {
this
.value(newtag);
}
else
{
value.push(newtag);
this
.value(value);
}
}
}
var
newitemtext;
function
dataBound() {
if
((newitemtext ||
this
._prev) && newitemtext !=
this
._prev) {
newitemtext =
this
._prev;
var
dataitems =
this
.dataSource.data();
var
isfound =
false
;
for
(
var
i = 0; i < dataitems.length; i++) {
var
dataItem = dataitems[i];
if
(dataItem.value != dataItem.text) {
dataItem.text =
"Add new tag: "
+ newitemtext;
this
.refresh();
isfound =
true
;
}
}
if
(!isfound) {
this
.dataSource.add({ text:
"Add new tag: "
+ newitemtext, value: newitemtext });
this
.refresh();
}
this
.search();
this
.open();
}
}
Regards,
Daniel
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
I've tried running this zip file, but it can only add 3 items, any idea?
Hi,
I'm also having problems with the code provided by Daniel.
After adding a second new item to the multiselect, the whole input field is blank.
Isn't there a native support for adding new items to a multiselect? The javascript solution seems to be a workaround.
Best Regards
The multiselect does not currently support this feature. This was previously requested. You can vote for it and follow its progress on this page.
Regards,
Daniel
Telerik