Solved

jQuery Accordion Div Oversize problem

Posted on 2014-02-16
26
686 Views
Last Modified: 2014-02-22
This test page which intends to eventually get data dynamically from our  database:

http://dev.himalayanacademy.com/looklisten/inspired-talks

is coming along well. I have two more issues and one strategy query.

1) when the accordion opens certain years, there is a huge vertical white space below the list of talks for that year. I don't know why and I don't know how to get the div to dynamically resize to just accommodate the list with no extra vertical white space.

2) My novice JS brain is challenged by the requirement that  Javascript must address specific ID's on the page otherwise if you use a class, then the operation will trigger all divs with that class. Hence my caveman JS code where I duplicate the accordion script three times and use a different div ID for each case. I program apps for desktop, server and mobile using LiveCode and in that environment I would use some kind of array that would only require me to declare the function once, but it would work across all instances. My question then is: there's got to be a better way, right? and if so, what is it?  where you want a click event to trigger any singular div but there could be many of them, and you only want a single function to do the job.

3) Third question is about strategy on delivery. In the first accordion, call "id=accordion-model" I'm including dummy data from the description field, which we have in the database. Looking at the total number of talks in the list, if I deliver *all* those plus their descriptions, that's a pretty heavy load of data to push to the browser... even if it is neatly display "underneath" hidden accordion sections, it could be a very sluggish loading  time. I will have to test to know exactly.

I was thinking perhaps it would be better just send 50 chars of the description data and then let the "more.." click event do an AJAX call for the full description for that one talk...

But I'm betwixt and between just fetching all the data one time versus some kind of ajax, partly because I'm no sure I could figure out how to do it. (I could make that a separate question)

Any insights on best practice for UX here will be appreciated.
0
Comment
Question by:Brahmanatha
  • 13
  • 13
26 Comments
 
LVL 25

Assisted Solution

by:Kyle Hamilton
Kyle Hamilton earned 500 total points
Comment Utility
first of all, you do not need all this. remove it:


 $(function() {
  $("#accordion-model").accordion();
  $(".audio-index-list").on("click", "li", function(){
    $(this).addClass("open").siblings().removeClass("open");
  });
});

 $(function() {
  $("#accordion-two").accordion();
  $(".audio-index-list").on("click", "li", function(){
    $(this).addClass("open").siblings().removeClass("open");
  });
});

 $(function() {
  $("#accordion-three").accordion();
  $(".audio-index-list").on("click", "li", function(){
    $(this).addClass("open").siblings().removeClass("open");
  });
});

Open in new window




You should only have one accordion element. Go to this page, and click on 'view html' to see the structure: http://jqueryui.com/accordion/

The within each accordion section, you can have your nested "accordions" which are triggered by the click function on each li.

This is all you will need:

 $(function() {
  $("#accordion").accordion();
  $(".audio-index-list").on("click", "li", function(){
    $(this).addClass("open").siblings().removeClass("open");
  });
});

Open in new window



To speak to your second question:
All those accordions within accordions are really messy. Especially with the extra padding that comes with the styling, they are hard to read. Scrolling is difficult because sometimes the whole page scrolls, and sometimes you are scrolling within an accordion. Having to scroll within an element on the page is extremely cumbersome.

You need to rethink your Information architecture instead of trying to cram everything on one page. Also then, your page load issue will magically go away :)
0
 

Author Comment

by:Brahmanatha
Comment Utility
Thanks Kyle... The  scrolling inside the open accordion only occurs on clicking "more" for the description... I agree. it's not good UX.

But what about the huge extra vertical white space that appears in some of them?
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
we can deal with the white space once they are implemented correctly. did you go to the link i posted and fix the html structure?
0
 

Author Comment

by:Brahmanatha
Comment Utility
Kyle, thanks for your guidance

Yes, HTML simplified:

Single div id="accordion" wraps the entire set of listings (there are three sets) because I'm breaking the "panel must be sibling of header" pattern with separate lists... did my home work...   I had to fix that by specifically declaring the header. I also see the "heightStyle" option that can be declared as a property.   But, though the explicit header property *does* work, the heightStyle: "content" does not. It should set the panels' heights to their content... but  it still defaults to auto, which sets panel height to height of longest one.

I disabled to the addition of a click to open more description for now, because, as you pointed out, the UX doesn't work well and I'll need to re-think that one. AJAX to fetch full description is looking better.

I'll fix the big blocks and borders' appearance once we get the height working, that's simple css... (Agreed. too much padding everywhere...)

I'm not getting any errors in console, so why heightStyle: "content"  is not implemented?

Excuse the expanded script: I'm trying to impress my brain with JS's brace and parentheses nested structures

<script type="text/javascript">

 $(

  function() 
 
  {
  
    $("#accordion").accordion

    (
    
      {
        header: "h3",   //this works  
        heightStyle: "content"  //this does not... why?
      }

    );

    //   Disable description expansion for now... UX needs work:
    //   $(".audio-index-list").on("click", "li", function(){
    //   $(this).addClass("open").siblings().removeClass("open");
  }

);

