0
votes

I have a grid, inside of some column of which I have created a combobox editing UI, using columns.editor function. My goal is every time a user selects some value from the combobox -while populating a newly created grid record-, this value to be removed from the list options of a next record's combobox.

One of the things i've tried is shown below:

function equipmentDropDownEditor(container, options) {
    var equipmentComboBox = $('<input id="equipmentDropDownEditor" required data-text-field="name" data-value-field="name" data-bind="value:' + options.field + '"/>')
        .appendTo(container)
        .kendoComboBox({
            autoBind: false,
            dataSource: equipmentTypesDS,
            dataBound: function(e) {

              var equipmentData = e.sender.dataSource.data();

              if(currentlyInsertedEquipmentTypes.length > 0){

                for(var i=0;i<currentlyInsertedEquipmentTypes.length;i++){

                    $.each( equipmentData, function( index, selectedEquipmentData ) {

                            if (selectedEquipmentData.name == currentlyInsertedEquipmentTypes[i]){

                                  var dataItem = e.sender.dataSource.at(index);
                                  console.log("dataItem: " + dataItem.name + " is being removed");
                                  e.sender.dataSource.remove(dataItem);

                            }
                    });
                }

              }

            }
        });
}

I've created a global array variable named "currentlyInsertedEquipmentTypes" inside of which I hold all the user's already selected values (for example if the user has created 2 records inside the grid and has selected "laptop" option in the combobox of the first and "workstation" option in the combobox of the second --> currentlyInsertedEquipmentTypes = ["laptop", "workstation"] ).

Inside the combobox dataBound event I check whether the user has already selected values (currentlyInsertedEquipmentTypes.length>0) and if he has, I locate the corresponding object inside the bound dataSource and I remove it, so that it wont be available in the next record's combobox list. This is where the whole thing crashes even though the data item removal takes place.

Am i missing something that i should do after the data item removal? Should i rebind the datasource to the combobox in some way? Any help would be much appreciated.

[EDIT]

---- The combobox datasource code

var equipmentTypesDS= new kendo.data.DataSource({

transport: {
    read: {
        url: "api/equipment_types",
        type: "GET",
        data: {
            //"equipment_category": 1
        },
        dataType: "json"
    }
},
schema: {
    data: "data",
    total: "total"
}

});

--- the kendo grid code:

                    $("#popup_equipment").kendoGrid({  
                        dataSource: {
                            schema:{
                                model:{
                                    id: "equipment_type_id",
                                    fields:{
                                        equipment_type_id: { editable: false },
                                        name: { }, //validation: {required: true}, defaultValue: "LAPTOP", 
                                        items:{ type: "number", defaultValue:1, validation: { required: true, min: 1} }
                                    }
                                }
                            }
                        },
                        toolbar: ["create"],
                        columns: [
                            { field: "name", title: "εξοπλισμός", width: "300px", editor: equipmentDropDownEditor, template: "#=name#" },
                            { field: "items", title:"πλήθος", width: "80px"},
                            { command: ["destroy"], title: "&nbsp;", width: "100px" }
                        ],
                        //editable: "inline",//true,
                        editable:{confirmation: false},
                        scrollable: false,
                        selectable: false
                     });

[EDIT 2]

$("#popup_equipment").kendoGrid({
    dataSource: {
        schema:{
            model:{
                id: "equipment_type_id",
                fields:{
                    equipment_type_id: { editable: false },
                    name: { }, //validation: {required: true}, defaultValue: "LAPTOP", 
                    items:{ type: "number", defaultValue:1, validation: { required: true, min: 1} }
                }
            }
        }
    },
    toolbar: ["create"],
    columns: [
        { field: "name", title: "εξοπλισμός", width: "60%", editor: equipmentDropDownEditor, template: "#=name#" },
        { field: "items", title:"πλήθος", width: "20%"},
        { command: ["destroy"], title: "&nbsp;", width: "20%" }
    ],
    editable:{confirmation: false},
    scrollable: false,
    selectable: false,
    save: function(e){
        console.log("GRID SAVE EVENT! ", e);
        var equipment_name = e.values.name;
        equipmentTypesDS.get(equipment_name).used = true;
        console.log("equipmentTypesDS", equipmentTypesDS);
        console.log("END OF GRID SAVE EVENT!");
    }
});




function equipmentDropDownEditor(container, options) {
    var equipmentComboBox = $('<input id="equipmentDropDownEditor" required data-text-field="name" data-value-field="name" data-bind="value:' + options.field + '"/>')
        .appendTo(container)
        .kendoComboBox({
            autoBind: false,
            dataSource: equipmentTypesDS,
        });
}


var equipmentTypesDS=  new kendo.data.DataSource({

    transport: {
        read: {
            url: "api/equipment_types",
            type: "GET",
            data: {
                //"equipment_category": 1
            },
            dataType: "json"
        }
    },
    schema: {
        data: "data",
        total: "total",
        model:{
            id: "name"
        }
    },
    filter: { field: "used", operator: "neq", value: true }
});
1

1 Answers

1
votes

I would suggest a different approach. Instead of removing the element filter it out.

Example: I define a DataSource with a list of Cities (your Inserted Equipment) as follow:

var cityDS = new kendo.data.DataSource ({
    data : [
        { City : "Seattle", used : false },
        { City : "Tacoma", used : false },
        { City : "Kirkland", used : false },
        { City : "Redmond", used : false },
        { City : "London", used : false },
        { City : "Philadelphia", used : false },
        { City : "New York", used : false },
        { City : "Boston", used : false }
    ],
    schema : {
        model : {
            id : "City"
        }
    },
    filter: { field: "used", operator: "eq", value: false }
});

As you can see I added a field called used that simply says if that City is already used or not. And I set it as id of this DataSource. In addition, I set a filter saying that I only want those where used id equal (eq) to false.

The editor function is pretty much yours:

function cityDropDownEditor(container, options) {
    var equipmentComboBox = $('<input required data-text-field="City" data-value-field="City" data-bind="value:' + options.field + '"/>')
    .appendTo(container)
    .kendoComboBox({
        autoBind: false,
        dataSource: cityDS
    });
}

but with no dataBound or any other event handler.

Finally in the Grid when I save a record, I filter that city from the list. Something like:

var grid = $("#grid").kendoGrid({
    dataSource: ds,
    editable  : "popup",
    pageable  : true,
    toolbar: [ "create" ],
    columns   :
    [
        { field: "FirstName", width: 90, title: "First Name" },
        { field: "LastName", width: 200, title: "Last Name" },
        { field: "City", width: 200, editor : cityDropDownEditor }
    ],
    save : function(e) {
        console.log("e", e);
        var city = e.model.City;
        cityDS.get(city).used = true;
    }
}).data("kendoGrid");

This might work if you start the Grid with no elements otherwise you would have to conveniently initialize the used field. It might require some additional code dealing with cases as changing the City but from your description, doesn't seem to be the case.

You can see this running here : http://jsfiddle.net/OnaBai/ZH4aD/