From efb54aab36d46946adea81c94a58e5446e7660ef Mon Sep 17 00:00:00 2001 From: liugang Date: Mon, 26 Jun 2023 15:10:48 +0800 Subject: [PATCH] + zin: add pasteDialog widget. --- lib/zin/func.php | 11 ++++-- lib/zin/wg/formbatchpanel/v1.php | 30 +++++++++++++++ lib/zin/wg/pastedialog/css/v1.css | 1 + lib/zin/wg/pastedialog/js/v1.js | 61 +++++++++++++++++++++++++++++++ lib/zin/wg/pastedialog/v1.php | 57 +++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 lib/zin/wg/pastedialog/css/v1.css create mode 100644 lib/zin/wg/pastedialog/js/v1.js create mode 100644 lib/zin/wg/pastedialog/v1.php diff --git a/lib/zin/func.php b/lib/zin/func.php index 1f1ef3ac7e..3df967bc32 100644 --- a/lib/zin/func.php +++ b/lib/zin/func.php @@ -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 { diff --git a/lib/zin/wg/formbatchpanel/v1.php b/lib/zin/wg/formbatchpanel/v1.php index f108299e62..3b654353ca 100644 --- a/lib/zin/wg/formbatchpanel/v1.php +++ b/lib/zin/wg/formbatchpanel/v1.php @@ -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(); + } } diff --git a/lib/zin/wg/pastedialog/css/v1.css b/lib/zin/wg/pastedialog/css/v1.css new file mode 100644 index 0000000000..f2af523141 --- /dev/null +++ b/lib/zin/wg/pastedialog/css/v1.css @@ -0,0 +1 @@ +.form-batch-table .form-batch-control .form-control.highlight {background-color: var(--dtable-checked-bg);} diff --git a/lib/zin/wg/pastedialog/js/v1.js b/lib/zin/wg/pastedialog/js/v1.js new file mode 100644 index 0000000000..97803adbfe --- /dev/null +++ b/lib/zin/wg/pastedialog/js/v1.js @@ -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); +}; diff --git a/lib/zin/wg/pastedialog/v1.php b/lib/zin/wg/pastedialog/v1.php new file mode 100644 index 0000000000..c44f183c76 --- /dev/null +++ b/lib/zin/wg/pastedialog/v1.php @@ -0,0 +1,57 @@ +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) + ) + ); + } +}