Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
Merge pull request #148 from AparnaKarve/react_bootstrap_select
Browse files Browse the repository at this point in the history
Custom Dropdown component with search support
  • Loading branch information
priley86 committed Mar 20, 2018
2 parents 70d58d1 + 38e819f commit 778bfb7
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 131 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@import './components/DualPaneMapper/DualPaneMapper.scss';
@import './components/SourceClusterSelect/SourceClusterSelect.scss';
@import './components/WarningModal/WarningModal.scss';

.dual-pane-mapper-form {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import PropTypes from 'prop-types';
import { Field, reduxForm } from 'redux-form';
import { length } from 'redux-form-validators';
import { noop, bindMethods } from 'patternfly-react';
import SourceClusterSelect from '../SourceClusterSelect/SourceClusterSelect';
import DatastoresStepForm from './components/DatastoresStepForm/DatastoresStepForm';
import { BootstrapSelect } from '../../../../../common/forms/BootstrapSelect';
import { getClusterOptions } from '../helpers';

class MappingWizardDatastoresStep extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -109,16 +110,27 @@ class MappingWizardDatastoresStep extends React.Component {

const { selectedCluster, selectedClusterMapping } = this.state;

const clusterOptions = getClusterOptions(clusterMappings);

// first we render the dropdown selection for each source cluster in clusterMappings,
// then we call `selectSourceCluster` and go get that cluster's datastores on selection
return (
<div>
<SourceClusterSelect
clusterMappings={clusterMappings}
selectSourceCluster={this.selectSourceCluster}
selectedCluster={selectedCluster}
selectedClusterMapping={selectedClusterMapping}
form={form}
<Field
name="cluster_select"
label={__('Map source datastores to target datastores for cluster')}
data_live_search="true"
component={BootstrapSelect}
options={clusterOptions}
option_key="id"
option_value="name"
onSelect={this.selectSourceCluster}
pre_selected_value={
clusterOptions.length === 1 ? clusterOptions[0].id : ''
}
choose_text={`<${__('Select a source cluster')}>`}
render_within_form="true"
form_name={form}
/>
<Field
name="datastoresMappings"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import PropTypes from 'prop-types';
import { noop, bindMethods } from 'patternfly-react';
import { Field, reduxForm } from 'redux-form';
import { length } from 'redux-form-validators';
import SourceClusterSelect from '../SourceClusterSelect/SourceClusterSelect';
import NetworksStepForm from './components/NetworksStepForm/NetworksStepForm';
import { BootstrapSelect } from '../../../../../common/forms/BootstrapSelect';
import { getClusterOptions } from '../helpers';

class MappingWizardNetworksStep extends React.Component {
constructor(props) {
Expand Down Expand Up @@ -107,14 +108,25 @@ class MappingWizardNetworksStep extends React.Component {

const { selectedCluster, selectedClusterMapping } = this.state;

const clusterOptions = getClusterOptions(clusterMappings);

return (
<div>
<SourceClusterSelect
clusterMappings={clusterMappings}
selectSourceCluster={this.selectSourceCluster}
selectedCluster={selectedCluster}
selectedClusterMapping={selectedClusterMapping}
form={form}
<Field
name="cluster_select"
label={__('Map source networks to target networks for cluster')}
data_live_search="true"
component={BootstrapSelect}
options={clusterOptions}
option_key="id"
option_value="name"
onSelect={this.selectSourceCluster}
pre_selected_value={
clusterOptions.length === 1 ? clusterOptions[0].id : ''
}
choose_text={`<${__('Select a source cluster')}>`}
render_within_form="true"
form_name={form}
/>
<Field
name="networksMappings"
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const getClusterOptions = clusterMappings => {
const sourceClustersWithAssociatedTargetClusters = clusterMappings.reduce(
(mappings, targetClusterWithSourceClusters) => {
const {
nodes: sourceClusters,
...targetCluster
} = targetClusterWithSourceClusters;
const sourceToTargetMappings = sourceClusters.map(sourceCluster => ({
sourceCluster,
targetCluster,
sourceClusterMappedToTargetCluster: {
name: `${sourceCluster.name} (${targetCluster.name})`,
id: sourceCluster.id
}
}));
return mappings.concat(sourceToTargetMappings);
},
[]
);

return sourceClustersWithAssociatedTargetClusters.map(
({ sourceClusterMappedToTargetCluster }) =>
sourceClusterMappedToTargetCluster
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@ import { required } from 'redux-form-validators';
import { Form } from 'patternfly-react';
import PropTypes from 'prop-types';
import { FormField } from '../../../../../common/forms/FormField';
import { BootstrapSelect } from '../../../../../common/forms/BootstrapSelect';

const PlanWizardGeneralStep = ({ transformationMappings }) => (
<Form className="form-horizontal">
<Field
name="infrastructure_mapping"
label={__('Infrastructure Mapping')}
required
component={FormField}
data_live_search="true"
component={BootstrapSelect}
validate={[required({ msg: __('Required') })]}
options={transformationMappings}
optionKey="id"
optionValue="name"
type="select"
option_key="id"
option_value="name"
form_name="planWizardGeneralStep"
/>
<Field
name="name"
Expand Down
115 changes: 115 additions & 0 deletions app/javascript/react/screens/App/common/forms/BootstrapSelect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React from 'react';
import PropTypes from 'prop-types';
import {
Form,
FormGroup,
Grid,
ControlLabel,
bindMethods
} from 'patternfly-react';
import { focus } from 'redux-form';

const $ = require('jquery');
require('bootstrap-select');

export class BootstrapSelect extends React.Component {
constructor(props) {
super(props);
bindMethods(this, ['renderFormGroup']);
}
componentDidMount() {
const {
input,
form_name,
meta: { visited, dispatch },
onSelect,
pre_selected_value
} = this.props;

$(`#${input.name}`).selectpicker('val', input.value || pre_selected_value);

$(`.${input.name}_select`).on('click', '.dropdown-toggle', e => {
if (!visited) dispatch(focus(form_name, input.name));
});
if (onSelect)
$(`#${input.name}`).on('changed.bs.select', e => {
onSelect(e.target.value);
});
}

renderFormGroup = (labelWidth, controlWidth) => {
const {
input,
label,
required,
data_live_search,
options,
option_key,
option_value,
choose_text,
meta: { visited, error, active }
} = this.props;
const formGroupProps = { key: { label }, ...this.props };

if (visited && !active && error) formGroupProps.validationState = 'error';

return (
<FormGroup {...formGroupProps}>
<Grid.Col componentClass={ControlLabel} sm={labelWidth}>
{label}
{required && ' *'}
</Grid.Col>
<Grid.Col sm={controlWidth}>
<select
id={input.name}
data-live-search={data_live_search}
className={`form-control ${input.name}_select`}
{...input}
>
<option disabled value="">
{choose_text || `<${__('Choose')}>`}
</option>
{options.map(val => (
<option value={val[option_key]} key={val[option_value]}>
{val[option_value]}
</option>
))}
</select>
{visited &&
!active &&
error && <Form.HelpBlock>{error}</Form.HelpBlock>}
</Grid.Col>
</FormGroup>
);
};

render = () => {
const { render_within_form } = this.props;

if (render_within_form) {
return (
<div>
<Form horizontal>{this.renderFormGroup(6, 4)}</Form>
</div>
);
}
return this.renderFormGroup(2, 9);
};
}

BootstrapSelect.propTypes = {
label: PropTypes.string,
input: PropTypes.object,
required: PropTypes.bool,
data_live_search: PropTypes.string,
type: PropTypes.string,
options: PropTypes.array,
option_key: PropTypes.string,
option_value: PropTypes.string,
meta: PropTypes.object,
form_name: PropTypes.string,
onSelect: PropTypes.func,
pre_selected_value: PropTypes.string,
choose_text: PropTypes.string,
render_within_form: PropTypes.string
};
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@
},
"dependencies": {
"axios": "^0.17.1",
"bootstrap-select": "^1.12.4",
"classnames": "^2.2.5",
"csv": "^2.0.0",
"cx": "^18.1.11",
"intl": "~1.2.5",
"jquery": "^3.3.1",
"moment": "^2.20.1",
"numeral": "^2.0.6",
"patternfly": "^3.35.1",
Expand Down

0 comments on commit 778bfb7

Please sign in to comment.