I've been experimenting with an unobtrusive Knockout data-binding jQuery plugin. Follow the link here.
I cannot seem to figure out how to keep the "data-bind" attribute out of a template, though. I can't decide whether or not it should even be done, either. I just have a hunch.
Example template:
<script id="storeTemplate" type="text/x-jquery-tmpl">
<li>
<div class="storeTitle" data-bind="click: select">${storeTitle}</div>
</li>
</script>
I'm thinking that it might be a good idea to pull data-bind="click: select" out of there. Does anyone have an idea as to how to do that? I've tried $(".storeTitle").dataBind( { click: "select" } ); A jQuery selector only selects objects that have already been created in the DOM, yet the elements we want to edit are not part of the DOM yet. Also, I would like to avoid applying bindings more than once.
It seems I just sort of answered my own question. Considering that the elements in the template are actually sitting in the DOM (just in string form) I could just modify the string and add the data-bind="click: select". Rather than doing string manipulation, a coworker suggested I just temporarily insert the template text as innerHTML to add it to the DOM, modify it using the plugin, insert the modified version back into the template as text and apply bindings.
Related
I have some client-side JavaScript that dynamically inserts some elements into the DOM. Those elements contain the markup for a dropdown element using the Dropdown plugin:
<p>
<a
id="resource-upload-label-1234"
href="#invalid-resource-1234"
class="label alert"
data-dropdown="invalid-resource-1234"
data-options="is_hover:true"
>
Invalid
</a>
</p>
<div id="invalid-resource-1234" class="f-dropdown content" data-dropdown-content>
<h4>Invalid File</h4>
<p>
This file is not a supported file type.
</p>
</div>
The problem is that the dropdown plugin isn't detecting this new element, so it is not adding the dropdown behaviors to the new elements.
As a test, I tried hard-coding the HTML directly in the HTML source, and the dropdown loads fine in that context. So I have Foundation and the dropdown plugin configured correctly. It's just not binding the functionality to the dynamically-generated elements.
Is there a bit of JavaScript that I can run to bind the dropdown functionality to #resource-upload-label-1234? I was looking at the source for the plugin, and it wasn't evident to me how to do this.
For efficiency you can use $(document).foundation('reflow');
To be even more efficient "target the actual type of foundation item
you need to 'reflow' $(document).foundation('orbit', 'reflow');"
(I'm quoting from: http://foundation.zurb.com/forum/posts/1766-reflow)
One solution that I just found that works is to call $(document).foundation(); again after inserting the new elements.
I am not sure if this is the "right way," but it works. If anyone knows of a more appropriate solution, don't be shy, and post it as an answer!
According to a comment on zurb/foundation#3885, it appears that calling foundation() again should not cause any problems, and perhaps foundation() is designed to be used this way.
I'm building a simple to-do list app, and while it's working, I suspect there's something I could be doing better.
listItem is the class each element will have as a list item. .delete is a temporary solution to remove a list item.
$('ul').append('<li class="listItem"><h2>' + textField + '</h2><h3 class="delete">X</h3></li>')
Is there a way to insert this HTML while keeping the JavaScript separate from the markup? Can I save the HTML as some sort of prototype that will automatically insert the textField value?
I'm looking at making the markup a bit more complex for each list item, so I don't want it to get even messier. Will I need to add another framework (like AngularJS maybe) to accomplish what I'm trying to do? Is it acceptable to have this much markup in my JavaScript?
Let me know if there's any more of my code that would help to answer the question.
EDIT: It's on GitHub if anyone's interested.
If you are about creating a heavy javascripting rendering, perhaps there are better libraries such has Angular.js. But this question might lead to opinion based answers and be of no good. Who can tell wich framework can fit who's needs?
If your particular needs are just to implement a simple list of elements with text content and a remove button, you can use jQuery.
I fiddled a bit of code for the remove button.
/* element rendering [can be populated within a loop or from an array] */
var textField = "this is text";
$('ul').append('<li class="listItem"><h2>' + textField + '</h2><h3 class="deleteThis">X</h3></li>');
/* remove button */
$(document).on("click", ".deleteThis", function() {
$(this).parent('.listItem').remove();
});
What you'll have to do then is just parsing your html with your text/content.
About your question : "How do I keep behavior and content separate when inserting HTML via jQuery?"; well, you just did it by using jQuery to .append() your element.
Well, AngularJS is a pretty good practice, but you can do something similar.
For example for embedding html code in my DOM I prefer using a javascript template engine as undercorejs (this is one of many), this is very ease and useful for repetitive html task. So your Js code will be more clean.
I recommend you to read about some javascript template engines.
I'm making a html template generator sort of like this. It's going to have specific style and markup so all it really has to do is take the inputs from the form and place them in the "template" and output as text for easy copy/paste. I was wondering if there is an easier way to make this, like using jQuery. Open to all suggestions.
jQuery has a selection of methods for dealing with the DOM that could come in useful for creating HTML markup from a form. It also has a few methods specific to forms themselves, if that suits your purposes.
Check out the API for Manipulation. There are a variety of methods you may find useful.
Since you are constructing HTML with form values, the .wrap() method could be quite valuable to surround content with the inputted tags, ids, and classes, which could be styled with a externally linked CSS file. See also the .wrapAll() and .wrapInner().
You may find the .html() method interesting as well for grabbing the contents of any element. It is somewhat the reverse of what you need but it could come in handy.
I understand that using custom html tags is improper for a variety of reasons, but I wanted to run a specific situation by you that might warrant a custom html tag and hopefully get told otherwise or possibly a better way of achieving my goal.
Throughout my code I have what I term as templates that are made up of a div tag with a template and a hidden class attached to it. This is not visible on the screen, but basically these "template" tags contains html that I use in Javascript to create a variety of different items. I do this so that I can style my templates in html rather than have to worry about mixing CSS in with my Javascript.
<!-- TEMPLATE -->
<div class="template hidden">
<span>Random Container</span>
Random Button
</div>
In javascript I would do something like
var template = document.getElementById("template");
var clone = template.cloneNode(true);
clone.removeClass("template hidden");
I would rather be able to do something like this
<template class="hidden">
<span>Random Container</span>
Random Button
</template>
So that if I have multiple templates in a single div I can grab them all rather than having to give them unique class names. Of course my reasoning for needing an implementation goes a lot deeper than this, but its not necessary to waste your time with the details. Let's just say that it will help clean up my Javascript ALOT.
Because the custom template tag is hidden and really is nothing more than a container that is convenient to call within javascript with document.getElementsByTagName("template"); Is this ok to do? I would probably prefix the tag with a custom name in case template ever gets implemented into html.
Modern browsers generally “support” custom tags in the sense of parsing them and constructing DOM nodes, so that the elements can be styled and processed in scripting.
The main problem is IE prior to IE 9, but it can be handled using document.createElement('...') once for each custom tag name.
Another problem is that validators will report the tags as errors, and if there are loads of such errors, you might not notice some real errors in markup. In principle you can create your own DTD to deal with this (I have an HTML DTD generator under construction, but it is trickier than I expected...).
With these reservations, use custom tags if they essentially simplify your job as compared with using classes.
Why not use one of HTML5's data attributes? They are for storing private data or custom info.
For your case, you could add data-type="template" or data-name="template" and then search and remove based on that. One simple function just like you would write to remove your <template> tag, but without breaking rules.
So, using your example, <div data-type="template" class="hidden"></div>
This is a follow-up question for In jQuery is it a bad idea to use name=X for all selectors?
I am using Backbone and decided that I wanted a way to differentiate between HTML elements that were bound and those that were not.
So I would write (in HAML):
.container
.title(name='title')
.separator
As you can see it's clear that the dynamic element is title.
The reason for this was so I could mess around with the style and rename classes without worrying about breaking the app. It also means in the template I can tell what the dynamic elements are without needing to go back and forth with the Backbone View.
My question now is, without using the [name] selector, does anyone have a code convention to keep track of which HTML elements are referenced from JS.
I have considering:
Using a common prefix on class names (e.g. class=bind-title)
Using some sort of custom HTML element (
Thanks!
FYI: I'm using CoffeeScript, Backbone and haml_coffee templates.
Updated jsperf to test all suggestions:
http://jsperf.com/class-or-name-attr-lookup/3
I would consider using a class to indicate that it is dynamic.
I'm not sure if you are aware of this but you can have multiple classes on one element. Like so:
.container
.dynamic.title(name='title')
.separator
This works in traditional HAML but I have not tried it with haml-coffee. If it doesn't work, you might have to specify the class like .title{:class => "dynamic"}(name='title').
I prefer this over a prefix on the class name because it's more semantically meaningful, which is how HTML should be used.
I am using data-view attribute on elements being set when rendering my Views.
This helps me to then show a tooltip in a browser window when I hover over View(s).