Filtering HTML comment nodes from innerHTML - javascript

I wanted to know if there is a way for filter the innerHTML of a DOM to just contain the actual HTML and discard all the comment nodes?
Actually, I'm working with Angularjs and writing some tests with Selenium. And Angular litters the rendered HTML with a lot of comments such as:
<!-- ngSwitchWhen: join -->
<div data-ng-switch-when="leave">
<!-- ngIf: isNow -->
.
.
.
</div>
I'm trying this currently for matching the result: #client is the WebDriver instance.
#client.findElement(By.xpath("//*[#id='log']/li")).getAttribute('innerHTML').then (innerHtml) ->
html = innerHtml.trim()
expect(html).to.equal """
<div class="image"><i class="icon-refresh"></i></div>
<div class="fade-6 content">Getting more activities...</div>
"""
This creates a big problem when I'm trying to test the returned DOM's structure with Mocha. What do I test for? I can't possibly repeat all the useless comments in my expected value, that would be immensely wasteful.
Is there a better way?

Writing tests that rely on innerHTML is not a good idea at all.
When you fetch innerHTML, the browser serialises the information in the DOM into a new markup string which is not necessarily the same as the markup that was originally parsed to make the DOM.
Markup details such as:
what order attributes are in
what case tags are
what whitespace there is in tags
what quotes are used to delimit attribute values
what content characters are encoded as entity or character references
are not stored in the DOM information set so are not preserved. Different browsers can and will produce different output. In some cases IE even returns invalid markup, or markup that does not round-trip back to the same information set when parsed.
+1 katspaugh's answer demonstrates ways to get the information out of the DOM rather than relying on innerHTML, which avoids this problem.
However, more generally, it is usually a bad idea to write tests that depend strongly on the exact markup your application uses. This is too-tight coupling between the requirements in the test and the implementation details. And any little change you make to the markup for even a trivial stylistic reason or textual update means you have to update all your tests to match. Tests are a useful tool to catch things that you didn't mean to break; tests that always break on every change are giving you no feedback on whether you broke something so are non-useful.
Whilst there's generally no magic bullet to separate tests completely from application markup, generally you should reduce the test to the minimum that satisfies the user's requirement, and add signalling to catch those cases. I don't know what exactly your app is doing but I would guess the requirement is something like: "When the user clicks the 'more' button, a busy-spinner should appear to let them know the information is being fetched".
To test this you might do a check like "does the element with id 'log' contain an element with class 'icon-refresh'?". If you wanted to be more specific that it's a spinner to do with fetching activities, you could add a class like "refresh-activities" to the "Getting more activities..." div, and detect the element with that class instead of relying on text which is likely to change (especially if you ever translate your app).

