Nested jQuery UI Accordions won't open with .active - jquery-ui

I have nested jQuery accordions in my markup where I try to auto-open on page load according to the path that was last opened in previous sessions.
I saved the path into a cookie, loading the cookie and run the following code
path.forEach(function(label){
var element = root.find("[data-caption='"+label+"']");
element.parent().accordion( "option", "active", parseInt(element.attr('data-index')) );
root = element.children().eq(1);
});
The issue is that for some reason the 'active' takes effect only for the first accordion and non of the nested ones.
I checked several times and:
element.parent() is indeed an accordion (otherwise it would have thrown an error).
data-caption is a unique key for elements in each iteration.
element.children().eq(1) is the active panel (according to the structure of jQuery UI Accordion).
the active element I am asking to open indeed exists for each iteration.
I don't know what is the issue here, any ideas?

I found the problem by myself and post here for future reference.
The issue is this part of the code
parseInt(element.attr('data-index'))
And the reason lies with how accordion counts elements within its panel.
In my panel I had several html elements which were not accordion and several which were. Now the code above brought me the index of the accordion element in compare to the entire panel.
The issue is that for some reason .active only counts sub elements which are accordion themselves. So for example if the panel index of an element is 3 but it has 1 non-accordion element before it in the panel, then it's "active" index is actually 2.
I don't know why they chose for this behaviour, but there you have it.
My solution was to place a different attribute on the element with it's "active" index and use it instead of data-index.
Now everything works like a charm.

Related

jQuery Mobile dynamically remove data-theme then refresh <ul>

I am implementing a “have not yet viewed” list where the user sees a list of items in a ul and those the user has not viewed have a data theme applied to highlight them. When the user clicks on the item it is displayed, and I need to remove the data theme so the item is no longer highlighted.
I have the logic correct to actually remove the attribute as I can see in the Elements section of Chrome’s Developer Tools the attribute is no longer in the li. But the highlight is still visible in the rendered page.
I’ve searched and have seen a number of suggestions involving refreshing the page, list, etc., all to no avail. You can see some of the attempts as follows (in the function "this" is the li):
$(this).removeAttr("data-theme");
//$(this).closest("ul").listview("refresh");
//$(this).closest("ul").listview();
//$('#mylist').listview();
//$("#content-notifications").page();
//$("#content-notifications").page("destroy").page();
//if ( $("#content-notifications").data("page") ) {
// $(this).closest("ul").listview("refresh");
//};
Anyone have the correct solution, because I can’t find it!
Thanks-
Matt
You have to manually remove the class for the old theme in li and add the class for new theme.
$(document).on("click","li",function(){
$(this).attr("data-theme","b").removeClass("ui-btn-up-a").addClass("ui-btn-up-b")
});
Demo here - http://jsfiddle.net/ENYxw/

Dynamically filling selectbox + jQuery UI sortable reset

I have a selectbox which takes its option values from a <ul> list. The list is changeable via jQuery UI sortable functionality, and the selectbox dynamically updates as you sort items differently.
I have made that functionality, the code is dirty but it does the job:
http://jsfiddle.net/trunkadelic/TtnTf/2/
What I need is a "reset" function, which brings the list (and thus, the selectbox) back to their original values. I am not sure how to approach this, even a nudge in the right direction would be much appreciated.
On page load I would store off the initial state of the list in a JavaScript variable. Then, when the reset link is clicked I would restore the state of the <ul> to what it was on page load. From there you can use the same method you already have to update the selectmenu to match.
I forked your jsFiddle to show this - http://jsfiddle.net/g8GLw/

How to bind backbone.js events to JQuery UI dialogue windows?

I'm very new to backbone.js but we're starting to use more and more JS on the front end and I wanted to use some framework to give the code structure - backbone seems to suit our needs.
So started off with a very simple test app that launches a dialogue window using jquery-ui. The problem I have is that since jquery-ui adds a wrapper DIV round the original template used by backbone, the events no longer fire.
I don't want to use the jquery-ui event model as I'd rather just use the one - how can I bind backbone's to this new structure?
It looks as though the call to _.template() is actually doing the wrapping in an extra div. The parent div with the events bound to it is being left behind appended to #well. A simple workaround is to call .parent() on the result of getting the element with the model class ID. See here for example
There's more than likely some information in the _ documentation that might shed some more light on the problem too.
OK - at the end of this project, I finally realised that I hadn't answered this. What happens is when you create a .dialog with JQueryUI, it actually detatches your original DOM element and moves it to the bottom of the DOM wrapped in it's own JQueryUI markup to turn it into a dialog.
Since the Backbone view's element has now been moved, Backbone doesn't pick up any events that fire as it's happening outside it's own "view" as far as it is concerned.
So what you have to do is reassign the view's element:
var dlg = this.$("#dialogue-properties").dialog({ ..});
this.setElement(dlg);
Where this is the view. This is done within the initialize method
You can create div wrapper in your view and modal it's content, as described here (first part of the post)
cocovan does a good job explaining the problem in his answer. However, as for the solution, the JQuery UI team actually added a method at the end of 2012 (Allow dialog to be attached to a element other than body) that takes care of this issue.
It is the appendTo(selector) method (jQuery Dialog appendTo method). So simply specify to which element you want the dialog appended.

