Merge branch 'develop' into dynamic-partials
This commit is contained in:
commit
7e5ce04a79
|
|
@ -1,5 +1,8 @@
|
|||
* **Build 17x** (2014-12-xx)
|
||||
- Improved asset caching (`cms.enableAssetCache`), when enabled the server will send a *304 Not Modified* header.
|
||||
- Introduced new *Table* widget and *DataTable* form widget.
|
||||
- There is now a simpler way for sending mail via `Mail::sendTo()`.
|
||||
- The List Filter query can now be extended with controller override `listFilterExtendQuery()`.
|
||||
|
||||
* **Build 171** (2014-12-17)
|
||||
- Add new methods `propertyName()` and `paramName()` to Component base class for accessing names of external properties.
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
$manager->registerFormWidget('Backend\FormWidgets\DataGrid', [
|
||||
'label' => 'Data Grid',
|
||||
'code' => 'datagrid'
|
||||
]); // @deprecated if year >= 2015
|
||||
$manager->registerFormWidget('Backend\FormWidgets\DataTable', [
|
||||
'label' => 'Data Table',
|
||||
'code' => 'datatable'
|
||||
]);
|
||||
$manager->registerFormWidget('Backend\FormWidgets\RecordFinder', [
|
||||
'label' => 'Record Finder',
|
||||
|
|
@ -138,11 +142,11 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
$manager->registerPermissions('October.Backend', [
|
||||
'backend.access_dashboard' => [
|
||||
'label' => 'system::lang.permissions.view_the_dashboard',
|
||||
'tab' => 'System'
|
||||
'tab' => 'system::lang.permissions.name'
|
||||
],
|
||||
'backend.manage_users' => [
|
||||
'backend.manage_users' => [
|
||||
'label' => 'system::lang.permissions.manage_other_administrators',
|
||||
'tab' => 'System'
|
||||
'tab' => 'system::lang.permissions.name'
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -217,6 +217,13 @@ class ListController extends ControllerBehavior
|
|||
return $widget->onRefresh();
|
||||
});
|
||||
|
||||
/*
|
||||
* Extend the query of the list of options
|
||||
*/
|
||||
$filterWidget->bindEvent('filter.extendQuery', function($query, $scope) {
|
||||
$this->controller->listFilterExtendQuery($query, $scope);
|
||||
});
|
||||
|
||||
// Apply predefined filter values
|
||||
$widget->addFilter([$filterWidget, 'applyAllScopesToQuery']);
|
||||
|
||||
|
|
@ -351,6 +358,16 @@ class ListController extends ControllerBehavior
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller override: Extend the query used for populating the filter
|
||||
* options before the default query is processed.
|
||||
* @param October\Rain\Database\Builder $query
|
||||
* @param array $scope
|
||||
*/
|
||||
public function listFilterExtendQuery($query, $scope)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CSS class name for a list row (<tr class="...">).
|
||||
* @param Model $record The populated model used for the column
|
||||
|
|
|
|||
|
|
@ -65,14 +65,14 @@ abstract class TableDataSourceBase
|
|||
/**
|
||||
* Returns a set of records from the data source.
|
||||
* @param integer $count Specifies the number of records to return.
|
||||
* @return array Returns the records.
|
||||
* @return array Returns the records.
|
||||
* If there are no more records, returns an empty array.
|
||||
*/
|
||||
public function readRecords($count = 10)
|
||||
{
|
||||
$result = $this->getRecords($this->offset, $count);
|
||||
$this->offset += count($result);
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
<?php namespace Backend\FormWidgets;
|
||||
|
||||
use Lang;
|
||||
use Backend\Widgets\Table;
|
||||
use Backend\Classes\FormWidgetBase;
|
||||
use System\Classes\ApplicationException;
|
||||
|
||||
/**
|
||||
* Data Table
|
||||
* Renders a table field.
|
||||
*
|
||||
* @package october\backend
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class DataTable extends FormWidgetBase
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public $defaultAlias = 'datatable';
|
||||
|
||||
/**
|
||||
* @var string Table size
|
||||
*/
|
||||
protected $size = 'large';
|
||||
|
||||
/**
|
||||
* @var Backend\Widgets\Table Table widget
|
||||
*/
|
||||
protected $table;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->size = $this->getConfig('size', $this->size);
|
||||
$this->table = $this->makeTableWidget();
|
||||
$this->table->bindToController();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Backend\Widgets\Table The table to be displayed.
|
||||
*/
|
||||
public function getTable()
|
||||
{
|
||||
return $this->table;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->prepareVars();
|
||||
return $this->makePartial('datatable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the list data
|
||||
*/
|
||||
public function prepareVars()
|
||||
{
|
||||
$this->populateTableWidget();
|
||||
$this->vars['table'] = $this->table;
|
||||
$this->vars['size'] = $this->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getSaveData($value)
|
||||
{
|
||||
$dataSource = $this->table->getDataSource();
|
||||
|
||||
$result = [];
|
||||
while ($records = $dataSource->readRecords()) {
|
||||
$result += $records;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populate data
|
||||
*/
|
||||
protected function populateTableWidget()
|
||||
{
|
||||
$dataSource = $this->table->getDataSource();
|
||||
$records = $this->getLoadData() ?: [];
|
||||
$dataSource->initRecords((array) $records);
|
||||
}
|
||||
|
||||
protected function makeTableWidget()
|
||||
{
|
||||
$config = $this->makeConfig((array) $this->config);
|
||||
$config->dataSource = 'client';
|
||||
$config->alias = $this->alias . 'Table';
|
||||
|
||||
$table = new Table($this->controller, $config);
|
||||
|
||||
$table->bindEvent('table.getDropdownOptions', [$this, 'getDataTableOptions']);
|
||||
|
||||
return $table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks at the model for getXXXDataTableOptions or getDataTableOptions methods
|
||||
* to obtain values for autocomplete field types.
|
||||
* @param string $field Table field name
|
||||
* @param string $data Data for the entire table
|
||||
* @return array
|
||||
*/
|
||||
public function getDataTableOptions($field, $data)
|
||||
{
|
||||
$methodName = 'get'.studly_case($this->fieldName).'DataTableOptions';
|
||||
|
||||
if (!$this->model->methodExists($methodName) && !$this->model->methodExists('getDataTableOptions')) {
|
||||
throw new ApplicationException(Lang::get('backend::lang.model.missing_method', ['class' => get_class($this->model), 'method' => 'getDataTableOptions']));
|
||||
}
|
||||
|
||||
if ($this->model->methodExists($methodName)) {
|
||||
$result = $this->model->$methodName($field, $data);
|
||||
}
|
||||
else {
|
||||
$result = $this->model->getDataTableOptions($this->fieldName, $field, $data);
|
||||
}
|
||||
|
||||
if (!is_array($result)) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -126,8 +126,9 @@ class DatePicker extends FormWidgetBase
|
|||
return null;
|
||||
}
|
||||
|
||||
if ($this->mode == 'datetime') {
|
||||
$value .= ' ' . post(self::TIME_PREFIX.$this->formField->getName(false)) . ':00';
|
||||
$timeValue = post(self::TIME_PREFIX . $this->formField->getName(false));
|
||||
if ($this->mode == 'datetime' && $timeValue) {
|
||||
$value .= ' ' . $timeValue . ':00';
|
||||
}
|
||||
elseif ($this->mode == 'time') {
|
||||
$value .= ':00';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<div
|
||||
id="<?= $this->getId() ?>"
|
||||
class="field-datatable size-<?= $size ?>">
|
||||
|
||||
<?= $table->render() ?>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 10px;
|
||||
font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
code,
|
||||
pre {
|
||||
font-family: Menlo, Monaco, monospace, sans-serif;
|
||||
}
|
||||
|
||||
div,
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
table,
|
||||
dl,
|
||||
blockquote,
|
||||
td,
|
||||
th,
|
||||
pre {
|
||||
font-size: 14px;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
div {
|
||||
border: 1px dashed #bbb !important;
|
||||
}
|
||||
a {
|
||||
color: #15c;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.redactor_placeholder {
|
||||
color: #999 !important;
|
||||
display: block !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
|
||||
object,
|
||||
embed,
|
||||
video,
|
||||
img {
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
}
|
||||
video,
|
||||
img {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
div,
|
||||
p,
|
||||
ul,
|
||||
ol,
|
||||
table,
|
||||
dl,
|
||||
blockquote,
|
||||
pre {
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
border: none;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
iframe,
|
||||
object,
|
||||
hr {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
blockquote {
|
||||
margin-left: 3em;
|
||||
color: #777;
|
||||
font-style: italic;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
padding-left: 2em;
|
||||
}
|
||||
ul ul,
|
||||
ol ol,
|
||||
ul ol,
|
||||
ol ul {
|
||||
margin: 2px;
|
||||
padding: 0;
|
||||
padding-left: 2em;
|
||||
border: none;
|
||||
}
|
||||
dl dt { font-weight: bold; }
|
||||
dd { margin-left: 1em;}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
font-size: 1em;
|
||||
}
|
||||
table td {
|
||||
padding: 5px;
|
||||
border: 1px solid #ddd;
|
||||
vertical-align: top;
|
||||
}
|
||||
table thead td {
|
||||
border-bottom: 2px solid #000;
|
||||
font-weight: bold;
|
||||
}
|
||||
code {
|
||||
background-color: #d8d7d7;
|
||||
}
|
||||
pre {
|
||||
overflow: auto;
|
||||
padding: 1em;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 3px;
|
||||
background: #f8f8f8;
|
||||
white-space: pre;
|
||||
font-size: 90%;
|
||||
}
|
||||
hr {
|
||||
display: block;
|
||||
height: 1px;
|
||||
border: 0;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: none;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 36px;
|
||||
line-height: 40px;
|
||||
}
|
||||
h2 {
|
||||
margin-bottom: 15px;
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
}
|
||||
h3 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 24px;
|
||||
line-height: 30px;
|
||||
}
|
||||
h4 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
}
|
||||
h5 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 1em;
|
||||
}
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
body.redactor_editor_wym {
|
||||
background: #f4f4f4;
|
||||
}
|
||||
.redactor_editor_wym div,
|
||||
.redactor_editor_wym p,
|
||||
.redactor_editor_wym ul,
|
||||
.redactor_editor_wym ol,
|
||||
.redactor_editor_wym table,
|
||||
.redactor_editor_wym dl,
|
||||
.redactor_editor_wym pre,
|
||||
.redactor_editor_wym h1,
|
||||
.redactor_editor_wym h2,
|
||||
.redactor_editor_wym h3,
|
||||
.redactor_editor_wym h4,
|
||||
.redactor_editor_wym h5,
|
||||
.redactor_editor_wym blockquote {
|
||||
margin: 0 0 10px 0;
|
||||
padding: 7px 10px;
|
||||
border: 1px solid #e4e4e4;
|
||||
background-color: #fff;
|
||||
}
|
||||
.redactor_editor_wym div {
|
||||
border: 1px dashed #bbb !important;
|
||||
}
|
||||
.redactor_editor_wym pre {
|
||||
border: 2px dashed #e4e4e4 !important;
|
||||
background-color: #fafafa !important;
|
||||
}
|
||||
.redactor_editor_wym code {
|
||||
background-color: #f4f4f4 !important;
|
||||
}
|
||||
.redactor_editor_wym ul,
|
||||
.redactor_editor_wym ol {
|
||||
padding-left: 2em !important;
|
||||
}
|
||||
.redactor_editor_wym ul li ul,
|
||||
.redactor_editor_wym ul li ol,
|
||||
.redactor_editor_wym ol li ol,
|
||||
.redactor_editor_wym ol li ul {
|
||||
border: none !important;
|
||||
}
|
||||
|
|
@ -2,26 +2,26 @@
|
|||
|
||||
return [
|
||||
'auth' => [
|
||||
'title' => 'Administration Area',
|
||||
'title' => 'Administration Area'
|
||||
],
|
||||
'field' => [
|
||||
'invalid_type' => 'Invalid field type used :type.',
|
||||
'options_method_not_exists' => 'The model class :model must define a method :method() returning options for the ":field" form field.',
|
||||
'options_method_not_exists' => "The model class :model must define a method :method() returning options for the ':field' form field."
|
||||
],
|
||||
'widget' => [
|
||||
'not_registered' => "A widget class name ':name' has not been registered",
|
||||
'not_bound' => "A widget with class name ':name' has not been bound to the controller",
|
||||
'not_bound' => "A widget with class name ':name' has not been bound to the controller"
|
||||
],
|
||||
'page' => [
|
||||
'untitled' => "Untitled",
|
||||
'untitled' => 'Untitled',
|
||||
'access_denied' => [
|
||||
'label' => "Access denied",
|
||||
'label' => 'Access denied',
|
||||
'help' => "You don't have the required permissions to view this page.",
|
||||
'cms_link' => "Return to the back-end",
|
||||
],
|
||||
'cms_link' => 'Return to the back-end'
|
||||
]
|
||||
],
|
||||
'partial' => [
|
||||
'not_found' => "The partial ':name' is not found.",
|
||||
'not_found' => "The partial ':name' is not found."
|
||||
],
|
||||
'account' => [
|
||||
'sign_out' => 'Sign out',
|
||||
|
|
@ -30,21 +30,21 @@ return [
|
|||
'restore' => 'Restore',
|
||||
'login_placeholder' => 'login',
|
||||
'password_placeholder' => 'password',
|
||||
'forgot_password' => "Forgot your password?",
|
||||
'enter_email' => "Enter your email",
|
||||
'enter_login' => "Enter your login",
|
||||
'email_placeholder' => "email",
|
||||
'enter_new_password' => "Enter a new password",
|
||||
'password_reset' => "Password Reset",
|
||||
'restore_success' => "An email has been sent to your email address with password restore instructions.",
|
||||
'forgot_password' => 'Forgot your password?',
|
||||
'enter_email' => 'Enter your email',
|
||||
'enter_login' => 'Enter your login',
|
||||
'email_placeholder' => 'email',
|
||||
'enter_new_password' => 'Enter a new password',
|
||||
'password_reset' => 'Password Reset',
|
||||
'restore_success' => 'An email has been sent to your email address with password restore instructions.',
|
||||
'restore_error' => "A user could not be found with a login value of ':login'",
|
||||
'reset_success' => "Your password has been successfully reset. You may now sign in.",
|
||||
'reset_error' => "Invalid password reset data supplied. Please try again!",
|
||||
'reset_fail' => "Unable to reset your password!",
|
||||
'reset_success' => 'Your password has been successfully reset. You may now sign in.',
|
||||
'reset_error' => 'Invalid password reset data supplied. Please try again!',
|
||||
'reset_fail' => 'Unable to reset your password!',
|
||||
'apply' => 'Apply',
|
||||
'cancel' => 'Cancel',
|
||||
'delete' => 'Delete',
|
||||
'ok' => 'OK',
|
||||
'ok' => 'OK'
|
||||
],
|
||||
'dashboard' => [
|
||||
'menu_label' => 'Dashboard',
|
||||
|
|
@ -66,7 +66,7 @@ return [
|
|||
'widget_title_default' => 'System status',
|
||||
'online' => 'online',
|
||||
'maintenance' => 'in maintenance',
|
||||
'update_available' => '{0} updates available!|{1} update available!|[2,Inf] updates available!',
|
||||
'update_available' => '{0} updates available!|{1} update available!|[2,Inf] updates available!'
|
||||
]
|
||||
],
|
||||
'user' => [
|
||||
|
|
@ -75,18 +75,19 @@ return [
|
|||
'menu_description' => 'Manage back-end administrator users, groups and permissions.',
|
||||
'list_title' => 'Manage Administrators',
|
||||
'new' => 'New Administrator',
|
||||
'login' => "Login",
|
||||
'first_name' => "First Name",
|
||||
'last_name' => "Last Name",
|
||||
'full_name' => "Full Name",
|
||||
'email' => "Email",
|
||||
'groups' => "Groups",
|
||||
'groups_comment' => "Specify which groups this person belongs to.",
|
||||
'avatar' => "Avatar",
|
||||
'password' => "Password",
|
||||
'password_confirmation' => "Confirm Password",
|
||||
'superuser' => "Super User",
|
||||
'superuser_comment' => "Check this box to allow this person to access all areas.",
|
||||
'login' => 'Login',
|
||||
'first_name' => 'First Name',
|
||||
'last_name' => 'Last Name',
|
||||
'full_name' => 'Full Name',
|
||||
'email' => 'Email',
|
||||
'groups' => 'Groups',
|
||||
'groups_comment' => 'Specify which groups this person belongs to.',
|
||||
'avatar' => 'Avatar',
|
||||
'password' => 'Password',
|
||||
'password_confirmation' => 'Confirm Password',
|
||||
'permissions' => 'Permissions',
|
||||
'superuser' => 'Super User',
|
||||
'superuser_comment' => 'Check this box to allow this person to access all areas.',
|
||||
'send_invite' => 'Send invitation by email',
|
||||
'send_invite_comment' => 'Use this checkbox to send an invitation to the user by email',
|
||||
'delete_confirm' => 'Do you really want to delete this administrator?',
|
||||
|
|
@ -97,15 +98,11 @@ return [
|
|||
'group' => [
|
||||
'name' => 'Group',
|
||||
'name_field' => 'Name',
|
||||
'description_field' => 'Description',
|
||||
'is_new_user_default_field' => 'Add new administrators to this group by default',
|
||||
'code_field' => 'Code',
|
||||
'code_comment' => 'Enter a unique code if you want to access it with the API.',
|
||||
'menu_label' => 'Groups',
|
||||
'list_title' => 'Manage Groups',
|
||||
'new' => 'New Administrator Group',
|
||||
'delete_confirm' => 'Do you really want to delete this administrator group?',
|
||||
'return' => 'Return to the group list',
|
||||
'return' => 'Return to the group list'
|
||||
],
|
||||
'preferences' => [
|
||||
'not_authenticated' => 'There is no an authenticated user to load or save preferences for.'
|
||||
|
|
@ -137,17 +134,17 @@ return [
|
|||
'description_label' => 'Description'
|
||||
],
|
||||
'form' => [
|
||||
'create_title' => "New :name",
|
||||
'update_title' => "Edit :name",
|
||||
'preview_title' => "Preview :name",
|
||||
'create_title' => 'New :name',
|
||||
'update_title' => 'Edit :name',
|
||||
'preview_title' => 'Preview :name',
|
||||
'create_success' => 'The :name has been created successfully',
|
||||
'update_success' => 'The :name has been updated successfully',
|
||||
'delete_success' => 'The :name has been deleted successfully',
|
||||
'missing_id' => "Form record ID has not been specified.",
|
||||
'missing_id' => 'Form record ID has not been specified.',
|
||||
'missing_model' => 'Form behavior used in :class does not have a model defined.',
|
||||
'missing_definition' => "Form behavior does not contain a field for ':field'.",
|
||||
'not_found' => 'Form record with an ID of :id could not be found.',
|
||||
'action_confirm' => "Are you sure?",
|
||||
'action_confirm' => 'Are you sure?',
|
||||
'create' => 'Create',
|
||||
'create_and_close' => 'Create and close',
|
||||
'creating' => 'Creating...',
|
||||
|
|
@ -159,9 +156,6 @@ return [
|
|||
'delete' => 'Delete',
|
||||
'deleting' => 'Deleting...',
|
||||
'deleting_name' => 'Deleting :name...',
|
||||
'reset_default' => 'Reset to default',
|
||||
'resetting' => 'Resetting',
|
||||
'resetting_name' => 'Resetting :name',
|
||||
'undefined_tab' => 'Misc',
|
||||
'field_off' => 'Off',
|
||||
'field_on' => 'On',
|
||||
|
|
@ -182,41 +176,39 @@ return [
|
|||
'select_placeholder' => 'please select',
|
||||
'insert_row' => 'Insert Row',
|
||||
'delete_row' => 'Delete Row',
|
||||
'concurrency_file_changed_title' => "File was changed",
|
||||
'concurrency_file_changed_description' => "The file you're editing has been changed on disk by another user. You can either reload the file and lose your changes or override the file on the disk.",
|
||||
'concurrency_file_changed_title' => 'File was changed',
|
||||
'concurrency_file_changed_description' => "The file you're editing has been changed on disk by another user. You can either reload the file and lose your changes or override the file on the disk."
|
||||
],
|
||||
'relation' => [
|
||||
'missing_definition' => "Relation behavior does not contain a definition for ':field'.",
|
||||
'missing_model' => "Relation behavior used in :class does not have a model defined.",
|
||||
'invalid_action_single' => "This action cannot be performed on a singular relationship.",
|
||||
'invalid_action_multi' => "This action cannot be performed on a multiple relationship.",
|
||||
'help' => "Click on an item to add",
|
||||
'related_data' => "Related :name data",
|
||||
'add' => "Add",
|
||||
'add_selected' => "Add selected",
|
||||
'add_a_new' => "Add a new :name",
|
||||
'cancel' => "Cancel",
|
||||
'close' => "Close",
|
||||
'add_name' => "Add :name",
|
||||
'create' => "Create",
|
||||
'create_name' => "Create :name",
|
||||
'update' => "Update",
|
||||
'update_name' => "Update :name",
|
||||
'preview' => "Preview",
|
||||
'preview_name' => "Preview :name",
|
||||
'remove' => "Remove",
|
||||
'remove_name' => "Remove :name",
|
||||
'delete' => "Delete",
|
||||
'delete_name' => "Delete :name",
|
||||
'delete_confirm' => "Are you sure?",
|
||||
'missing_model' => 'Relation behavior used in :class does not have a model defined.',
|
||||
'invalid_action_single' => 'This action cannot be performed on a singular relationship.',
|
||||
'invalid_action_multi' => 'This action cannot be performed on a multiple relationship.',
|
||||
'help' => 'Click on an item to add',
|
||||
'related_data' => 'Related :name data',
|
||||
'add' => 'Add',
|
||||
'add_selected' => 'Add selected',
|
||||
'add_a_new' => 'Add a new :name',
|
||||
'cancel' => 'Cancel',
|
||||
'add_name' => 'Add :name',
|
||||
'create' => 'Create',
|
||||
'create_name' => 'Create :name',
|
||||
'update' => 'Update',
|
||||
'update_name' => 'Update :name',
|
||||
'remove' => 'Remove',
|
||||
'remove_name' => 'Remove :name',
|
||||
'delete' => 'Delete',
|
||||
'delete_name' => 'Delete :name',
|
||||
'delete_confirm' => 'Are you sure?'
|
||||
],
|
||||
'model' => [
|
||||
'name' => "Model",
|
||||
'name' => 'Model',
|
||||
'not_found' => "Model ':class' with an ID of :id could not be found",
|
||||
'missing_id' => "There is no ID specified for looking up the model record.",
|
||||
'missing_id' => 'There is no ID specified for looking up the model record.',
|
||||
'missing_relation' => "Model ':class' does not contain a definition for ':relation'.",
|
||||
'missing_method' => "Model ':class' does not contain a method ':method'.",
|
||||
'invalid_class' => "Model :model used in :class is not valid, it must inherit the \Model class.",
|
||||
'mass_assignment_failed' => "Mass assignment failed for Model attribute ':attribute'.",
|
||||
'mass_assignment_failed' => "Mass assignment failed for Model attribute ':attribute'."
|
||||
],
|
||||
'warnings' => [
|
||||
'tips' => 'System configuration tips',
|
||||
|
|
@ -235,14 +227,14 @@ return [
|
|||
'highlight_active_line' => 'Highlight active line',
|
||||
'show_invisibles' => 'Show invisible characters',
|
||||
'show_gutter' => 'Show gutter',
|
||||
'theme' => 'Color scheme',
|
||||
'theme' => 'Color scheme'
|
||||
],
|
||||
'tooltips' => [
|
||||
'preview_website' => 'Preview the website'
|
||||
],
|
||||
'mysettings' => [
|
||||
'menu_label' => 'My Settings',
|
||||
'menu_description' => 'Settings relate to your administration account',
|
||||
'menu_description' => 'Settings relate to your administration account'
|
||||
],
|
||||
'myaccount' => [
|
||||
'menu_label' => 'My account',
|
||||
|
|
@ -271,7 +263,7 @@ return [
|
|||
'menu_label' => 'Back-end preferences',
|
||||
'menu_description' => 'Manage your account preferences such as desired language.',
|
||||
'locale' => 'Language',
|
||||
'locale_comment' => 'Select your desired locale for language use.',
|
||||
'locale_comment' => 'Select your desired locale for language use.'
|
||||
],
|
||||
'access_log' => [
|
||||
'hint' => 'This log displays a list of successful sign in attempts by administrators. Records are kept for a total of :days days.',
|
||||
|
|
@ -282,7 +274,7 @@ return [
|
|||
'ip_address' => 'IP address',
|
||||
'first_name' => 'First name',
|
||||
'last_name' => 'Last name',
|
||||
'email' => 'Email',
|
||||
'email' => 'Email'
|
||||
],
|
||||
'filter' => [
|
||||
'all' => 'all'
|
||||
|
|
|
|||
|
|
@ -97,6 +97,10 @@ return [
|
|||
'group' => [
|
||||
'name' => 'Csoport',
|
||||
'name_field' => 'Név',
|
||||
'description_field' => 'Leírás',
|
||||
'is_new_user_default_field' => 'Az új webhelygazdák hozzáadása alapértelmezésként ehhez a csoporthoz',
|
||||
'code_field' => 'Kód',
|
||||
'code_comment' => 'Adjon meg egy egyedi kódot, ha az API-val kíván hozzáférni.',
|
||||
'menu_label' => 'Csoportok',
|
||||
'list_title' => 'Csoportok kezelése',
|
||||
'new' => 'Új webhelygazda csoport',
|
||||
|
|
@ -192,11 +196,14 @@ return [
|
|||
'add_selected' => "Kijelöltek hozzáadása",
|
||||
'add_a_new' => "Új :name hozzáadása",
|
||||
'cancel' => "Mégse",
|
||||
'close' => "Bezárás",
|
||||
'add_name' => ":name hozzáadása",
|
||||
'create' => "Létrehozás",
|
||||
'create_name' => ":name létrehozása",
|
||||
'update' => "Frissítés",
|
||||
'update_name' => "A(z) :name frissítése",
|
||||
'preview' => "Előnézet",
|
||||
'preview_name' => "Előnézet neve",
|
||||
'remove' => "Eltávolítás",
|
||||
'remove_name' => "A(z) :name eltávolítása",
|
||||
'delete' => "Törlés",
|
||||
|
|
|
|||
|
|
@ -40,14 +40,14 @@ tabs:
|
|||
|
||||
permissions[superuser]:
|
||||
context: [create, update]
|
||||
tab: Permissions
|
||||
tab: backend::lang.user.permissions
|
||||
label: backend::lang.user.superuser
|
||||
type: checkbox
|
||||
comment: backend::lang.user.superuser_comment
|
||||
|
||||
groups:
|
||||
context: [create, update]
|
||||
tab: Permissions
|
||||
tab: backend::lang.user.permissions
|
||||
label: backend::lang.user.groups
|
||||
commentAbove: backend::lang.user.groups_comment
|
||||
type: checkboxlist
|
||||
|
|
|
|||
|
|
@ -208,12 +208,16 @@ class Filter extends WidgetBase
|
|||
protected function getOptionsFromModel($scope, $searchQuery = null)
|
||||
{
|
||||
$model = $this->scopeModels[$scope->scopeName];
|
||||
$query = $model->newQuery();
|
||||
|
||||
$this->fireEvent('filter.extendQuery', [$query, $scope]);
|
||||
|
||||
if (!$searchQuery) {
|
||||
return $model->all();
|
||||
return $query->get();
|
||||
}
|
||||
|
||||
$searchFields = [$model->getKeyName(), $this->getScopeNameColumn($scope)];
|
||||
return $model->searchWhere($searchQuery, $searchFields)->get();
|
||||
return $query->searchWhere($searchQuery, $searchFields)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -710,7 +710,7 @@ class Form extends WidgetBase
|
|||
}
|
||||
|
||||
$fieldName = $field->fieldName;
|
||||
$defaultValue = (!$this->model->exists) && !empty($field->defaults) ? $field->defaults : null;
|
||||
$defaultValue = (!$this->model->exists && $field->defaults !== '') ? $field->defaults : null;
|
||||
|
||||
/*
|
||||
* Array field name, eg: field[key][key2][key3]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class Table extends WidgetBase
|
|||
|
||||
protected $dataSource = null;
|
||||
|
||||
protected $recordsKeyColumn;
|
||||
protected $recordsKeyFrom;
|
||||
|
||||
protected $dataSourceAliases = [
|
||||
'client' => '\Backend\Classes\TableClientMemoryDataSource'
|
||||
|
|
@ -45,19 +45,22 @@ class Table extends WidgetBase
|
|||
{
|
||||
$this->columns = $this->getConfig('columns', []);
|
||||
|
||||
$this->recordsKeyColumn = $this->getConfig('key_column', 'id');
|
||||
$this->recordsKeyFrom = $this->getConfig('keyFrom', 'id');
|
||||
|
||||
$dataSourceClass = $this->getConfig('data_source');
|
||||
if (!strlen($dataSourceClass))
|
||||
$dataSourceClass = $this->getConfig('dataSource');
|
||||
if (!strlen($dataSourceClass)) {
|
||||
throw new SystemException('The Table widget data source is not specified in the configuration.');
|
||||
}
|
||||
|
||||
if (array_key_exists($dataSourceClass, $this->dataSourceAliases))
|
||||
if (array_key_exists($dataSourceClass, $this->dataSourceAliases)) {
|
||||
$dataSourceClass = $this->dataSourceAliases[$dataSourceClass];
|
||||
}
|
||||
|
||||
if (!class_exists($dataSourceClass))
|
||||
if (!class_exists($dataSourceClass)) {
|
||||
throw new SystemException(sprintf('The Table widget data source class "%s" is could not be found.', $dataSourceClass));
|
||||
}
|
||||
|
||||
$this->dataSource = new $dataSourceClass($this->recordsKeyColumn);
|
||||
$this->dataSource = new $dataSourceClass($this->recordsKeyFrom);
|
||||
|
||||
if (Request::method() == 'POST' && $this->isClientDataSource()) {
|
||||
$requestDataField = $this->alias.'TableData';
|
||||
|
|
@ -94,10 +97,10 @@ class Table extends WidgetBase
|
|||
public function prepareVars()
|
||||
{
|
||||
$this->vars['columns'] = $this->prepareColumnsArray();
|
||||
$this->vars['recordsKeyColumn'] = $this->recordsKeyColumn;
|
||||
$this->vars['recordsKeyFrom'] = $this->recordsKeyFrom;
|
||||
|
||||
$this->vars['recordsPerPage'] = $this->getConfig('records_per_page', false) ?: 'false';
|
||||
$this->vars['postbackHandlerName'] = $this->getConfig('postback_handler_name', 'onSave');
|
||||
$this->vars['recordsPerPage'] = $this->getConfig('recordsPerPage', false) ?: 'false';
|
||||
$this->vars['postbackHandlerName'] = $this->getConfig('postbackHandlerName', 'onSave');
|
||||
$this->vars['adding'] = $this->getConfig('adding', true);
|
||||
$this->vars['deleting'] = $this->getConfig('deleting', true);
|
||||
$this->vars['toolbar'] = $this->getConfig('toolbar', true);
|
||||
|
|
@ -106,9 +109,9 @@ class Table extends WidgetBase
|
|||
$isClientDataSource = $this->isClientDataSource();
|
||||
|
||||
$this->vars['clientDataSourceClass'] = $isClientDataSource ? 'client' : 'server';
|
||||
$this->vars['data'] = $isClientDataSource ?
|
||||
json_encode($this->dataSource->getAllRecords()) :
|
||||
[];
|
||||
$this->vars['data'] = $isClientDataSource
|
||||
? json_encode($this->dataSource->getAllRecords())
|
||||
: [];
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -150,7 +153,7 @@ class Table extends WidgetBase
|
|||
return $result;
|
||||
}
|
||||
|
||||
protected function isClientDataSource()
|
||||
protected function isClientDataSource()
|
||||
{
|
||||
return $this->dataSource instanceof \Backend\Classes\TableClientMemoryDataSource;
|
||||
}
|
||||
|
|
@ -167,8 +170,9 @@ class Table extends WidgetBase
|
|||
$eventResults = $this->fireEvent('table.getDropdownOptions', [$columnName, $rowData]);
|
||||
|
||||
$options = [];
|
||||
if (count($eventResults))
|
||||
if (count($eventResults)) {
|
||||
$options = $eventResults[0];
|
||||
}
|
||||
|
||||
return [
|
||||
'options' => $options
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ The options below are listed in the JavaScript notation. Corresponding data attr
|
|||
- `rowSorting` - enables the drag & drop row sorting. The sorting cannot be used with the pagination (`recordsPerPage` is not `null` or `false`).
|
||||
- `keyColumn` - specifies the name of the key column. The default value is **id**.
|
||||
- `postback` - post the client-memory data source data to the server automatically when the parent form gets submitted. The default value is `true`. The option is used only with client-memory data sources. When enabled, the data source data is available in the widget's server-side data source: `$table->getDataSource()->getRecords();` The data postback occurs only of the request handler name matches the `postbackHandlerName` option value.
|
||||
- `postbackHandlerName` - AJAX data handler name for the automatic data postback. The data will be posted only when the AJAX requests posts data to this handler. The default value is **onSave**.
|
||||
- `postbackHandlerName` - AJAX data handler name for the automatic data postback. The data will be posted only when the AJAX request posts data matching this handler name. The default value is **onSave**.
|
||||
- `adding` - determines whether users can add new records. Default value is **true**.
|
||||
- `deleting` - determines whether users can delete records. Default value is **true**.
|
||||
- `toolbar` - determines whether the toolbar is visible. The default value is **true**.
|
||||
|
|
@ -144,19 +144,19 @@ If the `options` element is not presented in the configuration, the options will
|
|||
|
||||
**TODO:** Document the AJAX interface
|
||||
|
||||
The drop-down options could depend on other columns. This works only with AJAX-based drop-downs. The column a drop-down depends on are defined with the `depends_on` property:
|
||||
The drop-down options could depend on other columns. This works only with AJAX-based drop-downs. The column a drop-down depends on are defined with the `dependsOn` property:
|
||||
|
||||
state:
|
||||
title: State
|
||||
type: dropdown
|
||||
depends_on: country
|
||||
dependsOn: country
|
||||
|
||||
Multiple fields are allowed as well:
|
||||
|
||||
state:
|
||||
title: State
|
||||
type: dropdown
|
||||
depends_on: [country, language]
|
||||
dependsOn: [country, language]
|
||||
|
||||
**Note:** Dependent drop-down should always be defined after their master columns.
|
||||
|
||||
|
|
@ -166,17 +166,17 @@ Multiple fields are allowed as well:
|
|||
|
||||
The widget is configured with YAML file. Required parameters:
|
||||
|
||||
* `columns` - the columns definitions, see below
|
||||
* `data_source` - The data source class. Should specify the full qualified data source class name or alias. See the data source aliases below.
|
||||
* `key_column` - name of the key column. The default value is **id**.
|
||||
* `records_per_page` - number of records per page. If not specified, the pagination will be disabled.
|
||||
* `postback_handler_name` - AJAX data handler name for the automatic data postback. The data will be posted only when the AJAX requests posts data to this handler. The default value is **onSave**. This parameter is applicable only with client-memory data sources.
|
||||
* `columns` - the columns definitions, see below.
|
||||
* `dataSource` - The data source class. Should specify the full qualified data source class name or alias. See the data source aliases below.
|
||||
* `keyFrom` - name of the key column. The default value is **id**.
|
||||
* `recordsPerPage` - number of records per page. If not specified, the pagination will be disabled.
|
||||
* `postbackHandlerName` - AJAX data handler name for the automatic data postback. The data will be posted only when the AJAX requests posts data to this handler. The default value is **onSave**. This parameter is applicable only with client-memory data sources.
|
||||
* `adding` - indicates if record deleting is allowed, default is **true**.
|
||||
* `deleting` - indicates if record deleting is allowed, default is **true**.
|
||||
* `toolbar` - specifies if the toolbar should be visible, default is **true**.
|
||||
* `height` - specifies the data table height, in pixels. The default value is **false** - the height is not limited.
|
||||
|
||||
The `data_source` parameter can take aliases for some data source classes for the simpler configuration syntax. Known aliases are:
|
||||
The `dataSource` parameter can take aliases for some data source classes for the simpler configuration syntax. Known aliases are:
|
||||
|
||||
* `client` = \Backend\Classes\TableClientMemoryDataSource
|
||||
|
||||
|
|
@ -187,9 +187,9 @@ Columns are defined as array with the `columns` property. The array keys corresp
|
|||
- `title`
|
||||
- `type` (string, checkbox, dropdown, autocomplete)
|
||||
- `width` - sets the column width, can be specified in percents (10%) or pixels (50px). There could be a single column without the width specified. It will be stretched to take the available space.
|
||||
- `readonly`
|
||||
- `readOnly`
|
||||
- `options` (for drop-down elements and autocomplete types)
|
||||
- `depends_on` (from drop-down elements)
|
||||
- `dependsOn` (from drop-down elements)
|
||||
|
||||
## Events
|
||||
|
||||
|
|
@ -245,9 +245,9 @@ $dataSource->purge();
|
|||
|
||||
## Reading data from the data source
|
||||
|
||||
The server-side data sources (PHP) automatically maintain the actual data, but that mechanism for the client-memory and server-memory data sources is different.
|
||||
The server-side data sources (PHP) automatically maintain the actual data, but that mechanism for the client-memory and server-memory data sources is different.
|
||||
|
||||
In case of the client-memory data source, the table widget adds the data records to the POST, when the form is saved (see `postback` and `postbackHandlerName` options). On the server side the data is inserted to the data source by the table widget.
|
||||
In case of the client-memory data source, the table widget adds the data records to the POST, when the form is saved using the AJAX Framework (see `postback` and `postbackHandlerName` options). The table data will be injected automatically to the AJAX request when the `postback` value is `true` and the `postbackHandlerName` matches the exact handler name of the request. On the server side the data is inserted to the data source and can be accessed using the PHP example below.
|
||||
|
||||
The server-memory data source always automatically maintain its contents in synch with the client using AJAX, and POSTing data is not required.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* General control styling
|
||||
*/
|
||||
.table-control .table-container {
|
||||
.control-table .table-container {
|
||||
border: 1px solid #808c8d;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
|
|
@ -9,18 +9,18 @@
|
|||
overflow: hidden;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.table-control table {
|
||||
.control-table table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.table-control table td,
|
||||
.table-control table th {
|
||||
.control-table table td,
|
||||
.control-table table th {
|
||||
padding: 0;
|
||||
font-size: 13px;
|
||||
color: #555555;
|
||||
}
|
||||
.table-control table [data-view-container] {
|
||||
.control-table table [data-view-container] {
|
||||
padding: 5px 10px;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
text-overflow: ellipsis;
|
||||
min-height: 28px;
|
||||
}
|
||||
.table-control table.headers:after {
|
||||
.control-table table.headers:after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
margin-top: -1px;
|
||||
border-bottom: 1px solid #bdc3c7;
|
||||
}
|
||||
.table-control table.headers th {
|
||||
.control-table table.headers th {
|
||||
padding: 7px 10px;
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
|
|
@ -49,84 +49,84 @@
|
|||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.table-control table.headers th [data-view-container] {
|
||||
.control-table table.headers th [data-view-container] {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
.table-control table.headers th:last-child {
|
||||
.control-table table.headers th:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
.table-control table.data td {
|
||||
.control-table table.data td {
|
||||
border: 1px solid #ecf0f1;
|
||||
/* TODO: this should be applied only when the control is active */
|
||||
}
|
||||
.table-control table.data td .content-container {
|
||||
.control-table table.data td .content-container {
|
||||
position: relative;
|
||||
padding: 1px;
|
||||
}
|
||||
.table-control table.data td.active {
|
||||
.control-table table.data td.active {
|
||||
border-color: #5fb6f5 !important;
|
||||
}
|
||||
.table-control table.data td.active .content-container {
|
||||
.control-table table.data td.active .content-container {
|
||||
padding: 0;
|
||||
border: 1px solid #5fb6f5;
|
||||
}
|
||||
.table-control table.data td.active .content-container:before,
|
||||
.table-control table.data td.active .content-container:after {
|
||||
.control-table table.data td.active .content-container:before,
|
||||
.control-table table.data td.active .content-container:after {
|
||||
content: ' ';
|
||||
background: #5fb6f5;
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
top: -2px;
|
||||
}
|
||||
.table-control table.data td.active .content-container:before {
|
||||
.control-table table.data td.active .content-container:before {
|
||||
width: 1px;
|
||||
bottom: -2px;
|
||||
}
|
||||
.table-control table.data td.active .content-container:after {
|
||||
.control-table table.data td.active .content-container:after {
|
||||
right: -2px;
|
||||
height: 1px;
|
||||
}
|
||||
.table-control table.data tr {
|
||||
.control-table table.data tr {
|
||||
background-color: white;
|
||||
}
|
||||
.table-control table.data tr:nth-child(2n) {
|
||||
.control-table table.data tr:nth-child(2n) {
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
.table-control table.data tr:first-child td {
|
||||
.control-table table.data tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
.table-control table.data tr:last-child td {
|
||||
.control-table table.data tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.table-control table.data td:first-child {
|
||||
.control-table table.data td:first-child {
|
||||
border-left: none;
|
||||
}
|
||||
.table-control table.data td:last-child {
|
||||
.control-table table.data td:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
.table-control .control-scrollbar > div {
|
||||
.control-table .control-scrollbar > div {
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.table-control .control-scrollbar table.data tr:last-child td {
|
||||
.control-table .control-scrollbar table.data tr:last-child td {
|
||||
border-bottom: 1px solid #ecf0f1;
|
||||
}
|
||||
.table-control .toolbar {
|
||||
.control-table .toolbar {
|
||||
background: white;
|
||||
border-bottom: 1px solid #bdc3c7;
|
||||
}
|
||||
.table-control .toolbar a {
|
||||
.control-table .toolbar a {
|
||||
color: #323e50;
|
||||
padding: 10px;
|
||||
opacity: 0.5;
|
||||
filter: alpha(opacity=50);
|
||||
}
|
||||
.table-control .toolbar a:hover {
|
||||
.control-table .toolbar a:hover {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100);
|
||||
}
|
||||
.table-control .toolbar a:before {
|
||||
.control-table .toolbar a:before {
|
||||
display: inline-block;
|
||||
content: ' ';
|
||||
width: 16px;
|
||||
|
|
@ -138,17 +138,17 @@
|
|||
background-position: 0 0;
|
||||
background-size: 32px auto;
|
||||
}
|
||||
.table-control .toolbar a.add-table-row-above:before {
|
||||
.control-table .toolbar a.add-table-row-above:before {
|
||||
background-position: 0 -56px;
|
||||
}
|
||||
.table-control .toolbar a.delete-table-row:before {
|
||||
.control-table .toolbar a.delete-table-row:before {
|
||||
background-position: 0 -113px;
|
||||
}
|
||||
.table-control .pagination ul {
|
||||
.control-table .pagination ul {
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.table-control .pagination ul li {
|
||||
.control-table .pagination ul li {
|
||||
list-style: none;
|
||||
padding: 4px 6px;
|
||||
-webkit-border-radius: 2px;
|
||||
|
|
@ -160,32 +160,32 @@
|
|||
background: #ecf0f1;
|
||||
line-height: 100%;
|
||||
}
|
||||
.table-control .pagination ul li a {
|
||||
.control-table .pagination ul li a {
|
||||
text-decoration: none;
|
||||
color: #95a5a6;
|
||||
}
|
||||
.table-control .pagination ul li.active {
|
||||
.control-table .pagination ul li.active {
|
||||
background: #5fb6f5;
|
||||
}
|
||||
.table-control .pagination ul li.active a {
|
||||
.control-table .pagination ul li.active a {
|
||||
color: #ffffff;
|
||||
}
|
||||
@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-devicepixel-ratio: 1.5), only screen and (min-resolution: 1.5dppx) {
|
||||
.table-control .toolbar a:before {
|
||||
.control-table .toolbar a:before {
|
||||
background-position: 0px -9px;
|
||||
background-size: 16px auto;
|
||||
}
|
||||
.table-control .toolbar a.add-table-row-above:before {
|
||||
.control-table .toolbar a.add-table-row-above:before {
|
||||
background-position: 0 -39px;
|
||||
}
|
||||
.table-control .toolbar a.delete-table-row:before {
|
||||
.control-table .toolbar a.delete-table-row:before {
|
||||
background-position: 0 -66px;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* String editor
|
||||
*/
|
||||
.table-control td[data-column-type=string] input[type=text] {
|
||||
.control-table td[data-column-type=string] input[type=text] {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
|
|
@ -196,7 +196,7 @@
|
|||
/*
|
||||
* Checkbox editor
|
||||
*/
|
||||
.table-control td[data-column-type=checkbox] div[data-checkbox-element] {
|
||||
.control-table td[data-column-type=checkbox] div[data-checkbox-element] {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
|
|
@ -209,14 +209,14 @@
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.table-control td[data-column-type=checkbox] div[data-checkbox-element]:hover {
|
||||
.control-table td[data-column-type=checkbox] div[data-checkbox-element]:hover {
|
||||
border-color: #808080;
|
||||
color: #4d4d4d;
|
||||
}
|
||||
.table-control td[data-column-type=checkbox] div[data-checkbox-element].checked {
|
||||
.control-table td[data-column-type=checkbox] div[data-checkbox-element].checked {
|
||||
border-width: 2px;
|
||||
}
|
||||
.table-control td[data-column-type=checkbox] div[data-checkbox-element].checked:before {
|
||||
.control-table td[data-column-type=checkbox] div[data-checkbox-element].checked:before {
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
|
@ -229,25 +229,25 @@
|
|||
left: 1px;
|
||||
top: -4px;
|
||||
}
|
||||
.table-control td[data-column-type=checkbox] div[data-checkbox-element]:focus {
|
||||
.control-table td[data-column-type=checkbox] div[data-checkbox-element]:focus {
|
||||
border-color: #5fb6f5;
|
||||
outline: none;
|
||||
}
|
||||
/*
|
||||
* Dropdown editor
|
||||
*/
|
||||
.table-control td[data-column-type=dropdown] {
|
||||
.control-table td[data-column-type=dropdown] {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.table-control td[data-column-type=dropdown] [data-view-container] {
|
||||
.control-table td[data-column-type=dropdown] [data-view-container] {
|
||||
padding-right: 20px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
.table-control td[data-column-type=dropdown] [data-view-container]:after {
|
||||
.control-table td[data-column-type=dropdown] [data-view-container]:after {
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
|
@ -262,13 +262,13 @@
|
|||
top: 8px;
|
||||
right: 10px;
|
||||
}
|
||||
.table-control td[data-column-type=dropdown] [data-view-container]:hover:after {
|
||||
.control-table td[data-column-type=dropdown] [data-view-container]:hover:after {
|
||||
color: #0181b9;
|
||||
}
|
||||
.table-control td[data-column-type=dropdown] [data-dropdown-open=true] {
|
||||
.control-table td[data-column-type=dropdown] [data-dropdown-open=true] {
|
||||
background: white;
|
||||
}
|
||||
.table-control td[data-column-type=dropdown] [data-dropdown-open=true] [data-view-container]:after {
|
||||
.control-table td[data-column-type=dropdown] [data-dropdown-open=true] [data-view-container]:after {
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
|
@ -277,10 +277,10 @@
|
|||
*margin-right: .3em;
|
||||
content: "\f106";
|
||||
}
|
||||
.table-control td[data-column-type=dropdown] .content-container {
|
||||
.control-table td[data-column-type=dropdown] .content-container {
|
||||
outline: none;
|
||||
}
|
||||
html.cssanimations .table-control td[data-column-type=dropdown] [data-view-container].loading:after {
|
||||
html.cssanimations .control-table td[data-column-type=dropdown] [data-view-container].loading:after {
|
||||
background-image: url(../../../../assets/images/loading-indicator-transparent.svg);
|
||||
background-size: 15px 15px;
|
||||
background-position: 50% 50%;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
if (dataString === null || dataString === undefined)
|
||||
throw new Error('The required data-data attribute is not found on the table control element.')
|
||||
|
||||
|
||||
this.data = JSON.parse(dataString)
|
||||
};
|
||||
|
||||
|
|
@ -71,11 +71,10 @@
|
|||
Client.prototype.createRecord = function(recordData, placement, relativeToKey, offset, count, onSuccess) {
|
||||
if (placement === 'bottom') {
|
||||
// Add record to the bottom of the dataset
|
||||
|
||||
this.data.push(recordData)
|
||||
} else if (placement == 'above' || placement == 'below') {
|
||||
}
|
||||
else if (placement == 'above' || placement == 'below') {
|
||||
// Add record above or below the passed record key
|
||||
|
||||
var recordIndex = this.getIndexOfKey(relativeToKey)
|
||||
if (placement == 'below')
|
||||
recordIndex ++
|
||||
|
|
@ -98,8 +97,10 @@
|
|||
if (recordIndex !== -1) {
|
||||
recordData[this.tableObj.options.keyColumn] = key
|
||||
this.data[recordIndex] = recordData
|
||||
} else
|
||||
}
|
||||
else {
|
||||
throw new Error('Record with they key '+key+ ' is not found in the data set')
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -124,16 +125,18 @@
|
|||
this.data.push(newRecordData)
|
||||
|
||||
this.getRecords(offset, count, onSuccess)
|
||||
} else
|
||||
}
|
||||
else {
|
||||
throw new Error('Record with they key '+key+ ' is not found in the data set')
|
||||
}
|
||||
}
|
||||
|
||||
Client.prototype.getIndexOfKey = function(key) {
|
||||
var keyColumn = this.tableObj.options.keyColumn
|
||||
|
||||
return this.data.map(function(record) {
|
||||
return record[keyColumn]
|
||||
}).indexOf(parseInt(key))
|
||||
return record[keyColumn] + ""
|
||||
}).indexOf(key + "")
|
||||
}
|
||||
|
||||
Client.prototype.getAllData = function() {
|
||||
|
|
|
|||
|
|
@ -278,9 +278,9 @@
|
|||
if (this.options.columns[i].width)
|
||||
header.setAttribute('style', 'width: '+this.options.columns[i].width)
|
||||
|
||||
header.textContent !== undefined ?
|
||||
header.textContent = this.options.columns[i].title :
|
||||
header.innerText = this.options.columns[i].title
|
||||
header.textContent !== undefined
|
||||
? header.textContent = this.options.columns[i].title
|
||||
: header.innerText = this.options.columns[i].title
|
||||
|
||||
row.appendChild(header)
|
||||
}
|
||||
|
|
@ -395,7 +395,7 @@
|
|||
Table.prototype.scrollCellIntoView = function() {
|
||||
if (!this.options.height || !this.activeCell)
|
||||
return
|
||||
|
||||
|
||||
$(this.dataTableContainer.parentNode).data('oc.scrollbar').gotoElement(this.activeCell)
|
||||
}
|
||||
|
||||
|
|
@ -605,7 +605,7 @@
|
|||
|
||||
Table.prototype.getToolbar = function() {
|
||||
return this.tableContainer.querySelector('div.toolbar')
|
||||
}
|
||||
}
|
||||
|
||||
// EVENT HANDLERS
|
||||
// ============================
|
||||
|
|
@ -675,13 +675,13 @@
|
|||
cmd = target.getAttribute('data-cmd')
|
||||
|
||||
switch (cmd) {
|
||||
case 'record-add-below':
|
||||
case 'record-add-below':
|
||||
this.addRecord('below')
|
||||
break
|
||||
case 'record-add-above':
|
||||
case 'record-add-above':
|
||||
this.addRecord('above')
|
||||
break
|
||||
case 'record-delete':
|
||||
case 'record-delete':
|
||||
this.deleteRecord()
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@
|
|||
|
||||
DropdownProcessor.prototype.createOptionsCachingKey = function(row) {
|
||||
var cachingKey = 'non-dependent',
|
||||
dependsOn = this.columnConfiguration.depends_on
|
||||
dependsOn = this.columnConfiguration.dependsOn
|
||||
|
||||
if (dependsOn) {
|
||||
if (typeof dependsOn == 'object') {
|
||||
|
|
@ -277,8 +277,7 @@
|
|||
DropdownProcessor.prototype.onItemClick = function(ev) {
|
||||
var target = this.tableObj.getEventTarget(ev)
|
||||
|
||||
if (target.tagName == 'LI')
|
||||
{
|
||||
if (target.tagName == 'LI') {
|
||||
this.updateCellFromSelectedItem(target)
|
||||
|
||||
var selected = this.findSelectedItem()
|
||||
|
|
@ -349,11 +348,11 @@
|
|||
// Determine if this drop-down depends on the changed column
|
||||
// and update the option list if necessary
|
||||
|
||||
if (!this.columnConfiguration.depends_on)
|
||||
if (!this.columnConfiguration.dependsOn)
|
||||
return
|
||||
|
||||
var dependsOnColumn = false,
|
||||
dependsOn = this.columnConfiguration.depends_on
|
||||
dependsOn = this.columnConfiguration.dependsOn
|
||||
|
||||
if (typeof dependsOn == 'object') {
|
||||
for (var i = 0, len = dependsOn.length; i < len; i++ ) {
|
||||
|
|
@ -362,8 +361,10 @@
|
|||
break
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else {
|
||||
dependsOnColumn = dependsOn == columnName
|
||||
}
|
||||
|
||||
if (!dependsOnColumn)
|
||||
return
|
||||
|
|
@ -372,9 +373,9 @@
|
|||
viewContainer = this.getViewContainer(cellElement)
|
||||
|
||||
this.fetchOptions(cellElement, function rowValueChangedFetchOptions(options) {
|
||||
var value = options[currentValue] !== undefined ?
|
||||
options[currentValue] :
|
||||
'...'
|
||||
var value = options[currentValue] !== undefined
|
||||
? options[currentValue]
|
||||
: '...'
|
||||
|
||||
viewContainer.textContent = value
|
||||
viewContainer = null
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* General control styling
|
||||
*/
|
||||
|
||||
.table-control {
|
||||
.control-table {
|
||||
.table-container {
|
||||
border: 1px solid #808c8d;
|
||||
.border-radius(4px);
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
margin-top: -1px;
|
||||
border-bottom: 1px solid #bdc3c7;
|
||||
}
|
||||
|
||||
|
||||
th {
|
||||
padding: 7px 10px;
|
||||
font-size: 13px;
|
||||
|
|
@ -108,12 +108,12 @@
|
|||
background-color: white;
|
||||
}
|
||||
|
||||
tr:nth-child(2n) {
|
||||
tr:nth-child(2n) {
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
}
|
||||
|
||||
table.data {
|
||||
table.data {
|
||||
tr:first-child td {
|
||||
border-top: none;
|
||||
}
|
||||
|
|
@ -211,7 +211,7 @@
|
|||
}
|
||||
|
||||
@media only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-devicepixel-ratio: 1.5), only screen and (min-resolution: 1.5dppx) {
|
||||
.table-control .toolbar {
|
||||
.control-table .toolbar {
|
||||
a {
|
||||
&:before {
|
||||
background-position: 0px -9px;
|
||||
|
|
@ -233,7 +233,7 @@
|
|||
* String editor
|
||||
*/
|
||||
|
||||
.table-control {
|
||||
.control-table {
|
||||
td[data-column-type=string] {
|
||||
input[type=text] {
|
||||
width: 100%;
|
||||
|
|
@ -250,7 +250,7 @@
|
|||
* Checkbox editor
|
||||
*/
|
||||
|
||||
.table-control {
|
||||
.control-table {
|
||||
td[data-column-type=checkbox] {
|
||||
div[data-checkbox-element] {
|
||||
width: 16px;
|
||||
|
|
@ -292,7 +292,7 @@
|
|||
* Dropdown editor
|
||||
*/
|
||||
|
||||
.table-control {
|
||||
.control-table {
|
||||
td[data-column-type=dropdown] {
|
||||
.user-select(none);
|
||||
|
||||
|
|
@ -334,7 +334,7 @@
|
|||
}
|
||||
|
||||
html.cssanimations {
|
||||
.table-control td[data-column-type=dropdown] {
|
||||
.control-table td[data-column-type=dropdown] {
|
||||
[data-view-container].loading:after {
|
||||
background-image:url(../../../../assets/images/loading-indicator-transparent.svg);
|
||||
background-size: 15px 15px;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<div
|
||||
<div
|
||||
id="<?= $this->getId() ?>"
|
||||
data-control="table"
|
||||
class="table-control"
|
||||
class="control-table"
|
||||
data-columns="<?= e(json_encode($columns)) ?>"
|
||||
data-data="<?= e($data) ?>"
|
||||
data-postback-handler-name="<?= e($postbackHandlerName) ?>"
|
||||
|
|
@ -9,6 +10,6 @@
|
|||
data-toolbar="<?= e($toolbar) ?>"
|
||||
data-height="<?= e($height) ?>"
|
||||
data-records-per-page="<?= e($recordsPerPage) ?>"
|
||||
data-key-column="<?= e($recordsKeyColumn) ?>"
|
||||
data-key-column="<?= e($recordsKeyFrom) ?>"
|
||||
data-client-data-source-class="<?= e($clientDataSourceClass) ?>"
|
||||
data-alias="<?= e($this->alias) ?>"></div>
|
||||
|
|
@ -39,7 +39,7 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
'label' => 'cms::lang.page.menu_label',
|
||||
'icon' => 'icon-copy',
|
||||
'url' => 'javascript:;',
|
||||
'attributes' => ['data-menu-item'=>'pages'],
|
||||
'attributes' => ['data-menu-item' => 'pages'],
|
||||
'permissions' => ['cms.manage_pages'],
|
||||
'counterLabel' => 'cms::lang.page.unsaved_label',
|
||||
],
|
||||
|
|
@ -47,7 +47,7 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
'label' => 'cms::lang.partial.menu_label',
|
||||
'icon' => 'icon-tags',
|
||||
'url' => 'javascript:;',
|
||||
'attributes' => ['data-menu-item'=>'partials'],
|
||||
'attributes' => ['data-menu-item' => 'partials'],
|
||||
'permissions' => ['cms.manage_partials'],
|
||||
'counterLabel' => 'cms::lang.partial.unsaved_label',
|
||||
],
|
||||
|
|
@ -55,7 +55,7 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
'label' => 'cms::lang.layout.menu_label',
|
||||
'icon' => 'icon-th-large',
|
||||
'url' => 'javascript:;',
|
||||
'attributes' => ['data-menu-item'=>'layouts'],
|
||||
'attributes' => ['data-menu-item' => 'layouts'],
|
||||
'permissions' => ['cms.manage_layouts'],
|
||||
'counterLabel' => 'cms::lang.layout.unsaved_label',
|
||||
],
|
||||
|
|
@ -63,7 +63,7 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
'label' => 'cms::lang.content.menu_label',
|
||||
'icon' => 'icon-file-text-o',
|
||||
'url' => 'javascript:;',
|
||||
'attributes' => ['data-menu-item'=>'content'],
|
||||
'attributes' => ['data-menu-item' => 'content'],
|
||||
'permissions' => ['cms.manage_content'],
|
||||
'counterLabel' => 'cms::lang.content.unsaved_label',
|
||||
],
|
||||
|
|
@ -71,7 +71,7 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
'label' => 'cms::lang.asset.menu_label',
|
||||
'icon' => 'icon-picture-o',
|
||||
'url' => 'javascript:;',
|
||||
'attributes' => ['data-menu-item'=>'assets'],
|
||||
'attributes' => ['data-menu-item' => 'assets'],
|
||||
'permissions' => ['cms.manage_assets'],
|
||||
'counterLabel' => 'cms::lang.asset.unsaved_label',
|
||||
],
|
||||
|
|
@ -79,7 +79,7 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
'label' => 'cms::lang.component.menu_label',
|
||||
'icon' => 'icon-puzzle-piece',
|
||||
'url' => 'javascript:;',
|
||||
'attributes' => ['data-menu-item'=>'components'],
|
||||
'attributes' => ['data-menu-item' => 'components'],
|
||||
'permissions' => ['cms.manage_pages', 'cms.manage_layouts', 'cms.manage_partials']
|
||||
]
|
||||
]
|
||||
|
|
@ -93,12 +93,30 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
*/
|
||||
BackendAuth::registerCallback(function ($manager) {
|
||||
$manager->registerPermissions('October.Cms', [
|
||||
'cms.manage_content' => ['label' => 'cms::lang.permissions.manage_content', 'tab' => 'Cms'],
|
||||
'cms.manage_assets' => ['label' => 'cms::lang.permissions.manage_assets', 'tab' => 'Cms'],
|
||||
'cms.manage_pages' => ['label' => 'cms::lang.permissions.manage_pages', 'tab' => 'Cms'],
|
||||
'cms.manage_layouts' => ['label' => 'cms::lang.permissions.manage_layouts', 'tab' => 'Cms'],
|
||||
'cms.manage_partials' => ['label' => 'cms::lang.permissions.manage_partials', 'tab' => 'Cms'],
|
||||
'cms.manage_themes' => ['label' => 'cms::lang.permissions.manage_themes', 'tab' => 'Cms']
|
||||
'cms.manage_content' => [
|
||||
'label' => 'cms::lang.permissions.manage_content',
|
||||
'tab' => 'cms::lang.permissions.name'
|
||||
],
|
||||
'cms.manage_assets' => [
|
||||
'label' => 'cms::lang.permissions.manage_assets',
|
||||
'tab' => 'cms::lang.permissions.name'
|
||||
],
|
||||
'cms.manage_pages' => [
|
||||
'label' => 'cms::lang.permissions.manage_pages',
|
||||
'tab' => 'cms::lang.permissions.name'
|
||||
],
|
||||
'cms.manage_layouts' => [
|
||||
'label' => 'cms::lang.permissions.manage_layouts',
|
||||
'tab' => 'cms::lang.permissions.name'
|
||||
],
|
||||
'cms.manage_partials' => [
|
||||
'label' => 'cms::lang.permissions.manage_partials',
|
||||
'tab' => 'cms::lang.permissions.name'
|
||||
],
|
||||
'cms.manage_themes' => [
|
||||
'label' => 'cms::lang.permissions.manage_themes',
|
||||
'tab' => 'cms::lang.permissions.name'
|
||||
]
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use Str;
|
||||
use Lang;
|
||||
use Event;
|
||||
use Config;
|
||||
use Cms\Classes\CodeBase;
|
||||
use Cms\Classes\CmsException;
|
||||
|
|
@ -167,6 +168,47 @@ abstract class ComponentBase extends Extendable
|
|||
return $this->alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a requested partial in context of this component,
|
||||
* see Cms\Classes\Controller@renderPartial for usage.
|
||||
*/
|
||||
public function renderPartial()
|
||||
{
|
||||
$this->controller->setComponentContext($this);
|
||||
return call_user_func_array([$this->controller, 'renderPartial'], func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the event cycle when running an AJAX handler.
|
||||
* @return boolean Returns true if the handler was found. Returns false otherwise.
|
||||
*/
|
||||
public function runAjaxHandler($handler)
|
||||
{
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('component.beforeRunAjaxHandler', [$handler], true)) ||
|
||||
($event = Event::fire('cms.component.beforeRunAjaxHandler', [$this, $handler], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
$result = $this->$handler();
|
||||
|
||||
/*
|
||||
* Extensibility
|
||||
*/
|
||||
if (
|
||||
($event = $this->fireEvent('component.runAjaxHandler', [$handler, $result], true)) ||
|
||||
($event = Event::fire('cms.component.runAjaxHandler', [$this, $handler, $result], true))
|
||||
) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//
|
||||
// External properties
|
||||
//
|
||||
|
|
|
|||
|
|
@ -84,11 +84,6 @@ class Controller extends BaseController
|
|||
*/
|
||||
protected $pageContents;
|
||||
|
||||
/**
|
||||
* @var string Alias name of an executing component.
|
||||
*/
|
||||
protected $componentContext;
|
||||
|
||||
/**
|
||||
* @var array A list of variables to pass to the page.
|
||||
*/
|
||||
|
|
@ -99,8 +94,19 @@ class Controller extends BaseController
|
|||
*/
|
||||
protected $statusCode = 200;
|
||||
|
||||
/**
|
||||
* @var self Cache of self
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* @var Cms\Classes\ComponentBase Object of the active component, used internally.
|
||||
*/
|
||||
protected $componentContext;
|
||||
|
||||
/**
|
||||
* @var array Component partial stack, used internally.
|
||||
*/
|
||||
protected $partialComponentStack = [];
|
||||
|
||||
/**
|
||||
|
|
@ -538,7 +544,7 @@ class Controller extends BaseController
|
|||
|
||||
if ($componentObj && method_exists($componentObj, $handlerName)) {
|
||||
$this->componentContext = $componentObj;
|
||||
$result = $componentObj->$handlerName();
|
||||
$result = $componentObj->runAjaxHandler($handlerName);
|
||||
return ($result) ?: true;
|
||||
}
|
||||
}
|
||||
|
|
@ -561,7 +567,7 @@ class Controller extends BaseController
|
|||
*/
|
||||
if (($componentObj = $this->findComponentByHandler($handler)) !== null) {
|
||||
$this->componentContext = $componentObj;
|
||||
$result = $componentObj->$handler();
|
||||
$result = $componentObj->runAjaxHandler($handler);
|
||||
return ($result) ?: true;
|
||||
}
|
||||
}
|
||||
|
|
@ -701,7 +707,7 @@ class Controller extends BaseController
|
|||
}
|
||||
elseif (($componentObj = $this->findComponentByPartial($partialName)) === null) {
|
||||
if ($throwException) {
|
||||
throw new CmsException(Lang::get('cms::lang.partial.not_found', ['name'=>$name]));
|
||||
throw new CmsException(Lang::get('cms::lang.partial.not_found', ['name'=>$partialName]));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
|
|
@ -1032,7 +1038,7 @@ class Controller extends BaseController
|
|||
* Searches the layout and page components by an alias
|
||||
* @return ComponentBase The component object, if found
|
||||
*/
|
||||
protected function findComponentByName($name)
|
||||
public function findComponentByName($name)
|
||||
{
|
||||
if (isset($this->page->components[$name])) {
|
||||
return $this->page->components[$name];
|
||||
|
|
@ -1054,7 +1060,7 @@ class Controller extends BaseController
|
|||
* Searches the layout and page components by an AJAX handler
|
||||
* @return ComponentBase The component object, if found
|
||||
*/
|
||||
protected function findComponentByHandler($handler)
|
||||
public function findComponentByHandler($handler)
|
||||
{
|
||||
foreach ($this->page->components as $component) {
|
||||
if (method_exists($component, $handler)) {
|
||||
|
|
@ -1075,7 +1081,7 @@ class Controller extends BaseController
|
|||
* Searches the layout and page components by a partial file
|
||||
* @return ComponentBase The component object, if found
|
||||
*/
|
||||
protected function findComponentByPartial($partial)
|
||||
public function findComponentByPartial($partial)
|
||||
{
|
||||
foreach ($this->page->components as $component) {
|
||||
$fileName = ComponentPartial::getFilePath($component, $partial);
|
||||
|
|
@ -1102,6 +1108,16 @@ class Controller extends BaseController
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the component context manually, used by Components when calling renderPartial.
|
||||
* @param ComponentBase $component
|
||||
* @return void
|
||||
*/
|
||||
public function setComponentContext(ComponentBase $component)
|
||||
{
|
||||
$this->componentContext = $component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets component property values from partial parameters.
|
||||
* The property values should be defined as {{ param }}.
|
||||
|
|
|
|||
|
|
@ -3,23 +3,23 @@
|
|||
return [
|
||||
'cms_object' => [
|
||||
'invalid_file' => 'Invalid file name: :name. File names can contain only alphanumeric symbols, underscores, dashes and dots. Some examples of correct file names: page.htm, page, subdirectory/page',
|
||||
'invalid_property' => 'The property ":name" cannot be set',
|
||||
'file_already_exists' => 'File ":name" already exists.',
|
||||
'error_saving' => 'Error saving file ":name". Please check write permissions.',
|
||||
'invalid_property' => "The property ':name' cannot be set",
|
||||
'file_already_exists' => "File ':name' already exists.",
|
||||
'error_saving' => "Error saving file ':name'. Please check write permissions.",
|
||||
'error_creating_directory' => 'Error creating directory :name. Please check write permissions.',
|
||||
'invalid_file_extension'=>'Invalid file extension: :invalid. Allowed extensions are: :allowed.',
|
||||
'error_deleting' => 'Error deleting the template file ":name". Please check write permissions.',
|
||||
'error_deleting' => "Error deleting the template file ':name'. Please check write permissions.",
|
||||
'delete_success' => 'Templates were successfully deleted: :count.',
|
||||
'file_name_required' => 'The File Name field is required.'
|
||||
],
|
||||
'theme' => [
|
||||
'active' => [
|
||||
'not_set' => "The active theme is not set.",
|
||||
'not_found' => "The active theme is not found.",
|
||||
'not_set' => 'The active theme is not set.',
|
||||
'not_found' => 'The active theme is not found.'
|
||||
],
|
||||
'edit' => [
|
||||
'not_set' => "The edit theme is not set.",
|
||||
'not_found' => "The edit theme is not found.",
|
||||
'not_set' => 'The edit theme is not set.',
|
||||
'not_found' => 'The edit theme is not found.',
|
||||
'not_match' => "The object you're trying to access doesn't belong to the theme being edited. Please reload the page."
|
||||
],
|
||||
'settings_menu' => 'Front-end theme',
|
||||
|
|
@ -27,22 +27,22 @@ return [
|
|||
'find_more_themes' => 'Find more themes on OctoberCMS Theme Marketplace.',
|
||||
'activate_button' => 'Activate',
|
||||
'active_button' => 'Activate',
|
||||
'customize_button' => 'Customize',
|
||||
'customize_button' => 'Customize'
|
||||
],
|
||||
'maintenance' => [
|
||||
'settings_menu' => 'Maintenance mode',
|
||||
'settings_menu_description' => 'Configure the maintenance mode page and toggle the setting.',
|
||||
'is_enabled' => 'Enable maintenance mode',
|
||||
'is_enabled_comment' => 'When activated website visitors will see the page chosen below.',
|
||||
'is_enabled_comment' => 'When activated website visitors will see the page chosen below.'
|
||||
],
|
||||
'page' => [
|
||||
'not_found' => [
|
||||
'label' => "Page not found",
|
||||
'help' => "The requested page cannot be found.",
|
||||
'label' => 'Page not found',
|
||||
'help' => 'The requested page cannot be found.'
|
||||
],
|
||||
'custom_error' => [
|
||||
'label' => "Page error",
|
||||
'help' => "We're sorry, but something went wrong and the page cannot be displayed.",
|
||||
'label' => 'Page error',
|
||||
'help' => "We're sorry, but something went wrong and the page cannot be displayed."
|
||||
],
|
||||
'menu_label' => 'Pages',
|
||||
'unsaved_label' => 'Unsaved page(s)',
|
||||
|
|
@ -63,7 +63,7 @@ return [
|
|||
'delete_confirm_single' => 'Do you really want delete this layout?'
|
||||
],
|
||||
'partial' => [
|
||||
'invalid_name' => "Invalid partial name: :name.",
|
||||
'invalid_name' => 'Invalid partial name: :name.',
|
||||
'not_found' => "The partial ':name' is not found.",
|
||||
'menu_label' => 'Partials',
|
||||
'unsaved_label' => 'Unsaved partial(s)',
|
||||
|
|
@ -82,11 +82,11 @@ return [
|
|||
'new' => 'New content file'
|
||||
],
|
||||
'ajax_handler' => [
|
||||
'invalid_name' => "Invalid AJAX handler name: :name.",
|
||||
'not_found' => "AJAX handler ':name' was not found.",
|
||||
'invalid_name' => 'Invalid AJAX handler name: :name.',
|
||||
'not_found' => "AJAX handler ':name' was not found."
|
||||
],
|
||||
'cms' => [
|
||||
'menu_label' => "CMS"
|
||||
'menu_label' => 'CMS'
|
||||
],
|
||||
'sidebar' => [
|
||||
'add' => 'Add',
|
||||
|
|
@ -113,7 +113,7 @@ return [
|
|||
'exit_fullscreen' => 'Exit fullscreen mode'
|
||||
],
|
||||
'asset' => [
|
||||
'menu_label' => "Assets",
|
||||
'menu_label' => 'Assets',
|
||||
'unsaved_label' => 'Unsaved asset(s)',
|
||||
'drop_down_add_title' => 'Add...',
|
||||
'drop_down_operation_title' => 'Action...',
|
||||
|
|
@ -141,7 +141,7 @@ return [
|
|||
'too_large' => 'The uploaded file is too large. The maximum allowed file size is :max_size',
|
||||
'type_not_allowed' => 'Only the following file types are allowed: :allowed_types',
|
||||
'file_not_valid' => 'File is not valid',
|
||||
'error_uploading_file' => 'Error uploading file ":name": :error',
|
||||
'error_uploading_file' => "Error uploading file ':name': :error",
|
||||
'move_please_select' => 'please select',
|
||||
'move_destination' => 'Destination directory',
|
||||
'move_popup_title' => 'Move assets',
|
||||
|
|
@ -155,23 +155,24 @@ return [
|
|||
'path' => 'Path'
|
||||
],
|
||||
'component' => [
|
||||
'menu_label' => "Components",
|
||||
'unnamed' => "Unnamed",
|
||||
'no_description' => "No description provided",
|
||||
'alias' => "Alias",
|
||||
'alias_description' => "A unique name given to this component when using it in the page or layout code.",
|
||||
'validation_message' => "Component aliases are required and can contain only Latin symbols, digits, and underscores. The aliases should start with a Latin symbol.",
|
||||
'invalid_request' => "The template cannot be saved because of invalid component data.",
|
||||
'menu_label' => 'Components',
|
||||
'unnamed' => 'Unnamed',
|
||||
'no_description' => 'No description provided',
|
||||
'alias' => 'Alias',
|
||||
'alias_description' => 'A unique name given to this component when using it in the page or layout code.',
|
||||
'validation_message' => 'Component aliases are required and can contain only Latin symbols, digits, and underscores. The aliases should start with a Latin symbol.',
|
||||
'invalid_request' => 'The template cannot be saved because of invalid component data.',
|
||||
'no_records' => 'No components found',
|
||||
'not_found' => "The component ':name' is not found.",
|
||||
'method_not_found' => "The component ':name' does not contain a method ':method'.",
|
||||
'method_not_found' => "The component ':name' does not contain a method ':method'."
|
||||
],
|
||||
'template' => [
|
||||
'invalid_type' => "Unknown template type.",
|
||||
'not_found' => "The requested template was not found.",
|
||||
'saved'=> "The template has been successfully saved."
|
||||
'invalid_type' => 'Unknown template type.',
|
||||
'not_found' => 'The requested template was not found.',
|
||||
'saved'=> 'The template has been successfully saved.'
|
||||
],
|
||||
'permissions' => [
|
||||
'name' => 'Cms',
|
||||
'manage_content' => 'Manage content',
|
||||
'manage_assets' => 'Manage assets',
|
||||
'manage_pages' => 'Manage pages',
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ return [
|
|||
'settings_menu' => 'Karbantartás mód',
|
||||
'settings_menu_description' => 'A karbantartás mód lap konfigurálása, és a beűllítás ki-/bekapcsolása.',
|
||||
'is_enabled' => 'A karbantartás mód engedélyezése',
|
||||
'is_enabled_comment' => 'Aktiválása esetén a webhely látogatói az alább bejelölt lapot fogják látni.',
|
||||
'is_enabled_comment' => 'Aktiválása esetén a webhely látogatói az alább kiválasztott lapot fogják látni.',
|
||||
],
|
||||
'page' => [
|
||||
'not_found' => [
|
||||
|
|
|
|||
|
|
@ -204,15 +204,15 @@ class ServiceProvider extends ModuleServiceProvider
|
|||
$manager->registerPermissions('October.System', [
|
||||
'system.manage_settings' => [
|
||||
'label' => 'system::lang.permissions.manage_system_settings',
|
||||
'tab' => 'System'
|
||||
'tab' => 'system::lang.permissions.name'
|
||||
],
|
||||
'system.manage_updates' => [
|
||||
'label' => 'system::lang.permissions.manage_software_updates',
|
||||
'tab' => 'System'
|
||||
'tab' => 'system::lang.permissions.name'
|
||||
],
|
||||
'system.manage_mail_templates' => [
|
||||
'label' => 'system::lang.permissions.manage_mail_templates',
|
||||
'tab' => 'System'
|
||||
'tab' => 'system::lang.permissions.name'
|
||||
],
|
||||
]);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -366,34 +366,10 @@ if (window.jQuery === undefined)
|
|||
$(this).request()
|
||||
})
|
||||
|
||||
document.addEventListener('click', function nativeClickListener(ev){
|
||||
// Faster native click listener. This implementation doesn't use
|
||||
// jQuery until it's really necessary.
|
||||
var target = ev.target ? ev.target : ev.srcElement
|
||||
|
||||
if (target.getAttribute('data-request') == null)
|
||||
return
|
||||
|
||||
var tagName = target.tagName
|
||||
if (tagName == 'A' || tagName == 'BUTTON') {
|
||||
$(target).request()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tagName == 'INPUT') {
|
||||
var type = target.getAttribute('type').toLowerCase()
|
||||
|
||||
if (type == 'button' || type == 'submit') {
|
||||
$(target).request()
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// $(document).on('click', 'a[data-request], button[data-request], input[type=button][data-request], input[type=submit][data-request]', function(){
|
||||
// $(this).request()
|
||||
// return false
|
||||
// })
|
||||
$(document).on('click', 'a[data-request], button[data-request], input[type=button][data-request], input[type=submit][data-request]', function(){
|
||||
$(this).request()
|
||||
return false
|
||||
})
|
||||
|
||||
$(document).on('keydown', 'input[type=text][data-request], input[type=submit][data-request], input[type=password][data-request]', function(e){
|
||||
if (e.keyCode == 13) {
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ return [
|
|||
'tr' => 'Turkish',
|
||||
],
|
||||
'directory' => [
|
||||
'create_fail' => "Cannot create directory: :name",
|
||||
'create_fail' => 'Cannot create directory: :name',
|
||||
],
|
||||
'file' => [
|
||||
'create_fail' => "Cannot create file: :name",
|
||||
'create_fail' => 'Cannot create file: :name',
|
||||
],
|
||||
'combiner' => [
|
||||
'not_found' => "The combiner file ':name' is not found.",
|
||||
|
|
@ -66,13 +66,13 @@ return [
|
|||
'disabled_help' => 'Plugins that are disabled are ignored by the application.',
|
||||
'selected_amount' => 'Plugins selected: :amount',
|
||||
'remove_confirm' => 'Are you sure?',
|
||||
'remove_success' => "Successfully removed those plugins from the system.",
|
||||
'remove_success' => 'Successfully removed those plugins from the system.',
|
||||
'refresh_confirm' => 'Are you sure?',
|
||||
'refresh_success' => "Successfully refreshed those plugins in the system.",
|
||||
'refresh_success' => 'Successfully refreshed those plugins in the system.',
|
||||
'disable_confirm' => 'Are you sure?',
|
||||
'disable_success' => "Successfully disabled those plugins.",
|
||||
'enable_success' => "Successfully enabled those plugins.",
|
||||
'unknown_plugin' => "Plugin has been removed from the file system.",
|
||||
'disable_success' => 'Successfully disabled those plugins.',
|
||||
'enable_success' => 'Successfully enabled those plugins.',
|
||||
'unknown_plugin' => 'Plugin has been removed from the file system.',
|
||||
],
|
||||
'project' => [
|
||||
'name' => 'Project',
|
||||
|
|
@ -114,6 +114,7 @@ return [
|
|||
'smtp_password' => 'Password',
|
||||
'smtp_port' => 'SMTP Port',
|
||||
'smtp_ssl' => 'SSL connection required',
|
||||
'sendmail' => 'Sendmail',
|
||||
'sendmail_path' => 'Sendmail Path',
|
||||
'sendmail_path_comment' => 'Please specify the path of the sendmail program.',
|
||||
'mailgun' => 'Mailgun',
|
||||
|
|
@ -242,6 +243,7 @@ return [
|
|||
'status_code' => 'Status',
|
||||
],
|
||||
'permissions' => [
|
||||
'name' => 'System',
|
||||
'manage_system_settings' => 'Manage system settings',
|
||||
'manage_software_updates' => 'Manage software updates',
|
||||
'manage_mail_templates' => 'Manage mail templates',
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ return [
|
|||
'search' => 'Keresés'
|
||||
],
|
||||
'mail' => [
|
||||
'log_file' => 'Naplófájl',
|
||||
'menu_label' => 'Levelezés konfigurálása',
|
||||
'menu_description' => 'Az e-mail küldés konfigurációjának kezelése.',
|
||||
'general' => 'Általános',
|
||||
|
|
@ -113,7 +114,6 @@ return [
|
|||
'smtp_password' => 'Jelszó',
|
||||
'smtp_port' => 'SMTP port',
|
||||
'smtp_ssl' => 'SSL-kapcsolat szükséges',
|
||||
'sendmail' => 'Sendmail',
|
||||
'sendmail_path' => 'Sendmail elérési útja',
|
||||
'sendmail_path_comment' => 'Adja meg a Sendmail program elérési útját.',
|
||||
'mailgun' => 'Mailgun',
|
||||
|
|
@ -191,7 +191,7 @@ return [
|
|||
],
|
||||
'none' => [
|
||||
'label' => 'Nincsenek frissítések',
|
||||
'help' => 'Nem találhatók új frissítések.',
|
||||
'help' => 'Nem található új frissítés.',
|
||||
],
|
||||
],
|
||||
'server' => [
|
||||
|
|
|
|||
Loading…
Reference in New Issue