In my eBook
Extending the DVWP (coming soon;
see the series it's based on
here),
I spent a few chapters covering
form action workflows that are triggered by a button on a SharePoint page.
One of the most heavily-commented parts was on
passing
workflow variables to a form action workflow.
Recently, I was working on a similar situation but was running into an issue passing a Javascript variable
into the function.
First I tried it this way:
<a href="javascript: if (submitPromotes('Unsubmitted','Pending'))
var mgrEmail = getMail(asUser.items.Manager);
{ddwrt:GenFireServerEvent(concat('__workflowStart=
{{C05C844E-915A-4CFC-87D7-3F53C56D2710},
New,{18D8A258-EBC9-4362-8092-ED5818E72827},mgrEmail=',{mgrEmail},'*}'))}">
What I wanted was for the
mgrEmail variablewhich is declared after determining that my
submitPromotes() function worksto be inserted as the value of
mgrEmail in the
GenFireServerEvent() call.
But, I was getting an error because {} is making the XSL look for an
xsl:variable or
xsl:param.
If I left the curly braces off, nothing was returned (i.e. ... mgrEmail=* ...).
What was I missing? How do I get Javascript to insert text into the
__doPostBack that's created here?
I know it's doable to create a hidden control and use jQuery to write my Javascript value to that control,
then call it with the curly braces on the GenFireServerEvent, so it pulls from the form when the button is
clicked... but it seemed like I should be able to get the Javascript variable in there directly.
As I often do, I asked my good friend Marc Anderson for an assist.
mgrEmail is a Javascript variable, not an XSL variable, so you need to concat it as such.
(Typing on my iPhone so can't really give you the solution.)
M.
Right! That's what I'm asking how to do. ;)
I asked if he could point me to a link or throw me a hint when he had more than thumbs to work with.
His reply confused me:
Obviously, I can't test this directly, but I'm thinking something like this:
<xsl:variable name="mgrEmail">
if (submitPromotes('Unsubmitted','Pending')) return getMail(asUser.items.Manager);
</xsl:variable>
<a href="javascript: {ddwrt:GenFireServerEvent(concat('__workflowStart=
{{C05C844E-915A-4CFC-87D7-3F53C56D2710},New,
{18D8A258-EBC9-4362-8092-ED5818E72827},mgrEmail=',{$mgrEmail},'*}'))}">
M.
At first, I thought he was expecting the Javascript to run and output to the
xsl:variable but a
Javascript call won't work like that.
But as I played with it, I realized that Marc was directing me to pass the
text of the Javascript call into
the concatenated string so that when it got to the page, the browser would read it as a Javascript concatenation.
See, I'm working with XSL which processes XML to generate HTML. At the same time the XSL is transforming, the SharePoint server is processing directives to place browser-readable markup on the page in place of its specialized controls and functions.
That's what's going on with the
GenFireServerEvent().
It's actually taking the concatenated string and resolving to a
__doPostBack(), which also includes
a concatenated string. If I include the Javascript call in that concatenation, the browser will assume that it's
just text and my variable will get to my workflow as the Javascript call itself. That won't work. So, I need to
pass the text of the call through
GenFireServerEvent() such that it stay intact and makes the Javascript
call when the button is clicked, just before the form action passes its result to the workflow.
Clear as mud?
Take a look and see if this clears it up at all:
<xsl:variable name="mgrEmail">' + getUEmail(asUser.items.Manager) + '</xsl:variable>
<a href="javascript: if (submitPromotes('Unsubmitted','Pending'))
{ddwrt:GenFireServerEvent(concat('__workflowStart={{C05C844E-915A-4CFC-87D7-3F53C56D2710},
New,{1CEADA32-A345-4027-A849-8F9B3EBADDD9},mgrEmail=',$mgrEmail,'}'))}">
This results in the link on the client side looking like this:
<a href="javascript: if (submitPromotes('Unsubmitted','Pending'))
__doPostBack('ctl00$m$g_ed6879b5_4062_47fa_b2a4_4a0744f8e43d',
'__workflowStart={{C05C844E-915A-4CFC-87D7-3F53C56D2710},New,{1CEADA32-A345-4027-A849-8F9B3EBADDD9},
mgrEmail=' + getUEmail(asUser.items.Manager) + '}')">Button code
</a>
So the result of
getUEmail() is concatenated into the fourth parameter of
workflowStart just
before it goes to the form action workflow.
Now, when I get to the form action workflow wizard, I can use the workflow variable
mgrEmail to send
an email to the user's manager.