diff --git a/README.md b/README.md
index 8ba45bc..72bb2c3 100755
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+
+# The repository has been moved to: https://github.com/sproutcore/sproutcore-table
+------
+
#Overview
This is a table view for [Sproutcore](http://www.github.com/sproutcore/sproutcore).
diff --git a/views/table_row.js b/views/table_row.js
index ca8027b..cc6e23d 100755
--- a/views/table_row.js
+++ b/views/table_row.js
@@ -33,7 +33,7 @@ SC.TableRowView = SC.ListItemView.extend({
return this.getPath('displayDelegate.tableDelegate');
}.property('displayDelegate').cacheable(),
-
+
render: function(context) {
var tableDelegate = this.get('tableDelegate'),
left = 3,
@@ -61,8 +61,8 @@ SC.TableRowView = SC.ListItemView.extend({
context = context.push('
');
if (contentCheckboxKey && contentCheckboxKey.contains(key)) {
- var value = SC.get(content, key) || false;
- this.renderCheckbox(context, value);
+ var value = SC.getPath(content, key) || false;
+ this.renderCheckbox(context, value, key);
}
else {
tableDelegate.renderTableCellContent(this, context, content, contentIndex, col, key);
@@ -72,6 +72,7 @@ SC.TableRowView = SC.ListItemView.extend({
left += width;
}
+
},
@@ -105,8 +106,8 @@ SC.TableRowView = SC.ListItemView.extend({
$cell.css({ width: width+'px', left: left+'px', });
if (contentCheckboxKey && contentCheckboxKey.contains(key)) {
- var value = SC.get(content, key) || false;
- this.updateCheckbox($cell, value);
+ var value = SC.getPath(content, key) || false;
+ this.updateCheckbox($cell, value, key);
}
else {
tableDelegate.updateTableCellContent(this, $cell, content, contentIndex, col, key);
@@ -132,9 +133,12 @@ SC.TableRowView = SC.ListItemView.extend({
var content = this.get('content');
// There may be a memory leak in SC with _checkboxRenderSource
- if (this._checkboxRenderSource) {
- this._checkboxRenderSource.destroy();
- this._checkboxRenderSource = this._checkboxRenderDelegate = null;
+ var sources = this._tr_cbSources;
+ if (sources) {
+ this.get('contentCheckboxKey').forEach(function(k) {
+ sources[k].destroy();
+ });
+ this._tr_cbSources = this._checkboxRenderDelegate = null;
}
this.updateContentObservers(null, content);
@@ -214,27 +218,217 @@ SC.TableRowView = SC.ListItemView.extend({
// CHECKBOX EDTITING
//
- updateCheckbox: function (jQuery, state) {
+ /** @private
+ Adds a checkbox with the appropriate state to the content. This method
+ will only be called if the list item view is supposed to have a
+ checkbox.
+
+ @param {SC.RenderContext} context the render context
+ @param {Boolean} state YES, NO or SC.MIXED_STATE
+ @returns {void}
+ */
+ renderCheckbox: function (context, state, key) {
var renderer = this.get('theme').checkboxRenderDelegate;
- var source = this._checkboxRenderSource;
+ // note: checkbox-view is really not the best thing to do here; we should do
+ // sc-list-item-checkbox; however, themes expect something different, unfortunately.
+ context = context.begin('div')
+ .addClass('sc-checkbox-view')
+ .addClass('sc-checkbox-view-for-' + key)
+ .addClass(this.get('theme').classNames)
+ .addClass(renderer.get('className'));
+
+ var sources = this._tr_cbSources;
+ if (!sources) {
+ sources = this._tr_cbSources = {};
+ }
+
+ var source = sources[key];
if (!source) {
- source = this._checkboxRenderSource =
- SC.Object.create({ renderState: {}, theme: this.get('theme') });
+ source = sources[key] = SC.Object.create({
+ renderState: {},
+ theme: this.get('theme')
+ });
}
+ var editableKeys = this.get('editableKeys');
+ var keyInEditableKeys = editableKeys && editableKeys.indexOf(key) !== -1;
+
source
.set('controlSize', SC.SMALL_CONTROL_SIZE)
.set('isSelected', state && (state !== SC.MIXED_STATE))
- .set('isEnabled', this.get('isEnabled') && this.get('contentIsEditable'))
+ .set('isEnabled', this.get('isEnabled') && this.get('contentIsEditable') && keyInEditableKeys)
.set('isActive', this._checkboxIsActive)
.set('title', '');
- renderer.update(source, jQuery.find('.sc-checkbox-view'));
+ renderer.render(source, context);
+ context = context.end();
this._checkboxRenderDelegate = renderer;
},
+
+ updateCheckbox: function (jQuery, state, key) {
+ var renderer = this.get('theme').checkboxRenderDelegate;
+
+ var sources = this._tr_cbSources;
+ var source = sources[key];
+
+ var editableKeys = this.get('editableKeys');
+ var keyInEditableKeys = editableKeys && editableKeys.indexOf(key) !== -1;
+
+ source
+ .set('controlSize', SC.SMALL_CONTROL_SIZE)
+ .set('isSelected', state && (state !== SC.MIXED_STATE))
+ .set('isEnabled', this.get('isEnabled') && this.get('contentIsEditable') && keyInEditableKeys)
+ .set('isActive', this._checkboxIsActive)
+ .set('title', '');
+
+ renderer.update(source, jQuery.find('.sc-checkbox-view-for-' + key));
+
+ this._checkboxRenderDelegate = renderer;
+ },
+
+ _isInsideCheckbox: function (evt) {
+ var del = this.displayDelegate;
+ var checkboxKey = this.getDelegateProperty('contentCheckboxKey', del);
+ // should be an array as it is set that way through render and update
+
+ return checkboxKey && checkboxKey.find(function (k) {
+ return this._isInsideElementWithClassName('sc-checkbox-view-for-' + k, evt);
+ }, this);
+ },
+
+ _addCheckboxActiveState: function (key) {
+ if (this.get('isEnabled') && this.get('editableKeys') && this.get('editableKeys').contains(key)) {
+ if (this._checkboxRenderDelegate) {
+ var sources = this._tr_cbSources;
+ var source = sources[key];
+
+ source.set('isActive', YES);
+
+ this._checkboxRenderDelegate.update(source, this.$('.sc-checkbox-view-for-' + key));
+ } else {
+ // for backwards-compatibility.
+ this.$('.sc-checkbox-view-for-' + key).addClass('active');
+ }
+ }
+ },
+
+ _removeCheckboxActiveState: function () {
+ var key = this._isMouseDownOnCheckboxFor;
+ if (this._checkboxRenderer) {
+ var sources = this._tr_cbSources;
+ var source = sources[key];
+
+ source.set('isActive', NO);
+
+ this._checkboxRenderDelegate.update(source, this.$('.sc-checkbox-view-for-' + key));
+ } else {
+ // for backwards-compatibility.
+ this.$('.sc-checkbox-view-for-' + key).removeClass('active');
+ }
+ },
+
+
+ /** @private
+ mouseDown is handled only for clicks on the checkbox view or or action
+ button.
+ */
+ mouseDown: function (evt) {
+ // Fast path, reject secondary clicks.
+ if (evt.which && evt.which !== 1) return false;
+
+ // if content is not editable, then always let collection view handle the
+ // event.
+ if (!this.get('contentIsEditable')) return NO;
+
+ // if occurred inside checkbox, item view should handle the event.
+ var inCheckboxForKey = this._isInsideCheckbox(evt);
+ if (inCheckboxForKey) {
+ this._addCheckboxActiveState(inCheckboxForKey);
+ this._isMouseDownOnCheckbox = YES;
+ this._isMouseInsideCheckbox = YES;
+ this._isMouseDownOnCheckboxFor = inCheckboxForKey;
+ return YES; // listItem should handle this event
+ } else if (this._isInsideDisclosure(evt)) {
+ this._addDisclosureActiveState();
+ this._isMouseDownOnDisclosure = YES;
+ this._isMouseInsideDisclosure = YES;
+ return YES;
+ } else if (this._isInsideRightIcon(evt)) {
+ this._addRightIconActiveState();
+ this._isMouseDownOnRightIcon = YES;
+ this._isMouseInsideRightIcon = YES;
+ return YES;
+ }
+ this.displayDidChange();
+ return NO; // let the collection view handle this event
+ },
+
+ /** @private */
+ mouseUp: function (evt) {
+ var ret = NO;
+
+ // if mouse was down in checkbox -- then handle mouse up, otherwise
+ // allow parent view to handle event.
+ if (this._isMouseDownOnCheckbox) {
+ // update only if mouse inside on mouse up...
+ var inCheckboxForKey = this._isInsideCheckbox(evt);
+ if (inCheckboxForKey && inCheckboxForKey === this._isMouseDownOnCheckboxFor) {
+ if (this.get('editableKeys') && this.get('editableKeys').contains(inCheckboxForKey)) {
+ this.toggleCheckbox(inCheckboxForKey);
+ }
+ }
+
+ this._removeCheckboxActiveState();
+ ret = YES;
+
+ // if mouse as down on disclosure -- handle mouse up. otherwise pass on
+ // to parent.
+ } else if (this._isMouseDownOnDisclosure) {
+ if (this._isInsideDisclosure(evt)) {
+ this.toggleDisclosure();
+ }
+
+ this._removeDisclosureActiveState();
+ ret = YES;
+ // if mouse was down in right icon -- then handle mouse up, otherwise
+ // allow parent view to handle event.
+ } else if (this._isMouseDownOnRightIcon) {
+ this._removeRightIconActiveState();
+ ret = YES;
+ }
+
+ // clear cached info
+ this._isMouseInsideCheckbox = this._isMouseDownOnCheckbox = NO;
+ this._isMouseDownOnDisclosure = this._isMouseInsideDisclosure = NO;
+ this._isMouseInsideRightIcon = this._isMouseDownOnRightIcon = NO;
+ // this._isMouseDownOnCheckboxFor = null;
+
+ return ret;
+ },
+
+ /** @private */
+ mouseMoved: function (evt) {
+ return NO;
+ },
+
+ toggleCheckbox: function (key) {
+ var content = this.get('content');
+ //del = this.displayDelegate;
+
+ if (content && content.get) {
+ var value = content.get(key);
+
+ value = (value === SC.MIXED_STATE) ? YES : !value;
+ content.set(key, value); // update content
+
+ this.displayDidChange(); // repaint view...
+ }
+
+ }
+
});