Listing & form
- improved Listing in order to make it more DRY - form builder with all field types - added support for data array in ValidModel->set() - updated models to comply with Listing & Form methods
This commit is contained in:
@@ -3,17 +3,191 @@ define(
|
||||
'react',
|
||||
'mailpoet',
|
||||
'classnames',
|
||||
'react-router'
|
||||
'react-router',
|
||||
'react-checkbox-group'
|
||||
],
|
||||
function(
|
||||
React,
|
||||
MailPoet,
|
||||
classNames,
|
||||
Router
|
||||
Router,
|
||||
CheckboxGroup
|
||||
) {
|
||||
|
||||
|
||||
var FormFieldSelect = React.createClass({
|
||||
render: function() {
|
||||
var options =
|
||||
Object.keys(this.props.field.values).map(function(value, index) {
|
||||
return (
|
||||
<option
|
||||
key={ 'option-' + index }
|
||||
value={ value }>
|
||||
{ this.props.field.values[value] }
|
||||
</option>
|
||||
);
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return (
|
||||
<select
|
||||
name={ this.props.field.name }
|
||||
id={ 'field_'+this.props.field.name }
|
||||
value={ this.props.item[this.props.field.name] }
|
||||
onChange={ this.props.onValueChange } >
|
||||
{options}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var FormFieldRadio = React.createClass({
|
||||
render: function() {
|
||||
var selected_value = this.props.item[this.props.field.name];
|
||||
var count = Object.keys(this.props.field.values).length;
|
||||
|
||||
var options = Object.keys(this.props.field.values).map(
|
||||
function(value, index) {
|
||||
return (
|
||||
<p key={ 'radio-' + index }>
|
||||
<label>
|
||||
<input
|
||||
type="radio"
|
||||
checked={ selected_value === value }
|
||||
value={ value }
|
||||
onChange={ this.props.onValueChange }
|
||||
name={ this.props.field.name } />
|
||||
{ this.props.field.values[value] }
|
||||
</label>
|
||||
</p>
|
||||
);
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ options }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var FormFieldCheckbox = React.createClass({
|
||||
render: function() {
|
||||
var selected_values = this.props.item[this.props.field.name] || '';
|
||||
if(
|
||||
selected_values !== undefined
|
||||
&& selected_values.constructor !== Array
|
||||
) {
|
||||
selected_values = selected_values.split(';').map(function(value) {
|
||||
return value.trim();
|
||||
});
|
||||
}
|
||||
var count = Object.keys(this.props.field.values).length;
|
||||
|
||||
var options = Object.keys(this.props.field.values).map(
|
||||
function(value, index) {
|
||||
return (
|
||||
<p key={ 'checkbox-' + index }>
|
||||
<label>
|
||||
<input type="checkbox" value={ value } />
|
||||
{ this.props.field.values[value] }
|
||||
</label>
|
||||
</p>
|
||||
);
|
||||
}.bind(this)
|
||||
);
|
||||
|
||||
return (
|
||||
<CheckboxGroup
|
||||
name={ this.props.field.name }
|
||||
value={ selected_values }
|
||||
ref={ this.props.field.name }
|
||||
onChange={ this.handleValueChange }>
|
||||
{ options }
|
||||
</CheckboxGroup>
|
||||
);
|
||||
},
|
||||
handleValueChange: function() {
|
||||
var field = this.props.field.name;
|
||||
var group = this.refs[field];
|
||||
var selected_values = [];
|
||||
|
||||
if(group !== undefined) {
|
||||
selected_values = group.getCheckedValues();
|
||||
}
|
||||
|
||||
return this.props.onValueChange({
|
||||
target: {
|
||||
name: field,
|
||||
value: selected_values.join(';')
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var FormFieldText = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<input
|
||||
type="text"
|
||||
className="regular-text"
|
||||
name={ this.props.field.name }
|
||||
id={ 'field_'+this.props.field.name }
|
||||
value={ this.props.item[this.props.field.name] }
|
||||
onChange={ this.props.onValueChange } />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var FormFieldTextarea = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<textarea
|
||||
type="text"
|
||||
className="regular-text"
|
||||
name={ this.props.field.name }
|
||||
id={ 'field_'+this.props.field.name }
|
||||
value={ this.props.item[this.props.field.name] }
|
||||
onChange={ this.props.onValueChange } />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var FormField = React.createClass({
|
||||
render: function() {
|
||||
|
||||
var description = false;
|
||||
if(this.props.field.description) {
|
||||
description = (
|
||||
<p className="description">{ this.props.field.description }</p>
|
||||
);
|
||||
}
|
||||
|
||||
var field = false;
|
||||
|
||||
switch(this.props.field.type) {
|
||||
case 'text':
|
||||
field = (<FormFieldText {...this.props} />);
|
||||
break;
|
||||
|
||||
case 'textarea':
|
||||
field = (<FormFieldTextarea {...this.props} />);
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
field = (<FormFieldSelect {...this.props} />);
|
||||
break;
|
||||
|
||||
case 'radio':
|
||||
field = (<FormFieldRadio {...this.props} />);
|
||||
break;
|
||||
|
||||
case 'checkbox':
|
||||
field = (<FormFieldCheckbox {...this.props} />);
|
||||
break;
|
||||
}
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<th scope="row">
|
||||
@@ -22,12 +196,8 @@ define(
|
||||
>{ this.props.field.label }</label>
|
||||
</th>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
name={ this.props.field.name }
|
||||
id={ 'field_'+this.props.field.name }
|
||||
value={ this.props.item[this.props.field.name] }
|
||||
onChange={ this.props.onValueChange } />
|
||||
{ field }
|
||||
{ description }
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
@@ -66,7 +236,7 @@ define(
|
||||
this.setState({ loading: true });
|
||||
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'subscribers',
|
||||
endpoint: this.props.endpoint,
|
||||
action: 'get',
|
||||
data: { id: id }
|
||||
}).done(function(response) {
|
||||
@@ -91,7 +261,7 @@ define(
|
||||
this.setState({ loading: true });
|
||||
|
||||
MailPoet.Ajax.post({
|
||||
endpoint: 'subscribers',
|
||||
endpoint: this.props.endpoint,
|
||||
action: 'save',
|
||||
data: this.state.item
|
||||
}).done(function(response) {
|
||||
@@ -100,19 +270,21 @@ define(
|
||||
if(response === true) {
|
||||
this.transitionTo('/');
|
||||
if(this.props.params.id !== undefined) {
|
||||
MailPoet.Notice.success('Subscriber succesfully updated!');
|
||||
this.props.messages['updated']();
|
||||
} else {
|
||||
MailPoet.Notice.success('Subscriber succesfully added!');
|
||||
this.props.messages['created']();
|
||||
}
|
||||
|
||||
} else {
|
||||
this.setState({ errors: response });
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
handleValueChange: function(e) {
|
||||
var item = this.state.item;
|
||||
item[e.target.name] = e.target.value;
|
||||
var item = this.state.item,
|
||||
field = e.target.name;
|
||||
|
||||
item[field] = e.target.value;
|
||||
|
||||
this.setState({
|
||||
item: item
|
||||
});
|
||||
@@ -121,7 +293,9 @@ define(
|
||||
render: function() {
|
||||
var errors = this.state.errors.map(function(error, index) {
|
||||
return (
|
||||
<p key={'error-'+index} className="mailpoet_error">{ error }</p>
|
||||
<p key={ 'error-'+index } className="mailpoet_error">
|
||||
{ error }
|
||||
</p>
|
||||
);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user