- basic implementation of Form.jsx
- fixed "colspan" issue on listings with no bulk actions and no records
This commit is contained in:
Jonathan Labreuille
2015-09-13 11:51:05 +02:00
parent 4a4fd1080e
commit e471d45827
3 changed files with 193 additions and 128 deletions

167
assets/js/src/form/form.jsx Normal file
View File

@@ -0,0 +1,167 @@
define(
[
'react',
'mailpoet',
'classnames',
'react-router'
],
function(
React,
MailPoet,
classNames,
Router
) {
var FormField = React.createClass({
render: function() {
return (
<tr>
<th scope="row">
<label
htmlFor={ 'field_'+this.props.field.name }
>{ 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 } />
</td>
</tr>
);
}
});
var Form = React.createClass({
mixins: [
Router.Navigation
],
getInitialState: function() {
return {
loading: false,
errors: [],
item: {}
};
},
componentDidMount: function() {
if(this.props.params.id !== undefined) {
if(this.isMounted()) {
this.loadItem(this.props.params.id);
}
}
},
componentWillReceiveProps: function(props) {
if(props.params.id === undefined) {
this.setState({
loading: false,
item: {}
});
} else {
this.loadItem(props.params.id);
}
},
loadItem: function(id) {
this.setState({ loading: true });
MailPoet.Ajax.post({
endpoint: 'subscribers',
action: 'get',
data: { id: id }
}).done(function(response) {
if(response === false) {
this.setState({
loading: false,
item: {}
}, function() {
this.transitionTo('/new');
}.bind(this));
} else {
this.setState({
loading: false,
item: response
});
}
}.bind(this));
},
handleSubmit: function(e) {
e.preventDefault();
this.setState({ loading: true });
MailPoet.Ajax.post({
endpoint: 'subscribers',
action: 'save',
data: this.state.item
}).done(function(response) {
this.setState({ loading: false });
if(response === true) {
this.transitionTo('/');
if(this.props.params.id !== undefined) {
MailPoet.Notice.success('Subscriber succesfully updated!');
} else {
MailPoet.Notice.success('Subscriber succesfully added!');
}
} else {
this.setState({ errors: response });
}
}.bind(this));
},
handleValueChange: function(e) {
var item = this.state.item;
item[e.target.name] = e.target.value;
this.setState({
item: item
});
return true;
},
render: function() {
var errors = this.state.errors.map(function(error, index) {
return (
<p key={'error-'+index} className="mailpoet_error">{ error }</p>
);
});
var formClasses = classNames(
{ 'mailpoet_form_loading': this.state.loading }
);
var fields = this.props.fields.map(function(field, index) {
return (
<FormField
field={ field }
item={ this.state.item }
onValueChange={ this.handleValueChange }
key={ 'field-'+index } />
);
}.bind(this));
return (
<form
className={ formClasses }
onSubmit={ this.handleSubmit }>
{ errors }
<table className="form-table">
<tbody>
{fields}
</tbody>
</table>
<input
className="button button-primary"
type="submit"
value="Save"
disabled={this.state.loading} />
</form>
);
}
});
return Form;
}
);

View File

@@ -72,7 +72,10 @@ define(
<tbody> <tbody>
<tr className="no-items"> <tr className="no-items">
<td <td
colSpan={ this.props.columns.length + 1 } colSpan={
this.props.columns.length
+ (this.props.is_selectable ? 1 : 0)
}
className="colspanchange"> className="colspanchange">
{ {
(this.props.loading === true) (this.props.loading === true)
@@ -97,7 +100,10 @@ define(
return ( return (
<tbody> <tbody>
<tr className={ selectAllClasses }> <tr className={ selectAllClasses }>
<td colSpan={ this.props.columns.length + 1 }> <td colSpan={
this.props.columns.length
+ (this.props.is_selectable ? 1 : 0)
}>
{ MailPoetI18n.selectAllLabel }&nbsp; { MailPoetI18n.selectAllLabel }&nbsp;
<a <a
onClick={ this.props.onSelectAll } onClick={ this.props.onSelectAll }

View File

@@ -5,149 +5,41 @@ define(
'jquery', 'jquery',
'mailpoet', 'mailpoet',
'classnames', 'classnames',
'form/form.jsx'
], ],
function( function(
React, React,
Router, Router,
jQuery, jQuery,
MailPoet, MailPoet,
classNames classNames,
Form
) { ) {
var Form = React.createClass({ var fields = [
mixins: [ {
Router.Navigation name: 'email',
], label: 'E-mail'
getInitialState: function() {
return {
loading: false,
errors: [],
item: {}
};
}, },
componentDidMount: function() { {
if(this.props.params.id !== undefined) { name: 'first_name',
if(this.isMounted()) { label: 'Firstname'
this.loadItem(this.props.params.id);
}
}
}, },
componentWillReceiveProps: function(props) { {
if(props.params.id === undefined) { name: 'last_name',
this.setState({ label: 'Lastname'
loading: false, }
item: {} ];
});
} else {
this.loadItem(props.params.id);
}
},
loadItem: function(id) {
this.setState({ loading: true });
MailPoet.Ajax.post({ var SubscriberForm = React.createClass({
endpoint: 'subscribers',
action: 'get',
data: { id: id }
}).done(function(response) {
if(response === false) {
this.setState({
loading: false,
item: {}
}, function() {
this.transitionTo('/new');
}.bind(this));
} else {
this.setState({
loading: false,
item: response
});
}
}.bind(this));
},
handleSubmit: function(e) {
e.preventDefault();
this.setState({ loading: true });
MailPoet.Ajax.post({
endpoint: 'subscribers',
action: 'save',
data: this.state.item
}).done(function(response) {
this.setState({ loading: false });
if(response === true) {
this.transitionTo('/');
if(this.props.params.id !== undefined) {
MailPoet.Notice.success('Subscriber succesfully updated!');
} else {
MailPoet.Notice.success('Subscriber succesfully added!');
}
} else {
this.setState({ errors: response });
}
}.bind(this));
},
handleItemChange: function(e) {
var item = this.state.item;
item[e.target.name] = e.target.value;
this.setState({
item: item
});
return true;
},
render: function() { render: function() {
var errors = this.state.errors.map(function(error, index) {
return (
<p key={'error-'+index} className="mailpoet_error">{ error }</p>
);
});
var formClasses = classNames(
{ 'mailpoet_form_loading': this.state.loading }
);
return ( return (
<form <Form fields={ fields } params={ this.props.params } />
className={ formClasses }
onSubmit={ this.handleSubmit }>
{ errors }
<p>
<input
type="text"
placeholder="Email"
name="email"
value={ this.state.item.email }
onChange={ this.handleItemChange }/>
</p>
<p>
<input
type="text"
placeholder="First name"
name="first_name"
value={ this.state.item.first_name }
onChange={ this.handleItemChange }/>
</p>
<p>
<input
type="text"
placeholder="Last name"
name="last_name"
value={ this.state.item.last_name }
onChange={ this.handleItemChange }/>
</p>
<input
className="button button-primary"
type="submit"
value="Save"
disabled={this.state.loading} />
</form>
); );
} }
}); });
return Form; return SubscriberForm;
} }
); );