Pixelastic

You can cut our wings but we will always remember what it was like to fly.

Posts tagged with "jQuery UI"

Setting the z-index of a jQuery UI datepicker

I ran into a collision issue with two of my absolutly positionned elements on a form page. I had an invisible flash buttun (used to launch an upload process) as well as jQuery UI datepicker.

The form was built in a way that when the datepicker was displayed, it was supposed to be on top of the invisible Flash button. Unfortunatly the button was in fact "on top" of the datepicker, but being invisible you do not notice it until you click.

This resulted in an upload dialog popping up and many confused users.

The fix

The Flash z-index is fixed in my CSS (10), so I thought that adding a greater z-index to the jQuery UI datepicker in CSS would be enough.

It is not. The jQuery UI datepicker seems to automatically set the z-index to 1, whatever you specified.

I checked the datepicker options, looking for a zIndex key, but found nothing...

I tried the beforeShow event, to manually set the z-index, but it seems that jQuery still update my value to 1 AFTER the event.

So I finally resorted to adding a small timeout to re-add my value after jQuery. This is a bit of a hack but given the context this is the only way I found.

// Set the datepicker zIndex on load
element.datepicker({
[...]
'beforeShow': function(input, datepicker) {
setTimeout(function() {
$(datepicker.dpDiv).css('zIndex', 100);
}, 500);
},
[...]
});

 

How to prevent a FOUC but still gracefully degrade the jQuery UI tabs

I finally managed to fix something that was bugging me for a very long time. I'm talking about the jQuery UI tabs.

They are pretty useful actually, but I always hated that FOUC they produce. For one split second, you'll see all your tabs content, then they'll be neatly re-arranged in tabs.

What I want are my tabs displayed correctly right away, on first load.

First, the markup

Here's a typical tabs markup :

<div class="tabs">
    <ul>
        <li><a href="#firstTab">First tab</a></li>
        <li><a href="#secondTab">Second tab</a></li>
    </ul>

    <div class="tabPanel" id="firstTab">
        First tab content
    </div>
   
    <div class="tabPanel" id="secondTab">
        Second tab content
    </div>
</div>

CSS to hide all tabs if Javascript is disabled

If your Javascript is disabled, so will jQuery UI. We will then hide the <ul> because it serves no purpose here. We will only show it if js is enabled

.tabs ul { display:none; }
.js .tabs ul { display:block; }

Applying jQuery UI tabs

By doing a $('.tabs').tabs(); jQuery UI will treat your <ul> as your tab menu and all your .tabPanel as their corresponding contents. It will hide all your panels, except for the first one. It does so by adding a .ui-tabs-panel class to every .tabPanel as well as a .ui-tabs-hide to every panel it hides.

Right now, you should add another CSS rule to hide the unused panels :

.ui-tabs-hide { display: none; }

But if you look at your page now, you'll see all your tabs content before they get hidden. That is the FOUC I was talking about. The jQuery UI documentation indicate that to remove it, you should directly add the .ui-tabs-hide class to panels you'll want to hide.

As also pointed in the doc, it will not gracefully degrade because users without Javascript won't even be able to see your other tabs. Also, it asks you to add server-side logic (HTML markup with jQuery specific classes) for something that should be handled entirely client-side.

Removing the FOUC while gracefully degrade

Ok, so what I did was writing two simple rules that will directly hide all unused panels while still displaying the active one, even before jQuery UI takes action.

.js .tabPanel + .tabPanel { display:none;}

That way, no FOUC, and users without Javascript still see all the content. Unfortunatly, if you now try clicking on your tabs, you'll see that nothing happens and you get stuck with your default panel always visible.

Fixing the jQuery UI tabs

As jQuery will add new classes to my elements, I'll just have to write more specific rules that use those classes. Here's the little piece of logic I came up with :

.js .tabPanel.ui-tabs-panel { display:block;}
.js .tabPanel.ui-tabs-panel.ui-tabs-hide { display:none;}

All the jQuery panels are shown, except for the one hidden by jQuery. All those rules being more and more specific, they will get applied once the tabs are activated but still override the previous display: declarations.

Conclusion

This is how I fixed an issue that was bugging me for years. Unfortunatly the CSS rules being dependent on the markup used, I haven't yet been able to write them in a global form that could be added to the main jQuery UI css files.

Unresponding jQuery UI dialog box

As this is the second time I encounter this "issue", I think it may be clever to post it here. At least, I won't have to debug it all the down again next time.

In a nutshell, I was working on a complex UI that involve several layers of dialog boxes, each one on top of the previous one. Each new dialog box is supposed to offer the user something to do, and once it is done, the dialog box disapear and the user can get back to the previous one.

The "issues" I was having was after closing a specific window, I wasn't able to focus the previous one. I mean, the window was there, I was even able to update its fields using jQuery, but I couldn't focus it either using keyboard or mouse.

After some digging, it appears that I wasn't correctly "closing" the previous window. I was actually doing a .dialog('destroy') instead of a .dialog('close') and this was causing my issue.

Calling close hides the dialog box, but keep it in the DOM. That way if I ever need the same dialog box again, jQuery is smart enough to re-use it.

Calling destroy on the other hand actually remove the dialog box from the DOM, forcing jQuery to recreate it from scrath.

It appears that calling destroy in my case caused a strange lose of focus, so I reverted to close instead.