tmpvar / weld

Template antimatter for Node.js (Browsers too!)
674 stars 39 forks source link

Is there an easy way to populate element's attribute? #19

Open anton-107 opened 13 years ago

anton-107 commented 13 years ago

It would be nice, if the front page contained example of how to populate template's attribute elements.

The most common example would be "href" attribute of a link - it's likely to be dependent on data. How can i bind data to this attribute?

framlin commented 13 years ago

Yes, indeed, I am looking for howto set a.href, too ....

mjudd commented 13 years ago

me three

heapwolf commented 13 years ago

there is an example on the front page, but i think you are right it could be more obvious, thanks for pointing this out! using the map option as a parameter to weld() is a good way to augment elements, or (conditionally based on a key or value) for instance...

    map: function(parent, element, key, val) { 
      element.setAttribute('href', '/foo');
    }

let me know if this helps!

ironchefpython commented 13 years ago

I've added a feature to my branch of weld that updates the href of anchors by default. You're more than welcome to try it.

http://github.com/ironchefpython/weld

aviflax commented 13 years ago

@hij1nx, I had to get @tmpvar to help me figure this out… I think we need to add more direct support for attributes to the API.

I really don't want to have to use this much boilerplate just to set an attribute value:

    var config = {
        map: function(parent, element, key, value) {
            if (key === 'id') {
                element.setAttribute('href', value);
                return true;
            }
        }
    }

what if we could do something like:

var config = {
    aliasAttr: {
        'id': {'href': 'id'}
    }

or maybe we could just add another case to alias, wherein if a value is an object, then it's understood to be a mapping of attribute names to datum names for that element.

So maybe something like:

var config = {
    alias: {
        'foo': 'bar',
        'id': {'href': 'id'}
    }
}
ironchefpython commented 13 years ago

@aviflax I put together some ideas for idioms for updating attributes without having to supply a config parameter here: https://gist.github.com/1056720

Your thoughts?

I think having anchor elements update the href attribute by default just makes sense, and I'd like to have a to update the attributes on arbitrary elements through a syntax like #4 on that list.

Or if the alias property of the config element seems cleanest, I could put together a patch for that next week. I have a projects coming up that I hope to make heavy use of weld.

tmpvar commented 13 years ago

Couple ideas:

  1. push the if statement into weld and provide a function to handle the attribute manipulation
var config = {
  map : {
    id : function(parent, el, k, v) {
      el.setAttribute('href', v);
    }
  }
}

If we build on that and you were to wrap your attributes in an object:

markup

<ul>
 <li class="bookmark">
  <a class="link"></a>
  <p class="description"></p>
 </li>
</ul>

data

var data = {
  bookmark : [{
    link : {
      url  : 'http://tmpvar.com',
      text : "tmpvar's rawkin homepage"
    }
  }]  
};

weld

weld(ul, data, {
  map : {
    link : function(parent, el, k, v) {

      // manually update the element (anything is possible!)
      el.href = v.url;
      el.textContent = v.text;

      // stop traversing this branch
      return false;
    }
  }
});

note: currently (weld 0.2.0), when link is matched it does not call map, it would have to for this to work as expected.

What do you think?

amiel commented 13 years ago

I am also interested in a way to set attributes. So far +1 for @tmpvar's idea.

morganrallen commented 12 years ago

Is there any opposition to an @ style attribute selector? My thinking is weld could do something like this.

{
 'avatar': {
   '@src': "/avatar.png"
 }
}

would turn

into <img class="avatar" src="/avatar.png" />

I have this working with only a couple lines of code but there are some other cases to consider too, preserving the existing contents for things like class (what if you wanted "avatar highlighted" but the class started as "avatar current" for example) or style.

Updating content would also be possible with something like this

{
 'name': [
  {
   '@class': "current-user"
  },
  'User Name'
 ]
}

I have not quite sorted this portion out yet.

OpenGrid commented 12 years ago

The most intuitive option for me would be to use selectors:

alias : {
  'id' : '[data-id]',
  'href' : 'key[href]'
}
coolaj86 commented 11 years ago

PureJS handles this really well:

http://beebole.com/pure/documentation/rendering-with-directives/

https://github.com/pure/pure

The reason that I was investigating weld is that I like the simpler syntax. But not handling attributes simply is kinda a bummer.

heapwolf commented 11 years ago

try plates, github.com/flatiron/plates