Wednesday, December 11, 2013

Multiselect in grid edit template.

When setting up a grid with a custom popup edit template, multiselects don't work quite as expected on save. They appear to bind the whole object, not the selected id values.

This snippet should be called as a create/update data formatter:


View
@(Html.Kendo().Grid()
    .DataSource(c => c.Ajax()
        .Create(...).Data("serialize"))
        .Update(...).Data("serialize"))
    ...)

JavaScript

function serialize(data) {
    if (data.FIELD_NAME != null) {
        var selected = data.FIELD_NAME;

        // Remove the old value to prevent binding conflicts.
        delete data.FIELD_NAME;    

        // Select out the values.
        for (var i = 0; i < selected.length; i++) {
            // Rebuild the field in a format friendly to ASP.Net MVC.
            data["FIELD_NAME[" + i + "]"] = selected[i].Value
        }
    }
}

Friday, December 6, 2013

MSBUILD : error MSB1008: Only one project can be specified.

I started switching projects over to a custom build process using community tasks. The TFS build points to a .proj file that then does some versioning for git and kicks off build and nugget or build and web deploy. Well, one project started giving me the error:

MSBUILD : error MSB1008: Only one project can be specified.
Switch: Production

It turns out the issue was in the build definition name - it had spaces in it. I renamed it from "Reslife Production Deploy" to just "Reslife.Publisher" and voila - works.

Wednesday, August 14, 2013

Preserving TabStrip State in KendoUI

Out of the box, there isn't a way to preserve tab-state across links in KendoUI web. For example, I find it handy on certain pages to present a couple of tabs such as a raw filterable grid of data, a quick search form, and logs. When the user drills down into something from there, then goes back, the state of the tabs is lost. Preserving the state of forms or grids within there is a whole different beast, but the tabs should be simple. Likewise, what if we could link directly to an open tab on a page?

Enter the url hash. Provided you're not using the Router, appending the #hash to the url is a viable and easy option. It's easy to add and tie into the TabStrip, obeys back button, and typically makes semantic sense.

It's possible to jump in on the TabStrip's activate event and add the tab's id to the URL, but that requires doing so for every single TabStrip where this behavior is desired. Sounds like a lot of boilerplate. I want it globally default.

So then next option is to monkey patch it. The basic action is that we replace the TabStrip plugin with a wrapper. The wrapper automatically adds an 'activate' listener to set the window hash. It will also check if there's a window hash on page load and set that as active.



So we add this in along with, but after, the basic kendoui includes. Any tab strip in the site will now automatically set itself up to preserve state - autowiring the activate event and on load.

We can customize the hash slug by adding in data-slug attributes to the tab strip headers like so:
<div id="Tabs">
    <ul>
        <li data-navigation="foo">Bar</li>
    </ul>
    ...
</div>


Note, have only really tested with ASP.Net MVC extensions.