How to link an action from javascript with spring web flow and jsf? - spring-webflow

I have a requirement where in from h:commandlink or a4j:commandlink using onclick event, I need to call plain javacript function (not using any javascript framework) which inturn needs to call the required action defined in spring's web flow flow.xml.
In other works,
This works fine for me:
Process: 1:
demo.xhtml:
<h:commandLink value="link next page" action="next"/>
spring-web-flow.xml
<view-state id="demo">
<transition from="next" to="nextPage"/>
</view-state>
Requirement:My need is to use something link this in javascript:
demo.xhtml:
<h:commandLink value="link next page" onClick="navigatePage();"/>
<script type="text/javascript">
function navigatePage(){
// some way to call the action="next" (as mentioned above) which will call the spring-web-flow transition.
}
Anyone if have come across such kind of solution then please help me.
Thanks in advance

you should have access to the variable flowExecutionUrl in your page. just use that with the parameter _eventId and it should work.
so this should work:
<h:commandLink value="link next page" onClick="navigatePage('${flowExecutionUrl}&_eventId=next');"/>
<script type="text/javascript">
function navigatePage(url){
window.location = url;
}
</script>

Related

JSF page loses CSS styles after submit [duplicate]

I am registering a change event listener for every input in the HTML using jQuery as below:
<h:head>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
$(':input').each(function() {
$(this).change(function() {
console.log('From docReady: ' + this.id);
});
});
});
function changeHandler() {
console.log("from changeHandler");
}
//]]>
</script>
</h:head>
<h:body>
<h:form id="topForm">
<p:commandButton id="myButton" value="update"
action="#{testBean.submit}"
partialSubmit="true" process=":myForm:panel"
update=":myForm:panel" />
</h:form>
<h:form id="myForm">
<p:panel id="panel">
<p:inputTextarea id="myTextarea"
value="#{testBean.val}"
onchange="changeHandler();"/>
</p:panel>
</h:form>
</h:body>
Both change events are being triggered if the user changes the content of myTextarea. However after pressing the update button, which partially updates the myTextarea, only the changeHandler is triggering afterwards. The event bound in $(document).ready() is not triggering anymore.
Is this PrimeFaces related and/or an expected behavior? If yes then how can I ensure to trigger the second event without rerunning document ready script again.
As to the cause of your problem, the ajax request will update the HTML DOM tree with new HTML elements from the ajax response. Those new HTML elements do —obviously— not have the jQuery event handler function attached. However, the $(document).ready() isn't re-executed on ajax requests. You need to manually re-execute it.
This can be achieved in various ways. The simplest way is to use $(document).on(event, selector, function) instead of $(selector).on(event, function). This is tied to the document and the given functionRef is always invoked when the given eventName is triggered on an element matching the given selector. So you never need to explicitly re-execute the function by JSF means.
$(document).on("change", ":input", function() {
console.log("From change event on any input: " + this.id);
});
The alternative way is to explicitly re-execute the function yourself on complete of ajax request. This would be the only way when you're actually interested in immediately execute the function during the ready/load event (e.g. to directly apply some plugin specific behavior/look'n'feel, such as date pickers). First, you need to refactor the $(document).ready() job into a reusable function as follows:
$(document).ready(function(){
applyChangeHandler();
});
function applyChangeHandler() {
$(":input").on("change", function() {
console.log("From applyChangeHandler: " + this.id);
});
}
(note that I removed and simplified your completely unnecessary $.each() approach)
Then, choose one of the following ways to re-execute it on complete of ajax request:
Use the oncomplete attribute of the PrimeFaces command button:
oncomplete="applyChangeHandler()"
Use <h:outputScript target="body"> instead of $(document).ready(),
<h:outputScript id="applyChangeHandler" target="body">
applyChangeHandler();
</h:outputScript>
and reference it in update attribute:
update=":applyChangeHandler"
Use <p:outputPanel autoUpdate="true"> to auto update it on every ajax request:
<p:outputPanel autoUpdate="true">
<h:outputScript id="applyChangeHandler">
applyChangeHandler();
</h:outputScript>
</p:outputPanel>
Use OmniFaces <o:onloadScript> instead of $(document).ready(), <h:outputScript> and all on em.
<o:onloadScript>applyChangeHandler();</o:onloadScript>

Control one iFrame from another iFrame

This works …
Link text
but this doesn't …
<script type="text/javascript">
window.onload = function() {
var a = document.getElementById("mylink");
a.onclick = function() {
parent.document.getElementById('frameName').src = 'page.html';
}
}
</script>
<a id="mylink" href="page.html">LINK</a>
Any idea why I can't get the element by id from one iFrame to another? Also I know very little code so I apologize in advance if its obvious.
First i would make sure that the security of the site within the IFrame allows you to do this kind of stuff. Check out this link:
Overcoming "Display forbidden by X-Frame-Options"
Next, i would worry about the target of your anchor tag. With specifying it will default to self. In your second piece of code the target will be _self. Thus, when you click the link your javascript will want to change the source of the IFrame while the link will want to change the entire page. I would pick either a JS or HTML implemetation of linking and not both. Here is something that i put together to show one way of changing the iFrame without an actual anchor tag.
<html>
<body>
<iframe id="frameName" src="page.html"></iframe>
<button onclick="changeFrame()">LINK</button>
<script>
function changeFrame() {
document.getElementById('frameName').src ='page2.html';
}
</script>
</body>
</html>

How to open a link like www.gmail.com from code?

I want to open an URL like gmail.com when a user clicks on a button. How can I open this link in new tab from code (I want to read link from database)?
You can use:
Response.Redirect
Method in ASP.NET to navigate to another web page.
call JavaScript from Page Behind Code Like this.
Page.ClientScript.RegisterStartupScript(this.GetType(),
"onLoad", "openNewWindow()", true);
<script language="JavaScript">
<!-- hide
function openNewWindow() {
popupWin = window.open('http://webdesign.about.com/',
'open_window',
'menubar, toolbar, location, directories, status, scrollbars, resizable, dependent, width=640, height=480, left=0, top=0')
}
// done hiding -->
</script>
you can also do it using window.location("http://www.yourpath.com")
As suggested before me use
Response.Redirect("http://www.gmail.com")
this should work as the method is designed also for absolute urls. Do not leave the http:// prefix.
<input type="button" onclick="openlink()"/>
<script>
function openlink()
{
document.location.href = "http://www.gmail.com";
}
</script>
just execute the below line on button click
window.location="http://www.google.com";

Cross-browser client-side redirection in a new tab or window

we need a kind of client-side redirection and the only options we have are:
window.location
window.open
HTTP 301, 302, 303 responses
window.location doesn't support opening the target location in a new tab or window. (I think this is related to browsing context)
window.open doesn't work in Chrome and seems to be dependent upon some client-side configurations made to the browser, which makes it a less favorable option, since we don't have control on it.
HTTP redirect response doesn't open a new tab or window, just like window.location.
Any idea?
After playing around with this for hours last night, I had a flash of inspiration this morning, and I have just tested this solution in FF3, Chrome, IE7 and IE8 - it's a bit hacky but it works in all.
<html>
<head>
<title>Redirect in a new window</title>
<script type="text/javascript">
function doIt () {
var form = document.createElement('form');
form.action = 'http://www.google.com/';
form.target = '_blank';
document.getElementById('hidden_div').appendChild(form);
form.submit();
}
</script>
<style>
#hidden_div {
display: none;
}
</style>
</head>
<body>
<div>
This is my page content<br />
This is a link to Google...<br />
...and this button will open Google in a new tab or window: <input type="button" value="Click Me!" onclick="doIt();" />
</div>
<div id="hidden_div"></div>
</body>
</html>
How It Works
You need a hidden <div> on your page somewhere that you can get a reference to in JS (no big deal - just create one with display: none).
When you want to do the redirect, use document.createElement() to create a new <form> element, assign it's action attribute with the address of the page where you want to take the user, and give it a target attribute as appropriate (I have used _blank in my example above). Then simply append it to your hidden <div> and call it's submit() method.
Hey presto, your redirect opens in a new window/tab!
Unfortunately you are still at the mercy of how the user configures their browser to handle target="_blank" but it will be either a new window or a new tab, and it should work everywhere...

asp.net mvc JavaScript in View User Controls rendered through regular browser request and AJAX request

I have this code in some of my ASCX files:
<%=Html.ActionLink(Resources.Localize.Routes_WidgetsEdit, "Edit", "Widget",
new { contentType = Model.ContentType, widgetSlug = Model.Slug, modal=true},
new
{
rel = "shadowbox;height=600;width=700",
title = Resources.Localize.Routes_WidgetsEdit,
#class = "editWidget"
})%>
Take note of that rel="shadowbox..." there. This is to wire up ShadowBox Lightbox clone for this ActionLink.
This works fine when user requests a page containing this User Control thru normal browser request. But I also render/build those View User controls trough AJAX requests. For instance, I would make request to /Widget/RenderToString/... using jQuery .ajax() method and it would return HTML code for that control. This works fine and it renders the code fine. I would then insert (append) the result to a DIV in a page from where the AJAX request was made. This also works fine and the returned HTML gets appended. The only problem is - ShadowBox is not wired up. Even though the code for it gets rendered.
It seems it requires page reload (F5) every time to wire ShadowBox up. Since I am doing AJAX GET and instant append to get rid of having to make a server roundtrip, I would also want ShadowBox to wire up without doing refresh.
Can someone help me with that? Thank you
UPDATE:
Yes, I have this in my Site.Master head:
<script src="<%=Url.Content("~/Scripts/shadowbox-build-3.0rc1/shadowbox.js") %>" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
// insert functions calls here that provide some default behaviour
externalLinks();
});
Shadowbox.init({
language: "en",
players: ["img", "html", "iframe"],
onClose: function() { location.reload(true) }
});
</script>
How do I init the Shadowbox again after AJAX call?
There are many shadowbox plugins... which one are you using? (I can't give you exact code without it.) In any case I imagine you have something in your $(document).ready(function () { ... }); that tells shadowbox plungin to bind itself. You need to call that again after the AJAX call.
Just found the solution here
// call this after adding the new HTML to the page
// set up all anchor elements with a "editWidget" class to work with Shadowbox
Shadowbox.setup("a.editWidget", {});

Resources