Titanium JIRA Archive
Alloy (ALOY)

[ALOY-440] Ti.UI.Picker has no collection binding

GitHub Issuen/a
TypeImprovement
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2014-08-21T03:16:58.000+0000
Affected Version/sn/a
Fix Version/sAlloy 1.5.0
ComponentsModels, XML
Labelsqe-manualtest
ReporterTony Lukasavage
AssigneeTim Poulsen
Created2012-12-20T17:21:38.000+0000
Updated2014-08-28T15:15:53.000+0000

Description

original discussion

http://developer.appcelerator.com/question/145992/databinding-on-picker

problem

Collection binding is not implemented for Ti.UI.Picker as it is for Ti.UI.TableView and other generic Titaniums views (View, Window, ScrollView, etc...).

solution

Support collection binding on Ti.UI.Picker just as it is on TableView. It will need special handling as the Ti.UI.Picker requires custom parsing for columns and rows. Something like this should be how it would work for devs:
<Alloy>
    <Collection src="book" />
    <Window class="container">
        <Picker dataCollection="book">
            <PickerRow title="{title}" />
        </Picker>
    </Window>
</Alloy>

Attachments

FileDateSize
android_ActualResult_noSpinner.png2014-08-14T23:11:01.000+000040150
android_ActualResult_withSpinner_PickerRowBinding.png2014-08-14T23:11:01.000+000040143
android_ActualResult_withSpinner.png2014-08-14T23:11:01.000+000038795

