Skip to content

Commit 4bcc613

Browse files
committed
winning submission from challenge 30084623 - Topcoder Connect - Wizard - Disabled condition
1 parent 8dd5ce8 commit 4bcc613

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
'use strict'
2+
import React, { PropTypes, Component } from 'react'
3+
import classNames from 'classnames'
4+
import Tooltip from '../Tooltip/Tooltip'
5+
import IconUICheckSimple from '../Icons/IconUICheckSimple'
6+
import { HOC as hoc } from 'formsy-react'
7+
8+
class TiledCheckboxGroup extends Component {
9+
constructor(props) {
10+
super(props)
11+
this.onChange = this.onChange.bind(this)
12+
this.getCheckMarkIconActive = this.getCheckMarkIconActive.bind(this)
13+
this.state = { curValue: props.getValue() || [] }
14+
}
15+
16+
onChange(value) {
17+
const index = this.state.curValue.indexOf(value)
18+
if (index > -1) {
19+
this.state.curValue.splice(index, 1)
20+
} else {
21+
this.state.curValue.push(value)
22+
}
23+
this.props.setValue(this.state.curValue)
24+
this.props.onChange(this.props.name, this.state.curValue)
25+
}
26+
27+
getCheckMarkIconActive() {
28+
return (this.props.checkMarkActiveIcon ? this.props.checkMarkActiveIcon : (
29+
<span className="check-mark">
30+
<IconUICheckSimple fill="#fff" width={12} height={12}/>
31+
</span>))
32+
}
33+
34+
render() {
35+
const { wrapperClass, options, theme, tabable } = this.props
36+
const hasError = !this.props.isPristine() && !this.props.isValid()
37+
const disabled = this.props.isFormDisabled() || this.props.disabled
38+
const errorMessage = this.props.getErrorMessage() || this.props.validationError
39+
40+
const renderOption = (opt, idx) => {
41+
const checked = this.state.curValue.indexOf(opt.value) > -1
42+
const itemClassnames = classNames('tiled-group-item', theme, {
43+
active: checked
44+
}, {
45+
disabled: opt.disabled
46+
})
47+
const handleClick = () => this.onChange(opt.value)
48+
const handleFocus = (e) => {
49+
e.target.parentNode.classList.add('focused')
50+
}
51+
const handleBlur = (e) => {
52+
e.target.parentNode.classList.remove('focused')
53+
}
54+
const Icon = opt.icon
55+
const setRef = (c) => this['element-' + idx] = c
56+
const renderTile = () => (
57+
<a onClick={ !disabled && !opt.disabled && handleClick } data-value={opt.value} className={itemClassnames} key={idx} >
58+
{
59+
!!tabable &&
60+
<input
61+
ref={setRef}
62+
type="checkbox"
63+
name={ this.props.name }
64+
style={{ position : 'absolute', left : '-9999px'}}
65+
onFocus={handleFocus}
66+
onChange={this.onChange}
67+
onBlur={handleBlur}
68+
/>
69+
}
70+
{
71+
this.props.showCheckMarkBeforeTitle
72+
&& (checked
73+
? this.getCheckMarkIconActive()
74+
: this.props.checkMarkUnActiveIcon)
75+
}
76+
<span className="icon">{ opt.icon && <Icon {...opt.iconOptions} />}</span>
77+
<span className="title">{opt.title}</span>
78+
<small>{opt.desc}</small>
79+
{
80+
!this.props.showCheckMarkBeforeTitle
81+
&& (checked
82+
? this.getCheckMarkIconActive()
83+
: this.props.checkMarkUnActiveIcon)
84+
}
85+
</a>
86+
)
87+
return (
88+
<span key={ idx } className="tiled-group-item-container">
89+
{
90+
opt.disabled && opt.errorMessage ?
91+
<Tooltip>
92+
<div className="tooltip-target" id={'tooltip-' + idx}>
93+
{renderTile()}
94+
</div>
95+
<div className="tooltip-body">
96+
<p>{opt.errorMessage}</p>
97+
</div>
98+
</Tooltip> :
99+
renderTile()
100+
}
101+
</span>
102+
)
103+
}
104+
105+
return (
106+
<div className={`${wrapperClass} tiled-group-row`}>
107+
108+
{this.props.label && (
109+
<label className="tc-label">
110+
{this.props.label}
111+
</label>)}
112+
{options.map(renderOption)}
113+
{ hasError ? (<p className="error-message">{errorMessage}</p>) : null}
114+
</div>
115+
)
116+
}
117+
}
118+
TiledCheckboxGroup.propTypes = {
119+
options: PropTypes.arrayOf(
120+
PropTypes.shape({
121+
title: PropTypes.string.isRequired,
122+
value: PropTypes.string.isRequired,
123+
desc: PropTypes.string
124+
// icon: PropTypes.
125+
}).isRequired
126+
).isRequired,
127+
checkMarkActiveIcon: PropTypes.node,
128+
checkMarkUnActiveIcon: PropTypes.node,
129+
showCheckMarkBeforeTitle: PropTypes.bool
130+
}
131+
132+
TiledCheckboxGroup.defaultProps = {
133+
onChange: () => {},
134+
showCheckMarkBeforeTitle: false
135+
}
136+
137+
export default hoc(TiledCheckboxGroup)

components/Formsy/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import CheckboxGroup from './CheckboxGroup'
99
import SliderRadioGroup from './SliderRadioGroup'
1010
import TiledRadioGroup from './TiledRadioGroup'
1111
import TiledCheckboxInput from './TiledCheckboxInput'
12+
import TiledCheckboxGroup from './TiledCheckboxGroup'
1213

1314
require('./FormFields.scss')
1415

@@ -39,6 +40,7 @@ export default {
3940
CheckboxGroup,
4041
SliderRadioGroup,
4142
TiledRadioGroup,
42-
TiledCheckboxInput
43+
TiledCheckboxInput,
44+
TiledCheckboxGroup
4345
}
4446
}

0 commit comments

Comments
 (0)