체크박스 목록

Checkbox List 셀 타입은 사용자에게 셀 내에 나열된 옵션 목록에서 여러 항목을 선택하는 기능을 제공합니다.

다음 코드를 사용하여 체크박스 목록 셀을 만듭니다. 체크박스 목록에는 라디오 목록과 동일한 메서드가 포함됩니다. 예:
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);