czesio
czesio

Reputation: 366

Avoid ComboBox sending values that aren't on the list

I'm using kendo complete for MVC in project.

I have list of countries in some forms and I display country name, but store country code.

I have following problem: When user enters something, which is not on the list, that value will be send to server. How to avoid them and send empty value (means: no value selected)?

Here is my code:

@Html.Kendo()
    .ComboBoxFor(model => model.CountryCode)
    .BindTo(ViewBag.Countries as IEnumerable<SelectListItem>)
    .Filter(FilterType.StartsWith)
    .Placeholder("Country")
    .HtmlAttributes(new { @class = "span9" })

Upvotes: 7

Views: 16137

Answers (8)

Werner Bisschoff
Werner Bisschoff

Reputation: 177

In order to check if a certain value entered into the combo box exists is to use the following two javascript methods.

You can test it as follows, assuming the ID of you combo box is "ComboBoxId"

@(Html.Kendo().ComboBoxFor(m => m.ComboBoxId)
      .BindTo(Model.ComboBoxItems)
      .Filter(FilterType.Contains)
      .HighlightFirst(true)
)
if (getValueOfKendoCombo('#ComboBoxId') === null) {
   alert('Please select a valid value from the list');
   return;
}

function getValueOfKendoCombo(comboBoxId) {
  var comboBox = $(comboBoxId).data('kendoComboBox');
  var ds = comboBox.dataSource; // data source in order to get a list of data items
  var data = ds['_data']; // object containing data
  var value = comboBox.value(); // value to test
  var itemValue = getByValue(data, value); // loop through all data items and determine if value exists
  if (itemValue == null) { // check if the input value exists
    comboBox.value(null); // set the comboBox text value to null, because it does not exist on the list
    return null; //return value null - use null to check if the value exists
  }
  return itemValue;
}

function getByValue(data, value) {
  // loop through all data items and determine if value exists against the Value of the object, otherwise return null
  for (var i = 0; i < data.length; i++) {
    if (data[i]['Value'] === value) {
      return data[i]['Value'];
    }
  }
  return null;
}

Upvotes: 0

xinthose
xinthose

Reputation: 3828

This is how I do it with MVVM:

HTML:

<div id="main_pane_add_truck" data-role="view" data-model="APP.models.main_pane_add_truck">
    <input id="main_pane_add_truck_customer_id" data-role="combobox" data-placeholder="Type a Customer" data-value-primitive="true" data-text-field="Name" data-value-field="CustomerID" 
    data-bind="value: customer_id, source: customer_id_ds, events: { change: customer_id_change }" />
</div>

Javascript model:

window.APP = {
models: {
    main_pane_add_truck: kendo.observable({
        customer_id: null,
        customer_id_ds: new kendo.data.DataSource({
            type: "odata",
            transport: {
                read: ROOTURL + BODYURL + "MyCustomers"
            },
            schema: {
                model: {
                    fields: {
                        CustomerID: { type: "number" },
                        Name: { type: "string" },
                    }
                }
            }
        }),
        customer_id_change: function customer_id_change(e) {
            try {
                var found = false;
                var combobox = $("#main_pane_add_truck_customer_id").data("kendoComboBox");
                var customer_id = e.data.customer_id;
                var dataSource = this.get("customer_id_ds");
                var data = dataSource.data();
                var data_length = data.length;
                if (data_length) {
                    for (var i = 0; i < data_length; i++) {
                        if (data[i].CustomerID === customer_id) {
                            found = true;
                        }
                    }
                    if (!found) {
                        this.set("customer_id", data[0].CustomerID);
                        combobox.select(0);
                    }
                }
                else {
                    this.set("customer_id", null);
                }
            }
            catch (e) {
                console.log(arguments.callee.name + " >> ERROR >> " + e.toString());
            }
        },
    }),
}
};

Upvotes: 0

Gaurang Dhandhukiya
Gaurang Dhandhukiya

Reputation: 427

To Set a value after entering a garbage value in kendo combobox search implement below code

$(document).ready(function() {
var items = [
    {value : '1',
     desc : 'fred'},
    {value : '2',
     desc : 'wilma'},
    {value : '3',
     desc : 'pebbles'},
    {value : '4',
     desc : 'dino'}
];

var cb = $('#comboBox').kendoComboBox({
    dataSource : items,
    dataTextField : 'desc',
    dataValueField : 'value',
    filter : 'contains',
    change : function (e) {
        if (this.value() && this.selectedIndex == -1) {    
            this._filterSource({
                value: "",
                field: this.options.dataTextField,
                operator: "contains"
            });
            this.select(1);
        }
    }
}).data('kendoComboBox');

$('#showValue').click(function () {
    alert(cb.value());
});

});

