diff --git a/gen/__init__.py b/gen/__init__.py index db657ed..85c4e48 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -403,7 +403,7 @@ class Action(Type): page='main', group=None, move=0, indexed=False, searchable=False, specificReadPermission=False, specificWritePermission=False, width=None, height=None, - action=None, result='computation', master=None, + action=None, result='computation', confirm=False, master=None, masterValue=None, focus=False, historized=False): Type.__init__(self, None, (0,1), index, default, optional, False, show, page, group, move, indexed, False, @@ -414,6 +414,8 @@ class Action(Type): # compute things and redirect the user to the same page, with some # status message about execution of the action. 'file' means that the # result is the binary content of a file that the user will download. + self.confirm = confirm # If True, a popup will ask the user if she is + # really sure about triggering this action. def __call__(self, obj): '''Calls the action on p_obj.''' diff --git a/gen/plone25/generator.py b/gen/plone25/generator.py index cd3a569..c45d460 100644 --- a/gen/plone25/generator.py +++ b/gen/plone25/generator.py @@ -142,6 +142,9 @@ class Generator(AbstractGenerator): msg('goto_last', '', msg.GOTO_LAST), msg('goto_source', '', msg.GOTO_SOURCE), msg('whatever', '', msg.WHATEVER), + msg('confirm', '', msg.CONFIRM), + msg('yes', '', msg.YES), + msg('no', '', msg.NO), ] # Create basic files (config.py, Install.py, etc) self.generateTool() diff --git a/gen/plone25/mixins/__init__.py b/gen/plone25/mixins/__init__.py index 61aa80c..0d7b1be 100644 --- a/gen/plone25/mixins/__init__.py +++ b/gen/plone25/mixins/__init__.py @@ -544,9 +544,10 @@ class AbstractMixin: res.append(transition) return res - def getAppyPage(self, isEdit, phaseInfo, appyName=True): + def getAppyPage(self, isEdit, phaseInfo, appyPages, appyName=True): '''On which page am I? p_isEdit indicates if the current page is an - edit or consult view. p_phaseInfo indicates the current phase.''' + edit or consult view. p_phaseInfo indicates the current phase. + p_appyPages is the list of displayable appy pages.''' pageAttr = 'pageName' if isEdit: pageAttr = 'fieldset' # Archetypes page name @@ -555,6 +556,11 @@ class AbstractMixin: res = self.REQUEST.get(pageAttr, default) if appyName and (res == 'default'): res = 'main' + # If the page is not among currently displayable pages, return the + # default page + if res not in appyPages: + res = 'main' + if not appyName: res = 'default' return res def getAppyPages(self, phase='main'): diff --git a/gen/plone25/skin/edit.pt b/gen/plone25/skin/edit.pt index abb9c52..767bc3a 100644 --- a/gen/plone25/skin/edit.pt +++ b/gen/plone25/skin/edit.pt @@ -17,7 +17,8 @@ js python:contextObj.getUniqueWidgetAttr(fields, 'helper_js'); phaseInfo python: contextObj.getAppyPhases(fieldset=fieldset, forPlone=True); phase request/phase|phaseInfo/name; - pageName python: contextObj.getAppyPage(isEdit, phaseInfo);"> + appyPages python: contextObj.getAppyPages(phase); + pageName python: contextObj.getAppyPage(isEdit, phaseInfo, appyPages);">
+ tal:define="formId python: '%s_%s' % (contextObj.UID(), field.getName())" + tal:attributes="id formId; action python: contextObj.absolute_url()+'/skyn/do'"> - + + The previous onClick is simply used to prevent Plone from adding a CSS class that displays a popup when the user triggers the form multiple times. @@ -506,6 +510,42 @@ } theForm.submit(); } + // Functions for opening and closing a popup + function openPopup(popupId) { + // Open the popup + var popup = document.getElementById(popupId); + // Put it at the right place on the screen + var scrollTop = window.pageYOffset || document.documentElement.scrollTop || 0; + popup.style.top = (scrollTop + 150) + 'px'; + popup.style.display = "block"; + // Show the greyed zone + var greyed = document.getElementById('appyGrey'); + greyed.style.top = scrollTop + 'px'; + greyed.style.display = "block"; + } + function closePopup(popupId) { + // Close the popup + var popup = document.getElementById(popupId); + popup.style.display = "none"; + // Hide the greyed zone + var greyed = document.getElementById('appyGrey'); + greyed.style.display = "none"; + } + // Function triggered when an action needs to be confirmed by the user + function askConfirm(formId) { + // Store the ID of the form to send if the users confirms. + var confirmForm = document.getElementById('confirmActionForm'); + confirmForm.actionFormId.value = formId; + openPopup("confirmActionPopup"); + } + // Function triggered when an action confirmed by the user must be performed + function doConfirm() { + // The user confirmed: retrieve the form to send and send it. + var confirmForm = document.getElementById('confirmActionForm'); + var actionFormId = confirmForm.actionFormId.value; + var actionForm = document.getElementById(actionFormId); + actionForm.submit(); + } --> Global form for deleting an object @@ -526,8 +566,7 @@
- - Portlet title, with link to tool. -
- If there is only one flavour, clicking on the portlet - title allows to see all root objects in the database. - - - - - - - TODO: implement a widget for selecting the needed flavour. - - Create a section for every root class. - - Section title, with action icons -
-
- - - - -
- - - - -
- - - Create a new object from a web form - - Create (a) new object(s) by importing data - - Search objects of this type (todo: update flavourNumber) - -
-
- Searches for this content type. - - - - Group name -
-   - -
- Group searches - -
- -
-
-
-
-
- - -
-
- - - All objects in flavour - - -
- -
-
-
Buttons for navigating among a list of elements (next, back, first, last, etc). diff --git a/gen/plone25/skin/view.pt b/gen/plone25/skin/view.pt index c009fd1..d8336f7 100644 --- a/gen/plone25/skin/view.pt +++ b/gen/plone25/skin/view.pt @@ -25,7 +25,8 @@ appName appFolder/id; phaseInfo python: contextObj.getAppyPhases(currentOnly=True, forPlone=False); phase request/phase|phaseInfo/name; - pageName python: contextObj.getAppyPage(isEdit, phaseInfo); + appyPages python: contextObj.getAppyPages(phase); + pageName python: contextObj.getAppyPage(isEdit, phaseInfo, appyPages); showWorkflow python: flavour.getAttr('showWorkflowFor' + contextObj.meta_type)"> diff --git a/gen/plone25/templates/Portlet.pt b/gen/plone25/templates/Portlet.pt index ca6e702..af3898c 100644 --- a/gen/plone25/templates/Portlet.pt +++ b/gen/plone25/templates/Portlet.pt @@ -12,7 +12,7 @@ appName string:; appFolder tool/getAppFolder; flavours tool/getFlavoursInfo" class="portlet"> - +
diff --git a/gen/plone25/templates/Styles.css.dtml b/gen/plone25/templates/Styles.css.dtml index d17ea1e..090d6fe 100644 --- a/gen/plone25/templates/Styles.css.dtml +++ b/gen/plone25/templates/Styles.css.dtml @@ -232,6 +232,30 @@ fieldset { .portletCurrent { font-weight: bold; } +div.appyGrey { + display: none; + position: absolute; + left: 0px; + top: 0px; + width:100%; + height:100%; + background:gray; + filter:alpha(Opacity=50); + opacity:0.5; + -moz-opacity:0.5; + -khtml-opacity:0.5 +} +div.appyPopup { + display: none; + position: absolute; + top: 30%; + left: 35%; + width: 350px; + z-index : 100; + background: white; + padding: 8px; + border: 1px solid gray; +} /* Uncomment this if you want to hide breadcrumbs */ /* diff --git a/gen/po.py b/gen/po.py index 1dc5c6e..959e1ae 100644 --- a/gen/po.py +++ b/gen/po.py @@ -100,6 +100,9 @@ class PoMessage: GOTO_LAST = 'Go to end' GOTO_SOURCE = 'Go back' WHATEVER = 'Whatever' + CONFIRM = 'Are you sure ?' + YES = 'Yes' + NO = 'No' def __init__(self, id, msg, default, fuzzy=False, comments=[]): self.id = id