Can I custom the process for 'Publish' button in Publish dialog in properties-local.xml? - orbeon

In document I see that we can custom the flow in properties-local.xml, but it is only available for Publish button outside (not publish button in dialog)
The flow I intend to do:
In Form builder, user click publish
Publish dialog showed, user click publish button in dialog.
Then it will call api from my server to send info.
In properties-local.xml, I modified inside this part:
<property as="xs:string" name="oxf.fr.detail.process.publish.orbeon.builder"> </property>
with this code:
<!-- show publish dialog -->
xf:show(
dialog = "fb-publish-dialog",
app = "{xxf:instance('fb-form-instance')/xh:head/xf:model[#id = 'fr-form-model']/xf:instance[#id = 'fr-form-metadata']/*/application-name}",
form = "{xxf:instance('fb-form-instance')/xh:head/xf:model[#id = 'fr-form-model']/xf:instance[#id = 'fr-form-metadata']/*/form-name}"
)
<!-- expect when user click publish button in dialog will execute this code -->
then save
then send(
uri = "http://localhost:8000/api/getFormBuilderInfo",
replace = "all"
method = "POST",
content = "xml")
The problem I don't know how to hook into publish button in dialog. Because I want to make sure that it has stored in orbeon database in order to creating new in form runner with appName and formName (which I get through api: http://localhost:8000/api/getFormBuilderInfo).

As of this writing, it isn't possible to invoke code after the form is published.
As a workaround, you could hook your code in the publish process, but this process runs before the form is being published, specifically before the Form Builder user is presented with a dialog asking them for a confirmation to publish the form. So, there will be delay between the time your code is invoked and the time the form is actually published, and of course there is a chance the user closes the dialog without going ahead with the publication of the form.
So, in practice, to use this workaround, you would need to apply some kind of heuristic, like "when your code is invoked, register some a listener to run, say in 5 minutes; when that time has passed, check if the form was actually published, and if so do the action that you needed to perform".

Related

How to set a form readonly (how to avoid the stay - leave popup)

