GithubHelp home page GithubHelp logo

nytimes / backbone.stickit Goto Github PK

View Code? Open in Web Editor NEW
1.6K 1.6K 177.0 1.15 MB

Backbone data binding, model binding plugin. The real logic-less templates.

License: MIT License

JavaScript 94.55% HTML 5.45%

backbone.stickit's People

Contributors

akre54 avatar andriijas avatar arjenw avatar bazineta avatar bregenspan avatar buzzedword avatar caleb avatar chodge avatar costa avatar danteoh avatar davidfou avatar delambo avatar fabriziofortino avatar hlindset avatar jaysoo avatar jeremywadsack avatar joeblynch avatar johanneszorn avatar kidkarolis avatar masterlambaster avatar megawac avatar noobiek avatar raganw avatar rwhitmire avatar sixdayz avatar trabianmatt avatar underbluewaters avatar viczam avatar yamsellem avatar yousefcisco avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

backbone.stickit's Issues

Add an example with short form binding in "Usage"

Hi and thanks for stickit !

When I first was linked this plugin (thanks @mehcode) I read through the doc fastly and I must admit I didn't notice at first the short form.
I think this is interesting to have in the "Usage" section, to directly show stickit's powerfulness/usefulness/clarity/brevity/blahy.

updateViewBindEl not playing nicely with backbone-nested

Hi there,

First off - great app! Love simply reading the code that is in stickit.

I am using https://github.com/afeld/backbone-nested with stickit and I've run into a small issue. It's probably not a problem of your library, but I was hoping for a solution. So, example:

 var Profile = Backbone.Model.extend({
      defaults: {
          name: { legal_first_name: 'John', legal_last_name: 'Carmack'},
          email: '[email protected]'
      }
 });

 var ProfileView = Backbone.View.extend({
       bindings: {
           '#first_name': 'name.legal_first_name',
           '#last_name': 'name.legal_last_name'
       }

       render: function() {
             this.stickit();
       }
 });

When I begin using this view with a rendered form template, here's what happens:

  • All fields are rendered correctly initially.

  • When I try to modify #first_name, by adding an "a" to the end of "John", updateViewBindEl is called, and contains the following context

    val: "John"
    originalVal: "Johna"

Eventually, val hits this line:

 else if (isContenteditable($el)) $el.html(val);

And updates the textbox back to "John", replacing what the user just typed.

However!

When I edit email, updateViewBindEl is never called, and the model is updated and nothing wonky happens in the textbox.. I don't truly understand what's going on, as I quickly took a debugger to the stickit code and it seems everything, including email is bound just the same.

Any help would be much appreciated, thanks again :)

bindings seem to be un-sticking

// Backbone.js 0.9.2
// backbone.stickit v0.5.2

seeing an issue where bindings between attributes and DOM seem to stop working in both directions after the first @model.save is called.

not sure where to start looking to troubleshoot.

thoughts?

Change event firing too soon in set function

This might be a problem just for me, but I thought I'd report it anyways.

In the wrapping of the set function, the Backbone.model.set() call comes before the attributes are iterated though and have a bind event triggered on each of them:

// Delegating to Backbone's model.set().
ret = oldSet.call(this, attrs, options);

// Iterate through the attributes that were just set.
.each(.keys(attrs || {}), .bind(function(attr) {
// Trigger a custom "bind" event for each attribute that has changed, unless {bind:false} option.
if (( !
.isEqual(now[attr], val) || (options.unset && _.has(now, attr))))
this.trigger('bind:' + attr, attrs[attr], options);
}, this));

If the view is listening to a change event on the model to render, and the render function calls this.stickit(), the bindings end up being applied twice. Moving the call to the Backbone.model.set() to after the bind events are triggered seems to fix this:

// Iterate through the attributes that were just set.
.each(.keys(attrs || {}), .bind(function(attr) {
// Trigger a custom "bind" event for each attribute that has changed, unless {bind:false} option.
if (( !
.isEqual(now[attr], val) || (options.unset && _.has(now, attr))))
this.trigger('bind:' + attr, attrs[attr], options);
}, this));

// Delegating to Backbone's model.set().
ret = oldSet.call(this, attrs, options);