Comment nodes are DOM nodes, as you know. You can iterate over all nodes and filter comments out by their node type:
recursivelyIterate(container, function (subNode) {
if (subNode.nodeType == Node.COMMENT_NODE) {
subNode.parentNode.removeChild(subNode);
}
});
(I haven't included the code for recursivelyIterate function, but it should be trivial to write one.)
Alternatively, leave them comments be and don't work with DOM nodes, work with DOM elements. getElementsByTagName, querySelectorAll and friends.

Related

How to add a <tr> so that the tasks can be shown 1 after the other in a JS/CSS/HTML To-Do List? [duplicate]

Under what circumstances is it illegal for an HTML page to contain elements with duplicate ID attributes?
As a developer who has worked with HTML for many years, I am aware that the intention is that element ids should be unique - what I am asking is for the practical negative effects of duplicate ids.
Granted, getElementByID()-like functions in some libraries might return arrays rather than a single element and this could cause issues when the developer had not anticipated this case. However, as far as I know, such functions will continue to operate so clearly they are not a breaking-effect of id duplicates.
So why is it that duplicate ids are said to be not allowed?
EDIT: The driver for the question was that I saw some templating libraries when generating list/repeated items, producing elements with duplicate ids and I wondered what the impact of that might be in practical terms and how to decide whether to adopt those libraries.
I also wondered about the effect of modal plugins, or any other, that might clone an existing hidden node and thereby create a duplicate via code, and then what the browser would do in that case.
It's always "illegal". Against the spec = illegal. Just because something "seems to work" due to a fluke or overly generous compiler doesn't mean it is valid code.
Another way to think about it: juhst becuse u kan reed ths duzint mayke it korrect Englesh. You have a generous compiler/brain which can understand that (e.g Google Chrome), but someone with more limited English knowledge (e.g. new to the market Browser X) or someone with a mental incapacity (e.g. Internet Explorer) might not understand it at all...but would be able to understand it if each word was spelled correctly/according to spec.
https://softwareengineering.stackexchange.com/questions/127178/two-html-elements-with-same-id-attribute-how-bad-is-it-really
A few reasons I can find:
According to the DOM spec, "If more than one element has an ID attribute with that value, what is returned is undefined"
And:
Incorrect doesn't come in shades of grey. This code violates the standard and is therefore incorrect. It would fail validation checking, and it should. That said, no browser currently on the market would complain about it, or have any problem with it at all. Browsers would be within their rights to complain about it, but none of the current versions of any of them currently do. Which doesn't mean future versions might not treat this code badly.
And:
Behavior trying to use that ID as a selector, either in css or javascript, is unguessable and probably varies from browser to browser.
And:
Many javascript libraries will not work as expected
And:
Experience says that getElementById in major browsers will return the first matched element in the document. But this may not always be the case in the future.
Specification says UNIQUE
HTML 4.01 specification says ID must be document-wide unique.
HTML 5 specification says the same thing but in other words. It
says that ID must be unique in its home subtree, which is basically
the document if we read the definition of it.
Avoid duplication
But since HTML renderers are very forgiving when it comes to HTML
rendering they permit duplicate IDs. This should be avoided if at all
possible and strictly avoided when programmatically accessing
elements by IDs in JavaScript. I'm not sure what getElementById
function should return when several matching elements are found?
Should it:
return an error?
return first matching element?
return last matching element?
return a set of matching elements?
return nothing?
But even if browsers work reliably these days, nobody can guarantee
this behavior in the future since this is against specification.
That's why I recommend you never duplicate IDs within the same
document.
This is an answer by Robert Koritnik at Software Engineering asked by danludwig
Question: Two HTML elements with same id attribute: How bad is it really?
Duplicate ids not allowed in HTML
That code is incorrect. Incorrect doesn't come in shades of grey. This
code violates the standard and is therefore incorrect. It would fail
validation checking, and it should. That said, no browser currently
on the market would complain about it, or have any problem with it at
all. Browsers would be within their rights o complain about it, but
none of the current versions of any of them currently do. Which
doesn't mean future versions might not treat this code badly.
~From Dan Ray
Duplicate ids and JavaScript
So if you use duplicate ids in your HTML many libraries will not work as expected. The most libraries will get the first id they find and return that element. When we look at pure JavaScript: the document.getElementById("idName"); should return in the case of multiple elements with the same id. It says it must return the first element, in tree order.
Under what circumstances is it illegal for an HTML page to contain
elements with duplicate ID attributes?
It is illegal in any circumstances as per the specification:
When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element's tree [...].
As a developer who has worked with HTML for many years, I am aware
that the intention is that element ids should be unique - what I am
asking is for the practical negative effects of duplicate ids.
The CSS selector specification does not define how to handle documents with non-unique ids, as far as I can tell. So you cannot safely use id selectors in CSS in those cases.
The id attribute is also used to navigate to fragments (aka "anchors"). According to the specification, the browser should navigate to the "first such element in tree order". But that might conflict with which element actually comes first from top to bottom. I.e. your layout could conflict with the actual fragment link.
Granted, getElementByID() style functions in jquery etc might return
arrays rather than a single element and this could cause issues when
the developer had not anticipated this case. However, as far as I
know, such functions will continue to operate so clearly they are not
a breaking-effect of id duplicates.
That is clearly wrong, getElementByID() never returns an array. As per the specification:
The getElementById(elementId) method, when invoked, must return the first element, in tree order, within context object’s descendants, whose ID is elementId, and null if there is no such element otherwise.
Your expectation is also wrong in the case of jQuery:
Each id value must be used only once within a document. If more than one element has been assigned the same ID, queries that use that ID will only select the first matched element in the DOM. This behavior should not be relied on, however; a document with more than one element using the same ID is invalid.
There is really no reason to violate the specification in this case, you don't gain anything by doing it. While your pages won't completely break, you could run into problems with CSS, fragment links, and probably other things. In addition, your documents will be invalid and duplicate ids might confuse other people that have to maintain your code.

How to select all tags except anchors (neither anchors inside another element) with document.querySelectorAll?

edit: Is it possible to get all the inner text from tags in HTML document except text from anchor tags <a> (neither the the text from <a> anchors inside another elements) with the document.querySelectorAll method?
My program has an input field that allows users to insert some selector to get the text for certain tags in a given site page.
So, if I want to insert a selector that gets text from all nodes except <a> tags, how can I accomplish that?
I mean *:not(a) does not work, because it selects tags that may have <a>descendants and not() selector does not accept complex selectors, so *:not(* a) does not work.
I know I could delete those nodes from document first, but is it possible to accomplish this task only selecting those nodes I want with the document.querySelectorAll method?
Example:
<html>
<... lots of other tags with text inside>
<div>
<p> one paragraph </p>
<a> one link </a>
</div>
</...>
</html>
I want all the text in the html except "one link"
edit:
If you do document.querySelectorAll('*:not(a)'), you select the div, that has inside an a element. So, the innerText of this div contains the text from a element
Thank you
Your question is how to allow users to extract information from arbitrary hypertext [documents]. This means that solving the problem of "which elements to scrape" is just part of it. The other part is "how to transform the set of elements to scrape into a data set that the user ultimately is interested in".
Meaning that CSS selectors alone won't do. You need data transformation, which will deal with the set of elements as input and yield the data set of interest as output. In your question, this is illustrated by the case of just wanting the text content of some elements, or entire document, but as if the a elements were not there. That is your transformation procedure in this particular case.
You do state, however, that you want to allow users to specify what they want to scrape. This translates to your transformation procedure having other variables and possibly being general with respect to the kind of transformations it can do.
With this in mind, I would suggest you look into technologies like XSLT. XSLT, for one, is designed for these things -- transforming data.
Depending on how computer literate you expect your users to be, you might need to encapsulate the raw power and complexity of XSLT, giving users a simple UI which translates their queries to XSLT and then feeds the resulting XSL stylesheets to an XSLT processor, for example. In any case, XSLT itself will be able to carry a lot of load. You also won't need both XSLT and CSS selectors -- the former uses XPath which you can utilize and even expose to users.
Let's consider the following short example of a HTML document you want scraped:
<html>
<body>
<p>I think the document you are looking for is at example.com.</p>
</body>
</html>
If you want all text extracted but not a elements, the following XSL stylesheet will configure an XSLT processor to yield exactly that:
<?xml version="1.0" encoding="utf-8" ?>
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="text" />
<template match="a" /><!-- empty template element, meaning that the transformation result for every 'a' element is empty text -->
</stylesheet>
The result of transforming the HTML document with the above XSL stylesheet document is the following text:
I think the document you are looking for is at .
Note how the a element is "stripped" leaving an empty space between "at" and the sentence punctuation ("."). The template element, being empty, configures the XSLT processor to not produce any text when transforming a elements ("a" is a valid, if very simple, XPath expression, by the way -- it selects all a elements). This is all part of XSLT, of course.
I have tested this with Free Online XSL Transformer which uses the very potent SAX library.
Of course, you can cover one particular use case -- yours -- with JavaScript, without XSLT. But how are you going to let your users express what they want scraped? You will probably need to invent some [simple] language -- which might as well be [the already invented] XSLT.
XSLT isn't readily available across different user agents or JavaScript runtimes, not out of the box -- native XSLT 1.0 implementations are indeed provided by both Firefox and Chrome (with the XSLTProcessor class) but are not specified by any standards body and so may be missing in your particular runtime environment. You may be able to find a suitable JavaScript implementation though, but in any case you can invoke the scraper on the server side.
Encapsulating the XSLT language behind some simpler query language and user interface, is something you will need to decide on -- if you're going to give your users the kind of possibilities you say you want them to have, they need to express their queries somehow, whether through a WYSIWYG form or with text.
clone top node, remove as from the clone, get text.
const bodyClone = document.body.cloneNode(true);
bodyClone.querySelectorAll("a").forEach(e => e.remove());
const { textContent } = bodyClone;
you can use
document.querySelectorAll('*:not(a)')
hope it will work.

How can I speedup adding large amounts of complex HTML to the DOM

I have a plain webpage that loads the majority of it's content through an AJAX call that returns a large amount of complex HTML. When I place the retrieved HTML in the DOM, it cripples the browser for quite a while (between 5 seconds on Chrome and 35 seconds on Edge).
Example how I append the HTML to the DOM:
$.ajax("example.php").done(function (response) {
const contentElement = document.getElementById('results');
contentElement.innerHTML = response;
});
I want to avoid having to return JSON and converting it to HTML at all cost because of the complexity of the application.
The odd thing is that the browser gets crippled a little while after the inserted HTML is already visible. See the timeline below, where I can see the HTML on my screen (with proper styling) before the ~5 sec long Parse HTML events happen.
How do I speed up the parsing and appending of the HTML to the DOM?
Edit: I have tried multiple browsers and multiple methods of injecting the HTML (documentFragments, innerHTML, jquery .html(), append()). All methods are roughly as slow.
Edit2: The exact HTML injected can be seen in this gist: https://gist.github.com/Rhinni/3032e74bab0de8f40e08a3392c0243b1
Part 1 - It's not the way the code is loaded, it's just the code is invalid and wouldn't work even if hardcoded on the page.
"The odd thing is that the browser gets crippled a little while after the inserted HTML is already visible. See the timeline below, where I can see the HTML on my screen (with proper styling) before the ~5 sec long Parse HTML events happen."
There are some things that should be addressed concerning the practicality of the HTML (its preposterousness speaks for itself), its validity (which it isn't) and functionality, (which it isn't and probably never had any).
You should validate your HTML because it is very invalid, but before we get into that, when you decide to validate that mess, you'll need to separate it into about 16 parts because most online services will fall or cut the validation process early if given that much to process at one time.
The following is a list of issues that are not isolated problems due to a typo. These issues are repeated multiple times. What concerns me the most is that the values and the majority of the variables appear to be customized by hand. Hopefully I am mistaken and you didn't spend hours on customizing values that will hinder rather than be of any real use.
1. #IDs must be unique -- under no circumstances should there ever be a duplicated #ID on the same page.
14 #accordion- fixed, 14 #headingOne - fixed, 7 #model, 7 #type, 7#brand,...
There's more duped #IDs, I changed the #accordion to #acordion1 to 14 because it was necessary for each #accordion to function rather than just the first one. All related attributes that has a direct relationship with #accordion needs to be changed as well, I managed to change toggle-parent="#accodion for the sake of functionality once again. So there's 15 functioning accordions, I added a Home tab with a properly designed accordion which you can use as a template if you decide to redesign the other 14 accordions.
2. In order to use Bootstrap components, you make them according to the document.
The OP code wasn't even close to having any tabs, if you referred to the Bootstrap documents or even W3School's short tutorials, you'd know that you are required to have an <a> for each tab, so your code was short of 16 <a> to toggle 16 tabs. This is why your page is only showing the first tab of 16 tabs, it isn't because the browser just fails midway.
3. Another invalid thing I noticed was that the attribute readonly (and required to a lesser extent) was applied to almost every form control.
Why would you need the readonly attribute on a <select> tag? When assigning attributes to elements, don't start adding a ton of attributes to everything. The clutter makes readability, maintenance, and debugging impossible.
4. There are 2 Plunks:
Plunk 1 is the solution to the OP (Original Post) question which is explained in detail in Part 2 of this answer. The HTML has been partially fixed, I don't have enough time to fix everything.
It has 16 tabs and 15 accordions that work.
Load time has been reduced from 34 sec to 2 sec. with Edge. It appears that Edge heroically tries to make sense of the HTML that was parsed and then fails. The real browsers like Firefox and Chrome justs dumps it and leaves it there.
Plunk 2 is the HTML from the OP code and my solution loading it.
The results are the same, OP code is failing due to the code itself, not because of a loading problem.
Part 2 - A stable way to parse a huge string into HTML. Not needed if OP code actually worked.
OP experiencing heavy latency when attempting to add a huge amount of markup to DOM by innerHTML. Up to 34 seconds to render it completely using Edge while other browsers OP reported at 3 seconds.
I got the load time down to 2 to 3 seconds on Edge and instantly on the real browsers (Chrome and Firefox).
Although OP had tried using createDocumentFragment() already, I believe it is key to a quick load and parse of said HTML. The other key components that the OP probably didn't use are:
insertAdjacentHTML() and Immediately Invoked Function Expression
Using insertAdjacentHTML() method instead of innerHTML property. insertAdjacentHTML() is a powerful and versatile version of innerHTML.
Similarities:
Both will take a given string and parse as HTML.
Both are quick.
Differences:
insertAdjacentHTML() inserts HTML into the DOM, it doesn't overwrite any existing HTML in an element or anywhere in the DOM. innerHTML overwrites the inside of an element.
innerHTML is directed by reference to an element to which it will take a string and overwrite all content of said element with the given string. If innerHTML is just directed to an element without a string, then it will return with the HTML content of said element. innerHTML ability to GET is the only thing insertAdjacentHTML() it can't do. In contrast, insertAdjacentHTML() ability to SET is powerful as explained: insertAdjacentHTML() is directed not only by reference to an element it is told exactly where to go in relation to the referenced element by its first parameter which is one of the 4 DOMStrings that correlate to a position:
"beforebegin" places the string right before the beginning of the element.
`$elector.before(str)`★
"afterend" places the string right after the end of the element.
`$elector.after(str)`★
"afterbegin" places the string within the element right after the brginning. In other words the string is inserted before the element's contents.
`$elector.prepend(str)`★
"beforeend" places the string within the element right before the end. Basically the string is placed after the element's content. This position is the most optimized for speed since the are no proceeding siblings to slow things down.
`$elector.append(str)`★
insertAdjacentHTML() second parameter is the string that will be parsed into HTML. Using Template Literals instead of literal strings allows us to a whole extra level of easy string manipulation.
`element.insertAdjacentHTML("beforeend", <input id="${ID+i}" type="${typeArr[i]}" value="${Math.floor(Math.random() * i}">)`
Immediately Invoked Function Expression is a function with a special pattern.
It is usually two anonymous functions:
The outer function is wrapped in parenthesis.
The inner function usually forms a closure.
Anonymous/expression functions are created when evaluated and then they are immediately invoked due to the extra parenthesis wrapped around them.
They have no name and the variables that the inner function uses can only be accessed by the outer function because they are local scope.
These conditions make an IIFE a one time thing. The signature of an IIFE have slight variances in their signature but the gist of one goes like this:
`(function() { var x = function() {...} x})();`
DOM manipulation is processor intensive and the more we avoid it the better. DocumentFragment was made in order for us to do all of the menial yet numerous tasks involving the DOM -- off of the DOM. We can add as many elements, text, attributes, set event handlers, etc. to the DocumentFragment and its descendants without touching the DOM. Once everything is complete, only one DOM operation needs to be done:
`document.body.appendChild(frag);`
Demo - if you'd like to test an actual working Demo, review this Plunk
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Monstrosity</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
(function() {
const str = `Huge Disaster of HTML`
const frag = document.createDocumentFragment();
const node = document.createElement('div');
let build = function(node, str, frag) {
node.insertAdjacentHTML('beforeend', str);
frag.appendChild(node);
document.body.appendChild(frag);
}
build(node, str, frag);
}());
</script>
</body>
</html>
Simply appending or inserting the HTML you have provided into the browser does not seem to have any adverse affects. At least for me on my browser/computer. (chrome)
Run this example and see if you experience any delays or pauses..
See Example
document.getElementById("test").innerHTML = toAppend;
Obviously this is not a complete test because I am missing your CSS and I have modified your html slightly by removing line breaks so that I could assign the text to a variable in the text editor.
If the example works for you then we need to investigate further the data coming from the server, and try adding css to the equation etc..
If the example is causing delays then the problem is likely hardware related, maybe you don't have enough available memory and or cpu which is crippling the browser.
I fixed the issue with the help of the answers of Trevor and Zer00ne, but it was something completely different.
The issue was caused by the Laravel Debugbar which tracks AJAX requests by default, and parses the response for debugging purposes. Disabling AJAX request tracking in the Debugbar config solved the issue.

Algorithmic, Automagic Ajax

I have made a framework that generates a HTML "DOM" tree on the server, as a tree of python objects, and then spits it out as a string to be sent to the client. The way it does this is via a recursive depth-first traversal of the tree: for example a div would spit out the opening "div", spit out all it's children's html and then spit out the closing "/div".
This tree is broken down into conceptual components, as shown below:
graph http://lhy.mit.edu/media/Flow_Chart.png
This only shows the first two levels of hierarchy; the actual site has many more: for example each comment in the comment bar is a self contained component, each button on the menu bar is a self contained component. As you can see, the various components do not need to be on the same depth in the tree. What constitutes a "component" is decided by me.
What I want is the complete html string for each component (everything from the root node of that component downwards), as well as the partial HTML string for every component (The HTML of that component, minus the HTML of its children). The partial HTML of main section, for example, would be the html, head and two div tags only. The complete html of main section, on the other hand, would be every node on the page.
How would i do this? I could just find the complete HTML string of every component and sub-component, mark the boundaries of each sub-component with some string and do Regex-Removals in order to find the partial HTML string for every component, but that feels clunky and inefficient.
I could do an iterative-deepening DFS, halting at the boundary between a component and its sub-components until every node in that component has been explored. I would then have the partial HTML for every component but then i would need to do a similarly hacky Regex-Inserts to later build up the complete HTML for every component.
I could do both, but that would take two passes and would be expensive, though maybe not as expensive as the above Regex gymnastics.
I could do a priority-queue Dijkstra's, having each component be strictly higher priority than its children. It would traverse the tree in the correct order, finishing each component before moving on to its children, but i have no idea how i would get the final well-formed HTML string out of it.
The purpose of all this is so the server can intelligently and completely autonomously determine the minimal set of components on the client's page that need to change on a page-transition between two arbitrary pages.
If i create a new page on my site, I should need no more than Zero extra lines of code to have it ajax smoothly with any existing page.
But first i need to get my graph-traversing html-spewing algorithms in order. Any ideas?
I am presuming your client is Javscript code as you didn't specify anything.
Don't do anything too complicated. In particular, for the love of god don't try using regexes to work with HTML.
Is your server sending you a fully funciton HTML string? In this case, you can convert this into an actual DOM you can work with (there are many ways to do so) and then use the .innerHTML of an element to get your "complete html"s and use the .tagName to get a tag's name.
I still don't really get why you need all this complication. If you already went through the trouble of downloading the whole "new page" there isn't too much of a reason to try to change as few parts as possible - just replace averything and forget about it (the calls to the server should be the most expensive thing anyway).
If you really want to use less brute force, than you should find a way to request/be notified of only the interesting changes without having to look at everything. Then, given the part that is to be changed and the text, you just need to do something like
document.getElementById('mainCommentArea').innerHTML = newHTML;

How do I insert a DOM element in an ordered list (in Dojo)?

I'm trying to make an AJAXy submission and have the resulting partial be inserted into my list at the proper place. I can think of a few options, but none is terribly good:
Option 1: Return JSON, do rendering in Javascript. That seems like the wrong place to render this, especially since the list itself is rendered in my application server. It has the benefit, though, of making it easy to access the value to be sorted (response.full_name).
Option 2: Return an HTML fragment, parse the sort value out. Parsing HTML in Javascript is probably worse than rendering it.
Option 3: Return an HTML fragment that also contains a <script> section that gets evaluated. This could add the DOM node to a master list and then make a JS call to insert itself at the right point. The downside here is that IE doesn't evaluate <script> tags when innerHTML or appendChild are called.
Personally I would do #1. Nothing is wrong with combining the server-side generated HTML with the client-side generated one, but if it is a complicated procedure it is better to keep it in one place (on the server in your case). So you may want to return (as JSON) two values: the sort value, and the HTML snippet.
After that it is simple: find the position, instantiate the snippet (e.g., using dojo.html.set()), and place it with dojo.place(). Or instantiate it directly in-place.

Categories

Resources