+ zin: add pasteDialog widget.
This commit is contained in:
+8
-3
@@ -982,6 +982,11 @@ function panel(): panel
|
||||
return createWg('panel', func_get_args());
|
||||
}
|
||||
|
||||
function pasteDialog(): pasteDialog
|
||||
{
|
||||
return createWg('pasteDialog', func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tooltip widget.
|
||||
*/
|
||||
@@ -1072,9 +1077,9 @@ function tree(): Tree
|
||||
/**
|
||||
* Zentao file list widget.
|
||||
*
|
||||
* ?array files
|
||||
* ?int objectID
|
||||
* ?string objectType
|
||||
* ?array files
|
||||
* ?int objectID
|
||||
* ?string objectType
|
||||
*/
|
||||
function fileList(): fileList
|
||||
{
|
||||
|
||||
@@ -29,6 +29,8 @@ class formBatchPanel extends formPanel
|
||||
* @access protected
|
||||
*/
|
||||
protected static $defineProps = array(
|
||||
'uploadParams?: string|false', // 多图上传的参数,如果设置为 `false` 则不显示按钮
|
||||
'pasteField?: string|false', // 多行录入的字段名,如果设置为 `false` 则不显示按钮
|
||||
'items?: array[]', // 使用一个列定义对象数组来定义批量表单项。
|
||||
'minRows?: int', // 最小显示的行数目。
|
||||
'maxRows?: int', // 最多显示的行数目。
|
||||
@@ -48,6 +50,34 @@ class formBatchPanel extends formPanel
|
||||
* @access protected
|
||||
*/
|
||||
protected static $defaultProps = array(
|
||||
'uploadParams' => false,
|
||||
'pasteField' => false,
|
||||
'batch' => true
|
||||
);
|
||||
|
||||
protected function buildHeadingActions()
|
||||
{
|
||||
$headingActions = $this->prop('headingActions');
|
||||
if(!$headingActions) $headingActions = array();
|
||||
|
||||
$uploadImage = $this->prop('uploadParams') && hasPriv('file', 'uploadImages');
|
||||
$pasteField = $this->prop('pasteField');
|
||||
|
||||
if($uploadImage || $pasteField)
|
||||
{
|
||||
global $lang;
|
||||
|
||||
if($uploadImage) $headingActions[] = array('url' => createLink('file', 'uploadImages', $this->prop('uploadParams')), 'class' => 'btn primary mr-4', 'data-toggle' => 'modal', 'data-width' => '0.7', 'text' => $lang->uploadImages);
|
||||
if($pasteField)
|
||||
{
|
||||
$headingActions[] = array('class' => 'btn primary', 'data-toggle' => 'modal', 'data-target' => '#paste-dialog', 'text' => $lang->pasteText);
|
||||
|
||||
$this->addToBlock('headingActions', pasteDialog(set::field($pasteField)));
|
||||
}
|
||||
}
|
||||
|
||||
$this->setProp('headingActions', $headingActions);
|
||||
|
||||
return parent::buildHeadingActions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
.form-batch-table .form-batch-control .form-control.highlight {background-color: var(--dtable-checked-bg);}
|
||||
@@ -0,0 +1,61 @@
|
||||
function importLines(target, field)
|
||||
{
|
||||
const $modal = $(target).closest('.modal');
|
||||
const $dialog = $modal.find('.modal-dialog');
|
||||
const $lines = $modal.find('textarea');
|
||||
const $form = $modal.closest('.panel').find('form');
|
||||
const modalID = $modal.attr('id');
|
||||
|
||||
$dialog.addClass('loading');
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
let $currentRow;
|
||||
|
||||
const lines = $lines.val().split('\n');
|
||||
$.each(lines, function(index, line)
|
||||
{
|
||||
line = line.trim();
|
||||
if(!line.length) return true;
|
||||
|
||||
if($currentRow)
|
||||
{
|
||||
$row = $currentRow.next();
|
||||
}
|
||||
else
|
||||
{
|
||||
$row = $form.find('tbody>tr [name^=' + field + ']').first().closest('tr');
|
||||
}
|
||||
|
||||
while($row.length && $row.find('[name^=' + field + ']').val().length)
|
||||
{
|
||||
$row = $row.next();
|
||||
}
|
||||
|
||||
if(!$row || !$row.length)
|
||||
{
|
||||
$form.data('zui.BatchForm').addRow();
|
||||
$row = $form.find('tbody>tr [name^=' + field + ']').last().closest('tr');
|
||||
}
|
||||
|
||||
$row.find('[name^=' + field + ']').val(line).addClass('highlight');
|
||||
|
||||
$currentRow = $row;
|
||||
});
|
||||
|
||||
$lines.val('');
|
||||
$dialog.removeClass('loading');
|
||||
|
||||
$modal.on('hidden.Modal.zui', function()
|
||||
{
|
||||
const $firstRow = $form.find('tbody>tr [name^=' + field + ']').first().closest('tr');
|
||||
$firstRow[0].scrollIntoView();
|
||||
});
|
||||
zui.Modal.hide('#' + modalID);
|
||||
|
||||
setTimeout(function()
|
||||
{
|
||||
$form.find('[name^=' + field + '].highlight').removeClass('highlight');
|
||||
}, 3000);
|
||||
}, 200);
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace zin;
|
||||
|
||||
class pasteDialog extends wg
|
||||
{
|
||||
static $defineProps = array(
|
||||
'field: string', // 表单中多行录入列的字段名,必选
|
||||
'title?: string', // 弹窗的标题,默认为“多行录入”
|
||||
'name?: string="importLines"' // 多行文本控件名称,默认为“importLines”
|
||||
);
|
||||
|
||||
public static function getPageCSS(): string|false
|
||||
{
|
||||
return file_get_contents(__DIR__ . DS . 'css' . DS . 'v1.css');
|
||||
}
|
||||
|
||||
public static function getPageJS(): string|false
|
||||
{
|
||||
return file_get_contents(__DIR__ . DS . 'js' . DS . 'v1.js');
|
||||
}
|
||||
|
||||
protected function build(): wg
|
||||
{
|
||||
global $lang;
|
||||
$field = $this->prop('field');
|
||||
$title = $this->prop('title');
|
||||
$name = $this->prop('name');
|
||||
if(empty($title)) $title = $lang->pasteText;
|
||||
|
||||
return modal
|
||||
(
|
||||
set::id('paste-dialog'),
|
||||
set::title($title),
|
||||
set::footerClass('center pt-2'),
|
||||
set::footerActions
|
||||
(
|
||||
array
|
||||
(
|
||||
btn
|
||||
(
|
||||
setClass('btn btn-wide primary'),
|
||||
on::click("importLines(target, '$field')"),
|
||||
$lang->save
|
||||
)
|
||||
)
|
||||
),
|
||||
editor
|
||||
(
|
||||
setID($name),
|
||||
set::name($name),
|
||||
set::placeholder($lang->pasteTextInfo)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user