paynestrike
paynestrike

Reputation: 4668

how to create a html element using javascript constructor?

I understand the basic idea of javascript constructor like

function Person(name){
  this.name = name
}

Person.prototype.sayhi = function(){
  return this.name+' says hi !!! '
}
var bob = new Person('bob')
bob.name // bob
bob.sayhi // bob says hi !!!

but lets say if i want to create a Album in real webapp, the server send an array of json data

like:[{'id':1,'album_name':'test','user':'user_id'}]

, each array item should be an album, now i want to construct this album as div element using this array item,how can i do that?

the reason why i want this is that if i can construct an album as real div element,then i can do this

 Album.prototype.open = function(){
    //some action
 }
 album = new Album(jdata)

 album.click(function(){
    this.open()
 })

is this possible , how to define this constructor , i think this may have something to do with constructor return value which really confuse me!!!

Upvotes: 4

Views: 8050

Answers (3)

Spencer Lockhart
Spencer Lockhart

Reputation: 1174

Create some template files with classes matching the object keys, and then cycle through the keys and populate the template file. For example:

function Album (album) {
    this.template = $('#template').clone().removeAttr('id');
    this.album = album;
}

Album.prototype.html = function () {
    var i, val;
    for (i in this.album) {
      if (!this.album.hasOwnProperty(i)) {
        continue;
      }
      val = this.album[i];
      this.template.find("." + i).html(val);
    }
    console.log(this.template);
    return this.template;
}

var foo = new Album({
    title: 'Cheap Thrills',
    artist: 'Frank Zappa',
    genre: 'Rock and Roll'
});

$('#main').html(foo.html());

that's a one-size-fits-all attempt, though it won't really fit all needs. You can set conditions or what-have-you for cases where this solution doesn't fit your needs. For example, if the data is an image url, setting the innerHTML isn't very useful, so you would instead set the 'src' attribute, or create an img tag with an SRC attribute.

A template file might look like this:

<div class="album">
  <div class="user"></div>
  <span class="foo"></span>
  <textarea class="bar"></textarea>
</div>

Here's a quick fiddle: http://jsfiddle.net/bxw7Z/

If you don't like the idea of using classes, try data-attributes instead.

Upvotes: 0

Vadim
Vadim

Reputation: 8789

You can do the following:

var i, data, Albom, albom;

Albom = function Albom(data) {
  var i,
      div = document.createElement('div');

  for(i in data) {
    div.setAttribute('data-'+i, data[i]);
  }

  div.innerHTML = data.album_name;

  for(i in this) {
    if(typeof this[i] === 'function') {
      div[i] = this[i].bind(div);
    } else {
      div[i] = this[i];
    }
  }

  return div;
};

Albom.prototype.open = function open() {
  alert(this.getAttribute('data-id'));
};

data = [
  {'id':1,'album_name':'test1','user':'user_id1'},
  {'id':2,'album_name':'test2','user':'user_id2'}
];

for(i in data) {
  albom = new Albom(data[i]);
  document.body.appendChild(albom);
}

Now new Albom(data) will produce new DOM element that has attributes from provided data object and will have all prototype properties and functions inside created element that will be executed in scope of this DOM element (so you can refer to this inside that methods).

For example you will be able to call albom.open() and an alert with text 2 will pop-up.

Working example you can see at: http://jsbin.com/isepay/10/edit

Upvotes: 3

anuj_io
anuj_io

Reputation: 2173

I think your approach is wrong. You should render the response JSON object using any client side templating engine (For e.g. Handlebars.JS).

Then define constructor & prototype methods like

function album(container){
    this.container=container
}

album.prototype.open=function() {
    container.show();
}

album.prototype.renderHTML=function(jdata) {
 //This is handlebar.js code

 template=$('#albumTemplate').text();
 compiledTemplate=Handlebars.compile(template);
 renderedTemplate=compiledTemplate(jdata);
 container.html(renderedTemplate);
}

Once this is done, you have album class ready & can start using it like this

var container=document.getElementById('myalbum001'),
    album=new album(container);

container.on('click',function(e){
    album.render(jdata);  //You can get jdata by making AJAX call before this line
    album.open()  
}

I will recommend you to quickly take a glance at Handlebar.js

Upvotes: -2

Related Questions