Permalink
Browse files

feature: ObservableList can filter items (works nice with MaterialRep…

…eat)
  • Loading branch information...
MikeMitterer committed Feb 29, 2016
1 parent 684d3d0 commit 27ac384bb238bdb9c935df12109ae700f46f91f8
@@ -73,7 +73,7 @@ class MaterialCheckbox extends MdlComponent with FallbackFormatter {
if(_inputElement == null) {
_inputElement = element.querySelector(".${_cssClasses.INPUT}");
}
return _inputElement;
return element.querySelector(".${_cssClasses.INPUT}");
}
/// Disable checkbox.
@@ -105,7 +105,9 @@ class MaterialCheckbox extends MdlComponent with FallbackFormatter {
}
void set checked(final bool _checked) => _checked ? check() : uncheck();
bool get checked => inputElement?.checked;
bool get checked {
return inputElement.checked;
}
void set disabled(final bool _disabled) => _disabled ? disable() : enable();
bool get disabled => inputElement?.disabled;
@@ -174,13 +176,13 @@ class MaterialCheckbox extends MdlComponent with FallbackFormatter {
eventStreams.add(element.onMouseUp.listen(_onMouseUp));
_updateClasses();
// Solves slow Touch on iOS...
// element.onTouchEnd.listen((_) {
// checked = !checked;
// });
_updateClasses();
/// Reformat according to [MaterialFormatter] definition
void _kickInFormatter() {
label = label;
@@ -221,7 +223,7 @@ class MaterialCheckbox extends MdlComponent with FallbackFormatter {
/// Check the inputs toggle state and update display.
void _checkToggleState() {
if (_inputElement.checked) {
if (inputElement.checked) {
element.classes.add(_cssClasses.IS_CHECKED);
} else {
@@ -231,7 +233,7 @@ class MaterialCheckbox extends MdlComponent with FallbackFormatter {
/// Check the inputs disabled state and update display.
void _checkDisabled() {
if (_inputElement.disabled) {
if (inputElement.disabled) {
element.classes.add(_cssClasses.IS_DISABLED);
} else {
@@ -117,9 +117,14 @@ class MaterialDivDataTable extends MdlComponent {
}
List<MaterialDivDataTableRow> get selectedRows {
return new UnmodifiableListView(_rows.where((final MaterialDivDataTableRow row) => row.isSelected));
final List<MaterialDivDataTableRow> temp =
new List.from(_rows.where((final MaterialDivDataTableRow row) => row.isSelected));
return temp;
//return new UnmodifiableListView(temp);
}
//- private -----------------------------------------------------------------------------------
void _init() {
@@ -270,25 +275,35 @@ class MaterialDivDataTableRow extends MdlComponent {
}
}
bool get isSelected => _selectableCheckbox != null ? _selectableCheckbox.checked : false;
bool get isSelected {
return _selectableCheckbox != null ? _selectableCheckbox.checked : false;
}
//- private -----------------------------------------------------------------------------------
void _init() {
_logger.fine("MaterialDivDataTableRow - init");
if(parent.isSelectable) {
final dom.HtmlElement firstCell = element.querySelector(':first-child');
if(firstCell != null) {
final dom.HtmlElement td = new dom.DivElement();
dom.HtmlElement td = element.querySelector(".${_cssClasses.CELL_CHECKBOX}");
final bool checkboxCellIsNotPredefined = (td == null);
td ??= new dom.DivElement();
td.classes.add(_cssClasses.CELL_CHECKBOX);
final bool checkboxIsNotPredefined = (element.querySelector(".${_cssClasses.SELECT}") == null);
final dom.LabelElement rowCheckbox = _createRowCheckbox();
td.append(rowCheckbox);
if(checkboxIsNotPredefined) {
td.append(rowCheckbox);
}
componentHandler().upgradeElement(td).then( (_) {
element.insertBefore(td, firstCell);
if(checkboxCellIsNotPredefined) {
element.insertBefore(td, firstCell);
}
});
}
@@ -329,18 +344,27 @@ class MaterialDivDataTableRow extends MdlComponent {
/// event handling.
dom.LabelElement _createRowCheckbox() {
final dom.LabelElement label = new dom.LabelElement();
dom.LabelElement label = element.querySelector(".${_cssClasses.SELECT}");
label ??= new dom.LabelElement();
label.classes.add(_cssClasses.CHECKBOX);
label.classes.add(_cssClasses.JS_CHECKBOX);
label.classes.add(_cssClasses.JS_RIPPLE_EFFECT);
label.classes.add(_cssClasses.SELECT);
final dom.CheckboxInputElement checkbox = new dom.CheckboxInputElement();
dom.CheckboxInputElement checkbox = label.querySelector(".${_cssClasses.CHECKBOX_INPUT}");
final bool checkboxIsNotPredefined = checkbox == null;
checkbox ??= new dom.CheckboxInputElement();
checkbox.classes.add(_cssClasses.CHECKBOX_INPUT);
if (element != null) {
checkbox.checked = element.classes.contains(_cssClasses.IS_SELECTED);
if(checkboxIsNotPredefined) {
checkbox.checked = element.classes.contains(_cssClasses.IS_SELECTED);
} else {
checkbox.checked ? element.classes.add(_cssClasses.IS_SELECTED) : element.classes.remove(_cssClasses.IS_SELECTED);
}
eventStreams.add( checkbox.onChange.listen( (final dom.Event event) {
final bool checked = checkbox.checked;
@@ -362,7 +386,9 @@ class MaterialDivDataTableRow extends MdlComponent {
}
}
label.append(checkbox);
if(checkboxIsNotPredefined) {
label.append(checkbox);
}
return label;
}
@@ -48,6 +48,7 @@ class ObservableList<T> extends ListBase<T> {
//final Logger _logger = new Logger('mdlobservable.ObservableList');
final List<T> _innerList = new List();
final List<T> _filterBackup = new List();
StreamController<ListChangedEvent<T>> _onChange;
@@ -118,8 +119,8 @@ class ObservableList<T> extends ListBase<T> {
@override
void clear() {
_fire(new ListChangedEvent<T>(ListChangeType.CLEAR));
_innerList.clear();
_clearList();
_clearFilter();
}
@override
@@ -150,11 +151,65 @@ class ObservableList<T> extends ListBase<T> {
itemsToRemove.forEach((final T element) => remove(element));
}
@override
void retainWhere(bool test(final T element)) {
final List<T> itemsToRemove = new List<T>();
_innerList.forEach((final T element) {
// remove items where test fails
if(test(element) == false) {
itemsToRemove.add(element);
}
});
itemsToRemove.forEach((final T element) => remove(element));
}
/// Filter items in list
///
/// final String text = filter.value.trim();
///
/// if(text.isNotEmpty) {
/// components.filter((final HackintoshComponent element) => element.name.contains(text));
/// } else {
/// components.resetFilter();
/// }
///
void filter(bool test(final T element)) {
if(_filterBackup.isEmpty) {
_filterBackup.addAll(_innerList);
}
_clearList();
addAll(_filterBackup.where(test));
}
/// Resets the item-List to it's original stand
void resetFilter() {
if(_filterBackup.isNotEmpty) {
_clearList();
addAll(_filterBackup);
_filterBackup.clear();
}
}
//- private -----------------------------------------------------------------------------------
void _fire(final ListChangedEvent<T> event) {
if( _onChange != null && _onChange.hasListener) {
_onChange.add(event);
}
}
/// Remove all items from list (DOM + innerList)
void _clearList() {
_fire(new ListChangedEvent<T>(ListChangeType.CLEAR));
_innerList.clear();
}
/// Remove items backed up items for filter
void _clearFilter() {
_filterBackup.clear();
}
}
@@ -223,8 +223,13 @@ class MaterialRepeat extends MdlTemplateComponent {
if(_items.isNotEmpty) {
_items.clear();
//element.children.clear();
element.children.removeWhere( (final dom.Element element) =>
!element.classes.contains(_cssClasses.KEEP_THIS_ELEMENT));
element.children.removeWhere( (final dom.Element element) {
if(!element.classes.contains(_cssClasses.KEEP_THIS_ELEMENT)) {
componentHandler().downgradeElement(element);
return true;
}
return false;
});
}
new Future(() {
completer.complete();
@@ -250,7 +255,15 @@ class MaterialRepeat extends MdlTemplateComponent {
final dom.Element templateTag = _templateTag;
_template = templateTag.innerHtml.trim().replaceAll(new RegExp(r"\s+")," ").replaceAll(new RegExp(r""),"");
_logger.fine("Template: |${_template}|");
// Hack around strange innerHtml behaviour:
// This
// <input type="checkbox" {{#component.checked}} checked {{/component.checked}} >
// imports as
// <input type="checkbox" {{#component.checked}}="" checked="" {{="" component.checked}}="">
//
_template = _template.replaceAll('}}=""',"}}").replaceAll('{{=""',"{{/");
_logger.info("Template: |${_template}|");
templateTag.remove();
_mustacheTemplate = new Template(template,htmlEscapeValues: false);

0 comments on commit 27ac384

Please sign in to comment.