Bindings hash targets only elements of same type

The bindings hash currently assumes that the view selector targets only elements of the same type.

For instance:

<input type="range" data-bind="myAttribute">
<span data-bind="myAttribute">

wouldn't work correctly/expectedly with:

bindings: {
    [data-bind="myAttribute"]': 'myAttribute'
},

but instead could be worked around with e.g.:

bindings: {
    input[data-bind="myAttribute"]': 'myAttribute',
    span[data-bind="myAttribute"]': 'myAttribute'
},

Just fiddled around with the code, and it would require some refactoring. E.g. make sure other view elements within same selector get updated; just iterating over $el (in updateViewBindEl) needs some extra work re. checkboxes, etc.

Please let me know if

  • I'm missing something,
  • you'd prefer a PR to make it happen,
  • you'd like to leave it as it is, but make the docs a bit more clear.

Can selectOptions collection be made to hang off this.model or optionalModel also in addition to window?

The question basically says it all - and the docs are pretty clear about the current options (pun not intended), but if I'm in an app that has pulled in the relevant collection to be displayed as a select dropdown, it seems a rather frequent use case to have that collection data be around the same model that I'm binding to in my view. Why the requirement and inflexibility to hang this off 'window' only (or as a String, I get it...)? Is there a good design reason, is it just easier for the framework to deal with, or?

What I'm finding to work for us is to right before calling 'this.stickit(..,..) to put the collection on the window. And then point to it in selectOptions. We do this because we feed our models into our template rendering, as they are smart enough to know how to render the collection. I get that the desire is for stickit to do that rendering, and to keep templates uber simple, but it seems like flexibility could be provided by the framework here with minor code changes. But I could be (am?) wrong. Thoughts?

Add Handlers

This is a continuation of the work that was started in #55. Big thanks to @trabianmatt for starting and inspiring this. I started a handlers branch where hopefully a few more passes can produce a final implementation.

The basic idea is to add an interface to extend or override stickit with custom handling. To achieve this, I created a Backbone.Stickit.addHandler namespace and added update and getVal to the bindings configuration. A handler is a binding configuration with an extra selector key. The selector is used to match against a bound view element and will be mixed in with other matching handlers in the order that they were added to derive a binding configuration, starting with the view bindings at the top of the mixin chain. For example, Stickit's default handler for textarea looks like the following:

Backbone.Stickit.addHandler({
  selector: 'textarea',
  events: ['keyup', 'change', 'paste', 'cut'],
  update: function($el, val) { $el.val(val); },
  getVal: function($el) { return $el.val(); }
});

A user could choose to override all or a subset of the keys in the default handler by adding a new handler with a selector:'textarea', or by adding a more selective selector that matches against a class when binding, like the following:

Backbone.Stickit.addHandler({
  selector: 'textarea.trimmed',
  update: function($el, val) { $el.val($.trim(val)); }
});

With those handlers in place, a user can override any or all handling in a binding configuration. Most of this complexity will be hidden from the user, as the default functionality of Stickit won't be changing, but it gives users a lot of flexibility to customize, like in #64 (which we may still add into core) or all the requests to add to/change select handling.

You can checkout the default handlers here.

Any thoughts on this implementation, naming, ...?

CC'ing @andriijas, @mehcode, and @trabianmatt - would love to hear your opinions if you have time.

visibleFn not executing on model change

Hi,

Is the visibleFn supposed to be run on model change events to observed attributes? I have the following binding in my application and the onGet function is run every time either of the model attributes being observed is changed but the visibleFn only runs on the initial stickit call.

'#ModifiedInfo': {
    observe: ['ModifiedByUser', 'ModifiedDate'],
    visible: function (values) {
        if (values && values.length && values[0]) {
            return true;
        }
        else {
            return false;
        }
    },
    visibleFn: function ($el, isVisible, options) {
        if (!isVisible) {
            $el.parent().hide();
        }
    },
    onGet: function (values) {
        if (values && values.length && values[0]) {
            var dt = app.utilities.formatDate(values[1], "M/d/yyyy");
            return values[0].FirstName + ' ' + values[0].LastName + ', ' + dt;
        }
    }
}

