0

Perhaps this is more of a theory question than a code question, but the underlying solution will be code based so I hope it fits in here ok.

The basic construct is that I have an unordered list of controls, that update depending on what is happening. The information is coming in via a JSON packet of [[url,text].[url2,text2]] arrarys to build on the anchor:

$.each( controls, function( i, item ) {
        $("<li id=\"control_"+i+"_"+ID+"\"><a href=\""+item[0]+"\">"+item[1]+"</a></li>").appendTo("#ul_controls_"+ID);
});

I have a document.on listener responding to the click events so re-attachment doesn't have to happen here.

This creates a basic list of links ie,

Start
Edit
View

are the default case.

When start is pressed, start and edit go away, and stop comes in

View
Stop

After it ends, the controls update again, removing stop and returning the edit and start options.

View
Start
Edit

As you can see, I've lost position from my original state (view is now on top instead of the bottom because it persists and appendTo, well, appends).

I have over-simplified this example, as there are MANY other controls for various stages being added in to the loop.

So, how do I keep position where start/stop trade places, edit comes and goes as it pleases, and view stays at the end (And remember, i have 5-10 more controls in this list depending on state, so relying on appending to just that 1 element is probably unreliable)

Some thoughts I had were:

  1. Always bring all controls physically into the DOM, and toggle visibility instead
  2. Instead of JSON url/name pairs, send a full $("#ul").html("<li> ... to last </li>"); style injection from the server for the whole bock every time instead of attaching and detaching individual li elements as needed (performance hit? JSON formatting concerns?)
  3. Come up with an ID scheme that can be sorted, or a slot-like solution, but the how-to on this is drawing blanks from my brain.

I appreciate any thoughts or advice on this.

BReal14
  • 1,603
  • 1
  • 12
  • 35
  • What's the reason for sending list items via JSON packets? Do the list items depend on some sort of DB queries or would it be possible to know all possible items at load time (of either the page or the anchor)? – DanielST Aug 12 '14 at 15:36
  • Due to the size of the system, and users wanting to see everything, the idea was to load only the bare essentials at load time. Upon selecting a particular line-item to interact with, a sub menu $.clones() an html template, attaches it to the dom, and then queries a cache to populate it with that line-item's information. Upon clicking start, that data feed becomes live data and updates the front end with what is happening semi-real time. The possibilities are NOT endless, but there are a lot of them. Given my option 1 above, brining in 20 elements, and hiding 17 of them seems backwards – BReal14 Aug 12 '14 at 16:05
  • ok, so you are using a mostly server-side approach. My approach is usually far more client sided for this kind of thing but that's more a matter of preference. I'll write up an answer. – DanielST Aug 12 '14 at 16:59
  • Appreciate the time. look forward to the response. – BReal14 Aug 12 '14 at 17:26

1 Answers1

2

Toggle Visibility

This usually works pretty well unless you have alot of elements that need to be hidden. Performance-wise, 20 hidden elements isn't an issue and the app will likely feel more responsive since you aren't querying a server to get markup changes. If you have many of the same object, each with the same possible 20 elements, then this is the wrong approach. See the JS object section if this is the case.

The logic for this might not fit nicely into your app though. All the rules for when what gets hidden need to be client-side in JS. Since those list items are links, I'm assuming you've been putting that kind of logic server-side.

Send full list with every JSON request

This consolidates all functionality server-side very well but I wouldn't recommend it unless the list updates very infrequently.

Sorting Scheme

Lots of options here. I'd recommend something like this.

When you define your items lists (server-side) give each one an order property such that, were all the items visible, they would each have a unique place.

ie: item = {href:"...",text:"...",order:1}

Then send that property at the same time as you send the item and use it as the <li>'s val attribute (or something). Then sort with something like any of the answers to this question (or with a sort plugin).

JS Object

This would be my approach (but I'm biased). I keep my server-side code for basic data retrieval and security checks.

Make each control box a JS "object" using whatever pattern you prefer. Initialize the control box objects on page load or when they are needed with the full list of items. Each object handles it's own server requests (data only, no markup), re-orders (or redraws) itself and stays alive via delegated event listeners on it's links. Ordering is done with a sorting scheme like above or by building it into the redraw logic. Or by toggling visibility.

Or something in that vain. I can't really be more specific than that since it comes down to details. While this is heavier client-side, it puts all your dom manipulation logic into one place, needs fewer server requests and isn't too hard to keep light.


Let me know if you want code examples of something specific. This question is fairly broad and, consequently, my answer is too.

Edit

Fiddle: http://jsfiddle.net/he027yh5/4/

Shows a basic algorithm to insert only missing values into the DOM (avoids deleting and inserting redundantly.) It's not coded very nicely and it needs error checking but it works and I guess it would be faster than rebuilding each update. I'm not convinced that rebuilding would have much impact in the first place though.

Community
  • 1
  • 1
DanielST
  • 13,783
  • 7
  • 42
  • 65
  • Understood... it's a bit vague indeed as I expected. The current setup is similar to the JS object method you describe. The current world order is for everything to get its own info. The amount of ajax requests just started to add up and cause load, so the idea now is to package it all in one big JSON grouping and DOM-distribute it out to the elements. Still, I'm stuck on the re-ordering when elements retain, as is the case with the view link. The update happens every 5 seconds. I don't want to append/destroy the same links over and over again when they haven't changed. – BReal14 Aug 12 '14 at 19:06
  • @briansol Can I get an idea of the worst case scenario, performance-wise, for the control boxes? Something like "x control boxes with several out of x visible". Unless I've misunderstood, removing and appending the links every 5 seconds will not have a significant performance hit. But if it's important, here's a fiddle: http://jsfiddle.net/he027yh5/2/ see answer edit for description. – DanielST Aug 12 '14 at 20:11
  • The performance hit is not to the DOM, rather to the server to figure out current state and return data. The invocation of the backed is a non-standard API similar to php's file_get_contents(). It's pretty bad. Buried in one of the above links, I saw a sorting routine that seems to be working for me. I'll write up an answer. thanks for pointing me in the right direction. – BReal14 Aug 12 '14 at 20:16
  • Using an html5 data var on my li, I was able to invoke the list sorting as offered in http://stackoverflow.com/a/11338910/1981678 that was linked above. I have a conditional check the dom vs the json packet and only invoke the sort if there's a difference. – BReal14 Aug 12 '14 at 20:35