Permalink
Browse files

Merge branch 'master' into dblclickmultiselect

  • Loading branch information...
aaronj1335 committed Oct 31, 2012
2 parents f5ecbb1 + 5be8187 commit af5a93e5bb72701227f38edb3ebc4f7dc07008f2
Showing with 75 additions and 34 deletions.
  1. +44 −15 src/widgets/powergrid.js
  2. +18 −8 src/widgets/powergrid/column/checkboxcolumn.js
  3. +13 −11 src/widgets/powergrid/test.js
View
@@ -18,7 +18,7 @@ define([
], function($, _, model, View, asCollectionViewable, ColumnModel, Spinner,
sort, template) {
- var EmptyColumnModel, PowerGrid, DummyModel,
+ var EmptyColumnModel, PowerGrid,
mod = /mac/i.test(navigator.userAgent)? 'metaKey' : 'ctrlKey';
EmptyColumnModel = ColumnModel.extend({});
@@ -28,6 +28,9 @@ define([
// could be true, false, or 'multi'
selectable: false,
+ // things seem less buggy when we do mouseup as opposed to click
+ selectableEvent: 'mouseup',
+
// this is the attribute set on the model corresponding to which
// grid row is selected. so if you want to know which model is
// selected in a grid, you can do something like:
@@ -70,7 +73,7 @@ define([
this.$el.addClass('selectable');
var method = /multi/i.test(selectable)?
'_onMultiselectableRowClick' : '_onSelectableRowClick';
- this.on('click', 'tbody tr', this[method]);
+ this.on(this.get('selectableEvent'), 'tbody tr', this[method]);
}
this.spinner = Spinner(null, {
@@ -189,8 +192,7 @@ define([
$(this.get('columnModel').renderTr(model)).insertAfter(currentRow);
$(currentRow).remove();
this._renderRowCount++;
- // console.log('rerendered row for',
- // model.get(this.get('columnModel').columns[0].get('name')));
+ // console.log('rerendered row for', model.get('text_field'));
},
_sort: function(opts) {
@@ -216,6 +218,12 @@ define([
},
+ col: function(columnName) {
+ return _.find(this.get('columnModel').columns, function(column) {
+ return column.get('name') === columnName;
+ });
+ },
+
disable: function() {
this.$el.addClass('disabled');
if (this.$el.is(':visible')) {
@@ -256,17 +264,18 @@ define([
},
select: function(model, opts) {
- var indices, self = this, changed = [],
- models = this.get('models'),
- a = this.get('selectedAttr'),
+ var indices, self = this, changes = [],
+ a = self.get('selectedAttr'),
+ models = self.get('models'),
selected = function(m) { return m.get(a); };
opts = opts || {};
+ // first just get a list of all the changes that need to happen
if (!opts.dontUnselectOthers) {
_.each(models, function(m) {
if (m !== model && m.get(a)) {
- changed.push(m.del(a, {silent: true}));
+ changes.push({model: m, action: 'del'});
}
});
}
@@ -278,19 +287,39 @@ define([
_.indexOf(models, model)
];
_.each(_.range(_.min(indices), _.max(indices)), function(i) {
- changed.push(models[i].set(a, true, {silent: true}));
+ if (models[i] !== model && !models[i].get(a)) {
+ changes.push({model: models[i], action: 'set'});
+ }
});
}
- this._disableRerender = true;
- changed.push(model.set(a, true));
- this._disableRerender = false;
+ if (!model.get(a)) {
+ changes.push({model: model, action: 'set'});
+ }
- if (changed.length > 0) {
- if (changed.length > 2) {
+ // now we actually make the changes, silently for everything but
+ // the last change (so no more than one change event is triggered)
+ self._disableRerender = true;
+ _.each(changes, function(change, i) {
+ var args = [a];
+ if (change.action === 'set') {
+ args.push(true);
+ }
+ if (i < changes.length-1) {
+ args.push({silent: true});
+ }
+ change.model[change.action].apply(change.model, args);
+ });
+ self._disableRerender = false;
+
+ // now, if needed, re-render (some portion of) the grid
+ if (changes.length > 0) {
+ if (changes.length > 2) {
self.rerender();
} else {
- _.each(changed, function(m) { self.rerender(m); });
+ _.each(changes, function(change) {
+ self.rerender(change.model);
+ });
}
// i don't think there should be a select event for the same
// reason i don't think we should have a grid.getSelected()
@@ -14,15 +14,17 @@ define([
init: function() {
this._super.apply(this, arguments);
+ var delegateSelector = 'tbody tr .'+this.columnClass()+' input';
if (this.get('prop') == null) {
this.set({prop: '_' + this.el.id + '_checked'},
{silent: true});
}
this._postRender();
- this.get('grid').on(
- 'change',
- 'tbody tr .'+this.columnClass()+' input',
- _.bind(this._onChange, this));
+ this.get('grid')
+ .on('change', delegateSelector, _.bind(this._onChange, this))
+ .on('mouseup', delegateSelector, function(evt) {
+ evt.stopPropagation();
+ });
},
_getName: function() {
@@ -51,11 +53,19 @@ define([
},
_onChange: function(evt) {
- var $target = $(evt.target), checked;
- this.get('grid')._modelFromTr($target.closest('tr'))
- .set(this.get('prop'), (checked = $target.is(':checked')));
+ var checked, self = this,
+ $target = $(evt.target),
+ model = self.get('grid')._modelFromTr($target.closest('tr'));
+ if (self.get('type') === 'radio') {
+ _.each(self.get('grid').get('models'), function(m) {
+ if (m !== model) {
+ m.del(self.get('prop'));
+ }
+ });
+ }
+ model.set(self.get('prop'), (checked = $target.is(':checked')));
if (!checked) {
- this.checkbox.$node.prop('checked', false);
+ self.checkbox.$node.prop('checked', false);
}
},
@@ -184,7 +184,7 @@ define([
equal(g._renderRowCount, 1, 'only one row was rerendered');
equal(g._renderCount, 1, 'grid wasnt rerendered');
- g.$el.find('td:contains(item 2)').trigger('click');
+ g.$el.find('td:contains(item 2)').trigger(g.get('selectableEvent'));
equal(g.$el.find('.selected').length, 1, 'click triggers selection');
equal(trim(g.$el.find('.selected td.col-text_field').text()),
'item 2', 'correct row selected');
@@ -268,7 +268,7 @@ define([
'item 6', 'correct row selected');
g.$el.find('td:contains(item 2)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
$selected = g.$el.find('.selected');
equal($selected.length, 3, 'three are selected');
equal(trim($selected.find('td.col-text_field').eq(0).text()),
@@ -278,14 +278,14 @@ define([
equal(trim($selected.find('td.col-text_field').eq(2).text()),
'item 6', 'correct row selected');
- g.$el.find('td:contains(item 5)').trigger('click');
+ g.$el.find('td:contains(item 5)').trigger(g.get('selectableEvent'));
$selected = g.$el.find('.selected');
equal($selected.length, 1, 'three are selected');
equal(trim($selected.find('td.col-text_field').eq(0).text()),
'item 5', 'correct row selected');
g.$el.find('td:contains(item 2)').trigger(
- $.Event('click', {shiftKey: true}));
+ $.Event(g.get('selectableEvent'), {shiftKey: true}));
$selected = g.$el.find('.selected');
equal($selected.length, 4, 'three are selected');
equal(trim($selected.find('td.col-text_field').eq(0).text()),
@@ -298,7 +298,7 @@ define([
'item 5', 'correct row selected');
g.$el.find('td:contains(item 4)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
$selected = g.$el.find('.selected');
equal($selected.length, 3, 'three are selected');
equal(trim($selected.find('td.col-text_field').eq(0).text()),
@@ -309,7 +309,7 @@ define([
'item 5', 'correct row selected');
g.$el.find('td:contains(item 3)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
$selected = g.$el.find('.selected');
equal($selected.length, 2, 'three are selected');
equal(trim($selected.find('td.col-text_field').eq(0).text()),
@@ -385,7 +385,7 @@ define([
g.select(g.get('collection').where({text_field: 'item 3'}));
equal(triggered.length, 1);
g.$el.find('td:contains(item 2)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
equal(triggered.length, 2);
g.select(g.get('collection').where({text_field: 'item 7'}));
equal(triggered.length, 3);
@@ -402,7 +402,7 @@ define([
g.select(g.get('collection').where({text_field: 'item 3'}));
g.$el.find('td:contains(item 2)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
equal(triggered.length, 0);
@@ -427,10 +427,10 @@ define([
}).then(function(g, options) {
equal(g._renderRowCount, 0);
g.$el.find('td:contains(item 2)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
equal(g._renderRowCount, 1);
g.$el.find('td:contains(item 2)').trigger(
- $.Event('click', {ctrlKey: true, metaKey: true}));
+ $.Event(g.get('selectableEvent'), {ctrlKey: true, metaKey: true}));
equal(g._renderRowCount, 1);
start();
});
@@ -716,6 +716,8 @@ define([
equal(g.$el.find('[type=checkbox]').length, g.get('models').length+1);
equal(g.$el.find('[type=checkbox]:checked').length, 0);
_.each(g.get('models'), function(m) { ok(!m.get('_checked')); });
+ // gecko and trident don't seem to register the click, so change
+ // events never fire and this test fails in those browsers
g.$el.find('thead [type=checkbox]').trigger('click');
setTimeout(function() {
equal(g.$el.find('[type=checkbox]').length,
@@ -725,7 +727,7 @@ define([
_.each(g.get('models'),
function(m) { ok(m.get('_checked')); });
start();
- }, 15);
+ }, 50);
});
});

0 comments on commit af5a93e

Please sign in to comment.