antd#Cascader JavaScript Examples
The following examples show how to use
antd#Cascader.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js From gobench with Apache License 2.0 | 6 votes |
render() {
return (
<div>
<h5 className="mb-3">
<strong>Basic</strong>
</h5>
<div className="mb-5">
<Cascader options={options} onChange={onChange} placeholder="Please select" />
</div>
</div>
)
}
Example #2
Source File: custom-render.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/cascader', module).add('custom-render', () =>
<Cascader
options={options}
defaultValue={['zhejiang', 'hangzhou', 'xihu']}
displayRender={displayRender}
style={{ width: '100%' }}
/>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>For instance, add an external link after the selected value.</p></>) } });
Example #3
Source File: custom-trigger.jsx From virtuoso-design-system with MIT License | 6 votes |
render() {
return (
<span>
{this.state.text}
<Cascader options={options} onChange={this.onChange}>
<a href="#">Change city</a>
</Cascader>
</span>
);
}
Example #4
Source File: fields-name.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/cascader', module).add('fields-name', () =>
<Cascader
fieldNames={{ label: 'name', value: 'code', children: 'items' }}
options={options}
onChange={onChange}
placeholder="Please select"
/>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Custom field names.</p></>) } });
Example #5
Source File: hover.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/cascader', module).add('hover', () =>
<Cascader
options={options}
expandTrigger="hover"
displayRender={displayRender}
onChange={onChange}
/>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Hover to expand sub menu, click to select option.</p></>) } });
Example #6
Source File: lazy.jsx From virtuoso-design-system with MIT License | 6 votes |
LazyOptions = () => {
const [options, setOptions] = React.useState(optionLists);
const onChange = (value, selectedOptions) => {
console.log(value, selectedOptions);
};
const loadData = selectedOptions => {
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
// load options lazily
setTimeout(() => {
targetOption.loading = false;
targetOption.children = [
{
label: `${targetOption.label} Dynamic 1`,
value: 'dynamic1',
},
{
label: `${targetOption.label} Dynamic 2`,
value: 'dynamic2',
},
];
setOptions([...options]);
}, 1000);
};
return <Cascader options={options} loadData={loadData} onChange={onChange} changeOnSelect />;
}
Example #7
Source File: search.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/cascader', module).add('search', () =>
<Cascader
options={options}
onChange={onChange}
placeholder="Please select"
showSearch={{ filter }}
/>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Search and select options directly.</p>
<blockquote>
<p>Now, <code>Cascader[showSearch]</code> doesn't support search on server, more info <a href="https://github.com/ant-design/ant-design/issues/5547">#5547</a></p>
</blockquote></>) } });
Example #8
Source File: size.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/cascader', module).add('size', () =>
<>
<Cascader size="large" options={options} onChange={onChange} />
<br />
<br />
<Cascader options={options} onChange={onChange} />
<br />
<br />
<Cascader size="small" options={options} onChange={onChange} />
<br />
<br />
</>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Cascade selection box of different sizes.</p></>) } });
Example #9
Source File: suffix.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/cascader', module).add('suffix', () =>
<>
<Cascader
suffixIcon={<SmileOutlined />}
options={options}
onChange={onChange}
placeholder="Please select"
/>
<br />
<br />
<Cascader suffixIcon="ab" options={options} onChange={onChange} placeholder="Please select" />
<br />
<br />
<Cascader
expandIcon={<SmileOutlined />}
options={options}
onChange={onChange}
placeholder="Please select"
/>
<br />
<br />
<Cascader expandIcon="ab" options={options} onChange={onChange} placeholder="Please select" />
</>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Use <code>suffixIcon</code> to customize the selection box suffix icon, and use <code>expandIcon</code> to customize the current item expand icon.</p></>) } });
Example #10
Source File: addon.jsx From virtuoso-design-system with MIT License | 6 votes |
storiesOf('antd/Input', module).add('addon', () =>
<Space direction="vertical">
<Input addonBefore="http://" addonAfter=".com" defaultValue="mysite" />
<Input addonBefore={selectBefore} addonAfter={selectAfter} defaultValue="mysite" />
<Input addonAfter={<SettingOutlined />} defaultValue="mysite" />
<Input addonBefore="http://" suffix=".com" defaultValue="mysite" />
<Input
addonBefore={<Cascader placeholder="cascader" style={{ width: 150 }} />}
defaultValue="mysite"
/>
</Space>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Using pre & post tabs example.</p></>) } });
Example #11
Source File: Casd.js From OpenRichpedia with MIT License | 6 votes |
render() {
return (
<Cascader
options={this.props.options}
onChange={this.props.onChange}
placeholder="Please select"
changeOnSelect
size="middle"
style={{ width: '300px' }}
bordered="true"
expandTrigger="hover"
/>
);
}
Example #12
Source File: index.js From scalable-form-platform with MIT License | 5 votes |
render() {
const popupContainer = this.props.formContext && this.props.formContext.popupContainer;
const {schema, id, options, disabled, readonly, autofocus, placeholder} = this.props;
let {value} = this.props;
if (typeof value === 'undefined' || value === '') {
value = [];
}
// 对于value值为空数组的情况,value的值传入undefined,这样才能显示组件的placeholder
if (value && value.length <= 0) {
value = undefined;
} else {
value = value.split(',');
}
// 兼容没有配置数据源的情形
let data = schema.data || [];
// 对data做格式化处理
this.formatTreeData(data);
//解析schema中约定的_errorType字段,用来标识是validate中哪种类型校验不通过
let validateMessage = '';
let _errorType = options._errorType || '';
if (_errorType !== '' && typeof options.validate !== 'undefined') {
validateMessage = this._getValidateMessage(_errorType, options.validate);
}
return (
<div className={classnames({
'ant-form-item-control': true,
'xform-custom-widget': true,
'xform-custom-cascader-select': true,
'has-error': _errorType !== ''
})}>
<Cascader
id={id}
expandTrigger="hover"
value={value}
options={data}
disabled={disabled}
readOnly={readonly}
onChange={this.handleSelectChange}
autoFocus={autofocus}
placeholder={placeholder}
getPopupContainer={popupContainer}
{...options}
/>
<div className="ant-form-explain">{validateMessage}</div>
</div>
);
}
Example #13
Source File: index.jsx From mixbox with GNU General Public License v3.0 | 5 votes |
function getElement(item) {
const {type = 'input', component, ...props} = item;
const commonProps = {
size: 'default',
};
// 样式
// const width = props.width || '100%';
// const elementCommonStyle = {width};
// props.style = props.style ? {...elementCommonStyle, ...props.style} : elementCommonStyle;
// 如果 component 存在,说明是自定义组件
if (component) {
return typeof component === 'function' ? component() : component;
}
if (isInputLikeElement(type)) {
if (type === 'number') return <InputNumber {...commonProps} {...props}/>;
if (type === 'textarea') return <TextArea {...commonProps} {...props}/>;
if (type === 'password') return <Password {...commonProps} {...props}/>;
return <Input {...commonProps} type={type} {...props}/>;
}
if (type === 'select') {
const {options = [], ...others} = props;
return (
<Select {...commonProps} {...others}>
{
options.map(opt => <Select.Option key={opt.value} {...opt}>{opt.label}</Select.Option>)
}
</Select>
);
}
if (type === 'select-tree') return <TreeSelect {...commonProps} {...props} treeData={props.options}/>;
if (type === 'checkbox') return <Checkbox {...commonProps} {...props}>{props.label}</Checkbox>;
if (type === 'checkbox-group') return <Checkbox.Group {...commonProps} {...props}/>;
if (type === 'radio') return <Radio {...commonProps} {...props}>{props.label}</Radio>;
if (type === 'radio-group') return <Radio.Group {...commonProps} {...props}/>;
if (type === 'radio-button') {
const {options = [], ...others} = props;
return (
<Radio.Group buttonStyle="solid" {...commonProps} {...others}>
{options.map(opt => <Radio.Button key={opt.value} {...opt}>{opt.label}</Radio.Button>)}
</Radio.Group>
);
}
if (type === 'cascader') return <Cascader {...commonProps} {...props}/>;
if (type === 'switch') return <Switch {...commonProps} {...props} style={{...props.style, width: 'auto'}}/>;
if (type === 'date') return <DatePicker {...commonProps} {...props}/>;
if (type === 'date-time') return <DatePicker {...commonProps} showTime {...props}/>;
if (type === 'date-range') return <DatePicker.RangePicker {...commonProps} {...props}/>;
if (type === 'month') return <DatePicker.MonthPicker {...commonProps} {...props}/>;
if (type === 'time') return <TimePicker {...commonProps} {...props}/>;
if (type === 'transfer') return <Transfer {...commonProps} {...props}/>;
if (type === 'icon-picker') return <IconPicker {...commonProps} {...props}/>;
throw new Error(`no such type: ${type}`);
}
Example #14
Source File: ChangeWind.js From aircon with GNU General Public License v3.0 | 5 votes |
render() {
const {getFieldDecorator, getFieldValue} = this.props.form
const formItemLayout = {
labelCol: {
xs: {span: 24},
sm: {span: 4},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 12},
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 12,
offset: 4,
},
},
}
return (
<div>
<CustomBreadcrumb arr={['客户界面', '空调使用', '风速调整']}/>
<Card bordered={false} title='风速调整'>
<Form layout='horizontal' style={{width: '70%', margin: '0 auto'}} onSubmit={this.handleSubmit}>
<FormItem label='风速' {...formItemLayout} required>
{
getFieldDecorator('residence', {
rules: [
{
type: 'array',
required: true,
message: '请选择风速'
}
]
})(
<Cascader options={options} expandTrigger="hover" placeholder=''/>
)
}
</FormItem>
<FormItem style={{textAlign: 'center'}} {...tailFormItemLayout}>
<Button type="primary" htmlType="submit" disabled={false}>确定</Button>
</FormItem>
</Form>
</Card>
<BackTop visibilityHeight={200} style={{right: 50}}/>
</div>
)
}
Example #15
Source File: basic.jsx From virtuoso-design-system with MIT License | 5 votes |
storiesOf('antd/cascader', module).add('basic', () =>
<Cascader options={options} onChange={onChange} placeholder="Please select" />,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Cascade selection box for selecting province/city/district.</p></>) } });
Example #16
Source File: change-on-select.jsx From virtuoso-design-system with MIT License | 5 votes |
storiesOf('antd/cascader', module).add('change-on-select', () => <Cascader options={options} onChange={onChange} changeOnSelect />, { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Allow only select parent options.</p></>) } });
Example #17
Source File: custom-dropdown.jsx From virtuoso-design-system with MIT License | 5 votes |
storiesOf('antd/cascader', module).add('custom-dropdown', () =>
<Cascader options={options} dropdownRender={dropdownRender} placeholder="Please select" />,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Customize the dropdown menu via <code>dropdownRender</code>.</p></>) } });
Example #18
Source File: default-value.jsx From virtuoso-design-system with MIT License | 5 votes |
storiesOf('antd/cascader', module).add('default-value', () =>
<Cascader
defaultValue={['zhejiang', 'hangzhou', 'xihu']}
options={options}
onChange={onChange}
/>,
{ docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Specifies default value by an array.</p></>) } });
Example #19
Source File: disabled-option.jsx From virtuoso-design-system with MIT License | 5 votes |
storiesOf('antd/cascader', module).add('disabled-option', () => <Cascader options={options} onChange={onChange} />, { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Disable option by specifying the <code>disabled</code> property in <code>options</code>.</p></>) } });
Example #20
Source File: config-provider.jsx From virtuoso-design-system with MIT License | 5 votes |
render() {
const { customize } = this.state;
return (
<div>
<Switch
unCheckedChildren="default"
checkedChildren="customize"
checked={customize}
onChange={val => {
this.setState({ customize: val });
}}
/>
<Divider />
<ConfigProvider renderEmpty={customize && customizeRenderEmpty}>
<div className="config-provider">
<h4>Select</h4>
<Select style={style} />
<h4>TreeSelect</h4>
<TreeSelect style={style} treeData={[]} />
<h4>Cascader</h4>
<Cascader style={style} options={[]} showSearch />
<h4>Transfer</h4>
<Transfer />
<h4>Table</h4>
<Table
style={{ marginTop: 8 }}
columns={[
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
]}
/>
<h4>List</h4>
<List />
</div>
</ConfigProvider>
</div>
);
}
Example #21
Source File: align.jsx From virtuoso-design-system with MIT License | 5 votes |
storiesOf('antd/Input', module).add('align', () =>
<>
<Mentions style={{ width: 100 }} rows={1} />
<Input.TextArea rows={1} style={{ width: 100 }} />
<Button type="primary">Button</Button>
<Input style={{ width: 100 }} />
<Text copyable>Ant Design</Text>
<Input prefix="1" suffix="2" style={{ width: 100 }} />
<Input addonBefore="1" addonAfter="2" style={{ width: 100 }} />
<InputNumber style={{ width: 100 }} />
<DatePicker style={{ width: 100 }} />
<TimePicker style={{ width: 100 }} />
<Select style={{ width: 100 }} defaultValue="jack">
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="disabled" disabled>
Disabled
</Option>
<Option value="Yiminghe">yiminghe</Option>
</Select>
<TreeSelect style={{ width: 100 }} />
<Cascader defaultValue={['zhejiang', 'hangzhou', 'xihu']} options={options} />
<RangePicker />
<DatePicker picker="month" />
<Radio.Group defaultValue="a">
<Radio.Button value="a">Hangzhou</Radio.Button>
<Radio.Button value="b">Shanghai</Radio.Button>
</Radio.Group>
<AutoComplete style={{ width: 100 }} placeholder="input here" />
<br />
<Input prefix="$" addonBefore="Http://" addonAfter=".com" defaultValue="mysite" />
<Input style={narrowStyle} suffix="Y" />
<Input style={narrowStyle} />
<Input style={narrowStyle} defaultValue="1" suffix="Y" />
</>,
{ docs: { page: () => (<><hr />
<p>order: 99
title:
zh-CN: 文本对齐
en-US: Text Align</p>
<h2 id="debugtrue">debug: true</h2></>) } });
Example #22
Source File: adminChallengeCreate.js From ctf_platform with MIT License | 4 votes |
CreateChallengeForm = (props) => {
const [form] = Form.useForm();
const [editorValue, setEditorValue] = React.useState("")
const [existingCats, setExistingCats] = React.useState([])
const [finalSortedChalls, setfinalSortedChalls] = React.useState([])
useEffect(() => {
var currentValues = form.getFieldsValue()
currentValues.flags = [""]
form.setFieldsValue(currentValues)
//Render existing categories select options
let existCats = []
for (let i = 0; i < props.allCat.length; i++) {
existCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
}
setExistingCats(existCats)
//Render existing challenges select options
let existChalls = {}
for (let i = 0; i < props.challenges.length; i++) {
if (!(props.challenges[i].category in existChalls)) existChalls[props.challenges[i].category] = []
existChalls[props.challenges[i].category].push({
value: props.challenges[i]._id,
label: props.challenges[i].name
})
}
let finalChalls = []
for (const category in existChalls) {
finalChalls.push({
value: category,
label: category,
children: existChalls[category]
})
}
setfinalSortedChalls(finalChalls)
}, [])
return (
<Form
form={form}
name="create_challenge_form"
className="create_challenge_form"
onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
onFinish={async (values) => {
props.setState({ edited: false })
if (typeof values.flags === "undefined") {
message.warn("Please enter at least 1 flag")
}
else {
//console.log(values)
props.setState({ loading: true })
if (values.visibility === "false") {
values.visibility = false
}
else {
values.visibility = true
}
if (values.dynamic === "false") {
values.dynamic = false
}
else {
values.dynamic = true
}
if (typeof values.writeup !== "undefined") {
if (typeof values.writeupComplete === "undefined") {
values.writeupComplete = true
}
}
const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
let requires = undefined
if (values.requires && values.requires.length > 0) requires = values.requires[1]
await fetch(window.ipAddress + "/v1/challenge/new", {
method: 'post',
headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
body: JSON.stringify({
"name": values.name,
"category": category,
"description": values.description,
"points": values.points,
"flags": values.flags,
"tags": values.tags,
"hints": values.hints,
"max_attempts": values.max_attempts,
"visibility": values.visibility,
"writeup": values.writeup,
"writeupComplete": values.writeupComplete,
"requires": requires,
"dynamic": values.dynamic,
"initial": values.initial,
"minSolves": values.minSolves,
"minimum": values.minimum
})
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
//console.log(data)
if (data.success === true) {
message.success({ content: "Created challenge " + values.name + " successfully!" })
form.resetFields()
props.handleCreateBack()
}
else if (data.error === "exists") {
message.warn("A challenge with an existing name exists")
}
else {
message.error({ content: "Oops. Unknown error, please contact an admin." })
}
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. Issue connecting with the server or client error, please check console and report the error. " });
})
props.setState({ loading: false })
}
}}
>
<Prompt
when={props.state.edited}
message='The challenge details you entered have not been saved. Are you sure you want to leave?'
/>
<h1>Challenge Name:</h1>
<Form.Item
name="name"
rules={[{ required: true, message: 'Please enter a challenge name' }]}
>
<Input allowClear placeholder="Challenge name" />
</Form.Item>
<Divider />
<h1>Challenge Category:</h1>
<h4>Select an Existing Category: </h4>
<Form.Item
name="category1"
rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
>
<Select
disabled={props.state.selectCatDisabled}
allowClear
showSearch
placeholder="Select an existing Category"
onChange={(value) => {
if (value) {
props.setState({ inputCatDisabled: true })
}
else {
props.setState({ inputCatDisabled: false })
}
}}
>
{existingCats}
</Select>
</Form.Item>
<h4>Enter a New Category</h4>
<Form.Item
name="category2"
rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
>
<Input onChange={(e) => {
e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
}} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
</Form.Item>
<Divider />
<Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
</div>}>
<h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>):</h1>
<Form.Item
name="description"
rules={[{ required: true, message: 'Please enter a description' }]}
valuePropName={editorValue}
>
<MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
</Form.Item>
<h3>Challenge Description Preview</h3>
<Card
type="inner"
bordered={true}
bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
className="challengeModal"
>
<MarkdownRender>{editorValue}</MarkdownRender>
</Card>
</Suspense>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "center" }}>
<Card>
<h1>Challenge Points:</h1>
<Form.Item
name="points"
rules={[{ required: true, message: 'Please enter challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={0}
>
<InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
</Form.Item>
</Card>
<Card>
<h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
<Form.Item
name="max_attempts"
rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
style={{ alignText: 'center' }}
initialValue={0}
>
<InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }} />
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="flags" >
{(fields, { add, remove }) => {
return (
<Card>
<h1>Flags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
>
<Input style={{ width: "50ch" }} placeholder="Flag" />
</Form.Item>
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
) : null}
</Space>
))}
<Form.Item>
<Button
type="dashed"
onLoad={() => { if (fields.length < 1) add() }}
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Flag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Form.List name="tags">
{(fields, { add, remove }) => {
return (
<Card>
<h1>Tags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing tag' }]}
>
<Input placeholder="Tag" style={{ width: "50ch" }} />
</Form.Item>
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Tag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
</div>
</div>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="hints" >
{(fields, { add, remove }) => {
return (
<Card>
<h1>Hints</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name, "hint"]}
fieldKey={[field.fieldKey, "hint"]}
rules={[{ required: true, message: 'Missing hint' }]}
>
<Input placeholder="Hint" style={{ width: "20vw" }} />
</Form.Item>
<Form.Item
{...field}
name={[field.name, "cost"]}
fieldKey={[field.fieldKey, "cost"]}
rules={[{ required: true, message: 'Missing cost for hint' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
>
<InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
</Form.Item>
<MinusCircleOutlined
style={{ color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Hint
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Card>
<h1>Writeup Link (Optional)</h1>
<Form.Item
name="writeup"
rules={[
{
type: 'url',
message: "Please enter a valid link",
}]}
>
<Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
</Form.Item>
<div style={{ display: "flex", alignContent: "center" }}>
<h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
<Form.Item
name="writeupComplete"
>
<Switch defaultChecked />
</Form.Item>
</div>
</Card>
<Card>
<h1>Visibility</h1>
<Form.Item
name="visibility"
rules={[{ required: true, message: 'Please set the challenge visibility' }]}
initialValue="false"
>
<Select style={{ width: "20ch" }}>
<Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
</Select>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }} />
<div style={{ display: "flex", flexDirection: "column" }}>
<Card>
<h1>Challenge Required: </h1>
<Form.Item
name="requires"
>
<Cascader
options={finalSortedChalls}
allowClear
showSearch
placeholder="Select an existing challenge" />
</Form.Item>
<p>Locks this challenge until the provided challenge above has been solved.</p>
</Card>
<Card>
<h1>Dynamic Scoring</h1>
<Form.Item
name="dynamic"
rules={[{ required: true, message: 'Please set whether the challenge uses dynamic scoring' }]}
initialValue="false"
>
<Select onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }} style={{ width: "20ch" }}>
<Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
</Select>
</Form.Item>
<h1>Initial Points:</h1>
<Form.Item
name="initial"
rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={500}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Initial number of points when there are 0/1 solves on a challenge</p>
<h1>Minimum Points:</h1>
<Form.Item
name="minimum"
rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={100}
>
<InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
</Form.Item>
<p>Minimum amount of points that the challenge can decay too</p>
<h1>Solves to Minimum:</h1>
<Form.Item
name="minSolves"
rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={50}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Number of solves on the challenge till it decays to the minimum point.</p>
</Card>
</div>
</div>
<Form.Item>
<div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "2vh" }}>
<div>
<Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()); }}>Preview</Button>
<Button loading={props.loadingStatus} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Challenge</Button>
</div>
<div>
<Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
</div>
</div>
</Form.Item>
</Form>
);
}
Example #23
Source File: adminChallengeEdit.js From ctf_platform with MIT License | 4 votes |
CreateChallengeForm = (props) => {
const [form] = Form.useForm();
const [editorValue, setEditorValue] = React.useState("")
const [existingCats, setExistingCats] = React.useState([])
const [finalSortedChalls, setFinalSortedChalls] = React.useState([])
//Render existing categories select options
useEffect(() => {
let existingCats = []
for (let i = 0; i < props.allCat.length; i++) {
existingCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
}
//Render existing challenges select options minus the challenge itself
let existingChalls = {}
for (let i = 0; i < props.challenges.length; i++) {
if (props.challenges[i].name !== props.initialData.name) {
if (!(props.challenges[i].category in existingChalls)) existingChalls[props.challenges[i].category] = []
existingChalls[props.challenges[i].category].push({
value: props.challenges[i]._id,
label: props.challenges[i].name
})
}
}
setExistingCats(existingCats)
let finalSortedChalls = []
for (const category in existingChalls) {
finalSortedChalls.push({
value: category,
label: category,
children: existingChalls[category]
})
}
setFinalSortedChalls(finalSortedChalls)
let initialData = JSON.parse(JSON.stringify(props.initialData))
if (props.initialData.visibility === false) {
initialData.visibility = "false"
}
else if (props.initialData.visibility === true) {
initialData.visibility = "true"
}
// if we put only props.initialData.requires, we are merely putting a reference to props.initialData.requires, which is this array, creating a "loop"
if (props.initialData.requires) initialData.requires = [props.IDNameMapping[props.initialData.requires], props.initialData.requires]
if (props.initialData.dynamic === false) {
initialData.dynamic = "false"
}
else if (props.initialData.dynamic === true) {
initialData.dynamic = "true"
props.setState({ dynamic: true })
}
else {
initialData.dynamic = "false"
}
initialData.category1 = initialData.category
form.setFieldsValue(initialData)
setEditorValue(initialData.description)
}, [])
return (
<Form
form={form}
name="create_challenge_form"
className="create_challenge_form"
onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
onFinish={async (values) => {
props.setState({ edited: false })
if (typeof values.flags === "undefined") {
message.warn("Please enter at least 1 flag")
}
else {
if (values.visibility === "false") {
values.visibility = false
}
else {
values.visibility = true
}
if (values.dynamic === "false") {
values.dynamic = false
}
else {
values.dynamic = true
}
if (typeof values.writeup !== "undefined") {
if (typeof values.writeupComplete === "undefined") {
values.writeupComplete = true
}
}
const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
props.setState({ editLoading: true })
let requires = ""
if (values.requires && values.requires.length > 0) requires = values.requires[1]
await fetch(window.ipAddress + "/v1/challenge/edit", {
method: 'post',
headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
body: JSON.stringify({
"id": props.initialData._id,
"name": values.name,
"category": category,
"description": values.description,
"points": values.points,
"flags": values.flags,
"tags": values.tags,
"hints": values.hints,
"max_attempts": values.max_attempts,
"visibility": values.visibility,
"writeup": values.writeup,
"writeupComplete": values.writeupComplete,
"requires": requires,
"dynamic": values.dynamic,
"initial": values.initial,
"minSolves": values.minSolves,
"minimum": values.minimum
})
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
if (data.success === true) {
message.success({ content: "Edited challenge \"" + props.initialData.name + "\" successfully!" })
props.handleEditChallBack()
setEditorValue("")
form.resetFields()
}
else if (data.error === "exists") {
message.warn("A challenge with an existing name exists")
}
else {
message.error({ content: "Oops. Unknown error" })
}
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})
props.setState({ editLoading: false })
}
}}
>
<Prompt
when={props.state.edited}
message='The challenge details you modified have not been saved. Are you sure you want to leave?'
/>
<p><b><u>ID:</u></b> <code>{props.initialData._id}</code></p>
<h1>Challenge Name:</h1>
<Form.Item
name="name"
rules={[{ required: true, message: 'Please enter a challenge name' }]}
>
<Input allowClear placeholder="Challenge name" />
</Form.Item>
<Divider />
<h1>Challenge Category:</h1>
<h4>Select an Existing Category: </h4>
<Form.Item
name="category1"
initialValue={""}
rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
>
<Select
disabled={props.state.selectCatDisabled}
allowClear
showSearch
placeholder="Select an existing Category"
onChange={(value) => {
if (value) {
props.setState({ inputCatDisabled: true })
}
else {
props.setState({ inputCatDisabled: false })
}
}}
>
{existingCats}
</Select>
</Form.Item>
<h4>Enter a New Category</h4>
<Form.Item
name="category2"
rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
>
<Input onChange={(e) => {
e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
}} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
</Form.Item>
<Divider />
<h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>)):</h1>
<Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
</div>}>
<Form.Item
name="description"
rules={[{ required: true, message: 'Please enter a description' }]}
valuePropName={editorValue}
>
<MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
</Form.Item>
<h3>Challenge Description Preview</h3>
<Card
type="inner"
bordered={true}
bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
className="challengeModal"
>
<MarkdownRender>{editorValue}</MarkdownRender>
</Card>
</Suspense>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignContent: "center" }}>
<Card className="settings-card">
<h1>Challenge Points:</h1>
<Form.Item
name="points"
rules={[{ required: true, message: 'Please enter challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={0}
>
<InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
</Form.Item>
</Card>
<Card className="settings-card">
<h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
<Form.Item
name="max_attempts"
rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
style={{ alignText: 'center' }}
initialValue={0}
>
<InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }}></Divider>
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="flags" >
{(fields, { add, remove }) => {
return (
<Card className="settings-card">
<h1>Flags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
>
<Input style={{ width: "50ch" }} placeholder="Flag" />
</Form.Item>
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
) : null}
</Space>
))}
<Form.Item>
<Button
type="dashed"
onLoad={() => { if (fields.length < 1) add() }}
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Flag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Form.List name="tags">
{(fields, { add, remove }) => {
return (
<Card className="settings-card">
<h1>Tags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing tag' }]}
>
<Input placeholder="Tag" style={{ width: "50ch" }} />
</Form.Item>
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Tag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
</div>
</div>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="hints" >
{(fields, { add, remove }) => {
return (
<Card className="settings-card">
<h1>Hints</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name, "hint"]}
fieldKey={[field.fieldKey, "hint"]}
rules={[{ required: true, message: 'Missing hint' }]}
>
<Input placeholder="Hint" style={{ width: "20vw" }} />
</Form.Item>
<Form.Item
{...field}
name={[field.name, "cost"]}
fieldKey={[field.fieldKey, "cost"]}
rules={[{ required: true, message: 'Missing cost for hint' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
>
<InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
</Form.Item>
<MinusCircleOutlined
style={{ color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Hint
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Card className="settings-card">
<h1>Writeup Link (Optional)</h1>
<Form.Item
name="writeup"
rules={[
{
type: 'url',
message: "Please enter a valid link",
}]}
>
<Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
</Form.Item>
<div style={{ display: "flex", alignContent: "center" }}>
<h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
<Form.Item
name="writeupComplete"
>
<Switch defaultChecked />
</Form.Item>
</div>
</Card>
<Card className="settings-card">
<h1>Visibility</h1>
<Form.Item
name="visibility"
rules={[{ required: true, message: 'Please set the challenge visibility' }]}
initialValue="false"
>
<Select style={{ width: "20ch" }}>
<Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
</Select>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }} />
<div style={{ display: "flex", flexDirection: "column" }}>
<Card>
<h1>Challenge Required: </h1>
<Form.Item
name="requires"
>
{/*
The issue with this is that displayRender is supposed to return an array,
but setting a value causes it to become a string and error out
*/}
<Cascader
options={finalSortedChalls}
allowClear
showSearch
placeholder="Select an existing challenge" />
</Form.Item>
<p>Locks this challenge until the provided challenge above has been solved.</p>
</Card>
<Card className="settings-card">
<h1>Dynamic Scoring</h1>
<Form.Item
name="dynamic"
rules={[{ required: props.state.dynamic, message: 'Please set whether the challenge uses dynamic scoring' }]}
initialValue="false"
>
<Select style={{ width: "20ch" }} onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }}>
<Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
</Select>
</Form.Item>
<h1>Initial Points:</h1>
<Form.Item
name="initial"
rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={500}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Initial number of points when there are 0/1 solves on a challenge</p>
<h1>Minimum Points:</h1>
<Form.Item
name="minimum"
rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={100}
>
<InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
</Form.Item>
<p>Minimum amount of points that the challenge can decay too</p>
<h1>Solves to Minimum:</h1>
<Form.Item
name="minSolves"
rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={50}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Number of solves on the challenge till it decays to the minimum point.</p>
</Card>
</div>
</div>
<Form.Item>
<div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "3ch" }}>
<div>
<Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()) }}>Preview</Button>
<Button type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }} loading={props.editLoading}>Edit Challenge</Button>
</div>
<div>
<Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
</div>
</div>
</Form.Item>
</Form>
);
}
Example #24
Source File: adminSubmissions.js From ctf_platform with MIT License | 4 votes |
CreateT = (props) => {
const [isHint, setIsHint] = useState(false)
const [isNonZero, setNonZero] = useState(false)
const [correctValue, setCorrectValue] = useState(true)
const [form] = Form.useForm();
return (
<Form
form={form}
name="register_form"
className="register-form"
onFinish={async (values) => {
// must use correctValue state value instead
await fetch(window.ipAddress + "/v1/submissions/new", {
method: 'post',
headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
body: JSON.stringify({
"author": values.author,
"challenge": values.challenge[1][0],
"challengeID": values.challenge[1][1],
"type": values.type,
"points": values.points,
"correct": correctValue,
"submission": values.submission,
"hint_id": values.hint_id
})
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
if (data.success === true) {
message.success({ content: "Created transaction successfully!" })
setNonZero(false)
setCorrectValue(false)
setIsHint(false)
props.setState({ createTModal: false })
props.refresh()
form.resetFields()
}
else if (data.error === "not-found") {
message.error("Oops. User not found.")
}
else {
message.error({ content: "Oops. Unknown error" })
}
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})
}}
>
<h4>Select an Account</h4>
<Form.Item
name="author"
rules={[{ required: true, message: 'Please enter an author' }]}
>
<Input allowClear prefix={<UserOutlined />} placeholder="Account which this transaction will belong to" />
</Form.Item>
<h4>Select a Challenge</h4>
<Form.Item
name="challenge"
rules={[{ required: true, message: 'Please select a challenge' }]}
>
<Cascader
options={props.challengeList}
allowClear
showSearch
placeholder="Select an existing challenge which this transaction will belong to" />
</Form.Item>
<h4>Select a Type</h4>
<Form.Item
name="type"
rules={[{ required: true, message: 'Please select the type of transaction' }]}
initialValue="submission"
>
<Select onSelect={(type) => { type === "hint" ? setIsHint(true) : setIsHint(false) }}>
<Option value="submission">Submission</Option>
<Option value="hint">Hint</Option>
<Option value="blocked_submission">Blocked Submission</Option>
</Select>
</Form.Item>
<h4>Input Amount of Points</h4>
<Form.Item
name="points"
rules={[{ required: true, message: 'Please input the amount of points' }]}
initialValue={0}
>
<InputNumber onChange={(value) => {
if (value !== 0) {
setNonZero(true)
setCorrectValue(true)
}
else setNonZero(false)
}} min={-100000} max={100000} ></InputNumber>
</Form.Item>
{!isHint ?
<div>
<h4>Choose whether this is a "Correct" submission</h4>
<Form.Item
name="correct"
rules={[{ required: true, message: 'Please select whether it is correct' }]}
initialValue={true}
valuePropName={correctValue}
>
<Select value={correctValue} onSelect={(value) => setCorrectValue(value)} disabled={isNonZero}>
<Option value={true}>Correct</Option>
<Option value={false}>Wrong</Option>
</Select>
</Form.Item>
<h4>Enter a Submission</h4>
<Form.Item
name="submission"
rules={[{ required: true, message: 'Please enter a submission' }]}
>
<Input allowClear placeholder="The user's flag input" />
</Form.Item>
</div>
:
<div>
<h4>Enter a hint ID (hint number of the challenge from <code>1-n</code>)</h4>
<Form.Item
name="hint_id"
rules={[{ required: true, message: 'Please enter a hint ID' }]}
initialValue={1}
>
<InputNumber min={-100000} max={100000}></InputNumber>
</Form.Item>
</div>}
<Form.Item>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<Button style={{ marginRight: "1.5vw" }} onClick={() => { props.setState({ createTModal: false }) }}>Cancel</Button>
<Button type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Transaction</Button>
</div>
</Form.Item>
</Form>
);
}
Example #25
Source File: adminSubmissions.js From ctf_platform with MIT License | 4 votes |
EditT = (props) => {
const [isHint, setIsHint] = useState(false)
const [isNonZero, setNonZero] = useState(false)
const [correctValue, setCorrectValue] = useState(true)
const [form] = Form.useForm();
if (typeof form.getFieldValue("author") === "undefined") {
let initialData = JSON.parse(JSON.stringify(props.initialData))
initialData.challenge = ["", [props.initialData.challenge, props.initialData.challengeID]]
if (initialData.type === "hint") setIsHint(true)
if (initialData.points !== 0) setNonZero(true)
form.setFieldsValue(initialData)
}
return (
<Form
form={form}
onFinish={async (values) => {
// must use correctValue state value instead
await fetch(window.ipAddress + "/v1/submissions/edit", {
method: 'post',
headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
body: JSON.stringify({
"id": props.initialData._id,
"author": values.author,
"challenge": values.challenge[1][0],
"challengeID": values.challenge[1][1],
"type": values.type,
"points": values.points,
"correct": correctValue,
"submission": values.submission,
"hint_id": values.hint_id
})
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
if (data.success === true) {
message.success({ content: "Edited transaction successfully!" })
setNonZero(false)
setCorrectValue(false)
setIsHint(false)
props.setState({ editTModal: false })
props.refresh()
form.resetFields()
}
else {
message.error({ content: "Oops. Unknown error" })
}
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})
}}
>
<p><b><u>ID:</u></b> <code>{props.initialData._id}</code></p>
<h4>Select an Account</h4>
<Form.Item
name="author"
rules={[{ required: true, message: 'Please enter an author' }]}
>
<Input allowClear prefix={<UserOutlined />} placeholder="Account which this transaction will belong to" />
</Form.Item>
<h4>Select a Challenge</h4>
<Form.Item
name="challenge"
rules={[{ required: true, message: 'Please select a challenge' }]}
>
<Cascader
options={props.challengeList}
allowClear
showSearch
placeholder="Select an existing challenge which this transaction will belong to" />
</Form.Item>
<h4>Select a Type</h4>
<Form.Item
name="type"
rules={[{ required: true, message: 'Please select the type of transaction' }]}
initialValue="submission"
>
<Select onSelect={(type) => { type === "hint" ? setIsHint(true) : setIsHint(false) }}>
<Option value="submission">Submission</Option>
<Option value="hint">Hint</Option>
<Option value="blocked_submission">Blocked Submission</Option>
</Select>
</Form.Item>
<h4>Input Amount of Points</h4>
<Form.Item
name="points"
rules={[{ required: true, message: 'Please input the amount of points' }]}
initialValue={0}
>
<InputNumber onChange={(value) => {
if (value !== 0) {
setNonZero(true)
setCorrectValue(true)
}
else setNonZero(false)
}} min={-100000} max={100000} ></InputNumber>
</Form.Item>
{!isHint ?
<div>
<h4>Choose whether this is a "Correct" submission</h4>
<Form.Item
name="correct"
rules={[{ required: true, message: 'Please select whether it is correct' }]}
initialValue={true}
valuePropName={correctValue}
>
<Select value={correctValue} onSelect={(value) => setCorrectValue(value)} disabled={isNonZero}>
<Option value={true}>Correct</Option>
<Option value={false}>Wrong</Option>
</Select>
</Form.Item>
<h4>Enter a Submission</h4>
<Form.Item
name="submission"
rules={[{ required: true, message: 'Please enter a submission' }]}
>
<Input allowClear placeholder="The user's flag input" />
</Form.Item>
</div>
:
<div>
<h4>Enter a hint ID (hint number of the challenge from <code>1-n</code>)</h4>
<Form.Item
name="hint_id"
rules={[{ required: true, message: 'Please enter a hint ID' }]}
initialValue={1}
>
<InputNumber min={-100000} max={100000}></InputNumber>
</Form.Item>
</div>}
<Form.Item>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<Button style={{ marginRight: "1.5vw" }} onClick={() => { props.setState({ editTModal: false }) }}>Cancel</Button>
<Button type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Edit Transaction</Button>
</div>
</Form.Item>
</Form>
);
}
Example #26
Source File: index.jsx From juno with Apache License 2.0 | 4 votes |
render() {
const {
app_service_tree,
use_cases,
editor,
selected_user_case,
node_addr_list,
selected_service,
right_menu_visible,
right_menu_position,
right_menu,
dispatch,
response,
active_tab,
selected_history_id,
public_cases,
settings,
setting_dialog_visible,
service_bind_dialog_visible,
proto_list,
appList,
use_case_loading,
} = this.props;
let addrOptions = node_addr_list?.hosts
? node_addr_list.hosts
.filter((i) => i.env !== 'prod' && i.env !== 'gray')
.map((item) => {
return (
<AutoComplete.Option key={item.addr} value={item.addr + ':' + node_addr_list.port}>
<Tag>{item.env}</Tag>
<span>
{item.addr}:{node_addr_list.port}
</span>
</AutoComplete.Option>
);
})
: [];
if (settings && settings.localhost) {
addrOptions.push(
<AutoComplete.Option
key={settings.localhost}
value={settings.localhost + ':' + node_addr_list.port}
>
<Tag>local</Tag>
<span>
{settings.localhost}:{node_addr_list.port}
</span>
</AutoComplete.Option>,
);
}
let metadata = editor.form.metadata || [];
if (!(metadata instanceof Array)) {
try {
metadata = JSON.parse(metadata);
} catch (e) {
metadata = [];
}
}
return (
<div className={styles.debugPage}>
<div className={styles.layoutHeader}>
<Cascader
showSearch
value={selected_service}
className={styles.serviceCascader}
displayRender={(labels) => {
return labels.join('/');
}}
placeholder="切换服务"
options={(app_service_tree || []).map((app) => {
return {
label: app.app_name,
value: app.app_name,
children: (app.services || []).map((service) => {
return {
value: '' + service.id,
label: service.name,
};
}),
};
})}
onChange={this.onChangeService}
/>
<Button
shape="circle"
icon={<SettingOutlined />}
className={styles.settingButton}
onClick={this.onShowSettingDialog}
/>
<Button
shape="circle"
icon={<LinkOutlined />}
className={styles.bindServiceButton}
onClick={this.onShowServiceBindDialog}
/>
</div>
<div className={styles.main}>
<div className={styles.layoutSider}>
<Tabs
type={'card'}
className={styles.leftTabs}
activeKey={active_tab}
onChange={this.onTabChange}
renderTabBar={(props, DefaultTabBar) => {
return (
<DefaultTabBar
{...props}
style={{
backgroundColor: 'rgb(250,250,250)',
padding: '10px 0 0 10px',
margin: '0',
flex: '0 0 50px',
}}
/>
);
}}
>
<Tabs.TabPane key="history" tab="History">
{active_tab === 'history' ? (
<History
selectedService={selected_service}
onChange={(id) => {
dispatch({ type: 'grpcDebugModel/loadHistoryItem', payload: id }).then(
(res) => {
if (res.code === 0) {
this.form.current.setFieldsValue({
case_name: editor.form.case_name,
address: res.data.addr,
});
}
},
);
}}
activeId={selected_history_id}
/>
) : null}
</Tabs.TabPane>
<Tabs.TabPane key="api" tab="API">
<ScrollArea style={{ height: '830px' }}>
<DirectoryTree
onRightClick={this.onUserCaseTreeRightClicked}
defaultExpandAll
onSelect={this.onSelectUserCaseTree}
selectedKeys={[selected_user_case]}
style={{ marginTop: '10px' }}
>
{(use_cases || []).map((method, id) => {
return (
<TreeNode
title={
method.description ? (
<Popover content={method.description}>{method.name}</Popover>
) : (
method.name
)
}
key={`method:${method.id}`}
>
<TreeNode
icon={<PlusOutlined />}
key={`new:${method.id}`}
title="New"
isLeaf
/>
{method.use_cases
? method.use_cases.map((tc, id) => {
return <TreeNode title={tc.name} key={`case:${tc.id}`} isLeaf />;
})
: null}
</TreeNode>
);
})}
</DirectoryTree>
</ScrollArea>
</Tabs.TabPane>
</Tabs>
</div>
{editor.form.method_id ? (
<Spin spinning={use_case_loading} wrapperClassName={styles.formSpin}>
{this.renderForm(editor, addrOptions, metadata, response)}
</Spin>
) : (
<div style={{ flex: '1 1 auto', padding: '100px' }}>
<Empty desciption={'请选择用例'} />
</div>
)}
</div>
<SettingDialog
onCancel={() => {
dispatch({
type: 'grpcDebugModel/showSettings',
payload: false,
});
}}
settings={settings}
onSave={this.onSaveSettings}
visible={setting_dialog_visible}
/>
<ServiceBindDialog
visible={service_bind_dialog_visible}
protoList={proto_list}
appList={appList}
onSubmit={this.onBindAppService}
onCancel={() => {
dispatch({
type: 'grpcDebugModel/showServiceBindDialog',
payload: false,
});
}}
/>
</div>
);
}
Example #27
Source File: index.js From gobench with Apache License 2.0 | 4 votes |
AdvancedFormExamples = () => {
const [confirmDirty, setConfirmDirty] = useState(false)
const handleConfirmBlur = e => {
const { value } = e.target
setConfirmDirty(confirmDirty || !!value)
}
const opts = {
name: 'file',
multiple: true,
action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76',
onChange(info) {
const { status } = info.file
if (status !== 'uploading') {
console.log(info.file, info.fileList)
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`)
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`)
}
},
}
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 4 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
},
}
const marks = {
0: '0',
10: '10',
20: '20',
30: '30',
40: '40',
50: '50',
60: '60',
70: '70',
80: '80',
90: '90',
100: '100',
}
const residences = [
{
value: 'zhejiang',
label: 'Zhejiang',
children: [
{
value: 'hangzhou',
label: 'Hangzhou',
children: [
{
value: 'xihu',
label: 'West Lake',
},
],
},
],
},
{
value: 'jiangsu',
label: 'Jiangsu',
children: [
{
value: 'nanjing',
label: 'Nanjing',
children: [
{
value: 'zhonghuamen',
label: 'Zhong Hua Men',
},
],
},
],
},
]
return (
<div>
<Helmet title="Advanced / Form Examples" />
<div className="kit__utils__heading">
<h5>Form Examples</h5>
</div>
<div className="card">
<div className="card-body">
<h5 className="mb-4">
<strong>Basic Form</strong>
</h5>
<Form {...formItemLayout} labelAlign="left">
<Form.Item name="fullname6" label="Fullname">
<Input placeholder="Your Fullname..." />
</Form.Item>
<Form.Item name="email6" label="Your Email...">
<Input placeholder="Your Email..." />
</Form.Item>
<Form.Item name="budget1" label="Budget" className="mb-3">
<Input placeholder="Your Budget..." addonBefore="$" />
</Form.Item>
<Form.Item name="amount" label="Amount">
<Slider marks={marks} />
</Form.Item>
<button type="submit" className="btn btn-success px-5">
Send Data
</button>
</Form>
</div>
</div>
<div className="card">
<div className="card-body">
<h5 className="mb-4">
<strong>Inline Form</strong>
</h5>
<Form layout="inline">
<Form.Item name="budget2" className="mb-1 mt-1">
<Input placeholder="Coins Amount" addonBefore="$" addonAfter=".00" />
</Form.Item>
<Form.Item name="budget3" className="mb-1 mt-1">
<Input placeholder="8 Digit Pin" addonBefore="$" />
</Form.Item>
<button type="button" className="btn btn-success mt-1 mb-1">
Confirm Transaction
</button>
</Form>
</div>
</div>
<div className="card">
<div className="card-body">
<h5 className="mb-4">
<strong>Two Columns</strong>
</h5>
<Form layout="vertical">
<div className="row">
<div className="col-md-6">
<Form.Item name="email3" label="E-mail">
<Input placeholder="Email" />
</Form.Item>
</div>
<div className="col-md-6">
<Form.Item name="pass3" label="Password">
<Input placeholder="Password" />
</Form.Item>
</div>
<div className="col-12">
<Form.Item name="address3-1" label="Adress">
<Input placeholder="1234 Main St." />
</Form.Item>
<Form.Item name="address3-2" label="Adress 2">
<Input placeholder="Apartment, studio, or floor" />
</Form.Item>
</div>
<div className="col-md-6">
<Form.Item name="city3" label="City">
<Input />
</Form.Item>
</div>
<div className="col-md-4">
<Form.Item name="state3" label="State">
<Cascader options={residences} />
</Form.Item>
</div>
<div className="col-md-2">
<Form.Item name="zip" label="Zip">
<Input />
</Form.Item>
</div>
<div className="col-12">
<Form.Item valuePropName="fileList" name="upload3" label="Upload Presentation">
<Dragger {...opts}>
<p className="ant-upload-drag-icon">
<InboxOutlined />
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">
Support for a single or bulk upload. Strictly prohibit from uploading company
data or other band files
</p>
</Dragger>
</Form.Item>
</div>
<div className="col-12">
<Form.Item valuePropName="checked" name="confirm3">
<Checkbox className="text-uppercase">
I CONSENT TO HAVING MDTK SOFT COLLECT MY PERSONAL DETAILS.
</Checkbox>
</Form.Item>
<Form.Item name="confirm4">
<button type="button" className="btn btn-light px-5">
Sign in
</button>
</Form.Item>
</div>
</div>
</Form>
</div>
</div>
<div className="card">
<div className="card-body">
<h5 className="mb-4">
<strong>Validation & Background</strong>
</h5>
<div className="bg-light rounded-lg p-5">
<div className="row">
<div className="col-lg-8 mx-auto">
<Form layout="vertical">
<Form.Item name="fullname" label="Username">
<Input />
</Form.Item>
<Form.Item name="gender" label="Gender">
<Select placeholder="Select a option and change input text above">
<Option value="male">male</Option>
<Option value="female">female</Option>
</Select>
</Form.Item>
<Form.Item name="email" label="E-mail">
<Input />
</Form.Item>
<Form.Item name="password" label="Password" hasFeedback>
<Input.Password />
</Form.Item>
<Form.Item name="confirm" label="Confirm Password" hasFeedback>
<Input.Password onBlur={handleConfirmBlur} />
</Form.Item>
<div className="border-top pt-4">
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</div>
</Form>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
Example #28
Source File: index.js From gobench with Apache License 2.0 | 4 votes |
AntdFormExample = () => {
return (
<Form {...formItemLayout}>
<Form.Item
label="Fail"
validateStatus="error"
help="Should be combination of numbers & alphabets"
>
<Input placeholder="unavailable choice" id="error" />
</Form.Item>
<Form.Item label="Warning" validateStatus="warning">
<Input placeholder="Warning" id="warning" prefix={<SmileOutlined />} />
</Form.Item>
<Form.Item
label="Validating"
hasFeedback
validateStatus="validating"
help="The information is being validated..."
>
<Input placeholder="I'm the content is being validated" id="validating" />
</Form.Item>
<Form.Item label="Success" hasFeedback validateStatus="success">
<Input placeholder="I'm the content" id="success" />
</Form.Item>
<Form.Item label="Warning" hasFeedback validateStatus="warning">
<Input placeholder="Warning" id="warning2" />
</Form.Item>
<Form.Item
label="Fail"
hasFeedback
validateStatus="error"
help="Should be combination of numbers & alphabets"
>
<Input placeholder="unavailable choice" id="error2" />
</Form.Item>
<Form.Item label="Success" hasFeedback validateStatus="success">
<DatePicker style={{ width: '100%' }} />
</Form.Item>
<Form.Item label="Warning" hasFeedback validateStatus="warning">
<TimePicker style={{ width: '100%' }} />
</Form.Item>
<Form.Item label="Error" hasFeedback validateStatus="error">
<Select>
<Option value="1">Option 1</Option>
<Option value="2">Option 2</Option>
<Option value="3">Option 3</Option>
</Select>
</Form.Item>
<Form.Item
label="Validating"
hasFeedback
validateStatus="validating"
help="The information is being validated..."
>
<Cascader options={[]} />
</Form.Item>
<Form.Item label="inline" style={{ marginBottom: 0 }}>
<Form.Item
validateStatus="error"
help="Please select the correct date"
style={{ display: 'inline-block', width: 'calc(50% - 12px)' }}
>
<DatePicker />
</Form.Item>
<span
style={{
display: 'inline-block',
width: '24px',
lineHeight: '32px',
textAlign: 'center',
}}
>
-
</span>
<Form.Item style={{ display: 'inline-block', width: 'calc(50% - 12px)' }}>
<DatePicker />
</Form.Item>
</Form.Item>
<Form.Item label="Success" hasFeedback validateStatus="success">
<InputNumber style={{ width: '100%' }} />
</Form.Item>
<Form.Item label="Success" hasFeedback validateStatus="success">
<Input allowClear placeholder="with allowClear" />
</Form.Item>
<Form.Item label="Warning" hasFeedback validateStatus="warning">
<Input.Password placeholder="with input password" />
</Form.Item>
<Form.Item label="Error" hasFeedback validateStatus="error">
<Input.Password allowClear placeholder="with input password and allowClear" />
</Form.Item>
</Form>
)
}
Example #29
Source File: FormDemo1.js From discern with BSD 3-Clause "New" or "Revised" License | 4 votes |
render() {
const {getFieldDecorator, getFieldValue} = this.props.form
const formItemLayout = {
labelCol: {
xs: {span: 24},
sm: {span: 4},
},
wrapperCol: {
xs: {span: 24},
sm: {span: 12},
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 12,
offset: 4,
},
},
}
const prefixSelector = getFieldDecorator('prefix', {
initialValue: 86,
})(
<Select style={{width: 70}}>
<Option value={86}>+86</Option>
<Option value={87}>+87</Option>
</Select>
);
const cardContent = '表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景'
return (
<div>
<CustomBreadcrumb arr={['输入', '表单', '基础表单']}/>
<TypingCard source={cardContent}/>
<Card bordered={false} title='基础表单'>
<Form layout='horizontal' style={{width: '70%', margin: '0 auto'}} onSubmit={this.handleSubmit}>
<FormItem label='邮箱' {...formItemLayout}>
{
getFieldDecorator('email', {
rules: [
{
type: 'email',
message: '请输入正确的邮箱地址'
},
{
required: true,
message: '请填写邮箱地址'
}
]
})(
<Input/>
)
}
</FormItem>
<FormItem label='密码' {...formItemLayout}>
{
getFieldDecorator('password', {
rules: [
{
required: true,
message: '请输入密码'
},
{
min: 6,
message: '密码至少为6个字符'
},
{
max: 16,
message: '密码最多为16个字符'
},
{
whitespace: true,
message: '密码中不能有空格'
}
]
})(
<Input type='password'/>
)
}
</FormItem>
<FormItem label='确认密码' {...formItemLayout} required>
{
getFieldDecorator('confirm', {
rules: [
{
validator: (rule, value, callback) => {
const {getFieldValue} = this.props.form
if (!getFieldValue('password')) {
callback('请先输入上面的密码!')
}
if (value && value !== getFieldValue('password')) {
callback('两次输入不一致!')
}
callback()
}
}
]
})(
<Input type='password'/>
)
}
</FormItem>
<FormItem {...formItemLayout} label={(
<span>
昵称
<Tooltip title='请输入您的昵称'>
<Icon type='question-circle-o'/>
</Tooltip>
</span>
)}>
{
getFieldDecorator('nickname', {
rules: []
})(
<Input/>
)
}
</FormItem>
<FormItem label='居住地' {...formItemLayout} required>
{
getFieldDecorator('residence', {
rules: [
{
type: 'array',
required: true,
message: '请选择居住地'
}
]
})(
<Cascader options={options} expandTrigger="hover" placeholder=''/>
)
}
</FormItem>
<FormItem label='电话' {...formItemLayout}>
{
getFieldDecorator('phone', {
rules: [
{
len: 11,
pattern: /^[1][3,4,5,7,8][0-9]{9}$/,
required: true,
message: '请输入正确的11位手机号码'
}
]
})(
<Input addonBefore={prefixSelector}/>
)
}
</FormItem>
<FormItem label='个人站点' {...formItemLayout}>
{
getFieldDecorator('website', {
rules: [
{
pattern: /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~/])+$/,
message: '请输入正确的站点地址'
}
]
})(
<Input/>
)
}
</FormItem>
<FormItem{...formItemLayout} label="验证码">
<Row gutter={8}>
<Col span={12}>
{getFieldDecorator('captcha', {
rules: [{required: true, message: '请输入验证码!'}],
})(
<Input/>
)}
</Col>
<Col span={12}>
<Button disabled={this.state.disabled} onClick={(e) => this.countdown(e)}>{this.state.text}</Button>
</Col>
</Row>
</FormItem>
<FormItem {...tailFormItemLayout}>
{getFieldDecorator('agreement', {
valuePropName: 'checked',
})(
<Checkbox>我已阅读并同意<a>协议</a></Checkbox>
)}
</FormItem>
<FormItem style={{textAlign: 'center'}} {...tailFormItemLayout}>
<Button type="primary" htmlType="submit" disabled={!getFieldValue('agreement')}>提交</Button>
</FormItem>
</Form>
</Card>
<BackTop visibilityHeight={200} style={{right: 50}}/>
</div>
)
}