</script>

Open in new window

0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
great job cleaning it up :)

it is definitely not doing what it should now. So I suspect there is a conflict somewhere. The way I would try to find the culprit is by removing all the scripts, and adding each piece back in one at a time. You should make sure you have the latest version of jquery and you're only loading it once. Make sure your copy of jquery ui doesn't have the query library included in it.

So, remove all other scripts on the page, and just add jquery and jquery-ui. See if that works like it's supposed to. Then start adding scripts back in one at a time, and test at each stage.

In the meantime, a very dirty yucky hack is to put in an override for the height, like this:

.ui-accordion .ui-accordion-content {
   height: auto !important;
}

Open in new window


Are you using jquery ui for anything else? if not, then you'd be better off writing your own accordion script (which I'd be happy to provide) instead of loading yet another library on your page. It's only a few lines of code.
0
 

Author Comment

by:Brahmanatha
Comment Utility
I don't think we are using query UI anywhere else. Our pages are dynamically built any way, so I can insert jQuery UI on the fly if it is needed elsewhere. Indeed simplifying the page is better I'd love to have a look at your code for a custom accordion.
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
here you go. View source for the code.

You can ignore the styling. If you delete all the styles above the comment /* Functionality */, the accordion will still work, and be completely unstyled.

in my version, you can have multiple accordion classes, and clicking on an open item will close it. There is also a line in the javascript that is commented out, will will automatically open the first item on page load.

http://candpgeneration.com/EE/accordion-plain.html

let me know if you have any uestions
0
 
LVL 25

Accepted Solution

by:
Kyle Hamilton earned 500 total points
Comment Utility
here's a version where you click on the very first submenu item to reveal a descripttion:

http://candpgeneration.com/EE/accordion-plain-v2.html
0
 

Author Closing Comment

by:Brahmanatha
Comment Utility
Thanks for going the extra mile on this and writing out that solution. I just tried to look you up over at  SnapOne. Is that your company or you are work for them?  Do you do freelance work?
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
Hi Brahmanatha,

SnapOne is the company I work for. And http://candpgeneration.com is my own company. However, I am not actively doing any work for CandP at the moment as I have just too many things on my plate. I very rarely take on freelance work right now. But please do checkout C&P, and feel free to contact me from there using the contact page :)

Best,
Koza
0
 

Author Comment

by:Brahmanatha
Comment Utility
OK, well, since you do pro bono here on EE I'll just have to use this channel for the small stuff.

http://dev.himalayanacademy.com/looklisten/inspired-talks now builds with includes for your CSS and JS...and is pulling a list from the database. I just have to finish the LiveCode model/lib that builds the DOM/accordion as per your example.   I added attribution in the CSS for Kyle Hamilton and EE.

Thanks for our generous spirit!
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
thank you. please post a link once it's all up and running :)
0
 

Author Comment

by:Brahmanatha
Comment Utility
I certainly will.

Your portfolio is impressive... what are you using for the RealWalkthru Panos.. Pano2VR? Or is that Robert's baby ( a relative I presume....)
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:Brahmanatha
Comment Utility
Kyle:

is setting a unique div a requirement for this to work?

<a href="#one">2014<span class="count"></span></a>

<a href="#two">2013<span class="count"></span></a>

<a href="#three">2012<span class="count"></span></a>

etc.  I need these to be numeric because my back end controller will run on a repeat loop and generate a numeric series. If these are essential, then I can prepend letter(s) (ID must start with an alpha char)  

<a href="#a1">2014<span class="count"></span></a>

<a href="#a2">2013<span class="count"></span></a>

<a href="#a3">2012<span class="count"></span></a>

I don't think this will break your scripts... just checking
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
those aren't ids. they are dummy links, actually, anchors. they have no impact on the script. why are you generating these? are they links?
0
 

Author Comment

by:Brahmanatha
Comment Utility
Yes, right dummy links- not IDs

I was just copying the DOM from you sample accordion-plain-V2.html

You have those dummy links there and I think u refer to them in your code below where you have set the variable called accordion head= $('.accordion>li>a'),

Which makes me to ask if those dummy links are critical for the script to function.

Actually I do not intend to make links for the panel heads so if these HREF dummy links wrapping the year header are not required then I will not output those when generating the Dom
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
make sure that whatever you use instead matches in the script. so if you do <h3>2012<h3>, then in the script, write $(".accordion>li>h3")
0
 

Author Comment

by:Brahmanatha
Comment Utility
Understood, merci
0
 

Author Comment

by:Brahmanatha
Comment Utility
Aloha, Kyle!  It work! I finished the database dig, parser and DOM builder...

http://dev.himalayanacademy.com/looklisten/inspired-talks/library

I stripped some of the elements down further. I will test later with the description.

