How to create html dynamically using jquery - javascript

I want to create a html page dynamically according to a JSON object and I implemented a method and its working fine my current code is given below
$(function(){
var result =JSON.parse(response);
var markup="";
for (var i=0;i<result.length;i++) {
markup+="<div id='nameDiv'>"+result[i].name+"</div>";
}
$('.divLoadData:last').after(markup);
});
But my actual markup is like this
<div class="divLoadData">
<div class="name" id="nameDiv">
Name
</div>
<div class="numberb">
<div id="age">
Age
</div>
</div>
<div class="numberb dob">
<div id="dob">
DOB
</div>
</div>
</div>
and it will grow eventually so my current method is not capable for creating this kind markup so is there any other way to do the same.

I think jQuery Tmpl (jQuery Template) is what you need.
https://github.com/BorisMoore/jquery-tmpl
You can just setup the template then bind it with JSON data. It will build the html for you.
for simple example
$.tmpl( "<li>${Name}</li>", { "Name" : "John Doe" }).appendTo( "#target" );
suit your case example
var movies = [
{ Name: "The Red Violin", ReleaseYear: "1998" },
{ Name: "Eyes Wide Shut", ReleaseYear: "1999" },
{ Name: "The Inheritance", ReleaseYear: "1976" }
];
var markup = "<li><b>${Name}</b> (${ReleaseYear})</li>";
// Compile the markup as a named template
$.template( "movieTemplate", markup );
// Render the template with the movies data and insert
// the rendered HTML under the "movieList" element
$.tmpl( "movieTemplate", movies )
.appendTo( "#movieList" );
Hope this help.

Related

How to make text content of a reusable navbar included in all pages to reflect

I included a reusuable navbar on multiple pages and it's working fine but when I tried changing the textContent of a word on same navbar, it shows undefined even when i have already declared the variable. What am I not getting right?
I wish to change the span with the id first_name to the name of the data.first_name in the array and I want it to reflect on every page.
$(function() {
$("#nav-placeholder").load("navbar.html");
var first_name = document.getElementById("first_name");
var data = [{
"first_name": "Chibuogwu"
}]
first_name.innerHTML = data.first_name;
});
<div class="content-side content-side-full text-center bg-black-10">
<div class="smini-hide">
<img class="img-avatar" src="assets/media/photos/avatar0.jpg" alt="">
<div class="mt-2 mb-1 font-w600">
<span id="first_name"> User</span></div>
</div>
</div>
When you use jQuery, use jQuery
Also load is async and data is an array
const data = [{
"first_name": "Chibuogwu"
}]
$(function() {
$("#nav-placeholder").load("navbar.html",function() {
$("#first_name").html(data[0].first_name);
});
});
data is an array so it should be accessed first. Please check below:
first_name.innerHTML = data[0].first_name;

Find linked DOM nodes by path with JsViews

Is there an easy way to find DOM nodes in the property path of the linked JS object?
For exmpale I have some object
<script type="text/javascript">
model = {
companyName : "JS Corporation",
address : "",
staff : [
{
name : "Jack Brown",
position : "SW developer"
},
{
name : "John Dow",
position : "Big Boss"
},
{
name: "Billy Hill",
position : ""
}
]
}
</script>
and template
<!-- TEMPLATE -->
<script type="text/x-jsrender" id='companyTamplate'>
<p>company name <input data-link='companyName'></p>
<p>address <input data-link='address'></p>
<fieldset>
<legend>Staff</legend>
{^{for staff}}
<div class='person'>
<p> name <input data-link='name'> </p>
<p> position <input data-link='position'> </p>
</div>
{{/for}}
</fieldset>
</script>
and link them
$.templates('#companyTamplate').link('#companyView',model);
Then I send my object as JSON to a server and get a validation error like this
{
errors : [
{
"path" : "address",
"error" : "empty string"
},
{
"path" : "staff[2].position",
"error" : "empty string"
}
]
}
I want to highlight the input field for address and postion.
For highlighting the address field i can just navigate to
input[data-link=address]
But when I have an error in some array member it's not so evident.
Workaround is to add in input field an attribute with a full path
<input data-link='position' data-link-path='staff[{{:#index}}].position' >
and then navigate to
input[data-link-path="staff[2].position"]
But it's easy to forget add the additional attribute.
Is there a more simple way to solve this problem?
There is not necessarily a one to one mapping from data node to views or DOM nodes. You could have one to none, or one to many (for example if you had two {^{for staff}} tags in your template).
But if you are able to use knowledge of the template structure, then you can navigate the view hierarchy and use APIs such $.view() view.contents() view.childTags() to get from the data back to a chosen element on which you want to act programmatically.
For example in your sample, the following gets the jQuery object for the "Billy Hill" 'position' input:
$.view().get(true, "array").views[2].contents(true, 'input[data-link="position"]')
If you had two {^{for staff}} blocks and you want to navigate to elements in the second block, you can use childTags() APIs to get to the second one:
$.view().childTags("for")[1].tagCtx.contentView.views[2].contents(true, 'input[data-link="position"]')
which again gets you to the "Billy Hill" 'position input'.
See View Hierarchy, $.view() and the various view object and tag object APIs.

