fixed multiple select component

This commit is contained in:
Jonathan Labreuille
2015-10-09 14:48:54 +02:00
parent be2c35c13e
commit ed9407a890
7 changed files with 102 additions and 65 deletions

View File

@@ -15,4 +15,12 @@ a:focus
// hide elements // hide elements
.mailpoet_hidden .mailpoet_hidden
display: none display: none
// select 2
.select2-container
width: 25em
@media screen and (max-width: 782px)
.select2-container
width: 100% !important

View File

@@ -4,7 +4,8 @@ define([
'form/fields/textarea.jsx', 'form/fields/textarea.jsx',
'form/fields/select.jsx', 'form/fields/select.jsx',
'form/fields/radio.jsx', 'form/fields/radio.jsx',
'form/fields/checkbox.jsx' 'form/fields/checkbox.jsx',
'form/fields/selection.jsx'
], ],
function( function(
React, React,
@@ -12,7 +13,8 @@ function(
FormFieldTextarea, FormFieldTextarea,
FormFieldSelect, FormFieldSelect,
FormFieldRadio, FormFieldRadio,
FormFieldCheckbox FormFieldCheckbox,
FormFieldSelection
) { ) {
var FormField = React.createClass({ var FormField = React.createClass({
renderField: function(data, inline = false) { renderField: function(data, inline = false) {
@@ -26,29 +28,33 @@ function(
var field = false; var field = false;
if(data.field['field'] !== undefined) { if(data.field['field'] !== undefined) {
field = data.field.field; data.field = jQuery.merge(data.field, data.field.field);
} else{ }
switch(data.field.type) {
case 'text':
field = (<FormFieldText {...data} />);
break;
case 'textarea': switch(data.field.type) {
field = (<FormFieldTextarea {...data} />); case 'text':
break; field = (<FormFieldText {...data} />);
break;
case 'select': case 'textarea':
field = (<FormFieldSelect {...data} />); field = (<FormFieldTextarea {...data} />);
break; break;
case 'radio': case 'select':
field = (<FormFieldRadio {...data} />); field = (<FormFieldSelect {...data} />);
break; break;
case 'checkbox': case 'radio':
field = (<FormFieldCheckbox {...data} />); field = (<FormFieldRadio {...data} />);
break; break;
}
case 'checkbox':
field = (<FormFieldCheckbox {...data} />);
break;
case 'selection':
field = (<FormFieldSelection {...data} />);
break;
} }
if(inline === true) { if(inline === true) {
@@ -75,7 +81,8 @@ function(
return this.renderField({ return this.renderField({
index: index, index: index,
field: subfield, field: subfield,
item: this.props.item item: this.props.item,
onValueChange: this.props.onValueChange || false
}); });
}.bind(this)); }.bind(this));
} else { } else {

View File

@@ -1,6 +1,7 @@
define([ define([
'react', 'react',
'jquery' 'jquery',
'select2'
], ],
function( function(
React, React,
@@ -9,43 +10,45 @@ function(
var Selection = React.createClass({ var Selection = React.createClass({
getInitialState: function() { getInitialState: function() {
return { return {
loading: false, items: []
items: [],
selected: []
} }
}, },
componentWillMount: function() { componentWillMount: function() {
this.loadCachedItems(); this.loadCachedItems();
}, },
componentDidMount: function() { componentDidMount: function() {
if(this.props.select2) { jQuery('#'+this.props.field.id).select2()
jQuery('#'+this.props.id).select2({ .on('change', this.handleChange);
width: '25em' },
}); componentDidUpdate: function() {
} jQuery('#'+this.props.field.id).select2(
'val',
(this.props.item[this.props.field.name])
);
}, },
loadCachedItems: function() { loadCachedItems: function() {
if(typeof(window['mailpoet_'+this.props.endpoint]) !== 'undefined') { if(typeof(window['mailpoet_'+this.props.field.endpoint]) !== 'undefined') {
var items = window['mailpoet_'+this.props.endpoint]; var items = window['mailpoet_'+this.props.field.endpoint];
this.setState({ this.setState({
items: items items: items
}); });
} }
}, },
handleChange: function() { handleChange: function() {
this.setState({ return this.props.onValueChange({
selected: jQuery('#'+this.props.id).val() target: {
value: jQuery('#'+this.props.field.id).select2('val'),
name: this.props.field.name
}
}); });
}, },
getSelected: function() {
return this.state.selected;
},
render: function() { render: function() {
var options = this.state.items.map(function(item, index) { var options = this.state.items.map(function(item, index) {
return ( return (
<option <option
key={ 'action-' + index } key={ item.id }
value={ item.id }> value={ item.id }
>
{ item.name } { item.name }
</option> </option>
); );
@@ -54,12 +57,12 @@ function(
return ( return (
<select <select
ref="selection" ref="selection"
id={ this.props.id || 'mailpoet_field_selection'} id={ this.props.field.id || 'mailpoet_field_selection'}
placeholder={ this.props.placeholder } placeholder={ this.props.field.placeholder }
multiple={ this.props.multiple } multiple={ this.props.field.multiple }
> onChange={ this.handleChange }
{ options } defaultValue={ this.props.item[this.props.field.name] }
</select> >{ options }</select>
); );
} }
}); });

View File

@@ -27,17 +27,14 @@ define(
type: 'text' type: 'text'
}, },
{ {
name: 'list', name: 'segments',
label: 'Lists', label: 'Lists',
tip: "The subscriber list that will be used for this campaign.", tip: "The subscriber list that will be used for this campaign.",
field: ( type: 'selection',
<Selection placeholder: "Select a list",
placeholder="Select a list" id: "mailpoet_segments",
id="mailpoet_segments" endpoint: "segments",
endpoint="segments" multiple: true
multiple={ true }
select2={ true } />
)
}, },
{ {
name: 'sender', name: 'sender',

View File

@@ -116,7 +116,8 @@ class Migrator {
'segment_id mediumint(9) NOT NULL,', 'segment_id mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', 'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)' 'PRIMARY KEY (id)',
'UNIQUE KEY subscriber_segment (subscriber_id, segment_id)'
); );
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }
@@ -128,7 +129,8 @@ class Migrator {
'segment_id mediumint(9) NOT NULL,', 'segment_id mediumint(9) NOT NULL,',
'created_at TIMESTAMP NOT NULL DEFAULT 0,', 'created_at TIMESTAMP NOT NULL DEFAULT 0,',
'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,', 'updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,',
'PRIMARY KEY (id)' 'PRIMARY KEY (id)',
'UNIQUE KEY newsletter_segment (newsletter_id, segment_id)'
); );
return $this->sqlify(__FUNCTION__, $attributes); return $this->sqlify(__FUNCTION__, $attributes);
} }

View File

@@ -107,7 +107,7 @@ class Newsletter extends Model {
$saved = $newsletter->save(); $saved = $newsletter->save();
if($saved === true) { if($saved === true) {
return true; return $newsletter->id();
} else { } else {
$errors = $newsletter->getValidationErrors(); $errors = $newsletter->getValidationErrors();
if(!empty($errors)) { if(!empty($errors)) {

View File

@@ -7,6 +7,7 @@ use MailPoet\Models\Newsletter;
use MailPoet\Models\Segment; use MailPoet\Models\Segment;
use MailPoet\Models\Subscriber; use MailPoet\Models\Subscriber;
use MailPoet\Models\NewsletterTemplate; use MailPoet\Models\NewsletterTemplate;
use MailPoet\Models\NewsletterSegment;
use MailPoet\Newsletter\Renderer\Renderer; use MailPoet\Newsletter\Renderer\Renderer;
if(!defined('ABSPATH')) exit; if(!defined('ABSPATH')) exit;
@@ -21,7 +22,12 @@ class Newsletters {
if($newsletter === false) { if($newsletter === false) {
wp_send_json(false); wp_send_json(false);
} else { } else {
wp_send_json($newsletter->asArray()); $segments = $newsletter->segments()->findArray();
$newsletter = $newsletter->asArray();
$newsletter['segments'] = array_map(function($segment) {
return $segment['id'];
}, $segments);
wp_send_json($newsletter);
} }
} }
@@ -31,12 +37,26 @@ class Newsletters {
} }
function save($data = array()) { function save($data = array()) {
$result = Newsletter::createOrUpdate($data); if(isset($data['segments'])) {
if($result !== true) { $segment_ids = $data['segments'];
wp_send_json($result); unset($data['segments']);
} else {
wp_send_json(true);
} }
$newsletter_id = Newsletter::createOrUpdate($data);
if($newsletter_id !== false && !empty($segment_ids)) {
// remove previous relationships with segments
NewsletterSegment::where('newsletter_id', $newsletter_id)->deleteMany();
// create relationship with segments
foreach($segment_ids as $segment_id) {
$relation = NewsletterSegment::create();
$relation->segment_id = $segment_id;
$relation->newsletter_id = $newsletter_id;
$relation->save();
}
}
wp_send_json(($newsletter_id !== false));
} }
function delete($id) { function delete($id) {