bindings to style attributes

135 views
Skip to first unread message

gsb

unread,
May 15, 2012, 11:52:51 AM5/15/12
to agil...@googlegroups.com
Well, my last question was not interesting enough to rate an answer; maybe this one will fair better.

I have a need, or so I think, to bind model data to the corresponding item's view 'style.'  Like setting the HTML elements background based on a model's data for a image url.

What might the least complicated approach to accomplish this binding?

Greg

Tom Lackner

unread,
May 15, 2012, 12:07:07 PM5/15/12
to agil...@googlegroups.com
Hey Greg,

I don't believe there's a way to update an element's style properties
via the bindings syntax. What would probably be easiest would to be
listen for changes to your model and then use jquery's .css() stuff to
make the changes you need.

Here's how you listen for changes on the model:

http://agilityjs.com/docs/docs.html#events-agility

t
--
Thomas Lackner * 305-978-8525

gsb

unread,
May 15, 2012, 12:39:14 PM5/15/12
to agil...@googlegroups.com
@Thomas Lackner, thanks.

Yes.  I am familiar with that approach, and it may well be the best that we can do just now.
I shall continue exploring and in the meantime, another member may yet post another idea.

Thanks again.

Greg

Tom Lackner

unread,
May 15, 2012, 1:07:06 PM5/15/12
to agil...@googlegroups.com
You could extend the data binding syntax pretty easily if you really
want to. You'd just have to invent your own way to format the
declarations (like .background-color=person_color). The code that
handles this is really easy to follow. Check it out here:

https://github.com/arturadib/agility/blob/master/agility.js#L441

gsb

unread,
May 15, 2012, 4:38:21 PM5/15/12
to agil...@googlegroups.com
Again, thank you Thomas.

This too I have reviewed.  I am quite familiar with the agility.js code now.  I suggest that this is a must to anyone that would use agility in a project.  I decided to avoid that option for now to insure compatibility with future releases.  And in hopes that the developers may one day provide a better and more integrated method.

Instead I opt'ed to modify my data 'persists' adapter which is a off site ajax call.  I do some post processing to generate a 'in-line styles' field that I put into a new model field, 'style.'  It is based on  1)  model data returned in a successful ajax call and  2)  a 'template' added into the 'view' as a new field - in addition to 'format' and 'style'.  This is an in-line style formatted string and saved in a new 'model' field.  I use a simple utility function to process the template and data which is based on John Resig's micro-templateting.  Simple enough.