Rendering one mustache partial multiple times with different data

I have two objects that I want to render side by side. There is never a case where I will want to render more, or less than two. My model is setup like so:
{
obj1: {...},
obj2: {...}
}
Using mustache templates, I want to render each object using the same partial:
<div>
<h1>Object 1</h1>
{{>objPartial}}
</div>
<div>
<h1>Object 2</h1>
{{>objPartial}}
</div>
However, mustache doesn't seem to support passing a context to the partial. Doing something like {{>objPartial obj1}} seems like it should be supported, but I can't find any documentation on setting a context for a partial.
Is this sort of thing supported? If not, how can I accomplish the same effect without duplicating the partial (objPartial1 and objPartial2)?
The syntax I think you are looking for is not {{>objPartial obj1}}, but rather it should be
{{#obj1}}
{{>objPartial}}
{{/obj1}}
The syntax for {{#}} isn't only for arrays - for non array objects the object becomes part of the current scope.
I've forked maxbeatty's example and modified it to show this syntax:
<script type="template/text" id="partial">
<ul>
{{#name}}
<li>{{.}}</li>
{{/name}}
</ul>
</script>
<script type="template/text" id="main">
<div>
<h1>Stooges</h1>
{{#object1}}
{{>objPartial}}
{{/object1}}
</div>
<div>
<h1>Musketeers</h1>
{{#object2}}
{{>objPartial}}
{{/object2}}
</div>
</script>​
<script type="text/javascript">
var partial = $('#partial').html(),
main = $('#main').html(),
data = {
object1: {
name: ["Curly", "Moe", "Larry"]},
object2: {
name: ["Athos", "Porthos", "Aramis", "D'Artagnan"]}
},
html = Mustache.to_html(main,data, {
"objPartial": partial
});
document.write(html);
</script>
Link to jsfiddle: http://jsfiddle.net/YW5zF/3/
You could adjust your model to include the h1 and div so you could loop over a list sending different data to objPartial each time
<script type="template/text" id="partial">
<ul>
{{#name}}
<li>{{.}}</li>
{{/name}}
</ul>
</script>
<script type="template/text" id="main">
{{#section}}
<div>
<h1>{{title}}</h1>
{{>objPartial}}
</div>
{{/section}}
</script>
<script type="text/javascript">
var partial = $('#partial').html(),
main = $('#main').html(),
data = {
section: [
{
title: "Object 1",
name: ["Curly", "Moe", "Larry"]},
{
title: "Object 2",
name: ["Athos", "Porthos", "Aramis", "D'Artagnan"]}
]
},
html = Mustache.to_html(main,data, {
"objPartial": partial
});
document.write(html);
</script>
See it on jsFiddle

How do I reuse HTML User Interface elements?

I have the following HTML:
<div id="addFieldUI" style="display: none">
<div>
Field Name:
<input type="text" />
</div>
<div>
Field Value
</div>
<div>
Data Type:
<select>
<option>Price</option>
</select>
</div>
I would like to reuse the HTML in at least two other jQuery modals. If I use $('#otherElem').html($('#addFieldUI').html()) to insert the HTML into an HTML element I have the problem of duplicate elements if I use input ids for the fields. Should I rather use input names? Should I use a 'script' code block instead of a div? How do I create reusable HTML?
EDIT
I am aware of jQuery data templates but in this case I just want to reuse HTML within MODAL dialogs. E.g. if I used the same form for creating and editing data.
Something like this, perhaps:
var counter = 0;
$('#otherElem').html(
$('#addFieldUI')
.clone()
.attr('id', 'addFieldUI-' + counter++)
.html()
);
You can use a class name as a hook, and than before appending to the other div use Js to dynamically add IDs
There is a library called jQuery Templates and you can always give that a go, I used often in ASP.NET MVC, but works everywhere.
in Git you have some demos
example:
<script id="movieTemplate" type="text/x-jquery-tmpl">
<li>
<b>${Name}</b> (${ReleaseYear})
</li>
</script>
<ul id="movieList"></ul>
<script type="text/javascript">
var movies = [
{ Name: "The Red Violin", ReleaseYear: "1998" },
{ Name: "Eyes Wide Shut", ReleaseYear: "1999" },
{ Name: "The Inheritance", ReleaseYear: "1976" }
];
$( "#movieTemplate" ).tmpl( movies ).appendTo( "#movieList" );
</script>

Representing a div as a Javascript object?

I want to show a list of various pets on my page. Each pet would linked to a javascript object representing that pet. This is the code for my Pet class:
function Pet()
{
var id, name, var color, var photo;
this.getHtml = function()
{
// Should return the html of a div representing the pet.
return html;
}
this.buy = function()
{
//Find out whether pet is for sale, show a buy form, etc
}
// Snip
}
Using this object, I want to do this:
var cat = new Pet();
cat.id = 1;
cat.name = 'Cat';
cat.color = 'Black';
cat.photo = 'http://example.com/cat.jpg';
var dog = new Pet();
dog.id = 2;
dog.name = 'Dog';
dog.color = 'White';
dog.photo = 'http://example.com/dog400.jpg';
$(document).append(cat.getHtml());
$(document).append(dog.getHtml());
By running this code, I want to get the following two divs to be added to my page:
<div id="pet_1">
Pet name: Cat <br>
Color: Black <br>
<img src='http://example.com/cat.jpg' alt='Cat' /><br>
<input type='button' value='Buy This Pet' onclick = 'cat.Buy()';/>
</div>
<div id="pet_2">
Pet name: Dog <br>
Color: White <br>
<img src='http://example.com/dog400.jpg' alt='Dog' /><br>
<input type='button' value='Buy This Pet' onclick = 'dog.Buy()';/>
</div>
The questions I have are:
1) What's the best way to write the pet.getHtml() function so that it would produce the above output? I would really prefer to not store the html inside a string within my javascript, rather I'd prefer if a template div could be stored outside the javascript somewhere, and each time that div's html is retrieved, the necessary info inserted, and the html code of the new div is returned.
2) Also, certain elements within the new div (such as the buy button) should be linked to the object that produced them, e.g the 'Buy now' buttons of the cat/dog div call the cat.buy(); and dog.buy(); methods when clicked.
How can this be accomplished?
There are two options here. You can either try a full blown client side MVC system for this. Personally I would recommend you look at backbone it's minimalistic and has a very lightweight View with no rendering/ui defaults.
Or write your own micro MVC system.
As for the views you can use a templating engine like EJS or jQuery tmpl.
An EJS view would be
<div id="<%= id %>">
Pet name: <%= name %><br>
Color: <%= color %><br>
<img src='<%= url %>' alt='<%= name %>' /><br>
<input type='button' value='Buy This Pet'/>
</div>
Then your code would look like :
function render() {
var container = container || $("<div></div>").appendTo(parent);
new EJS({url: view_url}).update(container[0], {
id: this.id,
color: this.color,
url: this.url,
name: this.name
});
var that = this;
container.find(":button").click(function() {
that.buy();
});
}
As for jQuery tmpl
<script id="petTemplate" type="text/x-jquery-tmpl">
<div id="${id}">
Pet name: ${name}<br>
Color: ${color}<br>
<img src='${url}' alt='${name}' /><br>
<input class="buy" type='button' value='Buy This Pet'/>
</div>
</script>
function render() {
var that = this;
$( "#petTemplate" ).tmpl( [{
id: this.id,
color: this.color,
url: this.url,
name: this.name
}] ).appendTo( parent ).find(".buy:button").click(function() {
that.buy();
});
}
Take a look at javascript templates. jQuery has a plugin in beta to accomplish this. Here are the docs.
There is a really good library called Pure that lets you integrate templates into a bunch of javascript frameworks.
Of course there are lots of docs on the subject on Google

Categories