fixed multiple select component
This commit is contained in:
@@ -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
|
@@ -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 {
|
||||||
|
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -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',
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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)) {
|
||||||
|
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user