Now I can simply bind (agility's internal one-way attribute binding) in the view's format as usual.

Pors:  Does the job in an agailiy'istic manner using simple attribute binding.  Also, keeps compatibility with future agility releases.

Cons:  Moved some data processing out of the standard controller and into the "ajax specific adapter" - although it is a specialized call to start with.

For now, this seems a valid compromise.

Thanks again.  ...comments welcome.

Greg

Mark Gidman

unread,
May 15, 2012, 5:33:02 PM5/15/12
to Agility.js
This might be slightly off topic but I guess I don't understand why so
much inline styling is done with agility. Why doesn't it make more
use of classes? To me, I would never want to bind style attributes to
data. I would always want to add/remove a css class instead.

Overall, agility is the most sensible and clean javascript MVC
framework I have seen. So far, I love it. This is one of the few
parts that I don't understand the reasoning behind it yet.

gsb

unread,
May 15, 2012, 5:58:11 PM5/15/12
to agil...@googlegroups.com
Hi Mark.  No, not really off subject I think.

And I agree:  I am loving agility.js as well - small, clean and focused.

And I do not see a lot of others wanting to use inline styles; I do not really like it either.  But in this case, the ajax call brings data including "background" images and sizes that are to become list item backgrounds.  Somehow the list item styles need to dynamically change based on the retrieved data set.  Using a simple inline style for each item seemed a reasonable way to go.

Otherwise I would need to make a new class for each line item, assign it to the correct line item and finally remove the class when the line item is destroyed or replaced. Or I might have hundreds of dynamically created classes, unused anymore, simply hanging around.

The image alone is insufficient since it alone can not dynamically define the line item's height.  So I additionally use the height data (also in the ajax call) to determine the display height.

Well Mark, I am wide open to suggestions.  But I am new to much of this and am limited by my own experience. 

Thanks again,

Mark Gidman

unread,
May 15, 2012, 7:17:59 PM5/15/12
to Agility.js
Interesting. So, in your scenario will the styling for each list item
be unique throughout the application? Or, would there be a relatively
limited set of combinations?

If there a limited set of options then a combination of css classes
and sprites might be the best option. This is typical of how many of
the other libraries handle things. From a performance perspective its
very efficient as the browser will cache the sprite between pages/
visits and most modern browser are pretty quick with css changes.
From a maintenance perspective this allows you to update the styling
of your app without risk of accidentally introducing bugs to the
javascript.

To see how a css class based approach might work you can look at
either jQueryUI or Sencha's ExtJs (more complex).

gsb

unread,
May 15, 2012, 7:58:22 PM5/15/12
to agil...@googlegroups.com
Yes Mark, "... in your scenario will the styling for each list item 
be unique throughout the application?"  The background of each line-item "<ul><li>..." is a random image from flickr.  The image itself and it's height are both unknown until the ajax returns successfully.  The height is used to set the height of the corresponding 'li' tag.

I am quite used to using CSS classes and avoid mixing HTML structure with CSS "look-and-feel."  However, in this case, Agility.js seems to lead me to this as a "reasonable" solution.  

Please Mark.  Do not misunderstand me.  I am open to suggestions.  I just do not see how traditional CSS classing, as I understand and use it, would be successfully implemented.  With the content and styling data virtually one in the same, similar data handling seemed natural.

Thanks for your interest and comments.  We seem to agree on most things.
Your further suggestions and examples are truly welcomed.

Greg


.

Mark Gidman

unread,
May 15, 2012, 8:30:49 PM5/15/12
to Agility.js
Yup - I agree with your assessment. In your situation classes is
probably not a good solution. Inline styles make the most sense.

I guess the only other idea I would have would be to send the whole li
back from the server and just swap out the view html. I'm not far
enough into Agility yet to know if this is a bad idea or not.

Good luck with your problem, seems like an interesting one.

- Mark

gsb

unread,
May 15, 2012, 9:04:12 PM5/15/12
to agil...@googlegroups.com
Again Mark.  I appreciate your time and comments.
I too am learning where and how to best use agility.
As you have said, it is an interesting framework.

Greg

Artur Adib

unread,
May 16, 2012, 9:41:34 AM5/16/12
to agil...@googlegroups.com
Hey guys, I like the idea of making Agility's styling more
class-oriented. Do you guys have a simple proposal? (examples of usage
welcome! :))

Also I'd love to see a simple reduced case/snippet that illustrates
the need -- it's been a while since I've thought about the overall
design and necessities of Agility.

Thanks, please keep up the discussion.

--
Artur Adib
http://twitter.com/arturadib

gsb

unread,
May 16, 2012, 12:17:34 PM5/16/12
to agil...@googlegroups.com

Hi Artur,

I started this issue I think so let me propose a simple solution.  Welll the problem as I see it first:

$$([prototype,] [{
  model: {...},
  view: {
      format: {...},
      style: {...}
    },
  controller: {...},
  user_defined_property: {...}
}])

This format builds a common class out of 'style' for each instance attached like: class="agility_3"

I needed each instance to have its own unique data driven styles - background image say.

So my solution was to add another field to the view element:

  view: {
           format: {...},
           inline: {...},
           style: {...}
  },

Upon instantiation, the in-line [styles] template is evaluated using the model's data to build an appropriate "in-line style" for the current item.

Mark's discussion with me seemed to center around using another global class instead of in-line styles.  That would be great - separation speaking, but would require the removal of said class upon removal of the view.  Doable, but better done as a part of agility I think.