We have the requirement that users, after terminating the input of a form, can only see the data; only authorized users can modify the data, see question
intermediate save and readonly after termination.
The first idea was to use the permission: owner can read the data.
This works smootly : afer saving, in the summary page the form is marked as readonly.
But there was also the requirement: users must be able to interrupt the input of the form and resume it later.
So in the permissions we had to set that the owner can read and update the data, and we use a field of the form to set the section to readonly.
The save-final button sets this field.
We have renamed this button to FINISH, and the save-draft button to intermediate save.
Clicking save-final also makes invisible the save buttons, so the user after clicking this button cannot change anymore the data.
Before clicking FINISH:
After clicking FINISH:
Selecting the form in the summary page and choosing review works smootly: the form is opened in view mode.
But clicking in the created or modified field opens the form in edit. And although all form fields are readonly, clicking at the summary button a window "Leave page Stay on page" is shown. I suppose, because of the vars of the database service the form results as a modified page.
After clicking leave Page, in the summary page a new draft form is shown. This draft form only an Administrator can delete. Because the user haven't the permission to delete.
So the question is:
is there a possibility to set the form read-only when the user clicks the FINISH button? So that in the summary page the form is marked as read only?
Or as another option: is there a possibility to disable the columns Created and Modified" in the summary page, so that only the first column in the summary page is clickable?
Link to the test code
Many thanks
I found as a possibility:
Inhibit the edit in the summary page
add an edit button to the detail page and associate it with the edit
action
Change the description of the Review button to Review/Edit
to 1) I inserted in the custom summary css the lines:
.orbeon .fr-summary-table-div td a,
.orbeon .fr-summary-table-div th a {
pointer-events: none;
}
to 2) Lines added in the properties-local.xml:
Add an edit button to the buttons of the detail page
<property as="xs:string" name="oxf.fr.detail.buttons.view.*.*" value="summary edit pdf"/>
Add the edit process to the edit button
<property as="xs:string" name="oxf.fr.detail.process.edit.apptest.*" value="edit"/>
Add descriptions to the edit key
<property as="xs:string" name="oxf.fr.resource.apptest.*.en.buttons.edit" value="EDIT"/>
<property as="xs:string" name="oxf.fr.resource.apptest.*.de.buttons.edit" value="Ă„ndern"/>
<property as="xs:string" name="oxf.fr.resource.apptest.*.it.buttons.edit" value="Aggiorna"/>
Show the edit button only if the input phase isn't terminated
<property as="xs:string" name="oxf.fr.detail.button.edit.visible.apptest.*">
//datenOK = false()
</property>
Summary page with review/edit button
Detail page with edit button (because the input phase isn't yet terminated)
Detail page without edit button (the input phase is already terminated)
In the test code was the action: Run action when the form loads
I changed the action in Run action when the control appears or changes its value
and now the popup page: stay on page - leave page appears anymore.

Intercepting Grails GSP actions on either client or server side

Grails 2.4.5 here. I am trying to implement the following UX behavior for my GSPs:
If a user has permission to click a button, then they may do so; however
If the user doesn't have permission to click a button, then when they click the button, a banner message (flash?) appears across the top of the screen with an rose/pinkish/red background stating 'You don't have permission to take this action'
To determine whether the user has the required permission, I have access to functionality from both the Groovy and GSP/taglib layers.
From the Groovy/controller layer:
SecurityUtils.hasPermission(String permission)
Ex: SecurityUtils.hasPermission('UPDATE_BUZZ')
From the GSP/taglib layer:
<sec:hasPermission permission="<permission name>">???</sec:hasPermission>
Ex: <sec:hasPermission permission="UPDATE_BUZZ">???</sec:hasPermission>
So, given those two available access checking mechanisms, and given the following controller:
class FizzController {
BuzzService BuzzService
def buzz() {
SomeData dataModel = buzzService.getModel(params)
render(view: 'buzz', model: [ dataModel: dataModel ])
}
}
...where buzz.gsp is:
<!-- Lots of HTML/GSP here -->
<g:submitButton name="update" value="Update" />
<!-- Lots more HTML/GSP down here -->
Given all that, my question is: How/where should I: (1) respond to the 'update' button's click handler, (2) perform the access check, and (3) render the error/banner/flash message? Code example (even pseudo-code) would be most awesome!
Here is what I would suggest:
Make sure your controller method is role based
Remove permission check in GSP, if the button should be visible to everyone
Create an AJAX call upon submission, if the response status is 403, display the banner.
If I were you, I'd probably try to use before-action filter in this case. In this filter I'd make a checking if current user has permissions to such an action (checking permissions should always be done in server-side, because of security reasons) and than:
if security check passes - just return true (controller will continue it's flow)
if security check fails - you can use default flash.message and return false (with propriate css style flasheed message could appears across the top of the screen with an rose/pinkish/red background)
Example code:
class UserFilters {
def filters = {
// ... other filters ...
permissionAllCheck(controller: '*', action: '*') {
before = {
doPermissionCheck(delegate)
}
}
}
private boolean doPermissionCheck(filters) {
if (! YourService.checkForPermissionForCurrentlyLoggedUser()) {
filters.flash.message = "You don't have permission to take this action"
return false
}
true
}
}
If you want to use filter only to specific controller/action, check applying section. Remember also, that you can use invert rule filter.
More info about different filterTypes.
You should also remember to add flash.message section to your layout (or selected views). You can always specify type of flash message and it's css style.
I am assuming by your question that you don't want a page refresh and perhaps not even an ajax call. Because if you did that then showing a banner is not difficult. You just want this to behave like JavaScript client-side validation (UX wise). If this assumption is wrong then don't read and use Aramiti's solution. Otherwise go ahead.
First solution
You can create a tag which takes a permission as input. Something like
<myTagLib:flashOnNoPermission permission="PERM" name="name" value="value">
</myTagLib:flashOnNoPermission>
This tag's definition can check the permission using sec:hasPermission. Then this tag can just render a template containing something like this
<hidden flash message>
<g:submitButton name="name" value="value" onclick="<unhide flash if no permission>"/>
Basically create a wrapper over grails button so that you can have flash messages alongwith buttons.
Problem
What if user's permissions are changed when user is on screen? Ajax takes care of that but this does not. Once screen is loaded then everything is fixed.
The banner is alongwith the button
Second solution
Add a common div at the top of your layout for displaying flash messages. Then create a tag similar to the above. Just don't add the flash message in the rendered template. Something like
<g:submitButton name="name" value="value" onclick="<unhide flash at top of layout if no permission>"/>
Problem
What if user's permissions are changed when he is on the screen?
Not sure why you need things onclick handler but if there is no reason just Aramiti's solution.
Best way would be to hide the button if the user has no permission to use it. That could be easily achieve through <sec:hasPermission permission="UPDATE_BUZZ">button</sec:hasPermission>
If you want button to be displayed even for user without permission, you could use the same hasPermission to add an extra class to the button. Now capture the clock event for that class using jQuery and show your message.

Displaying Data on Page without refreshing

MVS 2010 MVC 3:
I have a Submit page that has severial checkboxes that are been built dynamically as soon as the page load. The user can check one or more checkbox before submitting the form. On the right hand side of the page, there is somewhat a summary of all the previous selections that the user chose. The summary is available from the Submit page and will carry to the other pages. There is an "Add Comment" button at the very top of the page. When the user click it, a popup window with a textbox will display allowing the user to type a comment. How do I display this comment on the page without having a refresh the page?
The main reason for not wanting to do a refresh is because the user could have selected one or more checkboxes, they will lose their states as soon as the page is refreshed.
I tried parent.document.getElementById('DivCommentResult').html(data); - It displayed this message "Microsoft JScript runtime error: Unable to get value of the property 'html': object is null or undefined"
If I understand well, you have to bind the change of your check box to a function that submit a synchone ajax request that obtain the summary you need and replace target content with the result data of your request.
Is it what you want ?
I had to get the parent doucment and retrieve the div id from it.
Once I have it in hand, I set its innerHTML text to the data that I want to display.
var parentDocument = parent.document;
var el = parentDocument.getElementById('commentResult');
Once I have this, I simpley call el.innerHTML = data;

Update values on one jsp on submitting other in struts2

Hi i have functionality in which two jsp there. result.jsp and data.jsp.
When click on button data.jsp open in popup window. i add data in that form and submit data. On submitting popup will close and want data total on result.jsp.
How can i update result.jsp on submitting data.jsp with updated value??
You can use something like this in javascript included in your pop-up jsp as
url below is action you need to call after submitting the pop-up which generally is just a refresh to result.jsp(the action you used to view result.jsp)
//earlier code . now refresh the final page.
window.opener.document.forms[0].action="url.action";
window.opener.document.forms[0].submit();
//more code

How can I create my own validation rule in orbeon xforms?

Here's the problem, I need to validate the form before submitting in the next way, before user can submit anything he should click "Save" button, if he tries to click "Submit" one receives message something like "You should save form before submit".
First I thought that I can add system field to the form like save-indicator, add constraint to like that
<xforms:bind id="isSaved-bind" nodeset="isSaved"
name="isSaved" type="xforms:string" constraint="number(.)=1" required="true()"/>
And add
<xforms:setvalue ref="xxforms:instance('fr-form-instance')/person/isSaved">1</xforms:setvalue>
to actions when "Save" button beeing clicked.
But, the problem is that I have to rewrite all existing forms to insert new code there.
Is there any posibility to make global variable like "isSaved" and check it for every form, before submit, and show error message if user didn't save form?
Or may be there another way that I can't see?
Will be appreciated for any answers.
Form Runner keeps track of whether the form is clean or dirty, and you can access that information in xxforms:instance('fr-persistence-instance')/data-status. The code handling the submit is in apps/fr/includes/persistence/persistence-model.xml. There you could change the listener for DOMActivate on fr-submit-button to read like:
<xforms:action ev:event="DOMActivate" ev:observer="fr-submit-button">
<xforms:action if="instance('fr-persistence-instance')/data-status = 'clean'">
<xforms:setvalue ref="instance('fr-persistence-instance')/submit-or-save-or-send">submit</xforms:setvalue>
<xforms:dispatch name="fr-save-action" target="fr-persistence-model">
<xxforms:context name="fr:check-data-valid" select="true()"/>
</xforms:dispatch>
</xforms:action>
<xforms:action if="instance('fr-persistence-instance')/data-status = 'dirty'">
<xforms:message>You must save form before submitting it.</xforms:message>
</xforms:action>
</xforms:action>
Note that persistence-model.xml is in orbeon-form-runner.jar. To change that file, extract it from there, and place it in the WEB-INF/resources/apps/fr/includes/persistence/persistence-model.xml. That version on WEB-INF/resources will take precedence over the one in the jar file. Also note that these type of changes that rely on the internals of Form Runner or Form Builder have a chance to break when upgrading to a new version of Orbeon Forms. So you might want to carefully keep track of them, so you can more easily reapply the changes when you upgrade.
I use a global flag indicator to check if the form is saved before closing the window or submit and it works pretty well.
This information is cleary explained in this wiki.
All the best!

Resources