Expected post-change event callbacks not happening due to bindKey constraint

We're having some issues/confusion surrounding this block of stickit code:

// Setup a change:modelAttr observer to keep the view element in sync.
// modelAttr may be an array of attributes or a single string value.
.each(.flatten([modelAttr]), function(attr) {
observeModelEvent(model, self, 'change:'+attr, function(model, val, options) {
if (options == null || options.bindKey != bindKey)
updateViewBindEl(self, $el, config, getVal(model, modelAttr, config, self), model);
});
});

What we are seeing is that if we update a DOM element that is bound to a model attribute, we do not see callbacks for the binding definition - such as 'onGet' and 'afterUpdate' invoked. Instead, DOM elements that were not modified in the UI are called. You can see this on display in the following crude JSfiddle:

http://jsfiddle.net/zlendon/USjpy/

Where the 'other' callbacks are getting logged to the console, but the input's (that were changed by the user) callbacks are not getting called. This all becomes an issue when one leverages 'onSet' to modify the user's entered value before it gets saved in the model. Because we don't get any callback after the model's change event, we are seemingly missing a hook to go back and update the DOM element. I can somewhat understand the argument that we don't want to "surprise" the user by changing a value from underneath them, but I can give you an example use-case where we auto-format a user's entered date, adding dashes (or slashes) when the input has reached the appropriate length. We want to store this formatted value both on the model and update the UI. Because of the 'bindKey' constraint, we seem to be missing out on the potential two-binding that would occur to allow updating of the UI. Additionally, while I'm not sure if the 'bindKey' value matching option.bindKey is also at fault for afterUpdate/onGet/etal callbacks as well, it certainly seems limiting to not be allowing any callback on the DOM element that changed (but on others instead).

We'd be very interested to hear if there is a reason for this behavior and what the strategies to employ instead would be. Or if it is a bug that we could help out with we would be happy to submit a pull request as well.

Thanks for all your work to help make this a great project.

thanks,
Zach

Support configurable event bindings

Currently, stickit binds form elements with keydown and change events and doesn't provide a callback or a way to configure custom event options. Since it has been requested and I want stickit to be flexible, I would like to get some feedback/help on planning for custom event bindings. If added, I would like to include the following criteria:

  • Keep the default event handling in place so bindings can work with minimal configuration, and make any custom event configuration an override.
  • Delegate off of Backbone's events object, so the following events can be supported: keydown, keyup, keypress, mousedown, mouseup, click, doubleclick, mousemove,
    focusin, focusout, mouseenter, mouseleave, submit, change
  • Support multiple events/callbacks for one bound element.
  • Possibly handle events for non-form elements.
  • Possible callback parameters:
    • the wrapped event object ($event)
    • the bound element value
    • the current model value
    • the wrapped bound element ($el)
    • the name of the model attribute bound to the element

An idea for configuration:

bindings: {
  '#header': {
    modelAttr: 'header',
    keyup: 'keyupHandler',
    click: 'clickHandler'
  }
}

If implemented, I think that the setOptions could possibly be deprecated from the API since the user can take control of managing events and setting the model when needed.

Thoughts?

One way bindings

Would be nice if there was a way that you could have model->dom only binding.

I've got a case where the DOM representation technically is changing which causes stickit to re-render (undesirably) even though there wasn't a model change event.

First try at adding button support

Hi

I need help with this one, if you want button support that is :)

https://github.com/andriijas/backbone.stickit/tree/buttons

The test cases I added fail, which implies there is more work to do on my changes.

For test case 1 single buttons I dont know whats wrong - the options.bindKey != bindKey check fail

For test case 2 multiple buttons I think it has to do with #62, the value of the first button is used, not the clicked one.

Thanks

Add a createDefaultBindings method

I've been, thus far, using Backbone.ModelBinder as my model binding library of choice, but that's only because I've only just stumbled onto this project. I have to say, I modified ModelBinder extensively to add features I needed, but I wish I had found your project earlier, because it already includes all of the features I added to ModelBinder.

