"Add new" when item not available in list

12 posts, 0 answers
  1. Nicklas
    Nicklas avatar
    45 posts
    Member since:
    Oct 2012

    Posted 05 Jul 2013 Link to this post

    I came across this thread on the same issue, but without the use of server wrappers, which in my mind sort of complicates what I'm trying to accomplish. It led me to this example at JS Bin, but I can't seem to implement this in my existing code. Do you guys have any suggestions in regards to approaching this particular 'problem'?

    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>
    This is before I start mixing the code from the example I referenced earlier. Chose to remove it, because it just clutters my code anyway, in addition to not working. Hope you guys can help!
  2. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 09 Jul 2013 Link to this post

    Hello,

    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
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Nicklas
    Nicklas avatar
    45 posts
    Member since:
    Oct 2012

    Posted 10 Jul 2013 Link to this post

    Thank you! That seems to work! However, as you can see from my code I have some more going on when the change-event is fired. I do an ajax call in order to store the changes done in the multiselect, immideately. 

    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 () {
                
            }
        });
    }
    Any suggestion on how I can make these two work 'in harmony' ? My old code is the three first variables as well as the $.ajax part at the bottom.
  5. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 12 Jul 2013 Link to this post

    Hello again,

    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
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  6. Linus
    Linus avatar
    7 posts
    Member since:
    Nov 2012

    Posted 28 Jan 2014 in reply to Daniel Link to this post

    As a contribution to this (rather old) post I would like to provide a enhanced solution of MultiSelectAddItem.
    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...
  7. Alex
    Alex avatar
    4 posts
    Member since:
    Sep 2014

    Posted 03 Oct 2014 Link to this post

    I know this is an old post but I'm trying to achieve this too.

    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?
  8. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 07 Oct 2014 Link to this post

    Hello Alex,

    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.

     
  9. Alex
    Alex avatar
    4 posts
    Member since:
    Sep 2014

    Posted 10 Oct 2014 Link to this post

    Hi Daniel,

    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.
  10. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 15 Oct 2014 Link to this post

    Hello again Alex,

    Loading the data via Ajax should not make a difference but the dataTextField and dataValueField seems to be different
    .DataValueField("value")
    .DataTextField("text")
    so the fields used in the handlers should be changed:
    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.

     
  11. JP
    JP avatar
    3 posts
    Member since:
    Jan 2015

    Posted 11 Mar 2015 in reply to Daniel Link to this post

    Hi, 
    I've tried running this zip file, but it can only add 3 items, any idea?
  12. Marco
    Marco avatar
    8 posts
    Member since:
    Feb 2011

    Posted 16 Jun 2015 Link to this post

    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

  13. Daniel
    Admin
    Daniel avatar
    2117 posts

    Posted 18 Jun 2015 Link to this post

    Hello,

    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
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready