Skip to content

Commit

Permalink
fix(CustomInput): hidden attribute #1741 (#1777)
Browse files Browse the repository at this point in the history
* Investigation

* Fix for custom input hidden attr

* Updated CustomFileInput to output hidden attr

* fix(CustomInput): Input hidden whitespace

* fix(CustomInput): Hidden attr import quotes
  • Loading branch information
hedgecox committed Jan 31, 2020
1 parent 54648b6 commit bb39b55
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 104 deletions.
160 changes: 87 additions & 73 deletions src/CustomFileInput.js
Expand Up @@ -13,99 +13,113 @@ const propTypes = {
htmlFor: PropTypes.string,
cssModule: PropTypes.object,
onChange: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.array, PropTypes.func]),
children: PropTypes.oneOfType([
PropTypes.node,
PropTypes.array,
PropTypes.func
]),
innerRef: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.func,
PropTypes.func
])
};

class CustomFileInput extends React.Component {
constructor(props) {
super(props);
constructor(props) {
super(props);

this.state = {
files:null,
};
this.state = {
files: null
};

this.onChange = this.onChange.bind(this);
}

onChange(e) {
let input = e.target;
let {onChange} = this.props;
let files = this.getSelectedFiles(input);
this.onChange = this.onChange.bind(this);
}

if (typeof(onChange) === 'function') {
onChange(...arguments);
}
onChange(e) {
let input = e.target;
let { onChange } = this.props;
let files = this.getSelectedFiles(input);

this.setState({files})
if (typeof onChange === "function") {
onChange(...arguments);
}

getSelectedFiles(input) {
let {multiple} = this.props;
this.setState({ files });
}

if (multiple && input.files) {
let files = [].slice.call(input.files);
getSelectedFiles(input) {
let { multiple } = this.props;

return files.map(file => file.name).join(', ');
}
if (multiple && input.files) {
let files = [].slice.call(input.files);

if (input.value.indexOf('fakepath') !== -1) {
let parts = input.value.split('\\');
return files.map(file => file.name).join(", ");
}

return parts[parts.length - 1];
}
if (input.value.indexOf("fakepath") !== -1) {
let parts = input.value.split("\\");

return input.value;
return parts[parts.length - 1];
}

render() {
const {
className,
label,
valid,
invalid,
cssModule,
children,
bsSize,
innerRef,
htmlFor,
type,
onChange,
dataBrowse,
...attributes
} = this.props;

const customClass = mapToCssModules(
classNames(
className,
`custom-file`,
),
cssModule
);

const validationClassNames = mapToCssModules(
classNames(
invalid && 'is-invalid',
valid && 'is-valid',
),
cssModule
);

const labelHtmlFor = htmlFor || attributes.id;
const {files} = this.state;

return (
<div className={customClass}>
<input type="file" {...attributes} ref={innerRef} className={classNames(validationClassNames, mapToCssModules('custom-file-input', cssModule))} onChange={this.onChange}/>
<label className={mapToCssModules('custom-file-label', cssModule)} htmlFor={labelHtmlFor} data-browse={ dataBrowse }>{files || label || 'Choose file'}</label>
{children}
</div>
);
}
return input.value;
}

render() {
const {
className,
label,
valid,
invalid,
cssModule,
children,
bsSize,
innerRef,
htmlFor,
type,
onChange,
dataBrowse,
hidden,
...attributes
} = this.props;

const customClass = mapToCssModules(
classNames(className, `custom-file`),
cssModule
);

const validationClassNames = mapToCssModules(
classNames(invalid && "is-invalid", valid && "is-valid"),
cssModule
);

const labelHtmlFor = htmlFor || attributes.id;
const { files } = this.state;

return (
<div className={customClass} hidden={hidden || false}>
<input
type="file"
{...attributes}
ref={innerRef}
className={classNames(
validationClassNames,
mapToCssModules("custom-file-input", cssModule)
)}
onChange={this.onChange}
/>
<label
className={mapToCssModules("custom-file-label", cssModule)}
htmlFor={labelHtmlFor}
data-browse={dataBrowse}
>
{files || label || "Choose file"}
</label>
{children}
</div>
);
}
}

CustomFileInput.propTypes = propTypes;
Expand Down
78 changes: 47 additions & 31 deletions src/CustomInput.js
Expand Up @@ -16,11 +16,7 @@ const propTypes = {
htmlFor: PropTypes.string,
cssModule: PropTypes.object,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.array, PropTypes.func]),
innerRef: PropTypes.oneOfType([
PropTypes.object,
PropTypes.string,
PropTypes.func,
])
innerRef: PropTypes.oneOfType([PropTypes.object, PropTypes.string, PropTypes.func])
};

function CustomInput(props) {
Expand All @@ -40,51 +36,71 @@ function CustomInput(props) {

const type = attributes.type;

const customClass = mapToCssModules(classNames(
className,
`custom-${type}`,
bsSize ? `custom-${type}-${bsSize}` : false,
), cssModule);
const customClass = mapToCssModules(
classNames(className, `custom-${type}`, bsSize ? `custom-${type}-${bsSize}` : false),
cssModule
);

const validationClassNames = mapToCssModules(classNames(
invalid && 'is-invalid',
valid && 'is-valid',
), cssModule);
const validationClassNames = mapToCssModules(
classNames(invalid && "is-invalid", valid && "is-valid"),
cssModule
);

const labelHtmlFor = htmlFor || attributes.id;

if (type === 'select') {
if (type === "select") {
const { type, ...rest } = attributes;
return <select {...rest} ref={innerRef} className={classNames(validationClassNames, customClass)}>{children}</select>;
}

if (type === 'file') {
return (
<CustomFileInput {...props}/>
<select
{...rest}
ref={innerRef}
className={classNames(validationClassNames, customClass)}
>
{children}
</select>
);
}

if (type !== 'checkbox' && type !== 'radio' && type !== 'switch') {
return <input {...attributes} ref={innerRef} className={classNames(validationClassNames, customClass)} />;
if (type === "file") {
return <CustomFileInput {...props} />;
}

if (type !== "checkbox" && type !== "radio" && type !== "switch") {
return (
<input
{...attributes}
ref={innerRef}
className={classNames(validationClassNames, customClass)}
/>
);
}

const wrapperClasses = classNames(
customClass,
mapToCssModules(classNames(
'custom-control',
{ 'custom-control-inline': inline }
), cssModule)
mapToCssModules(
classNames("custom-control", { "custom-control-inline": inline }),
cssModule
)
);

const { hidden, ...rest } = attributes;
return (
<div className={wrapperClasses}>
<div className={wrapperClasses} hidden={hidden || false}>
<input
{...attributes}
type={type === 'switch' ? 'checkbox' : type}
{...rest}
type={type === "switch" ? "checkbox" : type}
ref={innerRef}
className={classNames(validationClassNames, mapToCssModules('custom-control-input', cssModule))}
className={classNames(
validationClassNames,
mapToCssModules("custom-control-input", cssModule)
)}
/>
<label className={mapToCssModules('custom-control-label', cssModule)} htmlFor={labelHtmlFor}>{label}</label>
<label
className={mapToCssModules("custom-control-label", cssModule)}
htmlFor={labelHtmlFor}
>
{label}
</label>
{children}
</div>
);
Expand Down

0 comments on commit bb39b55

Please sign in to comment.