Upvotes: 0

andrew.fox
andrew.fox

Reputation: 7933

Use DropDownList widget instead of ComboBox. DropDownList works very similar but prevents users from entering theirs own texts.

Upvotes: 1

fredo
fredo

Reputation: 127

Paladin, here is a solution when using ASP.NET MVC wrappers & a combobox. The following is the razor & javascript to get your solution working.

<div class="form-group">
    @Html.LabelFor(model => model.GlAccount, new { @class = "control-label col-md-4" })
    <div class="col-md-6">
        @(Html.Kendo<OrderRequest>().ComboBoxFor(m => m.GlAccount).DataValueField("Number").DataTextField("Description").Filter(FilterType.Contains).HighlightFirst(true)
                    .DataSource(src => src.Read(read => read.Action("GetGlAccounts", "Lookup", new { area = "" }))).Events(events => events.Change("app.common.onChangeRestrictValues")))
        @Html.ValidationMessageFor(model => model.GlAccount)
</div>

the following script will empty out the combobox if the entered value is not in the defined value list

<script>
function onChangeRestrictValues(e) {
  if (this.value() && this.selectedIndex == -1) {
    var dt = this.dataSource._data[0];
    this.text(dt[this.options.dataTextField]);
    this.select();
  }
}
</script>

You can check out a more thorough answer with references used @ my blog http://prestoasp.net/how-to-limit-a-kendo-ui-combobox-drop-down-to-valid-items-using-asp-net-mvc-wrappers/

The article also has links to the github .NET solution I'm using for prototyping stackoverlfow solutions

Cheers

Upvotes: 1

Petur Subev
Petur Subev

Reputation: 20203

Same question is covered here. use the change event of the ComboBox like this:

change : function (e) {
        if (this.value() && this.selectedIndex == -1) {   //or use this.dataItem to see if it has an object                 
            alert('Invalid Entry!');
            cb.select(1);
        }
    }

Here is the jsfiddle.

EDIT : How to use in Razor syntax:

@(Html.Kendo().ComboBox()
    .Name("cb")
    .Events(it => it.Change("cbIsChanged"))
    ...
        )

<script>
    cbIsChanged = function (e) {
        ...
    }
</script>

Upvotes: 16

Nick H
Nick H

Reputation: 494

I got this base code from the Telerik forums and modified it to be a bit smarter. This will use the current text in an attempt to find fuzzy search and if it finds nothing, blanks it.

Try it here: http://jsfiddle.net/gVWBf/27/

$(document).ready(function() {
    var items = [
        {value : '1',
         desc : 'fred'},
        {value : '2',
         desc : 'wilma'},
        {value : '3',
         desc : 'pebbles'},
        {value : '4',
         desc : 'dino'}
    ];

    var cb = $('#comboBox').kendoComboBox({
        dataSource : items,
        dataTextField : 'desc',
        dataValueField : 'value',
        filter : 'contains',
        change : function (e) {
            if (this.value() && this.selectedIndex == -1) {    
                this._filterSource({
                    value: this.value(),
                    field: this.options.dataTextField,
                    operator: "contains"
                });
                this.select(0);
                if ( this.selectedIndex == -1 ) {                    

                    this.text("");
                }
            }
        }
    }).data('kendoComboBox');


});

Upvotes: 1

Paritosh
Paritosh

Reputation: 11570

Kendo combobox API returns the value entered in the combobox - if the item is no there in the list. We have to manually find whether the item exist in the list or not.

Link - ComboBox / API

var comboId = '#movies';
alert(GetComboBoxValue(comboId));

Use this function to get Value of ComboBox.

function GetComboBoxValue(comboId){
    var comboValue = -1;
    $(comboId).data('kendoComboBox').select(function (dataItem) {
        // Note: you have to perhaps change the property - text as per the value
        // this is for the example provided in the link only
        if (dataItem.text == $(comboId').data('kendoComboBox').text()){
            comboValue = dataItem.value;
            break;
        }
    });
    //will return -1, if data is not found from the list
    return comboValue;
}

Upvotes: 1

Related Questions