Comments

  1. Tim Poulsen 2014-06-24

    The original sample doesn't account for columns. Supporting columns could mean any of the following might be expected. What is our goal with this ticket?
       // single collection, filtering and binding only at Picker level
       <Alloy>
         <Collection src="books"/>
         <Window>
           <Picker id="picker" top="50" dataCollection="books" dataFilter="doFilter">
             <PickerColumn id="column1">
               <PickerRow title="{column1}"/>
             </PickerColumn>
             <!-- Picker shorthand notation -->
             <Column id="column2">
               <Row title="{column2}"/>
             </Column>
           </Picker>
         </Window>
       </Alloy>
       
       // single collection, binding at Picker level, filtering at column level
       <Alloy>
         <Collection src="books"/>
         <Window>
           <Picker id="picker" top="50" dataCollection="books">
             <PickerColumn id="column1" dataFilter="doFilterOne">
               <PickerRow title="{title}"/>
             </PickerColumn>
             <!-- Picker shorthand notation -->
             <Column id="column2" dataFilter="doFilterTwo">
               <Row title="{genre}"/>
             </Column>
           </Picker>
         </Window>
       </Alloy>
       
       // binding and filtering at column level
       <Alloy>
         <Collection src="publishers"/>
         <Collection src="books"/>
         <Window>
           <Picker id="picker" top="50">
             <PickerColumn id="column1" dataCollection="books">
               <PickerRow title="{title}"/>
             </PickerColumn>
             <!-- Picker shorthand notation -->
             <Column id="column2" dataCollection="publishers" dataFilter="doFilter">
               <Row title="{publisher}"/>
             </Column>
           </Picker>
         </Window>
       </Alloy>
       
  2. Tim Poulsen 2014-07-16

    PR https://github.com/appcelerator/alloy/pull/483 Test app: https://github.com/skypanther/alloy/blob/ALOY-440/test/apps/testing/ALOY-440 Functional test: build the app, it should display a two-column picker with fruits in the left column and colors in the right. Due to the dataTransform applied, the colors should be in all-caps
  3. Tim Poulsen 2014-08-18

    I'm not sure where I got the idea that you could use a
  4. Feon Sua Xin Miao 2014-08-19

    **APPROVED**
  5. Feon Sua Xin Miao 2014-08-19

    PR merged
  6. Priya Agarwal 2014-08-20

    Verified with: Appc Studio - 3.4.0.201408180158 SDK - 3.4.0.v20140819094113 acs - 1.0.16 alloy - 1.5.0-dev npm - 1.3.2 titanium - 3.4.0-dev titanium-code-processor - 1.1.1 OS - mavericks (v10.9.4) Xcode - 6Beta5 Device - iPhone5s(v8.0), Nexus7(v4.4.4) Tested with app (test/apps/testing/ALOY-440) App runS without error and as expected. Able to see the two-column spinner, which is bound to the collections. Hence closing the issue.
  7. Federico Casali 2014-08-20

    See attached sample app 'AlloyPicker_dataCollection.zip'. 1. Run the sample on Android 2. Click on the top ActionBar to add a model from the 'book' collection 3. Click on the Picker Results: 2. Model item is correctly added and displayed in the TableView 3. In the picker, the existing rows are not flushed out each time data is fetched from the collection, therefore adding each time the whole collection items plus one. Reopening. TiSDK 3.4.0.v20140813022514 Appcelerator Studio 3.3.1.201408121314 CLI 3.4.0-dev Alloy 1.5.0-dev
  8. Tim Poulsen 2014-08-20

    PR https://github.com/appcelerator/alloy/pull/514 Functional review: The pull request includes a new test app, test/apps/testing/ALOY\-440c. Use it or the attached AlloyPicker_dataCollection.zip app. Run it for Android. Click the app's title in the action bar several times, after each click, drop down the picker to see that just as many rows are added to it as to the table.
  9. Feon Sua Xin Miao 2014-08-21

    *APPROVED*
  10. Feon Sua Xin Miao 2014-08-21

    PR merged
  11. Federico Casali 2014-08-22

    Verified as working as expected. Environment: TiSDK 3.4.0.v20140820125714 Appcelerator Studio 3.4.0.201408201526 CLI 3.4.0-dev Alloy 1.5.0-dev Closing.
  12. Joe Beuckman 2014-08-26

    Is there a problem with doing this in a Widget? I'm using Alloy 1.6.0-dev
        <Alloy>
        	<Collection src="StoreLocation"/>	
        	<Window>		
        		<Picker dataCollection="StoreLocation">
        			<PickerRow title="{store_name}" />
        		</Picker>
        	</Window>	
        </Alloy>
        
    StoreLocation is a model in the widget's models/ folder. It uses a syncadapter in the app's lib/alloy/sync folder and I see the models populated correctly after an initial fetch(). When the widget loads, before the fetch can be called, I get {color:red}"'null' is not an object (evaluating '$model.__transform')"{color}
  13. Tim Poulsen 2014-08-26

    Binding is supported on the tag, not This is to support pickers with multiple columns. We did not add a shortcut by which you'd bind the picker and have that translated to its autogenerated column. So, this should work:
        // binding and filtering at column level
        <Alloy>
          <Collection src="StoreLocation"/>
          <Window>
            <Picker>
              <PickerColumn dataCollection="storeLocation">
                <PickerRow title="{store_name}"/>
              </PickerColumn>
            </Picker>
          </Window>
        </Alloy>
        
  14. Joe Beuckman 2014-08-27

    Thanks! The error is gone. However, when I use my syncadapter, the collection looks full but the picker does not populate. I can only load the Picker by manually adding a model. This reports the correct number of models in the event handler, but the picker remains empty:
        Widget.Collections.StoreLocation.on('reset', function(){
            Ti.API.info('collection length = '+Widget.Collections.StoreLocation.length);
        });
        
        Widget.Collections.StoreLocation.fetch();
        
    This loads the picker correctly with one test entry:
        var model = Widget.createModel('StoreLocation', { store_name: "test" });
        Widget.Collections.StoreLocation.add(model);
        
    Do I need to do something besides fetch() to update the picker?
  15. Tim Poulsen 2014-08-27

    Hmm, the picker should be responding to the same set of events that any other data-bound control would respond to: fetch, reset, delete, etc. Are you using one of the stock sync adapters? Can you post a test app that shows the problem so I can investigate further?
  16. Joe Beuckman 2014-08-28

    Here is a minimal example of my problem. Thanks for your help. https://github.com/jbeuckm/AlloyWidgetCollectionPicker
  17. Tim Poulsen 2014-08-28

    What you posted doesn't show create or update methods within your sync adapter. What's triggering the read (fetch) method when you add a model? If you look at https://github.com/viezel/napp.alloy.adapter.restapi/blob/master/restapi.js you'll see that he's triggering fetch as part of the create & update calls.
  18. Joe Beuckman 2014-08-28

    I call fetch() from the widget's controller here: https://github.com/jbeuckm/AlloyWidgetCollectionPicker/blob/master/app/widgets/CollectionTest/controllers/widget.js#L6 Note that this works with a ScrollableView or TableView but not Picker.

JSON Source