Commit adcce185 authored by Jérome Perrin's avatar Jérome Perrin

ERP5Form/Formulator: Minimal support of Zope4's ZMI

Only the most used forms are updated
parent 81cb4c40
......@@ -93,6 +93,7 @@ class FormBoxWidget(Widget.Widget):
title='Form ID',
description=(
"ID of the form which must be rendered in this box."),
css_class="form-control",
default="",
required=0)
......@@ -101,6 +102,7 @@ class FormBoxWidget(Widget.Widget):
title='Context method ID',
description=(
"ID of the method that returns a context for this box."),
css_class="form-control",
default="",
required=0)
......@@ -109,6 +111,7 @@ class FormBoxWidget(Widget.Widget):
title='Default',
description=(
"A default value (not used)."),
css_class="form-control",
default="",
required=0)
......@@ -179,6 +182,7 @@ class FormBoxValidator(Validator.Validator):
'validator_form_field_prefix',
title='Validator Form Field Prefix',
description= "Field prefix value used when validating fields",
css_class="form-control",
default="my_",
display_width=40,
required=1
......
......@@ -185,6 +185,7 @@ class ListBoxWidget(Widget.Widget):
title='Lines',
description=(
"The number of lines of this list. Required."),
css_class="form-control",
default=20,
required=1)
property_names.append('lines')
......@@ -193,6 +194,7 @@ class ListBoxWidget(Widget.Widget):
title="Columns",
description=(
"A list of attributes names to display. Required."),
css_class="form-control",
default=[],
required=1)
property_names.append('columns')
......@@ -201,6 +203,7 @@ class ListBoxWidget(Widget.Widget):
title="More Columns",
description=(
"An optional list of attributes names to display."),
css_class="form-control",
default=[],
required=0)
property_names.append('all_columns')
......@@ -209,6 +212,7 @@ class ListBoxWidget(Widget.Widget):
title="List Style Columns",
description=(
"An optional list of list style columns to display."),
css_class="form-control",
default=[],
required=0)
property_names.append('style_columns')
......@@ -217,6 +221,7 @@ class ListBoxWidget(Widget.Widget):
title="Searchable Columns",
description=(
"An optional list of columns to search."),
css_class="form-control",
default=[],
required=0)
property_names.append('search_columns')
......@@ -225,6 +230,7 @@ class ListBoxWidget(Widget.Widget):
title="Sortable Columns",
description=(
"An optional list of columns to sort."),
css_class="form-control",
default=[],
required=0)
property_names.append('sort_columns')
......@@ -232,6 +238,7 @@ class ListBoxWidget(Widget.Widget):
sort = fields.ListTextAreaField('sort',
title='Default Sort',
description=('The default sort keys and order'),
css_class="form-control",
default=[],
required=0)
property_names.append('sort')
......@@ -240,6 +247,7 @@ class ListBoxWidget(Widget.Widget):
title='List Method',
description=('The method to use to list '
'objects'),
css_class="form-control",
default='',
required=0)
property_names.append('list_method')
......@@ -248,6 +256,7 @@ class ListBoxWidget(Widget.Widget):
title='Count Method',
description=('The method to use to count '
'objects'),
css_class="form-control",
default='',
required=0)
property_names.append('count_method')
......@@ -256,6 +265,7 @@ class ListBoxWidget(Widget.Widget):
title='Stat Method',
description=('The method to use to stat '
'objects'),
css_class="form-control",
default='',
required=0)
property_names.append('stat_method')
......@@ -264,6 +274,7 @@ class ListBoxWidget(Widget.Widget):
title='Row CSS Method',
description=('The method to set the css '
'class name of a row'),
css_class="form-control",
default='',
required=0)
property_names.append('row_css_method')
......@@ -272,6 +283,7 @@ class ListBoxWidget(Widget.Widget):
title='Selection Name',
description=('The name of the selection to '
'store selection parameters'),
css_class="form-control",
default='',
required=0)
property_names.append('selection_name')
......@@ -280,6 +292,7 @@ class ListBoxWidget(Widget.Widget):
title="Meta Types",
description=(
"Meta Types of objects to list."),
css_class="form-control",
default=[],
required=0)
property_names.append('meta_types')
......@@ -288,6 +301,7 @@ class ListBoxWidget(Widget.Widget):
title="Portal Types",
description=(
"Portal Types of objects to list."),
css_class="form-control",
default=[],
required=0)
property_names.append('portal_types')
......@@ -296,6 +310,7 @@ class ListBoxWidget(Widget.Widget):
title="Default Parameters",
description=(
"Default Parameters for the List Method."),
css_class="form-control",
default=[],
required=0)
property_names.append('default_params')
......@@ -303,6 +318,7 @@ class ListBoxWidget(Widget.Widget):
search = fields.CheckBoxField('search',
title='Search Row',
description=('Search Row'),
css_class="form-check-input",
default=0,
required=0)
property_names.append('search')
......@@ -310,6 +326,7 @@ class ListBoxWidget(Widget.Widget):
select = fields.CheckBoxField('select',
title='Select Column',
description=('Select Column'),
css_class="form-check-input",
default=0,
required=0)
property_names.append('select')
......@@ -318,6 +335,7 @@ class ListBoxWidget(Widget.Widget):
title='Anchor Column',
description=(
'An optional anchor column which can always clickable.'),
css_class="form-check-input",
default=0,
required=0)
property_names.append('anchor')
......@@ -327,6 +345,7 @@ class ListBoxWidget(Widget.Widget):
title='Hide Rows (On No Search Criterion)',
description=('Hide listbox rows if no search '
'criterion is provided by user'),
css_class="form-check-input",
default=0,
required=0)
property_names.append('hide_rows_on_no_search_criterion')
......@@ -335,6 +354,7 @@ class ListBoxWidget(Widget.Widget):
title="Editable Columns",
description=(
"An optional list of columns which can be modified."),
css_class="form-control",
default=[],
required=0)
property_names.append('editable_columns')
......@@ -343,6 +363,7 @@ class ListBoxWidget(Widget.Widget):
title="Stat Columns",
description=(
"An optional list of columns which can be used for statistics."),
css_class="form-control",
default=[],
required=0)
property_names.append('stat_columns')
......@@ -351,6 +372,7 @@ class ListBoxWidget(Widget.Widget):
title="URL Columns",
description=(
"An optional list of columns which can provide a custom URL."),
css_class="form-control",
default=[],
required=0)
property_names.append('url_columns')
......@@ -359,6 +381,7 @@ class ListBoxWidget(Widget.Widget):
title="Untranslatable Columns",
description=(
"An optional list of columns titles which should not be translated."),
css_class="form-control",
default=[],
required=0)
property_names.append('untranslatable_columns')
......@@ -369,6 +392,7 @@ class ListBoxWidget(Widget.Widget):
description=(
"An optional list of attributes which are set by hidden fields and "
"which are applied to each editable column."),
css_class="form-control",
default=[],
required=0)
property_names.append('global_attributes')
......@@ -376,6 +400,7 @@ class ListBoxWidget(Widget.Widget):
domain_tree = fields.CheckBoxField('domain_tree',
title='Domain Tree',
description=('Selection Tree'),
css_class="form-check-input",
default=0,
required=0)
property_names.append('domain_tree')
......@@ -384,6 +409,7 @@ class ListBoxWidget(Widget.Widget):
title="Domain Root",
description=(
"A list of domains which define the possible root."),
css_class="form-control",
default=[],
required=0)
property_names.append('domain_root_list')
......@@ -391,6 +417,7 @@ class ListBoxWidget(Widget.Widget):
report_tree = fields.CheckBoxField('report_tree',
title='Report Tree',
description=('Report Tree'),
css_class="form-check-input",
default=0,
required=0)
property_names.append('report_tree')
......@@ -399,6 +426,7 @@ class ListBoxWidget(Widget.Widget):
title="Report Root",
description=(
"A list of domains which define the possible root."),
css_class="form-control",
default=[],
required=0)
property_names.append('report_root_list')
......@@ -407,6 +435,7 @@ class ListBoxWidget(Widget.Widget):
title="Display style",
description=(
"A list of styles which change the listbox rendering."),
css_class="form-control",
default=[],
required=0)
property_names.append('display_style_list')
......@@ -415,6 +444,7 @@ class ListBoxWidget(Widget.Widget):
title="Default display style",
description=(
"A default display style for listbox rendering."),
css_class="form-control",
default=DEFAULT_LISTBOX_DISPLAY_STYLE,
required=0)
property_names.append('default_display_style')
......@@ -422,6 +452,7 @@ class ListBoxWidget(Widget.Widget):
global_search_column = fields.StringField('global_search_column',
title="Global search column",
description=("Global search column make query."),
css_class="form-control",
default=None,
required=0)
property_names.append('global_search_column')
......@@ -429,6 +460,7 @@ class ListBoxWidget(Widget.Widget):
page_navigation_template = fields.StringField('page_navigation_template',
title="Page Navigation Template",
description=("Page Navigation Template used to render listbox page navigation."),
css_class="form-control",
default=DEFAULT_LISTBOX_PAGE_NAVIGATION_TEMPLATE,
required=0)
property_names.append('page_navigation_template')
......@@ -437,6 +469,7 @@ class ListBoxWidget(Widget.Widget):
title='List Action',
description=('The id of the object action'
' to display the current list'),
css_class="form-control",
default='',
required=0)
property_names.append('list_action')
......@@ -445,6 +478,7 @@ class ListBoxWidget(Widget.Widget):
title='Page Template',
description=('The id of a Page Template'
' to render the ListBox'),
css_class="form-control",
default='',
required=0)
property_names.append('page_template')
......
......@@ -80,6 +80,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Update Method',
description=(
"The method to call to set the relation. Required."),
css_class="form-control",
default="Base_validateRelation",
required=1)
......@@ -87,6 +88,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Jump Method',
description=(
"The method to call to jump to the relation. Required."),
css_class="form-control",
default="Base_jumpToRelatedDocument",
required=1)
......@@ -94,6 +96,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Allow Jump',
description=(
"Do we allow to jump to the relation ?"),
css_class="form-check-input",
default=1,
required=0)
......@@ -101,6 +104,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Base Category',
description=(
"The method to call to set the relation. Required."),
css_class="form-control",
default="",
required=1)
......@@ -108,6 +112,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Portal Type',
description=(
"The method to call to set the relation. Required."),
css_class="form-control",
default="",
required=0)
......@@ -115,6 +120,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Allow Creation',
description=(
"Do we allow to create new objects ?"),
css_class="form-check-input",
default=1,
required=0)
......@@ -122,6 +128,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Container Getter Method',
description=(
"The method to call to get a container object."),
css_class="form-control",
default="",
required=0)
......@@ -129,6 +136,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Context Getter Method',
description=(
"The method to call to get the context."),
css_class="form-control",
default="",
required=0)
......@@ -136,6 +144,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Catalog Index',
description=(
"The method to call to set the relation. Required."),
css_class="form-control",
default="",
required=1)
......@@ -145,6 +154,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Relation Update Method',
description=(
"The method to invoke in order to update the relation"),
css_class="form-control",
default="",
required=0)
......@@ -152,6 +162,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='Relation Form',
description=(
"Form to display relation choices"),
css_class="form-control",
default="",
required=0)
......@@ -161,6 +172,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
"The display size in rows of the field. If set to 1, the "
"widget will be displayed as a drop down box by many browsers, "
"if set to something higher, a list will be shown. Required."),
css_class="form-control",
default=1,
required=1)
......@@ -168,12 +180,14 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title="Columns",
description=(
"A list of attributes names to display."),
css_class="form-control",
default=[],
required=0)
sort = fields.ListTextAreaField('sort',
title='Default Sort',
description=('The default sort keys and order'),
css_class="form-control",
default=[],
required=0)
......@@ -181,6 +195,7 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title="Parameter List",
description=(
"A list of paramters used for the portal_catalog."),
css_class="form-control",
default=[],
required=0)
......@@ -188,12 +203,14 @@ class MultiRelationStringFieldWidget(Widget.LinesTextAreaWidget,
title='List Method',
description=('The method to use to list'
'objects'),
css_class="form-control",
default='',
required=0)
proxy_listbox_ids = fields.ListTextAreaField('proxy_listbox_ids',
title='Proxy Listbox IDs',
description=('A list of listbox that can be used as proxy'),
css_class="form-control",
default='',
required=0)
......
......@@ -90,6 +90,7 @@ class ProxyWidget(Widget.Widget):
title='Form ID',
description= \
"ID of the master form.",
css_class="form-control",
default="",
display_width=40,
required=1)
......@@ -99,6 +100,7 @@ class ProxyWidget(Widget.Widget):
title='Field ID',
description= \
"ID of the field in the master form.",
css_class="form-control",
default="",
display_width=40,
required=1)
......
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<p class="form-help">
<main class="container-fluid">
<p class="form-help lead">
Change the display order and grouping of the fields in this form.
</p>
<table border="1" cellspacing="1" cellpadding="3">
<table class="table table-bordered">
<dtml-let all_groups="get_groups(include_empty=1)"
group_length="get_largest_group_length()"
first_group="all_groups and all_groups[0] or None">
......@@ -14,119 +15,91 @@ Change the display order and grouping of the fields in this form.
<dtml-let groups=sequence-item>
<dtml-in groups>
<dtml-let group=sequence-item>
<td nowrap valign="top">
<table border="0" cellspacing="0" cellpadding="0">
<td>
<table class="table">
<form action="." method="POST">
<input type="hidden" name="group" value="&dtml-group;">
<tr><td align="center" class="list-header">
<div class="list-nav">
<tr><td>
<div class="font-weight-bold">
<dtml-var group html_quote>
</div>
</td></tr>
<tr><td align="left">
<dtml-let fields="get_fields_in_group(group, include_disabled=1)" fields_amount="_.len(fields)">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td>
<dtml-let fields="get_fields_in_group(group)" fields_amount="_.len(fields)">
<table class="table table-borderless table-sm">
<dtml-in fields>
<dtml-let field=sequence-item field_id="field.id">
<tr><td height="25">
<div class="list-item">
<dtml-if expr="REQUEST.has_key(field_id)"><input type="checkbox" name="&dtml-field_id;" checked="checked">
<dtml-else><input type="checkbox" name="&dtml-field_id;">
</dtml-if>
&nbsp;<a href="&dtml-field_id;/manage_main"><img src="&dtml-BASEPATH1;/&dtml-icon;" alt="&dtml-meta_type;" title="&dtml-meta_type;" border="0"></a>&nbsp;<a href="&dtml-field_id;/manage_main"><dtml-var field_id></a>
</div>
<tr><td>
<input type="checkbox" name="&dtml-field_id;">&nbsp;<a href="&dtml-field_id;/manage_main"><img src="&dtml-BASEPATH1;/&dtml-icon;" alt="&dtml-meta_type;" title="&dtml-meta_type;" border="0"></a>&nbsp;<a href="&dtml-field_id;/manage_main"><dtml-var field_id></a>
</td></tr>
</dtml-let>
</dtml-in>
<dtml-in "_.range(group_length - fields_amount)">
<tr><td height="25"></td></tr>
<tr><td></td></tr>
</dtml-in>
</dtml-let>
</table>
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_move_field_up:method"
<tr><td>
<input class="btn btn-secondary" type="submit" name="manage_move_field_up:method"
value="Move Up">
<input class="btn btn-secondary" type="submit" name="manage_move_field_down:method"
value="Move Dn">
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_move_field_down:method"
value="Move Dn"><br><br>
</td></tr>
<tr><td align="center">
<div class="form-element">
<select class="form-element" name="to_group" size="1">
<option>Move to:</option>
<tr><td>
<div class="form-group">
<select class="form-control mb-2" name="to_group" size="1">
<option>Transfer Selected Fields to:</option>
<dtml-in all_groups>
<option><dtml-var sequence-item html_quote></option>
</dtml-in>
</select>
</div>
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_move_group:method"
<input type="submit" class="btn btn-secondary mb-2" name="manage_move_group:method"
value="Transfer">
</div>
</td></tr>
<dtml-if "group != first_group">
<tr><td align="center" class="list-header">
<div class="list-item">
Group
<tr><td>
<div class="form-group">
<input class="btn btn-secondary" type="submit" name="manage_move_group_up:method"
value="Move Group Up">
<input class="btn btn-secondary" type="submit" name="manage_move_group_down:method"
value="Move Group Down">
</div>
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_move_group_up:method"
value="Move Up">
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_move_group_down:method"
value="Move Dn"><br><br>
</td></tr>
<tr><td align="center">
<input type="text" name="new_name" value="" size="10">
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_rename_group:method"
value="Rename"><br>
<tr><td>
<div class="form-group">
<input type="text" class="form-control form-control-sm" name="new_name" value="" size="10">
<input class="btn btn-secondary" type="submit" name="manage_rename_group:method"
value="Rename Group">
</div>
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_remove_group:method"
value="Remove"><br>
<tr><td>
<input class="btn btn-secondary" type="submit" name="manage_remove_group:method"
value="Remove Group">
</td></tr>
<dtml-else>
<tr><td align="center" class="list-header">
<div class="list-item">
Group
<tr><td>
<div class="form-group">
<input type="text" class="form-control form-control-sm" name="new_group" value="" size="10">
<input type="submit" class="btn btn-secondary" name="manage_add_group:method" value="Create Group">
</div>
</td></tr>
<tr><td align="center">
<input type="text" name="new_group" value="" size="10">
</td></tr>
<tr><td align="center">
<input type="submit" name="manage_add_group:method" value="Create"><br><br>
</td></tr>
<tr><td align="center">
<input type="text" name="new_name" value="" size="10">
</td></tr>
<tr><td align="center">
<input class="form-element" type="submit" name="manage_rename_group:method"
value="Rename"><br>
<tr><td>
<div class="form-group">
<input type="text" class="form-control form-control-sm" name="new_name" value="" size="10">
<input class="btn btn-secondary" type="submit" name="manage_rename_group:method"
value="Rename Group">
</div>
</td></tr>
</dtml-if>
......@@ -141,5 +114,5 @@ Change the display order and grouping of the fields in this form.
</dtml-in>
</dtml-let>
</table>
</main>
<dtml-var manage_page_footer>
<style>form td:not(:last-child) { padding-right: 1em; }</style>
<dtml-var manage_page_header>
<style>
textarea.form-control {
resize: both;
}
textarea.form-control, input[type=text].form-control {
font-family: monospace;
}
</style>
<dtml-let help_product="'Formulator'" help_topic=meta_type>
<dtml-var manage_tabs>
</dtml-let>
<p class="form-help">
<main class="container-fluid">
<p class="form-help lead">
Surcharge <dtml-var meta_type> properties here.
</p>
<form action="manage_edit" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<table class="table table-striped table-hover table-sm">
<dtml-let proxy_field="this()"
current_field="None if proxy_field.getTemplateField() is None else proxy_field.getRecursiveTemplateField()">
......@@ -20,7 +28,7 @@ Surcharge <dtml-var meta_type> properties here.
<dtml-if fields>
<tr>
<td colspan="3" class="form-title">
<td colspan="4" class="font-weight-bold">
Proxy Widget properties <dtml-if "current_field is not None">(<dtml-var expr="current_field.meta_type">)</dtml-if>
</td>
</tr>
......@@ -32,20 +40,20 @@ Surcharge <dtml-var meta_type> properties here.
override="current_field.get_override(field_id)"
tales="current_field.get_tales(field_id)">
<tr>
<td align="left" valign="top">
<div class="form-label">
<td>
<dtml-if "tales or override">[</dtml-if><dtml-var "field.title()"><dtml-if "field.has_value('required') and field.get_value('required')">*</dtml-if><dtml-if "tales or override">]</dtml-if>
</div>
</td>
<td align="left" valign="top">
<td>
<dtml-var "field.render(value)">
</td>
<td><div class="form-element">
<td>
<dtml-var "field.meta_type">
</div></td>
<td><div class="form-element">
<dtml-var "field.get_value('description')">
</div></td>
</td>
<td>
<p class="form-text">
<small><dtml-var "field.get_value('description')"></small>
</p>
</td>
</tr>
</dtml-let>
</dtml-in>
......@@ -55,17 +63,17 @@ Surcharge <dtml-var meta_type> properties here.
</dtml-in>
<tr>
<td align="left" valign="top">
<div class="form-label">Proxy Target</div>
<td>
<div>Proxy Target</div>
</td>
<td align="left" valign="top">
<a href="manage_edit_target">Click to edit the target</a>
<td>
<a href="manage_edit_target" class="btn btn-info">Click to edit the target</a>
</td>
<td></td><td></td>
</tr>
</table>
<table cellspacing="0" cellpadding="2" border="0">
<table class="table table-striped table-hover table-sm">
<!-- Then, display Template Field properties -->
<dtml-if "current_field is not None">
......@@ -75,7 +83,7 @@ Surcharge <dtml-var meta_type> properties here.
<dtml-let group=sequence-item fields="form.get_fields_in_group(group)">
<dtml-if fields>
<tr>
<td colspan="3" class="form-title">
<td colspan="5" class="font-weight-bold">
<dtml-var group capitalize> properties
</td>
</tr>
......@@ -84,11 +92,12 @@ Surcharge <dtml-var meta_type> properties here.
<dtml-in fields>
<dtml-let field=sequence-item field_id="field.id"
is_datetime_field="field.meta_type == 'DateTimeField'"
value="proxy_field.get_recursive_orig_value(field_id)"
override="proxy_field.get_recursive_override(field_id)"
tales="proxy_field.get_recursive_tales(field_id)">
<tr>
<td align="left" valign="top">
<td>
<dtml-let checkbox_key="'surcharge_%s' % field_id" >
<dtml-if "proxy_field.is_delegated(field_id)">
<input type="checkbox"
......@@ -102,8 +111,7 @@ Surcharge <dtml-var meta_type> properties here.
</dtml-if >
</dtml-let >
</td>
<td align="left" valign="top">
<div class="form-label">
<td>
<dtml-if "tales or override">[
</dtml-if>
<dtml-var "field.title()">
......@@ -111,23 +119,24 @@ Surcharge <dtml-var meta_type> properties here.
</dtml-if>
<dtml-if "tales or override">]
</dtml-if>
</div>
</td>
<dtml-if "proxy_field.is_delegated(field_id)">
<td align="left" valign="top" class="to_disable delegated">
<td class="to_disable delegated <dtml-if is_datetime_field>form-inline</dtml-if>">
<dtml-var "field.render(value)">
</td>
<dtml-else >
<td align="left" valign="top" class="to_disable">
<td class="to_disable <dtml-if is_datetime_field>form-inline</dtml-if>">
<dtml-var "field.render(value)">
</td>
</dtml-if>
<td><div class="form-element">
<td>
<dtml-var "field.meta_type">
</div></td>
<td><div class="form-element">
<dtml-var "field.get_value('description')">
</div></td>
</td>
<td>
<p class="form-text">
<small><dtml-var "field.get_value('description')"></small>
</p>
</td>
</tr>
</dtml-let>
</dtml-in>
......@@ -140,13 +149,13 @@ Surcharge <dtml-var meta_type> properties here.
</dtml-let>
</table>
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value="Save Changes" />
</div>
<div class="zmi-controls">
<input class="btn btn-primary" type="submit" name="submit" value="Save Changes" />
</div>
</form>
</form>
</main>
<script type="text/javascript">
function isClass(object, className) {
if (object.className != undefined){
......
<tr class="list-header">
<td align="left" valign="top">
<div class="form-label">
<thead class="thead-light">
<tr>
<th>
Delegated
</div>
</td>
<td align="left" valign="top">
<div class="form-label">
</th>
<th>
Name
</div>
</td>
<td align="left" valign="top">
<div class="form-label">
</th>
<th class="w-50">
Value
</div>
</td>
<td align="left" valign="top">
<div class="form-label">
</th>
<th>
Field
</div>
</td>
</th>
<dtml-if "_['URL'].endswith(('/manage_main', '/manage_edit'))">
<td align="left" valign="top">
<div class="form-label">
<th>
Description
</div>
</td>
</th>
</dtml-if>
</tr>
</thead>
\ No newline at end of file
<style>form td:not(:last-child) { padding-right: 1em; }</style>
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<p class="form-help">
<main class="container-fluid">
<p class="form-help lead">
Edit <dtml-var meta_type> method TALES expressions here.
<dtml-if "not isTALESAvailable()"><br>
<span style="color: #FF0000;">
......@@ -14,7 +14,7 @@ This tab can therefore not be used.
<form action="manage_tales" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<table class="table table-striped table-hover table-sm">
<dtml-in "override_form.get_groups()">
......@@ -22,7 +22,7 @@ This tab can therefore not be used.
<dtml-if fields>
<tr>
<td colspan="3" class="form-title">
<td colspan="3" class="font-weight-bold">
Proxy Widget properties
</td>
</tr>
......@@ -34,17 +34,15 @@ This tab can therefore not be used.
<dtml-let field=sequence-item field_id="field.id"
value="current_field.get_tales(field.id)">
<tr>
<td align="left" valign="top">
<div class="form-label">
<td>
<dtml-var "field.title()">
</div>
</td>
<td align="left" valign="top">
<td>
<dtml-var "field.render(value)">
</td>
<td><div class="form-element">
<td>
<dtml-var "current_field.form.get_field(field.id).meta_type">
</div></td>
</td>
</tr>
</dtml-let>
</dtml-in>
......@@ -54,17 +52,17 @@ This tab can therefore not be used.
</dtml-in>
<tr>
<td align="left" valign="top">
<div class="form-label">Proxy Target</div>
<td>
<div>Proxy Target</div>
</td>
<td align="left" valign="top">
<a href="manage_tales_target">Click to edit the target</a>
<td>
<a href="manage_tales_target" class="btn btn-info">Click to edit the target</a>
</td>
<td></td>
</tr>
</table>
<table cellspacing="0" cellpadding="2" border="0">
<table class="table table-striped table-hover table-sm">
<!-- XXX Loop until find not a proxy field -->
<dtml-let proxy_field="this()"
......@@ -77,7 +75,7 @@ This tab can therefore not be used.
<dtml-let group=sequence-item fields="form.get_fields_in_group(group)">
<dtml-if fields>
<tr>
<td colspan="3" class="form-title">
<td colspan="4" class="font-weight-bold">
<dtml-var group capitalize> properties
</td>
</tr>
......@@ -86,11 +84,10 @@ This tab can therefore not be used.
<dtml-in fields>
<dtml-let field=sequence-item field_id="field.id"
value="proxy_field.get_recursive_tales(field_id)">
<tr>
<td align="left" valign="top">
<td>
<dtml-let checkbox_key="'surcharge_%s' % field_id" >
<dtml-if "proxy_field.is_delegated(field_id)">
<input type="checkbox"
......@@ -105,25 +102,21 @@ This tab can therefore not be used.
</dtml-let >
</td>
<td align="left" valign="top">
<div class="form-label">
<td>
<dtml-var "field.title()">
</div>
</td>
<dtml-if "proxy_field.is_delegated(field_id)">
<td align="left" valign="top" class="to_disable delegated">
<td class="to_disable delegated">
<dtml-var "field.render(value)">
</td>
<dtml-else >
<td align="left" valign="top" class="to_disable">
<td class="to_disable">
<dtml-var "field.render(value)">
</td>
</dtml-if>
<td><div class="form-element">
<td>
<dtml-var "current_field.form.get_field(field.id).meta_type">
</div></td>
</td>
</tr>
</dtml-let>
......@@ -138,12 +131,14 @@ This tab can therefore not be used.
</dtml-let>
</table>
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value="Save Changes" />
</div>
<div class="zmi-controls">
<input class="btn btn-primary" type="submit" name="submit" value="Save Changes" />
</div>
</form>
</main>
<script type="text/javascript">
function isClass(object, className) {
if (object.className != undefined){
......
......@@ -73,6 +73,8 @@ def initializeFieldForm(field_class):
tales_field = fields.TALESField(field.id,
title=field.get_value('title'),
description="",
css_class="form-control code",
extra='id="%s"' % field.id,
default="",
display_width=40,
required=0)
......@@ -81,6 +83,8 @@ def initializeFieldForm(field_class):
method_field = fields.MethodField(field.id,
title=field.get_value("title"),
description="",
css_class="form-control code",
extra='id="%s"' % field.id,
default="",
required=0)
override_form.add_field(method_field, "widget")
......@@ -89,6 +93,8 @@ def initializeFieldForm(field_class):
form.add_field(field, "validator")
tales_field = fields.TALESField(field.id,
title=field.get_value('title'),
css_class="form-control code",
extra='id="%s"' % field.id,
description="",
default="",
display_with=40,
......@@ -97,6 +103,8 @@ def initializeFieldForm(field_class):
method_field = fields.MethodField(field.id,
title=field.get_value("title"),
css_class="form-control code",
extra='id="%s"' % field.id,
description="",
default="",
required=0)
......
......@@ -878,9 +878,12 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
if (len(field_ids) == 1 and
self.move_field_up(field_ids[0], group)):
message = "Field %s moved up." % field_ids[0]
manage_tabs_type = "success"
else:
message = "Can't move field up."
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -892,9 +895,12 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
if (len(field_ids) == 1 and
self.move_field_down(field_ids[0], group)):
message = "Field %s moved down." % field_ids[0]
manage_tabs_type = "success"
else:
message = "Can't move field down."
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -909,9 +915,13 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
message = "Fields %s transferred from %s to %s." % (fields,
group,
to_group)
manage_tabs_type = "success"
else:
message = "Can't transfer fields."
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -923,9 +933,12 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
if (group and group != 'Select group' and
self.add_group(group)):
message = "Group %s created." % (group)
manage_tabs_type = "success"
else:
message = "Can't create group."
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -935,9 +948,12 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
"""
if self.remove_group(group):
message = "Group %s removed." % (group)
manage_tabs_type = "success"
else:
message = "Can't remove group."
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -949,12 +965,16 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
new_name = REQUEST['new_name'].strip()
if self.rename_group(group, new_name):
message = "Group %s renamed to %s." % (group, new_name)
manage_tabs_type = "success"
else:
message = "Can't rename group."
manage_tabs_type = "danger"
else:
message = "No new name supplied."
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -964,9 +984,12 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
"""
if self.move_group_up(group):
message = "Group %s moved up." % group
manage_tabs_type = "success"
else:
message = "Can't move group %s up" % group
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
security.declareProtected('Change Formulator Forms',
......@@ -976,9 +999,12 @@ class ZMIForm(ObjectManager, PropertyManager, RoleManager, Item, Form):
"""
if self.move_group_down(group):
message = "Group %s moved down." % group
manage_tabs_type = "success"
else:
message = "Can't move group %s down" % group
manage_tabs_type = "danger"
return self.formOrder(self, REQUEST,
manage_tabs_type=manage_tabs_type,
manage_tabs_message=message)
PythonForm = ZMIForm # NOTE: backwards compatibility
......
......@@ -28,6 +28,7 @@ class ValidatorBase:
"a user could submit a field that since got disabled, or "
"get a validation error as a field suddenly got enabled that "
"wasn't there when the form was drawn."),
css_class="form-check-input",
default=1)
editable = fields.CheckBoxField('editable',
......@@ -36,6 +37,7 @@ class ValidatorBase:
"If a field is not editable, then the user can only see"
"the value. This allows to drawn very different forms depending"
"on use permissions."),
css_class="form-check-input",
default=1)
def raise_error(self, error_key, field):
......@@ -64,6 +66,7 @@ class Validator(ValidatorBase):
"arguments to this method. Your method should return true if the "
"validation succeeded. Anything else will cause "
"'external_validator_failed' to be raised."),
css_class="form-control",
default="",
required=0)
......@@ -88,6 +91,7 @@ class StringBaseValidator(Validator):
description=(
"Checked if the field preserves whitespace. This means even "
"just whitespace input is considered to be data."),
css_class="form-check-input",
default=0)
message_names = Validator.message_names + ['required_not_found']
......@@ -123,6 +127,7 @@ class StringValidator(StringBaseValidator):
description=(
"Checked if the field delivers a unicode string instead of an "
"8-bit string."),
css_class="form-check-input",
default=0)
max_length = fields.IntegerField('max_length',
......@@ -131,6 +136,7 @@ class StringValidator(StringBaseValidator):
"The maximum amount of characters that can be entered in this "
"field. If set to 0 or is left empty, there is no maximum. "
"Note that this is server side validation."),
css_class="form-control",
default="",
required=0)
......@@ -140,6 +146,7 @@ class StringValidator(StringBaseValidator):
"If checked, truncate the field if it receives more input than is "
"allowed. The normal behavior in this case is to raise a validation "
"error, but the text can be silently truncated instead."),
css_class="form-check-input",
default=0)
message_names = StringBaseValidator.message_names +\
......@@ -208,7 +215,8 @@ class PatternValidator(StringValidator):
"should appear literally in the value in that place. Internal "
"whitespace is checked as well but may be included in any amount. "
"Example: 'dddd ee' is a Dutch zipcode (postcode). "
"NOTE: currently experimental and details may change!")
"NOTE: currently experimental and details may change!"),
css_class="form-control",
)
message_names = StringValidator.message_names +\
......@@ -235,6 +243,7 @@ class BooleanValidator(Validator):
title='Required',
description=(
"Checked if the field is required; the user has to check."),
css_class="form-check-input",
default=0)
message_names = Validator.message_names + ['required_not_found']
......@@ -264,6 +273,7 @@ class IntegerValidator(StringBaseValidator):
description=(
"The integer entered by the user must be larger than or equal to "
"this value. If left empty, there is no minimum."),
css_class="form-control",
default="",
required=0)
......@@ -272,6 +282,7 @@ class IntegerValidator(StringBaseValidator):
description=(
"The integer entered by the user must be smaller than this "
"value. If left empty, there is no maximum."),
css_class="form-control",
default="",
required=0)
......@@ -381,6 +392,7 @@ class LinesValidator(StringBaseValidator):
description=(
"Checked if the field delivers a unicode string instead of an "
"8-bit string."),
css_class="form-check-input",
default=0)
max_lines = fields.IntegerField('max_lines',
......@@ -388,6 +400,7 @@ class LinesValidator(StringBaseValidator):
description=(
"The maximum amount of lines a user can enter. If set to 0, "
"or is left empty, there is no maximum."),
css_class="form-control",
default="",
required=0)
......@@ -396,6 +409,7 @@ class LinesValidator(StringBaseValidator):
description=(
"The maximum length of a line. If set to 0 or is left empty, there "
"is no maximum."),
css_class="form-control",
default="",
required=0)
......@@ -404,6 +418,7 @@ class LinesValidator(StringBaseValidator):
description=(
"The maximum total length in characters that the user may enter. "
"If set to 0 or is left empty, there is no maximum."),
css_class="form-control",
default="",
required=0)
......@@ -474,6 +489,7 @@ class SelectionValidator(StringBaseValidator):
description=(
"Checked if the field delivers a unicode string instead of an "
"8-bit string."),
css_class="form-check-input",
default=0)
message_names = StringBaseValidator.message_names +\
......@@ -522,6 +538,7 @@ class MultiSelectionValidator(Validator):
description=(
"Checked if the field is required; the user has to fill in some "
"data."),
css_class="form-check-input",
default=1)
unicode = fields.CheckBoxField('unicode',
......@@ -529,6 +546,7 @@ class MultiSelectionValidator(Validator):
description=(
"Checked if the field delivers a unicode string instead of an "
"8-bit string."),
css_class="form-check-input",
default=0)
message_names = Validator.message_names + ['required_not_found',
......@@ -600,6 +618,7 @@ class FileValidator(Validator):
description=(
"Checked if the field is required; the "
"user has to fill in some data."),
css_class="form-check-input",
default=0)
property_names = Validator.property_names + ['required']
......@@ -640,17 +659,20 @@ class LinkValidator(StringValidator):
title='Check Link',
description=(
"Check whether the link is not broken."),
css_class="form-check-input",
default=0)
check_timeout = fields.FloatField('check_timeout',
title='Check Timeout',
description=(
"Maximum amount of seconds to check link. Required"),
css_class="form-control",
default=7.0,
required=1)
link_type = fields.ListField('link_type',
title='Type of Link',
css_class="form-control",
default="external",
size=1,
items=[('External Link', 'external'),
......@@ -716,6 +738,7 @@ class DateTimeValidator(Validator):
description=(
"Checked if the field is required; the user has to enter something "
"in the field."),
css_class="form-check-input",
default=1)
start_datetime = fields.DateTimeField('start_datetime',
......@@ -723,6 +746,7 @@ class DateTimeValidator(Validator):
description=(
"The date and time entered must be later than or equal to "
"this date/time. If left empty, no check is performed."),
css_class="form-control",
default=None,
input_style="text",
required=0)
......@@ -732,6 +756,7 @@ class DateTimeValidator(Validator):
description=(
"The date and time entered must be earlier than "
"this date/time. If left empty, no check is performed."),
css_class="form-control",
default=None,
input_style="text",
required=0)
......@@ -741,6 +766,7 @@ class DateTimeValidator(Validator):
description=(
"Allow time to be left empty. Time will default to midnight "
"on that date."),
css_class="form-check-input",
default=0)
message_names = Validator.message_names + ['required_not_found',
......
......@@ -100,6 +100,7 @@ class Widget:
description=(
"The title of this field. This is the title of the field that "
"will appear in the form when it is displayed. Required."),
css_class="form-control",
default="",
required=1)
......@@ -109,6 +110,7 @@ class Widget:
"Description of this field. The description property can be "
"used to add a short description of what a field does; such as "
"this one."),
css_class="form-control",
default="",
width="20", height="3",
required=0)
......@@ -118,6 +120,7 @@ class Widget:
description=(
"The CSS class of the field. This can be used to style your "
"formulator fields using cascading style sheets. Not required."),
css_class="form-control",
default="",
required=0)
......@@ -128,6 +131,7 @@ class Widget:
"the result dictionary when doing validation, and in the REQUEST "
"if validation goes to request. This can be used to support names "
"that cannot be used as Zope ids."),
css_class="form-control",
default="",
required=0)
......@@ -137,6 +141,7 @@ class Widget:
"This field will be on the form, but as a hidden field. The "
"contents of the hidden field will be the default value. "
"Hidden fields are not visible but will be validated."),
css_class="form-check-input",
default=0)
# NOTE: for ordering reasons (we want extra at the end),
......@@ -149,6 +154,7 @@ class Widget:
"string will be literally included in the rendered field."
"This property can be useful if you want "
"to add an onClick attribute to use with JavaScript, for instance."),
css_class="form-control",
default="",
required=0)
......@@ -375,6 +381,7 @@ class TextWidget(Widget):
"You can place text here that will be used as the default "
"value of the field, unless the programmer supplies an override "
"when the form is being generated."),
css_class="form-control",
default="",
required=0)
......@@ -382,6 +389,7 @@ class TextWidget(Widget):
title='Display width',
description=(
"The width in characters. Required."),
css_class="form-control",
default=20,
required=1)
......@@ -391,6 +399,7 @@ class TextWidget(Widget):
"The maximum input in characters that the widget will allow. "
"Required. If set to 0 or is left empty, there is no maximum. "
"Note that is client side behavior only."),
css_class="form-control",
default="",
required=0)
......@@ -400,6 +409,7 @@ class TextWidget(Widget):
"The type of the input field like 'color', 'date', 'email' etc."
"Note input types, not supported by old web browsers, will behave "
"as input type text."),
css_class="form-control",
default="text",
required=0)
......@@ -505,6 +515,7 @@ class CheckBoxWidget(Widget):
description=(
"Default setting of the widget; either checked or unchecked. "
"(true or false)"),
css_class="form-check-input",
default=0)
def render(self, field, key, value, REQUEST, render_prefix=None):
......@@ -648,6 +659,7 @@ class TextAreaWidget(Widget):
title='Default',
description=(
"Default value of the text in the widget."),
css_class="form-control",
default="",
width=20, height=3,
required=0)
......@@ -656,6 +668,7 @@ class TextAreaWidget(Widget):
title='Width',
description=(
"The width (columns) in characters. Required."),
css_class="form-control",
default=40,
required=1)
......@@ -663,6 +676,7 @@ class TextAreaWidget(Widget):
title="Height",
description=(
"The height (rows) in characters. Required."),
css_class="form-control",
default=5,
required=1)
......@@ -718,6 +732,7 @@ class LinesTextAreaWidget(TextAreaWidget):
title='Default',
description=(
"Default value of the lines in the widget."),
css_class="form-control",
default=[],
width=20, height=3,
required=0)
......@@ -727,6 +742,7 @@ class LinesTextAreaWidget(TextAreaWidget):
description=(
"When called with render_view, this separator will be used to "
"render individual items."),
css_class="form-control",
width=20,
default='<br />\n',
whitespace_preserve=1,
......@@ -818,7 +834,7 @@ class ItemsWidget(Widget):
"element of the tuple should be the value that will be submitted. "
"If you want to override this property you will therefore have "
"to return such a list."),
css_class="form-control",
default=[],
width=20,
height=5,
......@@ -835,6 +851,7 @@ class ItemsWidget(Widget):
"field. This property can be useful if you want "
"to add a disabled attribute to disable all contained items, for "
"instance."),
css_class="form-control",
default="",
required=0)
......@@ -858,6 +875,7 @@ class SingleItemsWidget(ItemsWidget):
description=(
"The default value of the widget; this should be one of the "
"elements in the list of items."),
css_class="form-control",
default="",
required=0)
......@@ -866,6 +884,7 @@ class SingleItemsWidget(ItemsWidget):
description=(
"If checked, the first item will always be selected if "
"no initial default value is supplied."),
css_class="form-check-input",
default=0)
def render_items(self, field, key, value, REQUEST, render_prefix=None):
......@@ -986,6 +1005,7 @@ class MultiItemsWidget(ItemsWidget):
"The initial selections of the widget. This is a list of "
"zero or more values. If you override this property from Python "
"your code should return a Python list."),
css_class="form-control",
width=20, height=3,
default=[],
required=0)
......@@ -995,6 +1015,7 @@ class MultiItemsWidget(ItemsWidget):
description=(
"When called with render_view, this separator will be used to "
"render individual items."),
css_class="form-control",
width=20,
default='<br />\n',
whitespace_preserve=1,
......@@ -1169,6 +1190,7 @@ class ListWidget(SingleItemsWidget):
"The display size in rows of the field. If set to 1, the "
"widget will be displayed as a drop down box by many browsers, "
"if set to something higher, a list will be shown. Required."),
css_class="form-control",
default=5,
required=1)
......@@ -1216,6 +1238,7 @@ class MultiListWidget(MultiItemsWidget):
"The display size in rows of the field. If set to 1, the "
"widget will be displayed as a drop down box by many browsers, "
"if set to something higher, a list will be shown. Required."),
css_class="form-control",
default=5,
required=1)
......@@ -1262,6 +1285,7 @@ class RadioWidget(SingleItemsWidget):
description=(
"Orientation of the radio buttons. The radio buttons will "
"be drawn either vertically or horizontally."),
css_class="form-control",
default="vertical",
required=1,
size=1,
......@@ -1313,6 +1337,7 @@ class MultiCheckBoxWidget(MultiItemsWidget):
description=(
"Orientation of the check boxes. The check boxes will "
"be drawn either vertically or horizontally."),
css_class="form-control",
default="vertical",
required=1,
size=1,
......@@ -1375,6 +1400,7 @@ class DateTimeWidget(Widget):
description=(
"The day will be hidden on the output. Instead the default"
"Day will be taken"),
css_class="form-check-input",
default=0)
hidden_day_is_last_day = fields.CheckBoxField('hidden_day_is_last_day',
......@@ -1382,16 +1408,19 @@ class DateTimeWidget(Widget):
description=(
"Defines wether hidden day means, you want the last day of the month"
"Else it will be the first day"),
css_class="form-check-input",
default=0)
timezone_style = fields.CheckBoxField('timezone_style',
title="Display timezone",
description=("Display timezone"),
css_class="form-check-input",
default=0)
default = fields.DateTimeField('default',
title="Default",
description=("The default datetime."),
css_class="form-control",
default=None,
display_style="text",
display_order="ymd",
......@@ -1403,12 +1432,14 @@ class DateTimeWidget(Widget):
description=(
"Default date and time will be the date and time at showing of "
"the form (if the default is left empty)."),
css_class="form-check-input",
default=0)
date_separator = fields.StringField('date_separator',
title='Date separator',
description=(
"Separator to appear between year, month, day."),
css_class="form-control",
default="/",
required=0,
display_width=2,
......@@ -1419,6 +1450,7 @@ class DateTimeWidget(Widget):
title='Time separator',
description=(
"Separator to appear between hour and minutes."),
css_class="form-control",
default=":",
required=0,
display_width=2,
......@@ -1430,6 +1462,7 @@ class DateTimeWidget(Widget):
description=(
"The type of input used. 'text' will show the date part "
"as text, while 'list' will use dropdown lists instead."),
css_class="form-control",
default="text",
items=[("text", "text"),
("list", "list"),
......@@ -1441,6 +1474,7 @@ class DateTimeWidget(Widget):
description=(
"The default timezone display when inputing a new date"),
default="GMT",
css_class="form-control",
items=gmt_timezones,
required=1,
size=1)
......@@ -1450,6 +1484,7 @@ class DateTimeWidget(Widget):
description=(
"The order in which date input should take place. Either "
"year/month/day, day/month/year or month/day/year."),
css_class="form-control",
default="ymd",
items=[("year/month/day", "ymd"),
("day/month/year", "dmy"),
......@@ -1461,12 +1496,14 @@ class DateTimeWidget(Widget):
title="Display date only",
description=(
"Display the date only, not the time."),
css_class="form-check-input",
default=0)
ampm_time_style = fields.CheckBoxField('ampm_time_style',
title="AM/PM time style",
description=(
"Display time in am/pm format."),
css_class="form-check-input",
default=0)
property_names = Widget.property_names +\
......@@ -1900,6 +1937,7 @@ class FloatWidget(TextWidget):
title="Input style",
description=(
"The type of float we should enter. "),
css_class="form-control",
default="-1234.5",
items=[("-1234.5", "-1234.5"),
("-1 234.5", "-1 234.5"),
......@@ -1914,6 +1952,7 @@ class FloatWidget(TextWidget):
title='Precision',
description=(
"Number of digits after the decimal point"),
css_class="form-control",
default='',
required=0)
......
<style>form td:not(:last-child) { padding-right: 1em; }</style>
<dtml-var manage_page_header>
<style>
textarea.form-control {
resize: both;
}
textarea.form-control, input[type=text].form-control {
font-family: monospace;
}
</style>
<dtml-let help_product="'Formulator'" help_topic=meta_type>
<dtml-var manage_tabs>
</dtml-let>
<p class="form-help">
<main class="container-fluid">
<p class="form-help lead">
Edit <dtml-var meta_type> properties here.
</p>
<form action="manage_edit" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<table class="table table-striped table-hover table-sm">
<dtml-in "form.get_groups()">
<dtml-let group=sequence-item fields="form.get_fields_in_group(group)">
<dtml-if fields>
<tr>
<td colspan="4" class="form-title">
<td colspan="4" class="font-weight-bold">
<dtml-var group capitalize> properties
</td>
</tr>
......@@ -26,24 +35,25 @@ Edit <dtml-var meta_type> properties here.
<dtml-let current_field="this()">
<dtml-in fields>
<dtml-let field=sequence-item field_id="field.id"
is_datetime_field="field.meta_type == 'DateTimeField'"
value="current_field.get_orig_value(field_id)"
override="current_field.get_override(field_id)"
tales="current_field.get_tales(field_id)">
<tr>
<td align="left" valign="top">
<div class="form-label">
<td>
<dtml-if "tales or override">[</dtml-if><dtml-var "field.title()"><dtml-if "field.has_value('required') and field.get_value('required')">*</dtml-if><dtml-if "tales or override">]</dtml-if>
</div>
</td>
<td align="left" valign="top">
<td class="<dtml-if is_datetime_field>form-inline</dtml-if>">
<dtml-var "field.render(value)">
</td>
<td valign="top" ><div class="form-element">
<td>
<dtml-var "field.meta_type">
</div></td>
<td align="left" valign="top"><div class="form-element">
<dtml-var "field.get_value('description')">
</div></td>
</td>
<td>
<p class="form-text">
<small><dtml-var "field.get_value('description')"></small>
</p>
</td>
</tr>
</dtml-let>
</dtml-in>
......@@ -53,13 +63,12 @@ Edit <dtml-var meta_type> properties here.
</dtml-in>
</table>
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value="Save Changes" />
</div>
<div class="zmi-controls">
<input class="btn btn-primary" type="submit" name="submit" value="Save Changes" />
</div>
</form>
</main>
<dtml-var manage_page_footer>
......
<tr class="list-header">
<td align="left" valign="top">
<div class="form-label">
<thead class="thead-light">
<tr>
<th>
Name
</div>
</td>
<td align="left" valign="top">
<div class="form-label">
</th>
<th class="w-50">
Value
</div>
</td>
<td align="left" valign="top">
<div class="form-label">
</th>
<th>
Field
</div>
</td>
</th>
<dtml-if "_['URL'].endswith(('/manage_main', '/manage_edit'))">
<td align="left" valign="top">
<div class="form-label">
<th>
Description
</div>
</td>
</th>
</dtml-if>
</tr>
</thead>
\ No newline at end of file
<style>form td:not(:last-child) { padding-right: 1em; }</style>
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<p class="form-help">
<main class="container-fluid">
<p class="form-help lead">
Edit <dtml-var meta_type> method TALES expressions here.
<dtml-if "not isTALESAvailable()"><br>
<span style="color: #FF0000;">
......@@ -13,50 +13,45 @@ This tab can therefore not be used.
</p>
<form action="manage_tales" method="POST">
<table cellspacing="0" cellpadding="2" border="0">
<dtml-in "override_form.get_groups()">
<dtml-let group=sequence-item fields="tales_form.get_fields_in_group(group)">
<dtml-if fields>
<tr>
<td colspan="3" class="form-title">
<h2>
<dtml-var group capitalize> properties
</td>
</tr>
</h2>
<dtml-var fieldListHeader>
<dtml-let current_field="this()">
<dtml-in fields>
<dtml-let field=sequence-item field_id="field.id"
value="current_field.get_tales(field.id)">
<tr>
<td align="left" valign="top">
<div class="form-label">
<dtml-var "field.title()">
</div>
</td>
<td align="left" valign="top">
<div class="form-group row">
<label
for='<dtml-var expr="field.id">'
class="form-label col-sm-3 col-md-2"><dtml-var "field.title()"></label>
<div class="col-sm-9 col-md-10">
<dtml-var "field.render(value)">
</td>
<td valign="top"><div class="form-element">
<small class="form-text text-muted">
<dtml-var "current_field.form.get_field(field.id).meta_type">
</div></td>
</tr>
</small>
</div>
</div>
</dtml-let>
</dtml-in>
</dtml-let>
</dtml-if>
</dtml-let>
</dtml-in>
</table>
</div>
<div class="form-element">
<input class="form-element" type="submit" name="submit"
value="Save Changes" />
</div>
</form>
<div class="zmi-controls">
<input class="btn btn-primary" type="submit" name="submit" value="Save Changes" />
</div>
</form>
</main>
<dtml-var manage_page_footer>
  • cc @kazuhiko

    I am using Zope4 already for a new ERP5 development, the formulator ZMI was too ugly and I thought it was easy to make it better. It was not :) but I feel it's a bit better. The main improvements over the same on Zope2 is that it's using monospaced fonts and larger fields, this should help with TALES expressions.

    I tried two approaches, one with the same tables and another one with more "modern" html (without table for the layout) on normal field TALES. I'm thinking of changing the normal field TALES to use the same tables as others.

    The checkboxes are a bit ugly , but I feel it's good enough.

    What do you think ?

    normal field image

    normal field TALES

    image

    proxyfield

    image

    proxyfield TALES

    image

  • These changes will not break Zope2 compatibility, right ?

    I tried two approaches, one with the same tables and another one with more "modern" html (without table for the layout) on normal field TALES. I'm thinking of changing the normal field TALES to use the same tables as others.

    As Zope4's ZMI still uses table layout, we can follow it here as well, I think.

    https://github.com/infrae/Products.Formulator/commits/master

    The upstream does not have any change in ZMI forms. It would be good to contribute our changes...?

  • ah thanks I already forgot about Zope 2 :) it works on zope2 and it looks like this, I feel it's a bit better than before, because of the monospace fonts

    image

    I did not know formulator was on github, I thought it was completely abandoned. There have been a 10 years gap in the commit history image

    but it seems these days there have been some changes again and there might be python3 support coming ( https://github.com/infrae/Products.Formulator/issues/1 ). I think we have really a lot of patches on formulator (many custom fields, "render_view" API for non editable fields, open office support) it's like a different product so I don't think it's worth trying to use the upstream version. I'll see if I can send a patch, but this is not really a priority, just doing this for ERP5 has already taken much more time that what I was supposed to spend :)

Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment