Newer
Older
import m from 'mithril';
import Stream from 'mithril/stream';
import {
List, ListTile, Search, IconButton, Button, Toolbar,
ToolbarTitle,
} from 'polythene-mithril';
import infinite from 'mithril-infinite';
import { icons, BackButton, ClearButton, SearchIcon } from './elements';
class SearchField {
oninit() {
this.value = Stream('');
this.setInputState = Stream();
// const clear = () => setInputState()({ value: '', focus: false});
this.clear = () => this.value('');
this.leave = () => this.value('');
}
view({ state, attrs }) {
// incoming value and focus added for result list example:
const value = attrs.value !== undefined ? attrs.value : state.value();
return m(Search, Object.assign(
{},
{
textfield: {
label: 'type here',
onChange: (newState) => {
state.value(newState.value);
state.setInputState(newState.setInputState);
// onChange callback added for result list example:
if (attrs.onChange) attrs.onChange(newState, state.setInputState);
value,
defaultValue: attrs.defaultValue,
},
buttons: {
focus: {
before: m(BackButton, { leave: state.leave }),
},
focus_dirty: {
before: m(BackButton, { leave: state.leave }),
after: m(ClearButton, { clear: state.clear }),
},
dirty: {
before: m(BackButton, { leave: state.leave }),
after: m(ClearButton, { clear: state.clear }),
export default class SelectList {
constructor({ attrs: { listTileAttrs, onSelect = false } }) {
this.searchValue = '';
this.listTileAttrs = listTileAttrs;
this.onSelect = onSelect;
// initialize the Selection
this.selected = null;
}
onupdate({ attrs: { selection = null } }) {
// make it possible to change the selection from outside, e.g. to set the field to an
// existing group moderator
if (selection) this.selected = selection;
item() {
return (data) => {
const attrs = {
compactFront: true,
hoverable: true,
className: 'themed-list-tile',
events: {
onclick: () => {
if (this.onSelect) { this.onSelect(data); }
this.selected = data;
this.showList = false;
},
},
};
// Overwrite default attrs
Object.assign(attrs, this.listTileAttrs(data));
return m(ListTile, attrs);
};
}
m(Toolbar, { compact: true, style: { background: 'rgb(78, 242, 167)' } }, this.selected ? [
icon: { svg: m.trust(icons.clear) },
events: {
onclick: () => {
if (this.onSelect) { this.onSelect(null); }
this.selected = null;
},
},
m(ToolbarTitle, { text: selectedText(this.selected) }),
label: 'Submit',
className: 'blue-button',
events: {
onclick: () => {
onSubmit(this.selected);
this.selected = null;
controller.setSearch('');
controller.refresh();
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
] : [
m(SearchField, Object.assign({}, {
style: { background: 'rgb(78, 242, 167)' },
onChange: ({ value, focus }) => {
// onChange is called either if the value or focus fo the SearchField
// changes.
// At value change we want to update the search
// at focus changt we hie the list of results. As focus change also
// happens while clicking on an item in the list of results, the list
// is hidden after a short Timeout that has to be sufficiently long
// to register the onclick of the listitem. Can be a problem for different
// OS and browsers.
if (focus) {
this.showList = true;
} else if (!focus) {
// don't close the list immidiately, as 'out of focus' could
// also mean that the user is clicking on a list item
setTimeout(() => { this.showList = false; m.redraw(); }, 500);
}
if (value !== this.searchValue) {
// if we always update the search value, this would also happen
// immidiately in the moment where we click on the listitem.
// Then, the list get's updated before the click is registered.
// So, we make sure this state change is due to value change and
// not due to focus change.
this.searchValue = value;
controller.debouncedSearch(value);
}
},
})),
onCancel ? m(Button, {
label: 'cancel',
className: 'blue-button',
events: { onclick: onCancel },
}) : '',
]),
(this.showList && !this.selected) ? m(List, {
style: { height: '400px', 'background-color': 'white' },
tiles: m(infinite, controller.infiniteScrollParams(this.item())),