Skip to content

Instantly share code, notes, and snippets.

@spncrlkt
Created September 16, 2015 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spncrlkt/9cde417ed43f751a3757 to your computer and use it in GitHub Desktop.
Save spncrlkt/9cde417ed43f751a3757 to your computer and use it in GitHub Desktop.
Inline editable tree, inputs lose focus onChange
import React from 'react';
import component from 'omniscient';
import immstruct from 'immstruct';
let d = React.DOM;
component.debug();
/* DATA */
/* inline or lazy loaded from API/local file/etc */
let structure = immstruct({
search: '',
tree: { title: 'TreeView', editing: false, children: [
{ title: 'Cool 1', editing: false, children: [
{ title: 'files', editing: false } ,
{ title: 'other stuff', editing: false, children: [
{ title: 'inside stuff', editing: false },
]},
]},
{ title: 'Good 2', editing: false, children: [
{ title: 'super 1', editing: false, children: [
{ title: 'stuff in super 1 1', editing: false, children: [
{ title: '4th aodimension', editing: false },
{ title: '4th dimensienthon', editing: false },
]},
{ title: 'stuff in netshsuper 1 1', editing: false, children: [
{ title: '4th dimensasnthion', editing: false },
{ title: '4th dimensisntehaon', editing: false },
]},
]},
{ title: 'super 2', editing: false, children: []}
]},
]}
});
/* EDITABLE STUFF */
var FocusOnRender = {
componentDidMount: function () {
//this.getDOMNode().select();
}
};
var FocusingInput = component(FocusOnRender, function (cursor, statics) {
var onChange = statics.onChange || function () {};
return d.input({ value: cursor.get('title'), onChange: onChange });
});
var EditMixin = {
onEdit: function () {
this.props.leaf.set('editing', true);
},
onSubmit: function (e) {
e.preventDefault();
this.props.leaf.set('editing', false);
},
onChange: function (e) {
this.props.leaf.update(function (state) {
var test = state.merge({'title': e.currentTarget.value});
return test;
});
},
}
var Editable = component(EditMixin, function ({leaf}) {
if (leaf.get('editing')) {
return d.form({ onSubmit: this.onSubmit },
FocusingInput(leaf, { onChange: this.onChange }),
d.button({}, 'Save'));
}
return d.span({ onClick: this.onEdit }, leaf.get('title'));
});
/* TREE STUFF */
var TreeView = component('TreeView', function (cursor) {
return d.div({}, RootNode(cursor.cursor('tree')));
});
var RootNode = component('RootNode', function (cursor) {
var rootsChildren = cursor.get('children')
return d.div({},
rootsChildren.toArray().map(function (child, i) {
return Node('node-' + child.get('title'), child);
})
);
});
var Node = component('Node', function (cursor) {
var children = cursor.get('children');
var nodeTitle = cursor.get('title');
if (typeof children === 'undefined' || children.size === 0) {
return Leaf('leaf-' + nodeTitle, cursor);
} else {
return d.div({},
Leaf('node-title-' + nodeTitle, cursor),
d.ul({},
children.toArray().map(function(child, i) {
return Node('node-' + child.get('title'), child);
})
)
);
}
});
var Leaf = component('Leaf', function (cursor) {
return d.li({ style: { cursor: 'pointer' } }, Editable({ leaf: cursor }));
});
/* RENDER CALLS */
render();
structure.on('swap', render);
function render () {
React.render(
TreeView(structure.cursor()),
document.body
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment