다음 코드를 사용하여 체크박스 목록 셀을 만듭니다.
체크박스 목록에는 라디오 목록과 동일한 메서드가 포함됩니다.
예:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import './styles.css';
import { AppFunc } from './app-func';
// import { App } from './app-class';
// 1. Functional Component sample
ReactDOM.render(<AppFunc />, document.getElementById('app'));
// 2. Class Component sample
// ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react';
import '@mescius/spread-sheets-resources-ko';
GC.Spread.Common.CultureManager.culture("ko-kr");
let spread = null;
export function AppFunc() {
const getEnumArray = (spreadEnum) => {
const newEnum = {};
for (const key of Object.keys(spreadEnum)) {
if ( isNaN( Number(key) ) ) {
newEnum[key] = spreadEnum[key];
}
}
return newEnum;
}
const [checkboxListOption, setCheckboxListOption] = React.useState({
itemsList: [],
directionList: getEnumArray(GC.Spread.Sheets.CellTypes.Direction),
direction: 0,
alignList: getEnumArray(GC.Spread.Sheets.CellTypes.TextAlign),
textAlign: 2,
flowLayout: true,
maxRowCount: 2,
maxColumnCount: 2,
itemHorizontalSpacing: 8,
itemVerticalSpacing: 2,
boxSize: 12,
});
const initSpread = (currSpread) => {
spread = currSpread;
const sheet = spread.getSheet(0);
sheet.suspendPaint();
const radio = new GC.Spread.Sheets.CellTypes.CheckBoxList();
radio.items([
{ text: "sample1", value: "0" },
{ text: "sample2", value: "1" },
{ text: "sample3", value: "2" },
]);
sheet.setCellType(0, 1, radio);
sheet.defaults.rowHeight = 50;
sheet.defaults.colWidth = 200;
sheet.resumePaint();
}
const initEvent = () => {
spread.bind(GC.Spread.Sheets.Events.SelectionChanged, () => {
const sheet = spread.getActiveSheet();
const row = sheet.getActiveRowIndex();
const column = sheet.getActiveColumnIndex();
const cellType = sheet.getCellType(row, column);
if (cellType instanceof GC.Spread.Sheets.CellTypes.CheckBoxList) {
readSetting(cellType);
} else {
readSetting(new GC.Spread.Sheets.CellTypes.CheckBoxList());
}
});
}
const onItemsAdd = () => {
const { itemsList } = checkboxListOption;
const newItemsList = [...itemsList];
const d = new Date();
d.setMonth(d.getMonth() + itemsList.length);
const str = d.getFullYear() + "-" + (d.getMonth() + 1);
newItemsList.push({ text: str, value: str });
setCheckboxListOption({...checkboxListOption, itemsList: newItemsList});
}
const onItemsRemove = () => {
const { itemsList } = checkboxListOption;
const newItemsList = [...itemsList];
newItemsList.pop();
setCheckboxListOption({...checkboxListOption, itemsList: newItemsList});
}
const readSetting = (cellType) => {
if (!cellType) {
cellType = new GC.Spread.Sheets.CellTypes.CheckBoxList();
}
const itemsList = cellType.items();
const direction = cellType.direction();
const textAlign = cellType.textAlign();
const flowLayout = cellType.isFlowLayout();
const maxRowCount = cellType.maxRowCount();
const maxColumnCount = cellType.maxColumnCount();
const boxSize = cellType.boxSize();
const { horizontal: itemHorizontalSpacing, vertical: itemVerticalSpacing } = cellType.itemSpacing();
setCheckboxListOption({ ...checkboxListOption, itemsList, direction, textAlign, flowLayout, maxRowCount, maxColumnCount, itemHorizontalSpacing, itemVerticalSpacing, boxSize:boxSize });
}
const applySetting = (settings) => {
const sheet = spread.getActiveSheet();
const row = sheet.getActiveRowIndex();
const column = sheet.getActiveColumnIndex();
const cellType = new GC.Spread.Sheets.CellTypes.CheckBoxList();
if (settings) {
cellType.items(settings.itemsList);
cellType.direction(settings.direction);
cellType.textAlign(settings.textAlign);
cellType.isFlowLayout(settings.flowLayout);
cellType.maxRowCount(settings.maxRowCount);
cellType.maxColumnCount(settings.maxColumnCount);
cellType.itemSpacing({ horizontal: settings.itemHorizontalSpacing, vertical: settings.itemVerticalSpacing });
var boxSizeValue = settings.boxSize;
var boxSize = Number(boxSizeValue);
if (isNaN(boxSize)) {
cellType.boxSize(boxSizeValue);
} else {
cellType.boxSize(boxSize);
}
sheet.getCell(row, column).cellType(cellType);
}
}
return (<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => { initSpread(spread); initEvent(); readSetting() }}>
<Worksheet />
<Worksheet />
</SpreadSheets>
</div>
<Panel onItemsAdd={onItemsAdd} onItemsRemove={onItemsRemove} applySetting={applySetting} setting={checkboxListOption} />
</div>);
}
function Panel(props) {
const [setting, setSetting] = React.useState(props.setting);
React.useEffect(() => {
setSetting(props.setting);
}, [props.setting]);
const itemsListJSX = () => {
return setting.itemsList.map((item) => {
return <option value={item.value}>{ item.text }</option>;
});
};
const directionListJSX = () => {
return Object.keys(setting.directionList).map((key) => {
return <div class="radio-item">
<input
type="radio"
id={'direction-' + key}
checked={Number(setting.direction) === setting.directionList[key]}
value={setting.directionList[key]}
onChange={(e) => {setSetting({ ...setting, direction: Number(e.target.value) })}}
/>
<label for={'direction-' + key}>{ key }</label>
</div>;
});
};
const alignListJSX = () => {
return Object.keys(setting.alignList).map((key) => {
return <div class="radio-item">
<input
type="radio"
id={'textAlign-' + key}
checked={Number(setting.textAlign) === setting.alignList[key]}
value={setting.alignList[key]}
onChange={(e) => {setSetting({ ...setting, textAlign: Number(e.target.value) })}}
/>
<label for={'textAlign-' + key}>{ key }</label>
</div>;
});
};
return (
<div class="options-container">
<div class="option-row">
<p>Change any options below then press the Set button to apply your changes.</p>
<label>Items:</label>
</div>
<div class="option-row">
<select id="items" size="5">
{ itemsListJSX() }
</select>
<input type="button" id="addItem" value="Add" onClick={() => {props.onItemsAdd()}} />
<input type="button" id="removeItem" value="Remove" onClick={() => {props.onItemsRemove()}} />
</div>
<hr />
<div class="option-row">
<label>Direction:</label>
</div>
<div class="option-row">
{ directionListJSX() }
</div>
<div class="option-row">
<label>Text Align:</label>
</div>
<div class="option-row">
{ alignListJSX() }
</div>
<hr />
<div class="option-row">
<label for="flowLayout">Flow Layout:</label>
<input id="flowLayout" type="checkbox" checked={setting.flowLayout} onChange={(e) => { setSetting({ ...setting, flowLayout: e.target.checked })}} />
</div>
<div class="option-row" id="rowCountDiv" style={{display: !setting.flowLayout && setting.direction === 1 ? 'block' : 'none'}}>
<label for="rowCount">Max Row Count:</label>
<input type="text" id="rowCount" value={setting.maxRowCount} onChange={(e) => {setSetting({ ...setting, maxRowCount: Number(e.target.value) })}} />
</div>
<div class="option-row" id="columnCountDiv" style={{display: !setting.flowLayout && setting.direction === 0 ? 'block' : 'none'}}>
<label for="columnCount">Max Column Count:</label>
<input type="text" id="columnCount" value={setting.maxColumnCount} onChange={(e) => {setSetting({ ...setting, maxColumnCount: Number(e.target.value) })}} />
</div>
<div class="option-row">
<label for="space-horizontal">Item horizontal Spacing:</label>
<input type="text" id="space-horizontal" value={setting.itemHorizontalSpacing} onChange={(e) => {setSetting({ ...setting, itemHorizontalSpacing: Number(e.target.value) })}} />
</div>
<div class="option-row">
<label for="space-vertical">Item vertical Spacing:</label>
<input type="text" id="space-vertical" value={setting.itemVerticalSpacing} onChange={(e) => {setSetting({ ...setting, itemVerticalSpacing: Number(e.target.value) })}} />
</div>
<hr />
<div class="option-row">
<label for="boxSize">boxSize:</label>
<input type="text" id="boxSize" class="boxSize" value={setting.boxSize} onChange={(e) => {setSetting({ ...setting, boxSize: e.target.value })}} />
</div>
<div class="option-row">
<input type="button" id="setProperty" value="Set" onClick={() => {props.applySetting(setting)}} />
</div>
</div>
);
}
import * as React from 'react';
import GC from '@mescius/spread-sheets';
import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react';
import '@mescius/spread-sheets-resources-ko';
GC.Spread.Common.CultureManager.culture("ko-kr");
const Component = React.Component;
export class App extends Component {
constructor(props) {
super(props);
this.spread = null;
this.state = {
itemsList: [],
directionList: this.getEnumArray(GC.Spread.Sheets.CellTypes.Direction),
direction: 0,
alignList: this.getEnumArray(GC.Spread.Sheets.CellTypes.TextAlign),
textAlign: 2,
flowLayout: true,
maxRowCount: 2,
maxColumnCount: 2,
itemHorizontalSpacing: 8,
itemVerticalSpacing: 2,
boxSize: 12,
}
}
render() {
return (<div class="sample-tutorial">
<div class="sample-spreadsheets">
<SpreadSheets workbookInitialized={spread => { this.initSpread(spread); this.initEvent(spread); this.readSetting() }}>
<Worksheet />
<Worksheet />
</SpreadSheets>
</div>
<Panel onItemsAdd={() => {this.onItemsAdd()}} onItemsRemove={() => {this.onItemsRemove()}} applySetting={(settings) => {this.applySetting(settings)}} setting={this.state} />
</div>);
}
initSpread(spread) {
this.spread = spread;
const sheet = spread.getSheet(0);
sheet.suspendPaint();
const radio = new GC.Spread.Sheets.CellTypes.CheckBoxList();
radio.items([
{ text: "sample1", value: "0" },
{ text: "sample2", value: "1" },
{ text: "sample3", value: "2" },
]);
sheet.setCellType(0, 1, radio);
sheet.defaults.rowHeight = 50;
sheet.defaults.colWidth = 200;
sheet.resumePaint();
}
initEvent(spread) {
spread.bind(GC.Spread.Sheets.Events.SelectionChanged, () => {
const sheet = spread.getActiveSheet();
const row = sheet.getActiveRowIndex();
const column = sheet.getActiveColumnIndex();
const cellType = sheet.getCellType(row, column);
if (cellType instanceof GC.Spread.Sheets.CellTypes.CheckBoxList) {
this.readSetting(cellType);
} else {
this.readSetting(new GC.Spread.Sheets.CellTypes.CheckBoxList());
}
});
}
onItemsAdd() {
const { itemsList } = this.state;
const newItemsList = [...itemsList];
const d = new Date();
d.setMonth(d.getMonth() + itemsList.length);
const str = d.getFullYear() + "-" + (d.getMonth() + 1);
newItemsList.push({ text: str, value: str });
this.setState({ itemsList: newItemsList });
}
onItemsRemove() {
const { itemsList } = this.state;
const newItemsList = [...itemsList];
newItemsList.pop();
this.setState({ itemsList: newItemsList });
}
readSetting(cellType) {
if (!cellType) {
cellType = new GC.Spread.Sheets.CellTypes.CheckBoxList();
}
const itemsList = cellType.items();
const direction = cellType.direction();
const textAlign = cellType.textAlign();
const flowLayout = cellType.isFlowLayout();
const maxRowCount = cellType.maxRowCount();
const maxColumnCount = cellType.maxColumnCount();
const boxSize = cellType.boxSize();
const { horizontal: itemHorizontalSpacing, vertical: itemVerticalSpacing } = cellType.itemSpacing();
this.setState({ itemsList, direction, textAlign, flowLayout, maxRowCount, maxColumnCount, itemHorizontalSpacing, itemVerticalSpacing, boxSize:boxSize });
}
applySetting(settings) {
const sheet = this.spread.getActiveSheet();
const row = sheet.getActiveRowIndex();
const column = sheet.getActiveColumnIndex();
const cellType = new GC.Spread.Sheets.CellTypes.CheckBoxList();
if (settings) {
cellType.items(settings.itemsList);
cellType.direction(settings.direction);
cellType.textAlign(settings.textAlign);
cellType.isFlowLayout(settings.flowLayout);
cellType.maxRowCount(settings.maxRowCount);
cellType.maxColumnCount(settings.maxColumnCount);
cellType.itemSpacing({ horizontal: settings.itemHorizontalSpacing, vertical: settings.itemVerticalSpacing });
var boxSizeValue = settings.boxSize;
var boxSize = Number(boxSizeValue);
if (isNaN(boxSize)) {
cellType.boxSize(boxSizeValue);
} else {
cellType.boxSize(boxSize);
}
sheet.getCell(row, column).cellType(cellType);
}
}
getEnumArray(spreadEnum) {
const newEnum = {};
for (const key of Object.keys(spreadEnum)) {
if ( isNaN( Number(key) ) ) {
newEnum[key] = spreadEnum[key];
}
}
return newEnum;
}
}
class Panel extends Component {
constructor(props) {
super(props);
this.state = this.props.setting;
}
componentWillReceiveProps(nextProps) {
this.setState(nextProps.setting);
}
render() {
const itemsListJSX = () => {
return this.state.itemsList.map((item) => {
return <option value={item.value}>{ item.text }</option>;
});
};
const directionListJSX = () => {
return Object.keys(this.state.directionList).map((key) => {
return <div class="radio-item">
<input
type="radio"
id={'direction-' + key}
checked={Number(this.state.direction) === this.state.directionList[key]}
value={this.state.directionList[key]}
onChange={(e) => {this.setState({ direction: Number(e.target.value) })}}
/>
<label for={'direction-' + key}>{ key }</label>
</div>;
});
};
const alignListJSX = () => {
return Object.keys(this.state.alignList).map((key) => {
return <div class="radio-item">
<input
type="radio"
id={'textAlign-' + key}
checked={Number(this.state.textAlign) === this.state.alignList[key]}
value={this.state.alignList[key]}
onChange={(e) => {this.setState({ textAlign: Number(e.target.value) })}}
/>
<label for={'textAlign-' + key}>{ key }</label>
</div>;
});
};
return (
<div class="options-container">
<div class="option-row">
<p>Change any options below then press the Set button to apply your changes.</p>
<label>Items:</label>
</div>
<div class="option-row">
<select id="items" size="5">
{ itemsListJSX() }
</select>
<input type="button" id="addItem" value="Add" onClick={() => {this.props.onItemsAdd()}} />
<input type="button" id="removeItem" value="Remove" onClick={() => {this.props.onItemsRemove()}} />
</div>
<hr />
<div class="option-row">
<label>Direction:</label>
</div>
<div class="option-row">
{ directionListJSX() }
</div>
<div class="option-row">
<label>Text Align:</label>
</div>
<div class="option-row">
{ alignListJSX() }
</div>
<hr />
<div class="option-row">
<label for="flowLayout">Flow Layout:</label>
<input id="flowLayout" type="checkbox" checked={this.state.flowLayout} onChange={(e) => { this.setState({ flowLayout: e.target.checked })}} />
</div>
<div class="option-row" id="rowCountDiv" style={{display: !this.state.flowLayout && this.state.direction === 1 ? 'block' : 'none'}}>
<label for="rowCount">Max Row Count:</label>
<input type="text" id="rowCount" value={this.state.maxRowCount} onChange={(e) => {this.setState({ maxRowCount: Number(e.target.value) })}} />
</div>
<div class="option-row" id="columnCountDiv" style={{display: !this.state.flowLayout && this.state.direction === 0 ? 'block' : 'none'}}>
<label for="columnCount">Max Column Count:</label>
<input type="text" id="columnCount" value={this.state.maxColumnCount} onChange={(e) => {this.setState({ maxColumnCount: Number(e.target.value) })}} />
</div>
<div class="option-row">
<label for="space-horizontal">Item horizontal Spacing:</label>
<input type="text" id="space-horizontal" value={this.state.itemHorizontalSpacing} onChange={(e) => {this.setState({ itemHorizontalSpacing: Number(e.target.value) })}} />
</div>
<div class="option-row">
<label for="space-vertical">Item vertical Spacing:</label>
<input type="text" id="space-vertical" value={this.state.itemVerticalSpacing} onChange={(e) => {this.setState({ itemVerticalSpacing: Number(e.target.value) })}} />
</div>
<hr />
<div class="option-row">
<label for="boxSize">boxSize:</label>
<input type="text" id="boxSize" class="boxSize" value={this.state.boxSize} onChange={(e) => {this.setState({ boxSize: e.target.value })}} />
</div>
<div class="option-row">
<input type="button" id="setProperty" value="Set" onClick={() => {this.props.applySetting(this.state)}} />
</div>
</div>
)
}
}
<!doctype html>
<html style="height:100%;font-size:14px;">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<!-- SystemJS -->
<script src="$DEMOROOT$/ko/react/node_modules/systemjs/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('$DEMOROOT$/ko/lib/react/license.js').then(function () {
System.import('./src/app');
});
</script>
</head>
<body>
<div id="app"></div>
</body>
</html>
.sample-tutorial {
position: relative;
height: 100%;
overflow: hidden;
}
.sample-spreadsheets {
width: calc(100% - 280px);
height: 100%;
overflow: hidden;
float: left;
}
.boxSize {
display: block;
}
.options-container {
float: right;
width: 280px;
padding: 12px;
height: 100%;
box-sizing: border-box;
background: #fbfbfb;
overflow: auto;
}
.option-row {
font-size: 14px;
padding: 5px;
}
.option-row {
padding-bottom: 5px;
}
label {
display: inline-block;
}
input {
padding: 4px 8px;
box-sizing: border-box;
}
select {
width: 100%;
}
input[type="checkbox"] + label {
display: inline-block;
width: auto;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#app {
height: 100%;
}
(function (global) {
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true,
react: true
},
meta: {
'*.css': { loader: 'css' }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
'@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js',
'@mescius/spread-sheets-resources-ko': 'npm:@mescius/spread-sheets-resources-ko/index.js',
'@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js',
'@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js',
'react': 'npm:react/umd/react.production.min.js',
'react-dom': 'npm:react-dom/umd/react-dom.production.min.js',
'css': 'npm:systemjs-plugin-css/css.js',
'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js',
'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
src: {
defaultExtension: 'jsx'
},
"node_modules": {
defaultExtension: 'js'
},
}
});
})(this);