Navigate to PDF action for Orbeon button - orbeon

I have set up a custom process for the submit button on some of my forms as below:
<property as="xs:string" name="oxf.fr.detail.process.submit.App.*">
require-valid
then confirm(message = "Are you sure you would like to submit the form?")
then suspend
then review
</property>
Instead of going to the review page, I would like it to navigate to the pdf copy of the form (as is done with the pdf button). I have has a look at the documentation, but haven't found an action for this. I have found pdf-url, but not sure how to use this to do what I want.
I found the xbl that is used to generate the pdf url for the pdf button, but got stuck on $app and $form being undefined.
<fr:href-button
xmlns:frf="java:org.orbeon.oxf.fr.FormRunner"
model="fr-persistence-model"
ref="instance('fr-triggers-instance')/pdf"
href=
"/fr/service/{
$app
}/{
$form
}/pdf/{{
string-join(
(
xxf:instance('fr-parameters-instance')/document/string(),
xxf:document-id(),
frf:filenameOrNull('pdf')[. != '']
),
'/'
)
}}.pdf">
<property as="xs:string" name="oxf.fr.detail.process.submit.App.*">
require-valid
then confirm(message = "Are you sure you would like to submit the form?")
then suspend
then navigate(uri = "/fr/service/{ $app }/{ $form }/pdf/{ string-join( ( xxf:instance('fr-parameters-instance')/document/string(), xxf:document-id()) , '/' ) }.pdf")
</property>
I've also noticed that it tries to confirm you want leave the page when it tries to redirect to the 404 of a pdf.
What would I replace then review with to go to the pdf?

Use:
navigate(
uri =
"/fr/service/{
xxf:instance('fr-parameters-instance')/app}/{
xxf:instance('fr-parameters-instance')/form}/pdf/{
string-join(
(
xxf:instance('fr-parameters-instance')/document/string(),
xxf:document-id()
),
'/')
}.pdf"
)
There should really be built-in functions to access the app name, form name, and document id. But for now you can access them from that fr-parameters-instance instance. The fr-parameters-instance contains:
<app></app>
<form></form>
<form-version></form-version>
<document></document>
<mode>new</mode>
<uuid/>
You can force the data status to safe with the set-data-status action.

work for me
uri =
"/fr/{
xxf:instance('fr-parameters-instance')/app}/{
xxf:instance('fr-parameters-instance')/form}/pdf/{
xxf:instance('fr-parameters-instance')/document/string()} "
)

Related

Orbeon Forms - Handling service response

I am using Orbeon Forms as my form builder. I have modified "submit" button of the Form Builder to have custom behaviors, please look at my snippet below:
<property as="xs:string" name="oxf.fr.detail.process.send.*.*">
save()
then send(
uri = "{xxf:property('ORBEON_API')}/api/submitForm",
replace = "none",
method = "POST",
content = "xml",
content-type = "application/xml",
nonrelevant = "keep",
serialization = "application/xml"
)
then set-workflow-stage(name = "submitted")
then success-message("save-success")
Now, I am trying to get response of the send() action but can't really find a document describing how to do this in Orbeon CE. I plan to receive an URI from this "{xxf:property('ORBEON_API')}/api/submitForm" so that I can use it to navigate to another page.
I found it is possible to store an Action's response into dataset using Action Settings in PE edition. Sadly, I am using the CE one.
My question is that: Is there a way/workaround for storing and manipulating Action's response in Orbeon CE? Any suggestions are much appreciated 👍.
Thanks in advance.
Currently, actions in processes can't return data, and this is really what you would want here (see #1688). However, send() stores the XML returned by your service in an instance called fr-send-submission-response. So you can access that instance and extract information returned by your service. From XPath, you'd use the following to access that instance:
xxf:instance('fr-send-submission-response')
For instance, the following will make a GET request on a URL that returns breakfast menu, and show the first item on the menu as the success message. (Yes, I know, this isn't a very realistic example! But at least it is one that anyone should be be able to run locally.)
<property as="xs:string" name="oxf.fr.detail.process.submit.*.*">
send(
method = "GET",
uri = "https://www.w3schools.com/XML/simple.xml",
replace = "instance"
)
then success-message(
message = "First item on the menu: {xxf:instance('fr-send-submission-response')/food[1]/name}"
)
</property>
The success message will show like:

How to change the behavior of the "Sign In" button of the OAuthCard to just open the URL without redirect

I have the Webchat (from the Microsoft Bot Framework) running embedded in another application that uses a browser under the hood.
When trying to add Authentication to the bot, I realized that the OAuthCard's Sign-in button doesn't work because is trying to open a blank window (about:blank) that is used to redirect the user to the login page of the identity provider. In the embedded context, the OS doesn't know how to handle the about:blank call. See the image below.
I'm following this example, that it is actually working on the browser:
Add authentication to a bot
Bot authentication example
I want to know if there is a way to change the behavior of the "Sign In" button of the OAuthCard to just open the sign-in URI directly without using the about:blank and redirect technique.
I was able to make it work after finding out that was possible to change the button type of the OAuthCard from "signin" to "openUrl" before the Webchat does the rendering.
There seems to exist a similar issue with Microsoft Teams. Here where I found the clue:
https://github.com/microsoft/botframework-sdk/issues/4768
According to the Webchat reference, it is possible to intersect and change the activities:
https://github.com/microsoft/BotFramework-WebChat/blob/master/docs/API.md#web-chat-api-reference
Here is the solution, that is more like a hack. I hope this would be configurable in the future:
// Change the button type in the OAuthCard to the type of OpenUrl
const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => action => {
if (action.type == "DIRECT_LINE/QUEUE_INCOMING_ACTIVITY" &&
action.payload.activity.hasOwnProperty("attachments") &&
action.payload.activity.attachments[0].contentType === "application/vnd.microsoft.card.oauth") {
action.payload.activity.attachments[0].content.buttons[0].type = "openUrl";
}
return next( action );
});
// Pass the store to the webchat
window.WebChat.renderWebChat({
...,
store
});

Yii appending new route to the exisitng route in url with Yii-bootstrap but working fine with CMenu

am actually having some issue with url routing while using TbMenu widget,i am using the format of /moduleId/ControllerId/ActionId in accessing module Controllers,here is an example
<?php $this->widget('bootstrap.widgets.TbNavbar', array(
'type'=>'inverse', // null or 'inverse'
'brand'=>'mysite',
'brandUrl'=>'#',
'collapse'=>true, // requires bootstrap-responsive.css
'items'=>array(
array(
'class'=>'bootstrap.widgets.TbMenu',
'items'=>array(
array('label'=>'Home','url'=>array('/site/index'), 'active'=>true),
array('label'=>'About', 'url'=>array('/site/page')),
array('label'=>'Contact us','url'=>array('/site/contact')),
),
),
'<form class="navbar-search pull-left" action=""><input type="text" class="search-query span2" placeholder="Search"></form>',
array(
'class'=>'bootstrap.widgets.TbMenu',
'htmlOptions'=>array('class'=>'pull-right'),
'items'=>array(
array('label'=>'Sign in', 'url'=>'/user/auth','visible'=>Yii::app()->user->isGuest),
'---',
[b] array('label'=>'Profile', 'url'=>'/user/user','visible'=>!Yii::app()->user->isGuest, 'items'=>array([/b]
[b]array('label'=>'Settings', 'url'=>'user/user/index'),[/b]
[b]array('label'=>'Logout', 'url'=>'user/user/logout')[/b],
)),
),
),
),
he three last line are the ones that are causing problem,when i try to access those links after clicking on home,page,contact us(using the Site controller actions that are auto-generated by the Yii) the route is appended to the existing url in stead of creating a new url to the module,for example if am on home page(after clicking home it has this as url localhost/mysite/index.php/site/index)**it gives me this url localhost/mysite/index.php/site/index/user/user/index,if i go the same link again with this as url it gives me **localhost/mysite/index/user/user/index/user/user/index if i click again it add another one again and again..but the strange in all is that it works fine with CMenu,here is snippet of CMenu that works fine,
<?php $this->widget('zii.widgets.CMenu',array(
'items'=>array(
array('label'=>'Home', 'url'=>array('/site/index')),
array('label'=>'About', 'url'=>array('/site/page', 'view'=>'about')),
array('label'=>'Contact', 'url'=>array('/site/contact')),
array('label'=>'Login', 'url'=>array('//user/auth'), 'visible'=>Yii::app()->user->isGuest),
array('label'=>'Logout ('.Yii::app()->user->name.')', 'url'=>array('//user/user/logout'), 'visible'=>!Yii::app()->user->isGuest),
array('label'=>'My profile ', 'url'=>array('/user/user/'), 'visible'=>!Yii::app()->user->isGuest),
),
)); ?>
i am assuming that it might be caused by the fact that those links are submenu but i am not sure since the first in those links is not submenu and has the same problem!thank you again
The TbMenu component is using CHtml::link to display the links...
CHtml::link(label, url, options)
CHtml::link method has one check
if url is an array ... then use controller->createUrl(...) method
if url is a string ... then just return that string.
So, I think, #dInGd0nG suggestion would work.
if not then you should be using array ...something like ( don't forget to prefix / )
array('label'=>'Settings', 'url'=> array('/user/user/index') ),
array('label'=>'Logout', 'url'=> array('/user/user/logout') )

Yii framework CHtml::link error jump to a named anchor in another page

I'm use Yii Framework.
I have a named anchor <a name="projet">projet</a> in about.php page.
I've created a link in the index page to the named anchor in the about page like that :
<?php echo CHtml::link('MyLink',array('site/page','view'=>'about#projet')); ?>
But when I click on the link "MyLink", I have an error 404 response with this message :
The requested view "about#projet" was not found.
And in the url I have:
localhost/myApps/index.php?r=site/page&view=about%23projet
I checked default charset application is UTF-8. So I don't understand why my link isn't well encoded.
Someone can help me please?
try this:
echo CHtml::link('MyLink',array('site/page','view'=>'about', '#'=>'projet'));

Detecting if this is an iframe load or direct

I am looking to only show a form if it is pulled on a page within an iframe. How do I do that? Is there a server side solution?
If you are using JQuery... (installation instructions here: http://jquery.com/ )
$(document).ready(function(){
if( window == window.top) { $('form#myform').hide(); }
});
Which just hides the form with id "myform" if the window is not the topmost window.
I can't think of purely serverside way, but you could use a bit of hybrid javascript/rails.
assuming that you have a dedicated iframe layout template e.g. 'layouts/iframe.erb'
you could put some javascript in the head to check if it is being loaded as an iframe, and if it is not, redirect to an action and maybe display a flash msg "can only load this page inside application"
The javascript/rails for the head
<script type="text/javascript">
function parentExists()
{
return (parent.location == window.location)? true : false;
};
function check_modal(){
if (parentExists()) {
window.location = '<%= url_for( :controller => "home", :action => 'iframe_action', :iframe_fail => 'true')%>'}
}
check_modal()
</script>
notice the param :iframe_fail which you could check for in a controller and do whatever you please if that param is present e.g. display flash msg or redirect
example controller
def iframe_action
if params[:iframe_fail]
flash[:notice] = 'can only load inside app'
else
#do something else
end
end
Not real pretty but might help you get the job done.
My iframe tag was like
%iframe{:height => "98%", :width => "98%",:"id" => "profileIframe"}
I wanted to hide header of my webpage within this iframe hence I used code as:
var $frame = $(window.parent.frames["profileIframe"]).contents();
$frame.find('.header-ui').hide();
If you observe then contents() returns a element as "#document", which is html of iframe, hence calling a javascript without this will try to access your actual webpage rendered in background of iframe.
You can only check it on the client side via JavaScript.
However: DO NOT DO THAT. There are plenty of legitimate uses of putting a site in a (i)frame. Breaking out of such iframe or changing your site in any way in such circumstances them will only make your users pissed unhappy.

Resources