Visible/hidden content affecting loading speed of page? How to retrieve external data on demand?

Example: A list of linked <H4> (<a><H4>maximum 200 characters</H4></a>) and their corresponding divs (<div>maximum 10000 characters</div>) are simultaneously fetched from a spreadsheet; when any one of those visible linked <H4> is clicked ( toggle() ), their corresponding prior hidden divs ( hide() ) gets displayed. The list of linked <H4> and related divs grows as the spreadsheet grows, like a Comments form.
Questions:
Does the <H4> list load faster (or appear faster on the page)
when the divs are hidden beforehand (hide())?
If question 1 is negatif, what would be the simplest jQuery function structure, in this example, to retrieve and display the divs after the linked <H4>s are loaded and only upon User <H4> click? I already have the data-fetching function figured out (google.jsapi) so I would need the correct jQuery function structure allowing User on-demand loading of supplementary data. Any pointers?
Note: Currently developing on jQuery 1.6+ . Code above is simplified for description only. The reason why the <H4>s are wrapped within <a> tags is a cross-browser issue and to allow accessibilty with accesskeys and Tab for keyboard Users (I tried the each() method for clickable H4s and Firefox did not let me down however IE 6-7 hated me for that and froze).
1) Does the list load faster (or appear faster on the page) when the divs are hidden beforehand (hide())?
Answer:
As long as you are loading hidden divs the same time you are loading your page, your page won't load faster/signifcantly faster
2) If question 1 is negatif, what would be the simplest jQuery function structure, in this example, to retrieve and display the divs after the linked s are loaded and only upon User click?
Answer:
Use ajax to populate divs on demand, create a page with empty hidden div, and load those div using ajax request when you are showing them. All this can be done using javascript/JQuery

Changing the hash but not moving the page using jquery ui tabs

I added the following code to change the hash to the tab name:
$("#tabs > ul").tabs({
select: function(event, ui){
window.location.hash = ui.tab.hash;
}
} );
This works fine in FF3 but in IE7 it moves down the page (depending on the tab selected anywhere from somewhere near the top of the page all the way down to the very end of the page).
I tried changing it to:
$("#tabs > ul").tabs();
$("#tabs > ul").bind("tabsshow", function(event, ui) {
window.location = ui.tab.hash;
})
This leads to identical behavior in both IE7 and FF3, which moves the page down to the top of the selected tab.
I would like the tab to be changed, the hash to be updated, but the page not moved at all, which is how it works in FF3 in my first example, but not in IE7.
Thanks.
Notes: JQuery 1.3.1 / JQuery-UI 1.6rc6
If there's an element on the page that has the same id as what you're setting the hash to, for instance you're trying to set the browser hash to #cars and there's already a div#cars on the page, the browser will scroll you down to where that div is.
To my knowledge, there are 3 possible workarounds
1) Change the browser hash to something else such as #thecars.
2) Change your existing markup in some similar manner.
3) On some event, changing the id of your similarly named markup, then changing the browser hash, then rechanging the name of markup back to it's original value should also theoretically work. This is obviously a bad and slow workaround, just thought I'd mention it.
You could try having a "return false;" after you set the window location but I can't be sure.
Unfortunately, your problems won't end there. There are other issues with navigating back and forth across multiple browsers--nothing may change, page may reload, page state might be mangled, javascript may get reinitialized etc.
You may want to have a look at Tabs v2 which uses the History/Remote plugin though it has not been updated for jQuery 1.3+.
This demo is easier to understand. If you look at the javascript source, you'll notice the use of iframes to handle states.
There is also the History Event plugin and the jHistory plugin to achieve what you want.
Would like to hear back how things turns out and what solution you went with.
What Chris suggested worked for me, had no clue even a div could link via the #. So my solution is quite simple, in the show: event handler, I do the following, it's not perfect in that back button won't be in history, but that's another job for BBQ history plugin. All my divs simply have id="tab-cars", id="tab-trucks"... strip out the 'tab-' part and put it into the url hash.
var name = ui.panel.id.substr(4);
location.hash = '#'+name;

Resources