mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
implement et2-searchbox and using it in NM
reorganized preprocessor a bit to fix some not replaced size attributes also pass on constructor args in all Et2Url widgets There is still a JS error in new searchbox, causing admin searchbox to not render :(
This commit is contained in:
parent
3cb8b1ecce
commit
ac0867ab77
@ -13,11 +13,12 @@
|
||||
use EGroupware\Api;
|
||||
|
||||
// add et2- prefix to following widgets/tags, if NO <overlay legacy="true"
|
||||
const ADD_ET2_PREFIX_REGEXP = '#<((/?)([vh]?box|date(-time[^\s]*|-duration|-since)?|textbox|textarea|button|colorpicker|url(-email|-phone|-fax)?))(/?|\s[^>]*)>#m';
|
||||
const ADD_ET2_PREFIX_REGEXP = '#<((/?)([vh]?box|date(-time[^\s]*|-duration|-since)?|button|colorpicker|url(-email|-phone|-fax)?))(/?|\s[^>]*)>#m';
|
||||
const ADD_ET2_PREFIX_LAST_GROUP = 6;
|
||||
|
||||
// unconditional of legacy add et2- prefix to this widgets
|
||||
const ADD_ET2_PREFIX_LEGACY_REGEXP = '#<(description|label|avatar|lavatar|image|vfs-mime|vfs-uid|vfs-gid|link|link-[a-z]+|favorites)\s([^>]+)/>#m';
|
||||
const ADD_ET2_PREFIX_LEGACY_REGEXP = '#<(description|searchbox|label|avatar|lavatar|image|vfs-mime|vfs-uid|vfs-gid|link|link-[a-z]+|favorites)\s([^>]+)/>#m';
|
||||
const ADD_ET2_PREFIX_LEGACY_LAST_GROUP = 2;
|
||||
|
||||
// switch evtl. set output-compression off, as we can't calculate a Content-Length header with transparent compression
|
||||
ini_set('zlib.output_compression', 0);
|
||||
@ -160,8 +161,26 @@ function send_template()
|
||||
$str = preg_replace('/<(image|description)\s([^><]*)expose_view="true"\s([^><]*)\\/>/',
|
||||
'<et2-$1-expose $2 $3></et2-$1-expose>', $str);
|
||||
|
||||
// fix <textbox multiline="true" .../> --> <et2-textarea .../>
|
||||
$str = preg_replace('#<textbox(.*?)\smultiline="true"(.*?)/>#', '<et2-textarea$1$2></et2-textarea>', $str);
|
||||
|
||||
// fix <(textbox|int(eger)?|float) precision="int(eger)?|float" .../> --> <et2-number precision=.../> or <et2-textbox .../>
|
||||
$str = preg_replace_callback('#<(textbox|int(eger)?|float|number).*?\s(type="(int(eger)?|float)")?.*?(/|></textbox)>#',
|
||||
static function ($matches)
|
||||
{
|
||||
if ($matches[1] === 'textbox' && !in_array($matches[4], ['float', 'int', 'integer'], true))
|
||||
{
|
||||
return '<et2-'.substr($matches[0], 1, -strlen($matches[6])-1).'></et2-textbox>'; // regular textbox --> nothing to do
|
||||
}
|
||||
$type = $matches[1] === 'float' || $matches[4] === 'float' ? 'float' : 'int';
|
||||
$tag = str_replace('<' . $matches[1], '<et2-number', substr($matches[0], 0, -2));
|
||||
if (!empty($matches[3])) $tag = str_replace($matches[3], '', $tag);
|
||||
if ($type !== 'float') $tag .= ' precision="0"';
|
||||
return $tag . '></et2-number>';
|
||||
}, $str);
|
||||
|
||||
// modify <(vfs-mime|link-string|link-list) --> <et2-*
|
||||
$str = preg_replace(ADD_ET2_PREFIX_LEGACY_REGEXP, '<et2-$1 $2></et2-$1>',
|
||||
$str = preg_replace(ADD_ET2_PREFIX_LEGACY_REGEXP, '<et2-$1 $'.ADD_ET2_PREFIX_LEGACY_LAST_GROUP.'></et2-$1>',
|
||||
str_replace('<description/>', '<et2-description></et2-description>', $str));
|
||||
|
||||
// change link attribute only_app to et2-link attribute app and map r/o link-entry to link
|
||||
@ -278,33 +297,6 @@ function send_template()
|
||||
}
|
||||
else
|
||||
{
|
||||
// fix deprecated attributes: needed, blur, ...
|
||||
static $deprecated = [
|
||||
'needed' => 'required',
|
||||
'blur' => 'placeholder',
|
||||
];
|
||||
$str = preg_replace_callback('#<[^ ]+[^>]* (' . implode('|', array_keys($deprecated)) . ')="([^"]+)"[ />]#',
|
||||
static function ($matches) use ($deprecated) {
|
||||
return str_replace($matches[1] . '="', $deprecated[$matches[1]] . '="', $matches[0]);
|
||||
}, $str);
|
||||
|
||||
// fix <textbox multiline="true" .../> --> <textarea .../> (et2-prefix and self-closing is handled below)
|
||||
$str = preg_replace('#<textbox(.*?)\smultiline="true"(.*?)/>#u', '<textarea$1$2/>', $str);
|
||||
|
||||
// fix <(textbox|int(eger)?|float) precision="int(eger)?|float" .../> --> <et2-number precision=...></et2-number>
|
||||
$str = preg_replace_callback('#<(textbox|int(eger)?|float|number).*?\s(type="(int(eger)?|float)")?.*?/>#u',
|
||||
static function ($matches) {
|
||||
if ($matches[1] === 'textbox' && !in_array($matches[4], ['float', 'int', 'integer'], true))
|
||||
{
|
||||
return $matches[0]; // regular textbox --> nothing to do
|
||||
}
|
||||
$type = $matches[1] === 'float' || $matches[4] === 'float' ? 'float' : 'int';
|
||||
$tag = str_replace('<' . $matches[1], '<et2-number', substr($matches[0], 0, -2));
|
||||
if (!empty($matches[3])) $tag = str_replace($matches[3], '', $tag);
|
||||
if ($type !== 'float') $tag .= ' precision="0"';
|
||||
return $tag . '></et2-number>';
|
||||
}, $str);
|
||||
|
||||
// fix <button(only)?.../> --> <et2-button(-image)? noSubmit="true".../>
|
||||
$str = preg_replace_callback('#<button(only)?\s(.*?)/>#u', function ($matches) use ($name) {
|
||||
$tag = 'et2-button';
|
||||
@ -354,8 +346,18 @@ function send_template()
|
||||
preg_match_all('/(^| )([a-z\d_-]+)="([^"]+)"/i', $matches[3], $attrs, PREG_PATTERN_ORDER);
|
||||
$attrs = array_combine($attrs[2], $attrs[3]);
|
||||
|
||||
// fix deprecated attributes: needed, blur, ...
|
||||
static $deprecated = [
|
||||
'needed' => 'required',
|
||||
'blur' => 'placeholder',
|
||||
];
|
||||
foreach($attrs as $name => $value)
|
||||
{
|
||||
if (isset($deprecated[$name]))
|
||||
{
|
||||
unset($attrs[$name]);
|
||||
$attrs[$name = $deprecated[$name]] = $value;
|
||||
}
|
||||
if (count($parts = preg_split('/[_-]/', $name)) > 1)
|
||||
{
|
||||
if ($name === 'parent_node') $parts[1] = 'Id'; // we can not use DOM property parentNode --> parentId
|
||||
|
@ -38,9 +38,9 @@ export class Et2Password extends Et2InvokerMixin(Et2Textbox)
|
||||
};
|
||||
}
|
||||
|
||||
constructor()
|
||||
constructor(...args : any[])
|
||||
{
|
||||
super();
|
||||
super(...args);
|
||||
|
||||
this.plaintext = true;
|
||||
this.suggest = 0;
|
||||
|
81
api/js/etemplate/Et2Textbox/Et2Searchbox.ts
Normal file
81
api/js/etemplate/Et2Textbox/Et2Searchbox.ts
Normal file
@ -0,0 +1,81 @@
|
||||
/**
|
||||
* EGroupware eTemplate2 - Searchbox widget
|
||||
*
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @package api
|
||||
* @link https://www.egroupware.org
|
||||
* @author Ralf Becker
|
||||
*/
|
||||
|
||||
/* eslint-disable import/no-extraneous-dependencies */
|
||||
import {Et2Textbox} from "./Et2Textbox";
|
||||
|
||||
/**
|
||||
* @customElement et2-searchbox
|
||||
*/
|
||||
export class Et2Searchbox extends Et2Textbox
|
||||
{
|
||||
/** @type {any} */
|
||||
static get properties()
|
||||
{
|
||||
return {
|
||||
...super.properties,
|
||||
/**
|
||||
* Define whether the searchbox overlays while it's open (true) or stay as solid box in front of the search button (false). Default is false.
|
||||
* @todo implement again
|
||||
*/
|
||||
overlay: Boolean,
|
||||
/**
|
||||
* Define whether the searchbox should be a fix input field or flexible search button. Default is true (fix).
|
||||
* @todo implement again
|
||||
*/
|
||||
fix: Boolean,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(...args : any[])
|
||||
{
|
||||
super(...args);
|
||||
|
||||
this.overlay = false;
|
||||
this.fix = true;
|
||||
|
||||
this.clearable = true;
|
||||
this.type = 'search';
|
||||
this.enterkeyhint = 'search';
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwritten to trigger a change/search
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
handleKeyDown(event: KeyboardEvent)
|
||||
{
|
||||
const hasModifier = event.metaKey || event.ctrlKey || event.shiftKey || event.altKey;
|
||||
|
||||
// Pressing enter when focused on an input should submit the form like a native input, but we wait a tick before
|
||||
// submitting to allow users to cancel the keydown event if they need to
|
||||
if (event.key === 'Enter' && !hasModifier)
|
||||
{
|
||||
event.preventDefault();
|
||||
|
||||
this._oldChange(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwritten to trigger a change/search
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
handleClearClick(event : MouseEvent)
|
||||
{
|
||||
event.preventDefault();
|
||||
|
||||
this.value = '';
|
||||
this._oldChange(event);
|
||||
}
|
||||
}
|
||||
// @ts-ignore TypeScript is not recognizing that this is a LitElement
|
||||
customElements.define("et2-searchbox", Et2Searchbox);
|
@ -56,9 +56,10 @@ export class Et2Url extends Et2InvokerMixin(Et2Textbox)
|
||||
];
|
||||
}
|
||||
|
||||
constructor()
|
||||
constructor(...args : any[])
|
||||
{
|
||||
super();
|
||||
super(...args);
|
||||
|
||||
this._invokerLabel = '⎆';
|
||||
this._invokerTitle = 'Open';
|
||||
this._invokerAction = () => {
|
||||
|
@ -34,9 +34,10 @@ export class Et2UrlEmail extends Et2InvokerMixin(Et2Textbox)
|
||||
];
|
||||
}
|
||||
|
||||
constructor()
|
||||
constructor(...args : any[])
|
||||
{
|
||||
super();
|
||||
super(...args);
|
||||
|
||||
this.defaultValidators.push(new IsEmail());
|
||||
this._invokerLabel = '@';
|
||||
this._invokerTitle = 'Compose mail to';
|
||||
|
@ -73,11 +73,6 @@ export class Et2UrlEmailReadonly extends Et2UrlReadonly
|
||||
return super.value;
|
||||
}
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
transformAttributes(attrs)
|
||||
{
|
||||
if (typeof attrs.onclick === 'undefined')
|
||||
|
@ -34,9 +34,10 @@ export class Et2UrlFax extends Et2UrlPhone
|
||||
];
|
||||
}
|
||||
|
||||
constructor()
|
||||
constructor(...args : any[])
|
||||
{
|
||||
super();
|
||||
super(...args);
|
||||
|
||||
//this.defaultValidators.push(...);
|
||||
this._invokerLabel = '📠';
|
||||
this._invokerTitle = 'Send';
|
||||
|
@ -16,11 +16,6 @@ import {Et2UrlReadonly} from "./Et2UrlReadonly";
|
||||
*/
|
||||
export class Et2UrlFaxReadonly extends Et2UrlReadonly
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
transformAttributes(attrs)
|
||||
{
|
||||
if (typeof attrs.onclick === 'undefined')
|
||||
|
@ -32,9 +32,10 @@ export class Et2UrlPhone extends Et2InvokerMixin(Et2Textbox)
|
||||
];
|
||||
}
|
||||
|
||||
constructor()
|
||||
constructor(...args : any[])
|
||||
{
|
||||
super();
|
||||
super(...args);
|
||||
|
||||
//this.defaultValidators.push(...);
|
||||
this._invokerLabel = '✆';
|
||||
this._invokerTitle = 'Call';
|
||||
|
@ -16,11 +16,6 @@ import {Et2UrlReadonly} from "./Et2UrlReadonly";
|
||||
*/
|
||||
export class Et2UrlPhoneReadonly extends Et2UrlReadonly
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
transformAttributes(attrs)
|
||||
{
|
||||
if (typeof attrs.onclick === 'undefined')
|
||||
|
@ -19,11 +19,6 @@ import {Et2Url} from "./Et2Url";
|
||||
*/
|
||||
export class Et2UrlReadonly extends Et2Description
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
static get styles()
|
||||
{
|
||||
return [
|
||||
|
@ -77,6 +77,7 @@ import {loadWebComponent} from "./Et2Widget/Et2Widget";
|
||||
import {Et2AccountFilterHeader} from "./Nextmatch/Headers/AccountFilterHeader";
|
||||
import {Et2SelectCategory} from "./Et2Select/Et2SelectCategory";
|
||||
import {Et2ColumnSelection} from "./Et2Nextmatch/ColumnSelection";
|
||||
import {Et2Searchbox} from "./Et2Textbox/Et2Searchbox";
|
||||
|
||||
//import {et2_selectAccount} from "./et2_widget_SelectAccount";
|
||||
let keep_import : Et2AccountFilterHeader
|
||||
@ -3208,7 +3209,7 @@ export class et2_nextmatch_header_bar extends et2_DOMWidget implements et2_INext
|
||||
}
|
||||
};
|
||||
headers : { id : string }[] | et2_widget[];
|
||||
et2_searchbox : et2_inputWidget;
|
||||
et2_searchbox : Et2Searchbox;
|
||||
private favorites : et2_DOMWidget; // Actually favorite
|
||||
|
||||
private nextmatch : et2_nextmatch;
|
||||
@ -3324,14 +3325,14 @@ export class et2_nextmatch_header_bar extends et2_DOMWidget implements et2_INext
|
||||
{
|
||||
self.nextmatch.applyFilters({search: this.get_value()});
|
||||
},
|
||||
value: settings.search,
|
||||
value: settings.search || '',
|
||||
fix: !egwIsMobile()
|
||||
};
|
||||
// searchbox widget
|
||||
this.et2_searchbox = <et2_searchbox>et2_createWidget('searchbox', searchbox_options, this);
|
||||
this.et2_searchbox = <Et2Searchbox>loadWebComponent('et2-searchbox', searchbox_options, this);
|
||||
|
||||
// Set activeFilters to current value
|
||||
this.nextmatch.activeFilters.search = settings.search;
|
||||
this.nextmatch.activeFilters.search = settings.search || '';
|
||||
|
||||
this.et2_searchbox.set_value(settings.search);
|
||||
jQuery(this.et2_searchbox.getInputNode()).attr("aria-label", egw.lang("search"));
|
||||
|
@ -86,6 +86,7 @@ import "./Layout/RowLimitedMixin";
|
||||
import "./Et2Vfs/Et2VfsMime";
|
||||
import "./Et2Vfs/Et2VfsUid";
|
||||
import "./Et2Textbox/Et2Password";
|
||||
import './Et2Textbox/Et2Searchbox';
|
||||
|
||||
/* Include all widget classes here, we only care about them registering, not importing anything*/
|
||||
import './et2_widget_vfs'; // Vfs must be first (before et2_widget_file) due to import cycle
|
||||
|
Loading…
Reference in New Issue
Block a user