Toffer and the bulk update DropDownList

*ugh*  I know…I know…my dorky blog post titles all pretty much suck…I don’t spend a lot of time on them, which is apprent, but I do try to including some sort of hint at what the post is about, so just roll with it…k?  🙂

Today my faithful followers (of which there’s still only one…ME, HAH!)…I’m going to build off a previous post about the Multi-Select Checkboxes.  In that post I gave some example code on how to add a checkbox column to a Kendo Grid while at the same time also putting a checkbox into the column header which would do a multi-select of all the checkboxes in the rows.

Building off that example, this post is about how I did a bulk update on all the selected rows.  Sure the Grid supports doing batch updating of the records through using Ajax calls to controller actions, but there are times when it’s still convienent to know how to spin through the collection of items in the grid, find the selected ones, and update a value in all of them…so here we go.  🙂

So to make things easy…we’re going to use a Grid that has the checkbox column, and then a few other columns of random data…but we’re going to enable the built in ToolBar to expose the Add, Save, and Cancel buttons.  Here’s the bare bones setup…

CSHTML Javascript Code:
$(function ()
{
    $('#ExampleKendoGrid').on('click', '.chkBx', function ()
    {
        var checked = $(this).is(':checked');
        var grid = $('#ExampleKendoGrid').data().kendoGrid;
        var dataItem = grid.dataItem($(this).closest('tr'));
        dataItem.set('Selected', checked);
    })
})

function checkAll(e)
{
    var state = $(e).is(':checked');
    var grid = $('#ExampleKendoGrid').data().kendoGrid;

    $.each(grid.dataSource.view(), function ()
    {
        if (this['Selected'] != state)
            this.dirty = true;

        this['Selected'] = state;
    });

    grid.refresh();
}

CSHTML Razor Code:
@{ var columnWidth = 170; }

@(Html.Kendo().Grid<YourObjectModel>()
    .Columns(c =>
    {
        c.Template(@<text></text>)
            .ClientTemplate("<input type='checkbox' #= Selected ?
checked='checked':'' # class='chkbx' />")

            .HeaderTemplate("<input type='checkbox' id='masterCheckBox'
onclick='checkAll(this)'/>")

            .Width(80);
        c.Bound(m => m.PropertyOne)
            .Title("One")
            .Width(columnWidth);
        c.Bound(m => m.PropertyTwo)
            .Title("Two")
            .Width(columnWidth);
        c.Bound(m => m.PropertyThree)
            .Title("Three")
            .Width(columnWidth);
        c.Bound(m => m.PropertyFour)
            .Title("Four")
            .Width(columnWidth);
        c.Bound(m => m.PropertyFive)
            .Title("Five")
            .Width(columnWidth);
    })
    .DataSource(ds => ds
        .Ajax()
        .Batch(true)
        .Create(c => c.Action("AddYourObjectModelItem", "Home"))
        .Destroy(d => d.Action("RemoveYourObjectModelItems", "Home"))
        .Model(m =>
        {
            m.Id(yom => yom.ID);
        })
        .Read(r => r.Action("GetYourObjectModelItems", "Home"))
        .Update(u => u.Action("UpdateYourObjectModelItems", "Home")))
    .Editable(e => e.Mode(GridEditMode.InCell))
    .Filterable()
    .Groupable()
    .Name("ExampleKendoGrid")
    .Navigatable()
    .Resizable(r => r.Columns(true))
    .Scrollable()
    .Selectable()
    .Sortable()
    .ToolBar(t =>
    {
        t.Create();
        t.Save();
    }))

There, not too scary.  From here, I decided that I wanted another control in my toolbar for doing bulk updates to one of my columns.  For the purpose of this demo…lets say we wanted to bulk update a value in the “Three” column.  I won’t be going into detail about how the grid is getting populated with data…I’m sure by now if you know what Kendo, Ajax, MVC, etc… are…you probably already have a grid populated with data (if you have quetsions about that area though, feel free to ask…I’ll help best I can).

First lets add the bulk update UI elements to the Toolbar…because I wanted to add my own controls into the Toolbar, I had to specify a custom template for the toolbar, and I couldn’t use the built in .Create and .Save buttons anymore…once I enabled the .Template section of the Toolbar, they disappear so I had to add them into the template (there was a post on the Telerik forums about it, but I’m having trouble finding it to link it here).  Here’s what I ended up with below…

.ToolBar(t =>
{
    t.Template(
        @<text>
            <table>
                <tr>
                    <td width="200px;" style="border: none">
                        @item.SaveButton()
                    </td>
                    <td width="170px;" style="border: none">
                        <label>
                            Bulk set value to all selected rows:
                        </label>
                    </td>
                    <td width="155px" style="border: none">
                        @(Html.Kendo().DropDownList()
                            .AutoBind(false)
                            .DataSource(ds =>
                            {
                                ds.Custom()
                                .Type("aspnetmvc-ajax")
                                .Transport(tr =>
                                {
                                    tr.Read(
                                        "GetPropertyThreeValues",
                                        "Home");
                                })
                                .Schema(s =>
                                {
                                    s.Data("Data")
                                    .Total("Total");
                                });
                            })
                            .HtmlAttributes(new { style = "width: 150px" })
                            .Name("BulkUpdateDropDownList"))
                    </td>
                    <td style="border: none">
                        <a class='k-button k-button-icontext'
onclick='BulkUpdateButtonClick()' href='#'>
Bulk Update
</a>

                    </td>
                </tr>
            </table>
        </text>);
})

That takes care of putting some UI into the grid for showing the controls for doing the bulk update, but it needs another Javascript method to back it up so I’ll add that now.

function BulkUpdateButtonClick(e)
{
    var myGrid = $('#ExampleKendoGrid').data("kendoGrid");
    var bulkUpdateDropDownList = $('#BulkUpdateDropDownList');

    var myGridObjects = myGrid.dataSource.data();
    var selectedBulkUpdateDropDownList = bulkUpdateDropDownList[0].value;

    var dataParams =
    {
        myGridObjects: myGridObjects,
        selectedThreeValue: selectedBulkUpdateDropDownList
    };

    var dataParamsJson = JSON.stringify(dataParams);

    var updateActionURL = '@Url.Action("UpdateSelectedItems", "Home")';

    $.ajax(
    {
        contentType: "application/json",
        data: dataParamsJson,
        dataType: "json",
        success: function (result)
        {
            myGrid.dataSource.data(result.Data);
            myGrid.refresh();
        },
        type: "POST",
        url: updateActionURL
    })
}

And that’s pretty much all there is too it.  I’ll add the controller actions I used to fill the grid in case it helps you in anyway.  Just keep in mind the model, the CRUD actions for the grid, and the action to fill the DropDownList are all pretty generic and can really be easily swapped out for whatever you’re using in your creation.  Hope this helps…Enjoy.  🙂

Model:
public class YourObjectModel
{
    public YourObjectModel() { }

    public bool Selected { get; set; }

    public int ID { get; set; }

    public string PropertyOne { get; set; }

    public string PropertyTwo { get; set; }

    public string PropertyThree { get; set; }

    public string PropertyFour { get; set; }

    public string PropertyFive { get; set; }
}

C# Controller Action Code:
public ActionResult GetYourObjectModelItems([DataSourceRequest]
DataSourceRequest request)

{
    Collection<YourObjectModel> payload =
new Collection<YourObjectModel>();

    for(int i = 0; i < 100; i++)
    {
        YourObjectModel newItem = new YourObjectModel();

        newItem.ID = i;
        newItem.PropertyOne = string.Format("Blah Bl{0}ah Blah", i);
        newItem.PropertyTwo = string.Format("Blah Bl{0}ah Blah", i + 1);
        newItem.PropertyThree = string.Format("Blah Bl{0}ah Blah", i + 2);
        newItem.PropertyFour = string.Format("Blah Bl{0}ah Blah", i + 3);
        newItem.PropertyFive = string.Format("Blah Bl{0}ah Blah", i + 4);
        newItem.Selected = false;

        payload.Add(newItem);
    }

    DataSourceResult result = payload.ToDataSourceResult(request);
    return Json(result);
}

public ActionResult GetPropertyThreeValues([DataSourceRequest]
DataSourceRequest request)

{
    Collection<string> threeValues = new Collection<string>();

    threeValues.Add("Please Select");
    threeValues.Add("A Value");
    threeValues.Add("To Use For");
    threeValues.Add("Updating The");
    threeValues.Add("Three Column");

    DataSourceResult result = threeValues.ToDataSourceResult(request);
    return Json(result);
}

public ActionResult UpdateSelectedItems([DataSourceRequest]
DataSourceRequest request,
IEnumerable<YourObjectModel> myGridObjects,
string selectedThreeValue)

{
    foreach(var gridObject in myGridObjects)
    {
        if(gridObject.Selected)
        {
            gridObject.PropertyThree = selectedThreeValue;
            gridObject.Selected = false;
        }
    }

    DataSourceResult result = myGridObjects.ToDataSourceResult(request);
    return Json(result);
}

Advertisements
Toffer and the bulk update DropDownList

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s