The page weight is 203K without descriptions... oh boy.. you are right... I see the jquery UI clocking in at  205kb... I think I need to use AJAX for descriptions, otherwise the page will take waaaay too long to load.

Thanks for your help!
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
starting to look really nice.

You have a small problem with the html:

<h3 class="count>">2001</h3>

Open in new window


this is causing the accordion not to be able to close. If you want the count, move it like this:

<h3>2001</h3><span class="count"></span>

Open in new window


I suspect that's just the code not getting generated correctly.

a page weight of 200k is not that bad. Before you go the ajax route, just test it and see if it has an actual impact on the performace.
0
 

Author Comment

by:Brahmanatha
Comment Utility
1) extra ">" in the class string... oops: fixed (easy) Thanks for catching that
2) added <span class="count"></span>  but it breaks

I suspect my in unknowing attempt to see if we could just count the H3's with

<h3 class="count">  I may have broken your JS

( or I changed too many calls to classes from what they were to "h3"

:-(

http://dev.himalayanacademy.com/looklisten/inspired-talks/library

I also checked with our team and, indeed, jQuery UI calls were "leftovers from experiments" and not in use at all. I removed those; upgraded to 1.11.1 and the page really loads fast now...  that's encouraging... I'll move on to including the descriptions in the data dig and then test your other JS.

So when I revert to your accordion-plain-v2.html  I'll be more careful about changing "a" to H3 in the CSS and JS... I think the only instances are where we see direct descent:

.accordion > li > a

becomes

.accordion > li > h3

in all cases... but nothing else.  Hopefully it won't break...stay tuned...

I appreciate your on going oversight!

Then Phase III (after descriptions) I can create a very focused search option, just for this subset of media... and still use my back end lib and your presentation layer to display the results.
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
I don't think it's the script or anything you did.

there are other errors on the page todo with fancybox. if you upgraded to the latest jquery, make sure that the other libraries you are using are compatible. latest jquery deprecated a lot of things.
0
 

Author Comment

by:Brahmanatha
Comment Utility
Hmmm. I wrestled with upgrades, finally found out we really *do* use jQuery UI... broken major sections of the site, put the libraries back... upgraded fancy box and ... after some sweat... everything works, no more fancy box errors

 but *still* if I add  

<span class="count"></span>

Open in new window


afgter the h3... the page breaks... the number "0" replaces all content in the sub-menu.

the problem may be that we have a gremlin still in the output of the lists. Some anchors are not being completed ... there is no closing "</a>" for nine anchors on the page

e.g.
<li>1998-12-06 - <a href="http://dev.himalayanacademy.com/index.lc/view/gr_1998-12-06_religious-lethargy" title="Click to View">Religious Lethargy</li>

Open in new window


if you view source... I parse the output from the database and the list of 9 lines with missing anchors at the end... So, while this does not break your accordion... it could be breaking the count function.
0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
It should work. it works when I inject it in your site:

example output from your site:
<h3 class="">2001<span class="count">104</span></h3>

this is the structure you need. notice the span is inside the h3. that's important. If you want to put the count span somewhere ele, we'll need to adjust the script.

<h3>2001<span class="count"></span></h3>

Open in new window

0
 

Author Comment

by:Brahmanatha
Comment Utility
duh! "inside H3"  OK done it works...Yay..

Here's my serverside Livecode function now... You can see why I find JS challenging after coding in xTalk (starting with HyperCard and moving forward today with LiveCode)

function buildAccordion tTalksList,tAuthor

    ##### mark up the data with HTML for accordion
    ### See Kyle Hamilton's samples in the manager section under sample code

	set the itemdel to "|"
	put 0 into tYear

	repeat for each line x in tTalksList 
		
			if (item 2 of x) <>  tAuthor then # we are done with one author's  listing
				exit repeat
			end if 

		# parse for the year

		put char 1 to 4 of (item 1 of x)  into tDate

			if (tDate<>tYear)  then # we are starting a new year

					if (tYear<>0) then # close previous submenu UL
						put  "</ul>"  & cr after tAuthorsList
					end if

				put tDate into tYear

				put  "<li>" & cr & "<h3>" & tYear &  ( format ("<span class=\"count\"></span>")) & "</h3> " &  cr & \
				format ("<ul class=\"sub-menu\">") & cr  after tAuthorsList

				# pass the descripton data in the main command later then
Add description UL here next...

			end if 

		# build list items next

		put "<li>" &(item 1 of x)& " - " &  (item 3 of x)  & "</li>" &cr after tAuthorsList

	end repeat

   return tAuthorsList

end buildAccordion

Open in new window

0
 
LVL 25

Expert Comment

by:Kyle Hamilton
Comment Utility
Looks great. If you need help with the nested accordion (descriptions), feel free to post another question.

^^ that syntax looks like Chinese to me :)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
In this tutorial viewers will learn how to customize the background color and font color of highlighted text using the ::selection element in CSS Begin by defining the selected text as an element in CSS by typing "::selection": Style the ::selection…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now