There is, however, one convenience method in Backbone.ModelBinder that I use heavily in my projects, and that's Backbone.ModelBinder.createDefaultBindings. You can see from the comments at that link what it's supposed to do, but essentially you can pass it a DOM element (the root el from which to scan), an attribute type (usually name or ID), an optional universal converter method (like a combo version of onGet/onSet), and an optional elAttribute parameter (that specifies which element attribute you'd like the binding to act on). It scans the DOM, starting at the specified root $el, for any elements with the specified attribute, creating a binding object for each one, applying the converter/elAttribute if supplied, and returns the resulting bindings hash. You can then modify/merge/extend it with custom bindings and/or overrides before actually calling modelbinder.bind(finalBindings);

It comes in really handy when a majority of the bindings on a given view are simple "keep this field value updated" style bindings - you can just call the method to auto-create a bindings object for the majority of the elements in a view, then add or modify any non-standard bindings before bind is called. It really helps cut down on the amount of code necessary in a LOT of cases.

Reasoning behind allowing event registration

First I'd like to say that the library looks great. Good job. 👍

Just a minor question that came to mind as I was browsing through the documentation / code.

What is the reasoning behind allowing event registration like click in the bindings hash when the events hash already does this?

Binding Collections

I'm new to stickit and was wondering if it can be used to bind collections instead of just models. I have it working for models, but not my collection. Thanks in advance!

If anyone has a quick code snippet, that'd be appreciated.

Provide first class support for showing/hiding elements

It's very common to show/hide UI elements based on properties of a model (especially common - a boolean value that maps to visible/hidden). You can currently do by binding class names with a formatter, but it's kind of clunky. It would be nice if there was first class support for controlling element visibility in stickit.

Keyup event fired too late

There seems to be an issue with the keyup event being fired on the wrong field when quickly tabbing to the next field after typing. The keyup event is being fired on the field that was tabbed to instead of on the field that was typed in.

Steps to reproduce:

  1. Type "testing" in an input field
  2. Quickly tab away from the field

After doing this the model's attribute will be "testin", as the field never received the last keyup event.

Issues with select list

I found the following issues

  1. Line 197 has no reference to model, the function "updateViewBindEl" should pass the reference to the model. changes to line 92, 95 and 168 is required to pass the model
  2. In the function to build the list box, the value of the is not getting set. This has to be added "option.val(optionVal);" after line 215 to set it.
  3. I don't like the way set (on the model) is called on each key press for text box and text area. Any validations in the model gets immediately applied and it fails as all the attributes in the model (for example - that is mapped to fields in a form) are not completed yet. Set should called upon an event which could be set as an option

Access nested model attribute

It doesn't seem possible to bind a nested model attribute to a dom element.

For example:

bindings:
    '#title':
      modelAttr: 'model_data.client.name'

Change modelAttr to observe

I would like to change the modelAttr binding configuration key/name to observe for a couple of reasons:

  • observe is a common term in binding contexts and it is much more intuitive
  • it matches the observe key that is used in the attributes bindings for similar reasons
  • modelAttr isn't intuitive since we added support for binding to multiple model attributes
  • observe is succinct - "modelAttr" is two words, one which is abbreviated, and it looks ugly in the api

Since this key is the cornerstone of model view binding, I'll keep backward-compatibility for modelAttr, and I'll leave this open for discussion...

if one binding dom element doesn't exist, nothing renders

in your bindings object, if one of the elements doesn't exist, it appears as though it's failing silently and nothing is being rendered.

this makes it difficult for instance if you want to hide things in the dom if the user isn't logged in.

Take advantage of new listenTo

first: thanks for making stickit better everyday, and my life as frontend developer easier and more fun!

Lets investigate if stickit can take any advantage of the new event features in backbone 0.9.9 (listenTo, stopListening, once etc)

Binding image or custom binding (and some naming considerations)

If we could have a way to bind images to source URLs that would be good. Right now it just places the URL inside the body of the <img /> tag (unless I'm missing something).

Also for naming and extensibility I'm thinking of something like this:

bindings: {
  ".photo": {
    observe: "photo",

    // Methods 'get' and 'set' which are in charge of reading / writing the model
    // If set is null then model may not be written to at all
    // This could also be called 'read' and 'write'
    get: function (model, name) { model.get(name); },
    set: function (model, value, name) { model.set(name, value); },

    // Methods 'clean' and 'prepare' which are what onSet and onGet were
    // Instead of updateModel, `clean` could return undefined to signal not to set it
    prepare: function (value, name) { return _(value).prune(15); },
    clean: function (value, name) { return _(value).dasherize(); },

    // Methods 'afterUpdate' and 'update' that correspond to the view; if update is used 
    // it replaces what ever method you're using to update -- afterUpdate is just a hook that 
    // is called after the update method to do whatever (fading, etc)
    // Instead of `updateView`, just set `update` to null
    // `updateMethod` could be kept to allow easy overriding instead of replacing update
    update: function ($el, value, name) { $el.attr('src', value); },

    // Remove visibleFn and have `hide` and `show` callbacks to remove unneeded logic 
    // from consumers code.
    hide: function($el, name) { $el.fadeOut(500); },

    // For.. eventsOverride.. I prefer just 'events' but I can see why you
    // went with eventsOverride.. its just not very succinct -- perhaps another name 
  }
}

Just some thoughts to provide flexibility and make it more terse in naming. Not saying that the names must be this. These are just my thoughts on a direction I would go after seeing your awesome library if I were to build it myself. I just don't like clunky names like updateModel, updateView (one that takes a function and one that takes a boolean) everywhere. I do want to have the functionality that update provides.


For some more ideas (that should really have separate issues to discuss them):

As @andriijas mentioned, we do have some nice prototype chain code. I'll submit a PR to add this in if you're interested. This would add the ability for the binding hashes to respect inheritance.

Another thing is that you could wrap View#render to automatically invoke stickit if it has not yet been invoked (this would allow for backwards compatibility and more advanced uses like two binding hashes).

Don't break iterate on bindings's selectors after an element is not found

Hello!

I'm thinking about replacing Backbone.Modelbinder with Stickit and the bigger feature I'm missing is the fact that Modelbinder automatically search the view el for elements that has the same name attribute as a model attribute.

So I wrote a simple function to generate a valid hash for all the model attributes:

generateNameHash: function() {
      var obj;
      obj = {};
      _.each(this.model.attributes, function(val, key) {
        obj["[name=" + key + "]"] = key;
      });
      return obj;
},

The problem lies on line 59 of Stickit:

// Fail fast if the selector didn't match an element.
if (!$el.length) return false;

If Stickit found that no element exists with that selector it justs break the whole _.each cycle and so no more selector is parsed.

I understand that this behaviour may be good to catch errors but replacing return false with return true will just skip the current iteration and go to the next selector, without break anything, at least for what I can tell.

Sorry for my bad english, I hope you understand my point.

jQuery events are not unbound when stickit is called multiple times

It seems that the switch from Backbone delegated events to jQuery events has introduced a bug whereby re-rendering a Backbone view and calling stickit again causes the bound elements to continue to set attributes on the model.

For example, I have a view that I render multiple times. Each time I render, I call stickit(). The first time it renders, there are no problems. But the second time, when I try to enter text into a field it keeps getting replaced with the previously set value from the model.

I see that stickit() calls unstickModel, but judging from the behavior it seems that the jQuery events are staying around. I see that you've wrapped view.remove to unbind these events but when I rerender I don't call view.remove.

I might be wrong and there is some other issue going on but we just upgraded stickit and it appears that this is what's causing the problem.

Select doesn't work when prepopulated

I see that you've added selectOptions, but it's mandatory and the library doesn't work on a select that's already pre-populated. Is there any interest in making it work for this case?

Cursor jumps to end of input when using Stickit + Html5 email input type and webkit

Hey all,

I just started using stickit and I love it, BUT, I have this issue.

If my template is using the html5 email input type like so:

<input type="email" name="email" class="span12" required />

In my view I have these bindings:

  bindings:
    "input[name=email]":
      modelAttr: "email"

Typing initially into the textbox is fine, but when I try to change it, my cursor gets moved to the end of the line.

Here's a short video: https://dl.dropbox.com/u/80354/stickit-thing.swf

I was able to reproduce this in Safari, Chrome, and the iOS Simulator, but not Firefox.

Thanks!

Dynamic bindings for form events

Looking at https://github.com/NYTimes/backbone.stickit/blob/master/backbone.stickit.js#L115-L136; I notice you're throwing events into this.events and then re-invoking this.delegateEvents.

Can we change that to invoking this.$el.on and then (on unstickit) calling this.$el.off?

The main problem is as follows:

List = Backbone.View.extend({

  bindings: {
    '.actions .selector': {
      observe: '$checked'
    }
  },

  events: {
    'change .selector': function(event) {
      // ...
    }
  }

);

I only want the manual event binding to be invoked when directly changing the checkbox via a click. However, I do want the the bindings hash to sync the state of the checkbox with the model.

Attributes didn't use observe's value

Thanks so much for the great plugin, it is really useful. There is a bug that I found for attributes in bindings. Sorry I didn't do a pull requests but here is the patch:

*** backbone.stickit.js Tue Sep 18 15:39:16 2012
--- backbone.stickit.new.js Tue Sep 18 15:39:27 2012
***************
*** 64,70 ****
                                  _.each(attributes, function(attrConfig) {
                                          var lastClass = '',
                                                  updateAttr = function() {
!                                                         var val = applyViewFn(self, attrConfig.format) || model.get(modelAttr);
                                                          // If it is a class then we need to remove the last value and add the new.
                                                          if (attrConfig.name == 'class') {
                                                                  $el.removeClass(lastClass).addClass(val);
--- 64,70 ----
                                  _.each(attributes, function(attrConfig) {
                                          var lastClass = '',
                                                  updateAttr = function() {
!                                                         var val = applyViewFn(self, attrConfig.format, model.get(attrConfig.observe)) || model.get(modelAttr);
                                                          // If it is a class then we need to remove the last value and add the new.
                                                          if (attrConfig.name == 'class') {
                                                                  $el.removeClass(lastClass).addClass(val);

Support Multiple Selects

Hello,

It looks like stickit does not support multiple select values. I propose two methods:

  1. By default join all selected items with commas (e.g. "option1,option2,option3") and store in model.
  2. Have a callback option which lets the developer format the multiple select options as they desire.

e.g.

formatData : function( values, attribute ) {
  // values is array [ 'option1', 'option2', 'option3' ]
  return values.join('-');
}

Support optgroup

I've overlooked the documentation or it is not supported-stickit does not like optgroups and will remove them from my select elements if they are in there!

Great stuff otherwise!

Add options hash as last parameter to binding callbacks

Hi

What do you think of extending the onSet and onGet to get the options hash as third argument?

What I want to do is to have a way of updating the view (my form elements val) with whatever result that comes out of my onSet callback, not just set it on the model.

I dont have any use case for it right now, but if we get this we might as well have the other way around as well ie onGet returned value set on model.

Thanks

Investigate/Remove the need for Model.set wrapper

I originally included the set wrapper so that I could always intercept an attribute change, but this can most likely be handled by listening to change:attribute events. My original understanding/ignorance of the {silent:true} set option was that it silenced change and change:attribute events, but I recently learned otherwise - I'm surprised that I haven't been burned by that yet!

Thanks to @asciidisco for spotting this.

Handling for multiple checkboxes

Looking through the project documentation, tests and getElVal(), it appears that checkbox use cases are primarily designed for a 'per checkbox' case, but documented for an ambiguous number of checkboxes. This has been causing me some issues, which I'll try to explain.

As an example, you'll see in getElVal() backbone.stickit.js function the following code:

        if (isCheckbox($el)) val = $el.prop('checked');
        else if (isNumber($el)) val = Number($el.val());
        else if (isRadio($el)) val = $el.filter(':checked').val();

For a radio button, one would actually get the 'value' of the radio button input. For checkboxes, as expected based on the above code, I'm only seeing true/false being returned. This expectation is confirmed by the checkbox unit tests that I saw in the project, which all seemed to only have 1 checkbox in them.

This all works fine, as I referenced, when only 1 checkbox is in play, but it seems to run into some issues when we start talking multiple checkboxes. You can see the start of such checkbox handling issues (I believe) in action in a simple use case in this jsfiddle:

http://jsfiddle.net/zlendon/baYtM/7/

My issue is that I don't just care what checkbox is checked, but I want to know what the value of that checkbox is. Since only the true/false value is set on the model, I don't have any access outside the 'stickit' layer to any other information about the DOM checkbox element that triggered the 'change' (or similar) JS event. If one was generating each of their DOM elements from their model, this might be less of an issue, but considering the ability to define 1-way bindings, and to be able to define binding selectors across multiple elements, this seems like it runs into some significant problems. It certainly is becoming somewhat of a significant blocker for my backbone.stickit usage efforts.

In the end, I'm not sure if this is truly an 'issue' or if it is an inappropriate usage of the 'stickit'. If you could please provide guidance/insight into how best to move forward with 'stickit' in this type of use case, I'd be most appreciative.

thanks,
Zach

How to unselect values on select lists

I am using a list to build up the options for my select lists. When I first bind and there is no selection in the model I get a blank option for no selection. However if there is a value in the model to bind to the option then the blank selection is not rendered and therefore I can never deselect the option. I tried to render my own "select one" option in my collection but then if the value is unselected I get my blank option as well as the one rendered by stickit. Here is an example

No Selection in the model

<select id="manufacturerId" name="manufacturer">
    <option></option>
    <option>Joe</option>
</select>

With selection in the model

<select id="manufacturerId" name="manufacturer">
    <option>Joe</option>
</select>

Many other frameworks allow you to configure whether there is a select one option and to customize the label.

Any suggestions would be appreciated. The problem is that once selected I cannot deselect to a blank value and if I add a blank it gets duplicated when there is now selection.

Adding 'value' attribute to option and not just stickit_bind_val

I'm trying to integrate Select2 and Stickit.

Select2 requires that each option in a select has the value attribute assigned or it considers the item, "unselectable", making it not useful unfortunately.

I've seen a few issues opened and closed about this, but as an option, I'd like to see Stickit be able to set the standard value attribute for an option element.

I don't see an event where the values could be added post binding, collection updates, etc. I'd considered creating an addHandler for select, but apparently it runs before the list has been constructed. (If there was a two-phase pass, update, updated, that would work as well).

I'm aware of the code that stores the value in the option's stickit_bind_val, but, I don't know how to transfer the value from there to the value attribute.

Thanks for considering this idea.

Add ability to select the views $el via the selector

Hi,
first of all, thanks for this. This is the first sane approach & model <-> view bindings in backbone i´ve seen so far.

I recently was in the situation that i needed to change the 'view.el' elements class,
after digging into the sources i was not able to find a way to do that (maybe I missed smth.)

So, i added a 'custom selector' named ':el', by changing line 51 from

$el = self.$(selector);

to

$el = selector = ':el' ? self.$el : self.$(selector);

Now you can use your bindings to do smth. like this:

bindings: {
    ':el': {
        attributes: [{
            name: 'class',
            observe: 'hidden',
            format: 'toggleVisibility'
        }]
    }
}

Your thoughts?
Would love to see this in core.

Regards
Sebastian

No way to define 'value' for select options

By pointing to a backbone collection with the appropriate data attributes, we are leveraging stickit to generate options for a select dropdown. Through 2-way binding and proper stickit 'selectOptions' configuration, when an option is selected from the list, the proper 'value' is being set on the model side. However, there's nothing in stickit that populates the 'value' attribute for individual options (on initial rendering) within the DOM. This is now becoming a problem for our functional automated test suite, as it was keying off those values. It also seems that it makes sense to have the DOM match up with the models on key attributes like this. Is there a way people are defining value attributes for options that keeps with the 2-way binding, generate input elements from models/collections "spirit" of stickit? And/or can/should we enhance stickit to populate these value attributes? At least on the latter (presuming there's not clear answer to the former question) I would vote in favor of such an enhancement.

bind input type by name

Hi,
just started working with stickit and i would like to know if and how i can bind to
input type by 'name' property, so instead of 'input#nativeAdTitle' i can do 'input[name=nativeAdTitle]'

Thanks

delegateEvents unbinds all already bound events?

Hi

I think the new way of binding to elements by passing an optional event hash to backbone delegateEvents unbinds already bound events via the view.events hash - ive did some testing and got very strange results.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.