How to set an attribute of a DOM element in Clojurescript? - clojurescript

I wish to set the "value" property of an "input" element using Clojurescript, but I am having trouble with the syntax of setProperties in goog.com. Has anyone got a working example?
Update
------
This seems to work:
(goog.dom.setProperties
(goog.dom/getElement "element-name")
(clj->js {:value "text"}))

If you need to create throwaway JS objects for use with JS APIs, you can do so directly using js-obj:
(js-obj "value" "text")
;; produces {"value": "text"} in the compiled output
Of course if you already have a ClojureScript map with the appropriate entries, clj->js will be more convenient.
More importantly, you might want to consider switching to a ClojureScript library for DOM manipulation. Several are available:
Luke VanderHart's Domina, which might have been the first one, is used by Enfocus (listed below) and Pedestal;
Prismatic's dommy, notable due to its own merits as well as the very entertaining blog posts about it on Prismatic's blog (which can serve as a great introduction to the benefits of macros: first one, second one, third one);
Creighton Kirkendall's Enfocus, which is in a nutshell an Enlive-like library for ClojureScript, which is awesome;
Kevin Lynagh's Singult, which is a Hiccup-style library for ClojureScript with cool functionality for merging in changes to the DOM, rather than rerendering from scratch.

Related

Is it possible to use the vaadin-grid inside a LitElement of a Polymer application?

What is the minimum example, if any, using the Polymer PWA (https://polymer.github.io/pwa-starter-kit/), to show correctly a vaadin-grid?
I tried many different combinations, but never a working one, with, often, this warning:
property-accessors.js:275 Polymer::Attributes: couldn't decode Array as JSON
Am I doing anything totally wrong?
Thanks
Andrea
Starting from the v5.2.0-beta1 we recommend using following Grid features:
column helper elements (vaadin-grid-filter-column, vaadin-grid-sort-column)
column convenience properties (path, header and text-align)
renderers for more complex cases where you previously used templates
See the example here: https://glitch.com/edit/#!/lying-blanket?path=app.js:29:42
https://lying-blanket.glitch.me/
Note: I'm using fetch API here for simplicity only, you can use XHR if necessary.

How to turn text into DOM elements using Clojurescript? (And Om?)

In a ClojureScript/Om app, I have a DOM and a string of HTML.
How can I translate that string of HTML into elements I can insert into the DOM?
I've started down the path of parsing the HTML with hickory, planning to then process the hickory data to create DOM elements, but I think there must be a simpler way I'm overlooking.
(I don't need to validate the HTML, I can assume it's safe and valid enough.)
You don't need to parse the HTML string. It's unnecessary overhead. React/Om supports something like DOM's innerHTML property. Just set the prop this way:
(om.dom/div #js {:dangerouslySetInnerHTML #js {:__html "<b>Bold!</b>"}} nil)
If you work with plain DOM without Om, set the innerHTML property like:
(let [div (. js/document getElementById "elId")]
(set! (. div -innerHTML) "<b>Bold!</b>"))
Aleš Roubíček answer is much better. I'll leave this un case it helps somebody.
Hickory offers a as-hiccup function. Hiccup uses Clojure data structures to represent HTML. You could feed those data structures to Clojurescript libraries that follow the same conventions:
Hiccups to generate regular DOM elements.
Sablono to generate React DOM elements and use with Om.
You could also use Kioo/Enfocus and instead of passing a file path, pass the string directly. This would be more direct and instead of using two libraries (Hickory + Sablono) you would use only one. The caveat is that Kioo and Enfocus follow the Enlive style of templating (which is great but has a learning curve) and the docs are focused on file paths and not strings (even though it is possible to pass strings).

Configure code folding in LightTable

LightTable has code folding since v0.6.1, it's key binding is C-= by default. It works for Python files out of the box, but it does nothing with Clojure files. The Codemirror code sets fold to "indent" at https://github.com/LightTable/Python/blob/master/codemirror/python.js#L351. My question is how can I add code folding to a file type that's not handled by Codemirror by default. I'd like to do it without having to touch a js file, hopefully writing only a little ClojureScript in my user settings.
Unfortunately folding needs a folding helper function that will starting from a given position seek the start and end position for the fold. These currently exist for languages that use braces (like java, c++) or indentation (python). So, unless someone writes a helper function that can parse s-expressions and find where to fold them, folding in clojure will not work.

which javascript template engine is nest suited to generate JSON

Both mustache and handlebars are awesome. I like them both for their individual simplicity and excellence. Mustache because it's a one template works in lots of places and handlebars because it provides just a few more features.
The challenge I have is that they seem to have been implemented to output HTML or some other document structure where the tags are in pairs and there are no separators.
To further clarify, if you have an array of items that would be output in a list then this works well:
<ul>
{{#each items}}
<li>{{name}}</li>
{{/each}}
</ul>
This works great. But if you want to output something JSON-like:
[
{{#each items}}
{ name:{{name}} }
{{/each}}
]
This does not work because JSON requires that there be commas separating items in a list. And you cannot put a comma after the innermost '}' because that would cause an error too.
There are several posts/recommendations where people have requested that an optional separator attribute be added to the #each or adding a #join. One committer said that it should be implemented as a plug-in because the core needs to be simple.
The politics aside. Being able to format a javascript object as a JSON string seems well suited for templates.
**One final idea. There may actually be a better Javascript Idiom for reformating a JavaScript object. I suppose that would also be interesting to consider.
PS: the one reason I like the template is because it becomes self documenting.
UPDATE:
#Kevin over at the handlebarsjs team was able to create a "Helper" function that implemented the feature I was missing. It's not like to make it into the core any time soon but that code worked:
[
{{#join items sep=','}}
{ name:{{name}} }
{{/join}}
]

Mapping plain text back into HTML document

Situation: I have a group of strings that represent Named Entities that were extracted from something that used to be an HTML doc. I also have both the original HTML doc, the stripped-of-all-markup plain text that was fed to the NER engine, and the offset/length of the strings in the stripped file.
I need to annotate the original HTML doc with highlighted instances of the NEs. To do that I need to do the following:
Find the start / end points of the NE strings in the HTML doc. Something that resulted in a DOM Range Object would probably be ideal.
Given that Range object, apply a styling (probably using something like <span class="ne-person" data-ne="123">...</span>) to the range. This is tricky because there is no guarantee that the range won't include multiple DOM elements (<a>, <strong>, etc.) and the span needs to start/stop correctly within each containing element so I don't end up with totally bogus HTML.
Any solutions (full or partial) are welcome. The back-end is mostly Python/Django, and the front-end is using jQuery. We would rather do this on the back-end, but I'm open to anything.
(I was a bit iffy on how to tag this question, so feel free to re-tag it.)
Use a range utility method plus an annotation library such as one of the following:
artisan.js
annotator.js
vie.js
The free software Rangy JavaScript library is your friend. Regarding your two tasks:
Find the start / end points of the […] strings in the HTML doc. You can use Range#findText() from the TextRange extension. It indeed results in a DOM Level 2 Range compatible object [source].
Given that Range object, apply a styling […] to the range. This can be handled with the Rangy Highlighter module. If necessary, it will use multiple DOM elements for the highlighting to keep up a DOM tree structure.
Discussion: Rangy is a cross-browser implementation of the DOM Level 2 range utility methods proposed by #Paul Sweatte. Using an annotation library would be a further extension on range library functionality; for example, Rangy will be the basis of Annotator 2.0 [source]. It's just not required in your case, since you only want to render highlights, not allow users to add them.