-
-
Save jaehess/1483422 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| example design of an expandable list view that expands selected items in place using alternate list item view | |
| */ | |
| tasksView: SC.ScrollView.design({ | |
| hasHorizontalScroller: NO, | |
| layout: { top: 24, bottom: 0, left: 0, right: 0 }, | |
| backgroundColor: 'white', | |
| contentView: Tasks.ExpandableListView.design({ | |
| contentBinding: 'Tasks.controller.arrangedObjects', | |
| selectionBinding: 'Tasks.controller.selection', | |
| selectedShowing: 'detailView', | |
| exampleView: Tasks.ExpandableView.design({ | |
| nowShowing: 'summaryView', | |
| summaryView: SC.View.design({ | |
| childViews: ... | |
| }), | |
| detailView: SC.View.design({ | |
| childViews: ... | |
| }) | |
| }) | |
| }) | |
| }) | |
| /** @object | |
| An expansion delegate automatically expands the | |
| example view of the index which is selected. | |
| */ | |
| Tasks.expansionDelegate = SC.Object.create(SC.CollectionViewDelegate, | |
| SC.CollectionRowDelegate, | |
| /** @scope Tasks.ExpansionDelegate.prototype */ { | |
| selectedIdx: null, | |
| customRowHeightIndexes: SC.IndexSet.create(), | |
| collectionViewSelectionForProposedSelection: function(view, sel) { | |
| if (sel.sources().length) { | |
| var idx = sel.indexSetForSource(sel.sources()[0]).min(); | |
| this.customRowHeightIndexes.remove(this.selectedIdx).add(idx); | |
| this.selectedIdx = idx; | |
| } else { | |
| this.customRowHeightIndexes.remove(this.selectedIdx); | |
| this.selectedIdx = null; | |
| } | |
| return sel; | |
| }, | |
| contentIndexRowHeight: function(view, content, idx) { | |
| if (this.selectedIdx === idx) { | |
| // TODO I don't like this, but I don't know yet how to obtain a size estimate | |
| return 1000; | |
| } else { | |
| return this.get('rowHeight'); | |
| } | |
| }, | |
| toString: function() { | |
| return "Tasks.ExpansionDelegate:%@<%@>".fmt(SC.guidFor(this), this.selectionIdx); | |
| } | |
| }); | |
| /** @class | |
| Enables selected items to be automatically expanded in-place. | |
| @extends SC.ListView | |
| */ | |
| Tasks.ExpandableListView = SC.ListView.extend({ | |
| delegate: Tasks.expansionDelegate, | |
| /** | |
| Since we expand the selection automatically, | |
| multiple selection is not allowed | |
| */ | |
| allowsMultipleSelection: NO, | |
| didReload: function() { | |
| var sel = this.get('selection'); | |
| if (sel && sel.sources().length) { | |
| var idx = sel.indexSetForSource(sel.sources()[0]).min(); | |
| var selectedView = this.childViews[idx]; | |
| if (!selectedView) | |
| return; | |
| var showing = this.get('selectedShowing'); | |
| selectedView.set('nowShowing', showing); | |
| } | |
| } | |
| }); | |
| /** @class | |
| Renders each work item as a member of a collection view. | |
| @extends SC.ListItemView | |
| */ | |
| Tasks.ExpandableView = SC.ListItemView.extend( | |
| /** @scope Tasks.WorkItemView.prototype */ { | |
| classNames: ['expandable-item-view'], | |
| /** | |
| {SC.String} | |
| Identifies the view that will be shown when the list | |
| item is selected | |
| */ | |
| selectedShowing: null, | |
| /** | |
| {SC.String} | |
| Identifies the view that will be shown when the list | |
| item is not selected and when the item is just created | |
| */ | |
| nowShowing: null, | |
| /** | |
| Replaces any child views with the passed new content. | |
| This method is automatically called whenever your contentView property | |
| changes. You can override it if you want to provide some behavior other | |
| than the default. | |
| @param {SC.View} newContent the new content view or null. | |
| */ | |
| replaceContent: function(newContent) { | |
| if (this.childViews.length) | |
| this.replaceChild(newContent, this.childViews[0]) ; | |
| else | |
| this.appendChild(newContent); | |
| }, | |
| /** @private */ | |
| createChildViews: function() { | |
| // if contentView is defined, then create the content | |
| var nowShowing = this.get('nowShowing') ; | |
| if (nowShowing && nowShowing.length>0) this.nowShowingDidChange(); | |
| }, | |
| /** | |
| Invoked whenever the nowShowing property changes. This will try to find | |
| the new content if possible and set it. If you set nowShowing to an | |
| empty string or null, then the current content will be cleared. | |
| If you set the content manually, the nowShowing property will be set to | |
| SC.CONTENT_SET_DIRECTLY | |
| */ | |
| nowShowingDidChange: function() { | |
| var nowShowing = this.get('nowShowing') ; | |
| var content = null; | |
| //its a property path | |
| if(SC.typeOf(nowShowing) === SC.T_STRING){ | |
| // if nowShowing was set because the content was set directly, then | |
| // do nothing. | |
| if (nowShowing === SC.CONTENT_SET_DIRECTLY) return ; | |
| // otherwise, if nowShowing is a non-empty string, try to find it... | |
| if (nowShowing && nowShowing.length>0) { | |
| content = this.get(nowShowing).create(); | |
| } | |
| }else{ //its a view | |
| content = nowShowing; | |
| } | |
| // only allow views | |
| if (content && !(content instanceof SC.View)) content = null; | |
| // set content | |
| this.set('contentView', content) ; | |
| }.observes('nowShowing'), | |
| /** | |
| Invoked whenever the content property changes. This method will simply | |
| call replaceContent. Override replaceContent to change how the view is | |
| swapped out. | |
| */ | |
| contentViewDidChange: function() { | |
| this.replaceContent(this.get('contentView')); | |
| }.observes('contentView'), | |
| render: function(context, firstTime) { | |
| var content = this.get('content'), | |
| del = this.displayDelegate, | |
| level = this.get('outlineLevel'), | |
| indent = this.get('outlineIndent'), | |
| key, working ; | |
| // outline level wrapper | |
| working = context.begin("div").addClass("sc-outline"); | |
| if (level>=0 && indent>0) working.addStyle("left", indent*(level+1)); | |
| this.renderChildViews(working, true); | |
| // handle action | |
| key = this.getDelegateProperty('listItemActionProperty', del) ; | |
| value = (key && content) ? (content.get ? content.get(key) : content[key]) : null ; | |
| if (value) { | |
| this.renderAction(working, value); | |
| context.addClass('has-action'); | |
| } | |
| context = working.end(); | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment