jQuery UI Tabs widget

I have been using the Tabs widget from the jQuery UI. It works great but we came across a situation which was greatly frustrating to solve.

We have a Single Page App that is using the Tab Widget to display logically grouped data. When we want to save the data, we are calling our API. If there is a problem the API will return an error message.

What we where looking to do is prevent the changing of the tab if the API returned an error.

We are using jquery 1.10 because this application still has a user base that is using IE 6, 7 and 8, so we cannot use jQuery 2.

There is a method on the Tabs UI, beforeActivate that looked to be the answer, as according to the documentation:

Can be canceled to prevent the tab from activating

We created a javascript function that would call our API. But we could not get the change of tab to be cancelled. This is because in jQuery 1.10, there is no longer an option to make a synchronous call.

With jQuery 1.10, you have to use the .done, and .fail of the ajax promise. Unfortunately with this you are unable to cancel the tab event because the ajax call always returns true immediately.

I thought we would never solve this issue. We searched for some time, but we could not find anybody else who where trying to achieve what we wanted to do. So what we came up with will be what I think may be a unique hack, but it was the only solution that we could come up with that works.

I remember that within jquery, you can determine if an event was triggered by a human or by a computer.

To determine this with the Tabs widget, all that is required is to check the event.originalEvent. If the originalEvent is undefined, then it means that the event was triggered by a computer.

This is a snippet of the solution that we came up with

beforeActivate: function (event, ui) {
        if (event.originalEvent !== undefined) {
            //event.originalEvent is undefined when the tab is activated via code (i.e. after save)
            event.preventDefault();
            this.Save([this.Tabs()[ui.oldTab.index() | 0]])
            .fail(function () { console.log('save failed'); })
            .done(function () {
                $('#tabs').tabs('option', 'active', ui.newTab.index() | 0);
            })
            .always(function () {
            });
        }
}

The first thing is we check to see if the event was triggered by a human by checking the event.originalEvent. If the code was triggered by a human we prevent the default event from happening, which is the change of tab. From this we called our Save event. This is bound using knockoutjs which is not shown, but it could be any $.ajax call. Once the promise returns we check to see if the call failed or succeeded.

If the call fails we are using the excellent toastr library to display the error message returned. If the call passes, then we call the tabs activate method passing in the index of the new tab. Because this code was called by the computer, the event.originalEvent is undefined which will allow the UI to change tabs.

I may not be the best solution, but this is a solution that works.

Advertisements

My musing about anything and everything

Tagged with: ,
Posted in ajax, jquery, jqueryui
One comment on “jQuery UI Tabs widget

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

Enter your email address to follow this blog and receive notifications of new posts by email.

Join 11 other followers

%d bloggers like this: