Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select editor with records #243

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
826 changes: 492 additions & 334 deletions demo/js/demo.bundle.js

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions dist/react-bootstrap-table.min.js

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions examples/js/cell-edit/combo-edit-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { Component } from 'react';
import addProducts from '../utils/addProducts';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';

const log = o => console.log(o);

const cellEditProp = {
mode: "click",
afterSaveCell: log
};

const classifier = [
{ id: 2100, text: "$2100" },
{ id: 2101, text: "$2101" },
{ id: 2102, text: "$2102" },
{ id: 2103, text: "$2103" },
{ id: 2104, text: "$2104" }
];

const editable = {
type: "select",
options: {}
};

export default class ComboEditTable extends Component {

render(){
return (
<BootstrapTable data={addProducts(5)} cellEdit={cellEditProp}>
<TableHeaderColumn dataField="id" isKey={true}>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField="name">Product Name</TableHeaderColumn>
<TableHeaderColumn dataField="price"
displayField="text"
valueField="id"
editable={editable}
classifier={classifier}>Product Price
</TableHeaderColumn>
</BootstrapTable>
);
}

}
10 changes: 10 additions & 0 deletions examples/js/cell-edit/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import DbClickToEditTable from './dbclick-to-edit-table';
import BlurToSaveTable from './blur-to-save-table';
import CellEditHookTable from './cell-edit-hook-table';
import NonEditableTable from './non-editable-table';
import ComboEditTable from './combo-edit-table';

class Demo extends React.Component {
render() {
Expand Down Expand Up @@ -54,6 +55,15 @@ class Demo extends React.Component {
</div>
</div>
</div>
<div className="col-md-offset-1 col-md-8">
<div className="panel panel-default">
<div className="panel-heading">Combobox Editor Example&nbsp;(Press ENTER to save, ESC to cancel)</div>
<div className="panel-body">
<h5>Source in /examples/js/cell-edit/combo-edit-table.js</h5>
<ComboEditTable />
</div>
</div>
</div>
</div>
);
}
Expand Down
15 changes: 15 additions & 0 deletions examples/js/utils/addProducts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default function addProducts (quantity) {
var products = [];
var startId = products.length;

for (var i = 0; i < quantity; i++) {
var id = startId + i;
products.push({
id: id,
name: "Item name " + id,
price: 2100 + i
});
}

return products;
}
5 changes: 4 additions & 1 deletion src/BootstrapTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ class BootstrapTable extends React.Component {
width: column.props.width,
text: column.props.children,
sortFunc: column.props.sortFunc,
index: i
index: i,
classifier: column.props.classifier,
displayField: column.props.displayField,
valueField: column.props.valueField
};
});
}
Expand Down
25 changes: 12 additions & 13 deletions src/Editor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';
var Editor=function(editable, attr, format, editorClass, defaultValue){
import ComboBoxEditor from './editors/ComboBoxEditor';

var Editor=function(editable, attr, format, editorClass, defaultValue, classifier, displayField, valueField){


if(editable===true||typeof editable==="string"){//simple declare
Expand All @@ -25,18 +27,15 @@ var Editor=function(editable, attr, format, editorClass, defaultValue){
(editable.className?(" "+editable.className):"");

if(editable.type === 'select'){//process select input
var options = [], values=editable.options.values;
if(Array.isArray(values)){//only can use arrray data for options
var rowValue;
options=values.map(function(d,i){
rowValue=format?format(d):d;
return(
<option key={'option'+i} value={d}>{rowValue}</option>
)
});
}
return(
<select {...attr} defaultValue={defaultValue}>{options}</select>
return (
<ComboBoxEditor ref={attr.ref}
options={editable.options}
attr={attr}
defaultValue={defaultValue}
classifier={classifier}
displayField={displayField}
valueField={valueField}
format={format} />
);
} else if(editable.type === 'textarea'){//process textarea input
//put other if exist
Expand Down
33 changes: 32 additions & 1 deletion src/TableBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,27 @@ class TableBody extends React.Component{
this.adjustBody();
}

getFieldValue(data, column) {
const { valueField, displayField, classifier, name } = column;
let fieldValue = data[name];

if (classifier) {
const valueById = o => {
return o[valueField] == fieldValue;
};
const fromClassifier = (cls, fn) => {
let value;
const rec = cls.find(fn);
if (rec) value = rec[displayField];
return value;
};

fieldValue = fromClassifier(classifier, valueById);
}

return fieldValue;
}

render(){
var containerClasses = classSet("table-container");

Expand All @@ -43,7 +64,8 @@ class TableBody extends React.Component{

var tableRows = this.props.data.map(function(data, r){
var tableColumns = this.props.columns.map(function(column, i){
var fieldValue = data[column.name];
// var fieldValue = data[column.name];
var fieldValue = this.getFieldValue(data, column);
if(this.editing &&
column.name !== this.props.keyField && // Key field can't be edit
column.editable && // column is editable? default is true, user can set it false
Expand All @@ -62,6 +84,9 @@ class TableBody extends React.Component{
key={i}
blurToSave={this.props.cellEdit.blurToSave}
rowIndex={r}
classifier={column.classifier}
displayField={column.displayField}
valueField={column.valueField}
colIndex={i}>
{fieldValue}
</TableEditColumn>
Expand All @@ -81,6 +106,9 @@ class TableBody extends React.Component{
className={tdClassName}
cellEdit={this.props.cellEdit}
hidden={column.hidden}
classifier={column.classifier}
displayField={column.displayField}
valueField={column.valueField}
onEdit={this.handleEditCell.bind(this)}
width={column.width}>
{formattedValue}
Expand All @@ -93,6 +121,9 @@ class TableBody extends React.Component{
className={tdClassName}
cellEdit={this.props.cellEdit}
hidden={column.hidden}
classifier={column.classifier}
displayField={column.displayField}
valueField={column.valueField}
onEdit={this.handleEditCell.bind(this)}
width={column.width}>
{fieldValue}
Expand Down
1 change: 0 additions & 1 deletion src/TableColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ class TableColumn extends React.Component{
classname += " col-md-"+width;
}


var opts = {};
if(this.props.cellEdit){
if(this.props.cellEdit.mode == Const.CELL_EDIT_CLICK){
Expand Down
22 changes: 12 additions & 10 deletions src/TableEditColumn.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ class TableEditColumn extends React.Component{
}
componentDidMount(){
var input = this.refs.inputRef;
if (React.isValidElement(input)) { // editor input is wrapped in React element
input = input.refs.inputRef
}
// input.value = this.props.children||'';
input.focus();
}
Expand All @@ -75,20 +78,19 @@ class TableEditColumn extends React.Component{
}

render(){
var editable=this.props.editable,
format=this.props.format,
attr={
ref:"inputRef",
onKeyDown:this.handleKeyPress.bind(this),
onBlur:this.handleBlur.bind(this)
};
//put placeholder if exist
editable.placeholder&&(attr.placeholder=editable.placeholder);
var { editable, format, classifier, displayField, valueField } = this.props;
var attr={
ref:"inputRef",
onKeyDown:this.handleKeyPress.bind(this),
onBlur:this.handleBlur.bind(this)
};
//put placeholder if exist
editable.placeholder&&(attr.placeholder=editable.placeholder);

var editorClass=classSet({'animated':this.state.shakeEditor,'shake':this.state.shakeEditor});
return(
<td ref="td" style={{position:'relative'}}>
{Editor(editable,attr,format,editorClass,this.props.children||'')}
{Editor(editable,attr,format,editorClass,this.props.children||'', classifier, displayField, valueField)}
<Notifier ref="notifier"></Notifier>
</td>
)
Expand Down
63 changes: 63 additions & 0 deletions src/editors/ComboBoxEditor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, { Component, PropTypes } from 'react';

export default class ComboBoxEditor extends Component {

static propTypes = {
options: PropTypes.object.isRequired,
format: PropTypes.oneOfType([
PropTypes.func,
PropTypes.bool
]),
attr: PropTypes.object.isRequired,
defaultValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
classifier: PropTypes.arrayOf(PropTypes.object),
displayField: PropTypes.string,
valueField: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
])
};

formatValue(value) {
const format = this.props.format;
return format ? format(value) : value;
}

createFromArray(values) {
return values.map((v, i) =>
<option key={'option'+i} value={v}>{this.formatValue(v)}</option>
);
}

createFromClassifier(values, displayField, valueField) {
const optionsFromRec = (v, i) => {
const value = v[valueField];
let text = v[displayField];

return <option key={'option'+ value} value={value}>{this.formatValue(text)}</option>;
};

return values.map(optionsFromRec);
}

createOptions() {
const { options: { values }, classifier, displayField, valueField} = this.props;
if (classifier) {
return this.createFromClassifier(classifier, displayField, valueField);
}
else return this.createFromArray(values);
}

render() {
const { attr, defaultValue } = this.props;
const selectOptions = this.createOptions();

return (
<select {...attr} defaultValue={defaultValue}>{selectOptions}</select>
);
}

}