So for now, in order to stay compatible with current and future agility releases, I am using in-line styles per item instance as well as the agility generated class styles for the entire collection, knowing that upon removal, there is no more clean up required;  no classes to remove.

I hope that helps.  Tonight I can try to make a small use case as embarassing as my code may be. 

Greg




On Wednesday, May 16, 2012 9:41:34 AM UTC-4, Artur wrote:
Hey guys, I like the idea of making Agility's styling more
class-oriented. Do you guys have a simple proposal? (examples of usage
welcome! :))

Also I'd love to see a simple reduced case/snippet that illustrates
the need -- it's been a while since I've thought about the overall
design and necessities of Agility.

Thanks, please keep up the discussion.

--
Artur Adib
http://twitter.com/arturadib


On Tue, May 15, 2012 at 5:30 PM, Mark Gidmanwrote:

Tom Lackner

unread,
May 16, 2012, 1:04:27 PM5/16/12
to agil...@googlegroups.com
Perhaps it would be better to simply allow a variant data-bind syntax
inside the style string?

var clock = $$({
model: {
time: '12:00:00'
},
view: {
format: '<span data-bind="time"/>',
style: '& { color:white; background:data-bind(background);
padding:4px 8px; }'
}
});
$$.document.append(clock);


t

gsb

unread,
May 16, 2012, 1:10:27 PM5/16/12
to agil...@googlegroups.com
Yes.  That would be sweet I think!  

greg



On Wednesday, May 16, 2012 1:04:27 PM UTC-4, Thomas Lackner wrote:
Perhaps it would be better to simply allow a variant data-bind syntax
inside the style string?

var clock = $$({
  model: {
    time: '12:00:00'
  },
  view: {
    format: '<span data-bind="time"/>',
    style: '& { color:white; background:data-bind(background);
padding:4px 8px; }'
  }
 });
$$.document.append(clock);


t

Tom Lackner

unread,
May 16, 2012, 1:20:08 PM5/16/12
to agil...@googlegroups.com
Actually, the more I think about it, perhaps we should clone Less'
syntax and use something like:

style: '& { color:white; background:@background; padding:4px 8px; }'

This is handy because it's simple to parse - @ doesn't do much in CSS
as it is so a regex should work. See here:

http://lesscss.org/

Mark Gidman

unread,
May 16, 2012, 1:39:31 PM5/16/12
to Agility.js
Greg's use case is more complicated that what I typically need. I
think Tom's solution would work quite well for it.

As for me, I would just like to be able use databinding to add/remove
externally defined css classes (not the agility_x ones).
> ...
>
> read more »

Artur Adib

unread,
May 17, 2012, 7:08:39 PM5/17/12
to agil...@googlegroups.com
On Wed, May 16, 2012 at 1:39 PM, Mark Gidman <crave...@gmail.com> wrote:
> I would just like to be able use databinding to add/remove
> externally defined css classes (not the agility_x ones).

I agree, and I think that focusing on external classes is more robust
than enriching inline styling, which can quickly become very complex.

The question remains though- What is the simplest/most elegant
solution for binding CSS classes to models?

Tom Lackner

unread,
May 17, 2012, 7:14:24 PM5/17/12
to agil...@googlegroups.com
Can't you already use data-bind to set an element's class attribute? 

Also, how would you use external classes to set an element's background-image to a user's avatar photo from a Rest API? Just an example, but things like that are a common use case..

J. David Beutel

unread,
May 17, 2012, 7:57:05 PM5/17/12
to agil...@googlegroups.com
I'd like a way for Agility to add or remove a class (e.g., "error") from a static set of base classes on the HTML.  Unfortunately, data-bind is all or nothing.

Mark Gidman

unread,
May 17, 2012, 9:10:30 PM5/17/12
to Agility.js
I'm not sure how you would data-bind an element's class attribute
right now. (again, still learning Agility)  The closest thing I can
see would be to use a method similar to this snippet from the docs:
  var icon = $$({path:url}, '<p>Image src from model: <img data-
bind="src=path"/></p>');
I suppose this would work if you wanted to replace the entire
attribute value.  Typically though you probably only want to add/
remove one or two classes rather than all of them.

I think what I would be looking for is the ability to associate a call
to toggleClass() with changes to the data.  Consider the use case of a
multiple choice question with an "other" answer.  You may want to use
a radio group with options A, B, C and Other.  Along with this you
might have a textbox to allow the user to enter their "other" answer.
 By default you may have a .hidden class assigned to this textbox.  If
the user selects the Other radio option, you would want to toggle that
class off the textbox. If they change their mind and then click A, B,
or C then you would want to toggle the class back on the textbox so it
hides again.

This behavior is seems like its already possible with agility just by
attaching a handler to the change event, evaluating the data and
executing toggleClass on the proper element.  A little bit more
sophisticated, but maybe more logical approach would be to have user
defined properties that react to changes in the model and then adjust
the styling based on changes to those properties.  In the use case
above, we might have a boolean isOther property that watches for model
changes.  Then we would toggle the .hidden class based on whether
isOther is true or false.  This might be more complicated than
necessary, but it would allow for more advanced rules on the data-
binding.

As for the avatar example, I wouldn't want to use css classes at all.
 I would prefer to databind the background image url in an inline
style.

In general, I can see the reasoning behind agility dynamically
creating css classes from the style definitions but this is not a
feature I see myself using much.  If I'm going to adjust something in
the look and feel that's highly specific to an instance of an object
then inline styling is probably ok.



On May 17, 6:14 pm, Tom Lackner <lack...@gmail.com> wrote:
> Can't you already use data-bind to set an element's class attribute?
>
> Also, how would you use external classes to set an element's
> background-image to a user's avatar photo from a Rest API? Just an example,
> but things like that are a common use case..
>
>
>
>
>
>
>
> On Thu, May 17, 2012 at 7:08 PM, Artur Adib <artura...@gmail.com> wrote:
> ...
>
> read more »

Mark Gidman

unread,
May 17, 2012, 9:11:59 PM5/17/12
to Agility.js
Agreed

Artur Adib

unread,
May 17, 2012, 9:54:41 PM5/17/12
to agil...@googlegroups.com
On Thu, May 17, 2012 at 7:57 PM, J. David Beutel <jdbe...@gmail.com> wrote:
> I'd like a way for Agility to add or remove a class (e.g., "error") from a
> static set of base classes on the HTML.  Unfortunately, data-bind is all or
> nothing.


I agree too. I'm all ears for ideas...

gsb

unread,
May 17, 2012, 11:07:18 PM5/17/12
to agil...@googlegroups.com
"...specific to an instance of an object then inline styling is probably ok..."
I agree.  I liked the "less" examples.

Greg

Mark Gidman

unread,
May 17, 2012, 11:16:34 PM5/17/12
to Agility.js
"..all ears for ideas..."


Here's an idea. Consider this as a sample view definition:

view: {
...
css: [{
'required': function(){
return (data.something > 0) ? true : false;
}
},{
'error': function(){
return (this.customProperty) ? true : false;
}
}],
...
}

The intended behavior would be that a css class named "required" would
be applied to the root whenever data.something was greater than zero.

Css class "error" would be applied whenever this.customProperty was
true and removed when it wasn't.

Thoughts?


On May 17, 10:07 pm, gsb <G...@GypsyTrader.com> wrote:
> "...specific to an instance of an object then inline styling is probably
> ok..."
> I agree.  I liked the "less" examples.
>
> Greg
>
>
>
>
>
>
>
> On Thursday, May 17, 2012 9:54:41 PM UTC-4, Artur wrote:
>
> > On Thu, May 17, 2012 at 7:57 PM, J. David Beutel <jdbeu...@gmail.com>

Colin McCormack

unread,
May 18, 2012, 1:15:02 AM5/18/12
to agil...@googlegroups.com
Why not extend the data-bind little language so you could have style+=something, where the += is interpreted as 'append' where = is interpreted as 'replace'?  Should be pretty simple, the parser's in agility.js, it can't be *that* complex.

gsb

unread,
May 18, 2012, 9:02:15 AM5/18/12
to agil...@googlegroups.com
@Mark

I think that your example is a bit much to push into the framework.
In fact, that is exactly what the 'change' event is all about, IMHO.

Myself, I am more concerned with taking the model instance data and binding it to the associated view instance.  That would be a great start I think.  Complex logic need not be imbedded into the binding mechanism itself, but rather, is better served in the controller.

Greg

Mark Gidman

unread,
May 18, 2012, 9:13:56 AM5/18/12
to Agility.js
> I think that your example is a bit much to push into the framework.
I can see your point and don't necessarily disagree. It really
depends on what the vision for the framework is. Either way, its not
a showstopper for me. I was just throwing out an option to generate
more discussion. The more we talk, the more Artur gets a feel for
what people want/need/prefer.

gsb

unread,
May 18, 2012, 12:24:24 PM5/18/12
to agil...@googlegroups.com
Great!

As someone else put it, "brilliantly simple" - words to set the goals by, I think.  One of the best features is the binding mechanism and this conversation is sure to aid him in that arena.

Second is the encapsulation and the reusability of Agility objects as independent UI objects.  This can only be enhanced with a "clean and clear path" to redefinition of the $root element on a per-object basis.  That simply enhances Agility's integration with other frameworks and existing projects.

And size: Agility certainly fits into the 'micro-lib' category if not the 'nano' in fact.
Light weight and powerful; focused and easy to learn and use - just what developers are always looking for, IMHO.

Add in the jQuery dependency for it's proven cross-mobile and cross-browser capabilities and Agility will fit into all but a very few developers' tool box as a go-to framework for client-side development.

Proof of stability, good documentation with lots of examples and super support are icing on the cake.

The bumper sticker:  "Agility Rules"  ... well maybe I get carried away sometimes

Greg

defl...@gmail.com

unread,
May 11, 2013, 5:51:59 AM5/11/13
to agil...@googlegroups.com

Hello, i now writing my first app with Agility.js and like this framework very much, thanks to the authors.

Currently i guess the biggest demand in my development is actually 'data-bind', now it is only binds to strings if i got it right.
So here is example snippet:

$$({ name: 'Joe' }, '<div data-bind="name"></div>'); // this will result in <div>Joe</div>

but then i wish to use not only string values in model, but also arrays and objects, here is how it works currently:

$$({ name: ['Joe', 'Paul'] }, '<div data-bind="name"></div>'); // this will result in <div>Joe,Paul</div>
$$({ name: { first: 'Joe' } }, '<div data-bind="name"></div>'); // this will result in <div>[object Object]</div>

I guess the both above examples actually produce substantially useless result.

The more obvious result in my opinion should be something like:

$$({ name: ['Joe', 'Paul'] }, '<div data-bind="name"></div>'); // this could result in <div>Joe</div><div>Paul</div>
$$({ name: { first: 'Joe', class: 'Test' } }, '<div data-bind="name"></div>'); // this could result in <div first="Joe" class="test"></div>

And the second case allows us in a mesaure solve topic problem:

$$({ style: { style: "color: red; background: black" } }, '<div data-bind="style"></div>'); // this could result in <div style="color: red; background: black"></div>

вторник, 15 мая 2012 г., 19:52:51 UTC+4 пользователь gsb написал:
Well, my last question was not interesting enough to rate an answer; maybe this one will fair better.

I have a need, or so I think, to bind model data to the corresponding item's view 'style.'  Like setting the HTML elements background based on a model's data for a image url.

What might the least complicated approach to accomplish this binding?

Greg

דוד לוי

unread,
May 17, 2013, 8:22:53 AM5/17/13
to agil...@googlegroups.com
Hi
I'm looking too for an answer but my target is OPTION of SELECT box which has a value attribute and inner text did you find a solution?
Reply all
Reply to author
Forward
0 new messages