Ajax form updates in JSF shows ViewExpiredException - java

I have a jsf 1.2 application with some links in the index page. This links are oppened by clicks, on new jquery dialogs. Every link open a new page of my app in a distinct dialog, so, the application can open many links in many dialogs in a single page. All my managed beans have session scope.
My problem is, when i open a new dialog and click in any link inside, my application still works fine, but after this, if i click in other link in my index page to open another dialog, the app shows me a ViewExpiredException. I have tried update my jsf to 2.0, set EnableRestoreView11Compatibility in web.xml to true, use keepAlive in my beans, but nothing works.
I think its happened because i have a main page with one state and, when i click to open a new page in a jquery dialog, it loads the entire page and put the html inside. So, the request made no reference to the state of main page. How can i resolve this?

It seems like the bug in JSF which is not fixed yet , it is planned for fix in JSF 2.3
You can use the below workaround posted in java.net for the jquery.
http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790
var patchJSF = function () {
jsf.ajax.addOnEvent(function (e) {
if (e.status === 'success') {
$("partial-response:first changes:first update[id='javax.faces.ViewState']",
e.responseXML).each(function (i, u) {
// update all forms
$(document.forms).each(function (i, f) {
var field = $("input[name='javax.faces.ViewState']", f);
if (field.length == 0) {
field = $("<input type=\"hidden\" name=\"javax.faces.ViewState\" />").
appendTo(f);
}
field.val(u.firstChild.data);
});
});
}
});
}

Related

How to skip the back page in jsp after user has logged in? [duplicate]

How to disable browser's BACK Button (across browsers)?
Do not disable expected browser behaviour.
Make your pages handle the possibility of users going back a page or two; don't try to cripple their software.
I came up with a little hack that disables the back button using JavaScript. I checked it on chrome 10, firefox 3.6 and IE9:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<title>Untitled Page</title>
<script type = "text/javascript" >
function changeHashOnLoad() {
window.location.href += "#";
setTimeout("changeHashAgain()", "50");
}
function changeHashAgain() {
window.location.href += "1";
}
var storedHash = window.location.hash;
window.setInterval(function () {
if (window.location.hash != storedHash) {
window.location.hash = storedHash;
}
}, 50);
</script>
</head>
<body onload="changeHashOnLoad(); ">
Try to hit the back button!
</body>
</html>
What is it doing?
From Comments:
This script leverages the fact that browsers consider whatever comes after the "#" sign in the URL as part of the browsing history. What it does is this: When the page loads, "#1" is added to the URL. After 50ms the "1" is removed. When the user clicks "back", the browser changes the URL back to what it was before the "1" was removed, BUT - it's the same web page, so the browser doesn't need to reload the page. – Yossi Shasho
Others have taken the approach to say "don't do this" but that doesn't really answer the poster's question. Let's just assume that everyone knows this is a bad idea, but we are curious about how it's done anyway...
You cannot disable the back button on a user's browser, but you can make it so that your application breaks (displays an error message, requiring the user to start over) if the user goes back.
One approach I have seen for doing this is to pass a token on every URL within the application, and within every form. The token is regenerated on every page, and once the user loads a new page any tokens from previous pages are invalidated.
When the user loads a page, the page will only show if the correct token (which was given to all links/forms on the previous page) was passed to it.
The online banking application my bank provides is like this. If you use the back button at all, no more links will work and no more page reloads can be made - instead you see a notice telling you that you cannot go back, and you have to start over.
This question is very similar to this one...
You need to force the cache to expire for this to work. Place the following code on your page code behind.
Page.Response.Cache.SetCacheability(HttpCacheability.NoCache)
While i'm looking for the answer myself,
"Best Practice" is.... outdated... Just like browsers are.(Really browsers are ugly fossils)
The best/safest solution would be for browsers to implement a method/request where the user can grant the page the ability to control the interface.
Why? Because for my current project i'm building a 100% JavaScript built and controlled interface.. And back button's have no place in my project since there is no page change. (Ie bloody fast and no page-flashes because of a refresh.. Just like a real application!)
I know why the ability to "highjack" the interface isn't there, and i understand it. But atleast we should have the ability to request it from the browser! Now that would truly be "best practice" without the highjack dangers.
But browsers being browsers.. I don't expect anything exiting to happen in this regard.
I was searching for the same question and I found following code on a site. Thought to share it here:
function noBack()
{
window.history.forward()
}
noBack();
window.onload = noBack;
window.onpageshow = function(evt){ if(evt.persisted) noBack(); }
window.onunload = function(){ void(0); }
However as noted by above users, this is never a good practice and should be avoided for all reasons.
If you rely on client-side technology, it can be circumvented. Javascript may be disabled, for example. Or user might execute a JS script to work around your restrictions.
My guess is you can only do this by server-side tracking of the user session, and redirecting (as in Server.Transfer, not Response.Redirect) the user/browser to the required page.
<body onLoad="if(history.length>0)history.go(+1)">
There have been a few different implementations. There is a flash solution and some iframe/frame solutions for IE. Check out this
http://www.contentwithstyle.co.uk/content/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps
BTW: There are plenty of valid reasons to disable (or at least prevent 1 step) a back button -- look at gmail as an example which implements the hash solution discussed in the above article.
Google "how ajax broke the back button" and you'll find plenty of articles on user testing and the validity of disabling the back button.
I also had the same problem, use this Java script function on head tag or in , its 100% working fine, would not let you go back.
<script type = "text/javascript" >
function preventBack(){window.history.forward();}
setTimeout("preventBack()", 0);
window.onunload=function(){null};
</script>
Try this code. Worked for me. It basically changes the hash as soon as the page loads which changes recent history page by adding "1" on URL. So when you hit back button, it redirects to same page everytime.
<script type="text/javascript">
var storedHash = window.location.hash;
function changeHashOnLoad() { window.location.hash = "1";}
window.onhashchange = function () {
window.location.hash = storedHash;
}
</script>
<body onload="changeHashOnLoad(); ">
</bod>
You should be using posts with proper expires and caching headers.
Instead of trying to disable the browser back button it's better to support it.
.NET 3.5 can very well handle the browser back (and forward) buttons. Search with Google: "Scriptmanager EnableHistory".
You can control which user actions will add an entry to the browser's history (ScriptManager -> AddHistoryPoint) and your ASP.NET application receives an event whenever the user clicks the browser Back/Forward buttons.
This will work for all known browsers
Globally, disabling the back button is indeed bad practice. But, in certain situations, the back button functionality doesn't make sense.
Here's one way to prevent unwanted navigation between pages:
Top page (file top.php):
<?php
session_start();
$_SESSION[pid]++;
echo "top page $_SESSION[pid]";
echo "<BR><a href='secondary.php?pid=$_SESSION[pid]'>secondary page</a>";
?>
Secondary page (file secondary.php):
<?php
session_start();
if ($_SESSION[pid] != $_GET[pid])
header("location: top.php");
else {
echo "secondary page $_SESSION[pid]";
echo "<BR><a href='top.php'>top</a>";
}
?>
The effect is to allow navigating from the top page forward to the secondary page and back (e.g. Cancel) using your own links. But, after returning to the top page the browser back button is prevented from navigating to the secondary page.
Even I faced the same situation before...and didn't have any help.
try these things maybe these will work for you
in login page <head> tag:
<script type="text/javascript">
window.history.forward();
</script>
in Logout Button I did this:
protected void Btn_Logout_Click(object sender, EventArgs e)
{
connObj.Close();
Session.Abandon();
Session.RemoveAll();
Session.Clear();
HttpContext.Current.Session.Abandon();
}
and on login page I have put the focus on Username textbox like this:
protected void Page_Load(object sender, EventArgs e)
{
_txtUsername.Focus();
}
hope this helps...
:)
someone plz teach me how to edit this page...
IF you need to softly suppress the delete and backspace keys in your Web app, so that when they are editing / deleting items the page does not get redirected unexpectedly, you can use this code:
window.addEventListener('keydown', function(e) {
var key = e.keyCode || e.which;
if (key == 8 /*BACKSPACE*/ || key == 46/*DELETE*/) {
var len=window.location.href.length;
if(window.location.href[len-1]!='#') window.location.href += "#";
}
},false);
Try this code.
You just need to implement this code in master page and it will work for you on all the pages
<script type="text/javascript">
window.onload = function () {
noBack();
}
function noBack() {
window.history.forward();
}
</script>
<body onpageshow="if (event.persisted) noBack();">
</body>
The problem with Yossi Shasho's Code is that the page is scrolling to the top every 50 ms. So I have modified that code. Now its working fine on all modern browsers, IE8 and above
var storedHash = window.location.hash;
function changeHashOnLoad() {
window.location.href += "#";
setTimeout("changeHashAgain()", "50");
}
function changeHashAgain() {
window.location.href += "1";
}
function restoreHash() {
if (window.location.hash != storedHash) {
window.location.hash = storedHash;
}
}
if (window.addEventListener) {
window.addEventListener("hashchange", function () {
restoreHash();
}, false);
}
else if (window.attachEvent) {
window.attachEvent("onhashchange", function () {
restoreHash();
});
}
$(window).load(function () { changeHashOnLoad(); });
This seems to have worked for us.
history.pushState(null, null, $(location).attr('href'));
window.addEventListener('popstate', function () {
history.pushState(null, null, $(location).attr('href'));
});
<script>
$(document).ready(function() {
function disableBack() { window.history.forward() }
window.onload = disableBack();
window.onpageshow = function(evt) { if (evt.persisted) disableBack() }
});
</script>

displaying portlet in another portlet without popup

Is there any way in to display one portlet in an other portlet ?
Problem i am facing is that i have two portlets in Liferay,i want's to display the complete second portlet in the reserved div area of the first portlet,so that i can use all the functionality of second portlet in the first one(I don't want to use popup for this particular scenario). or in other words
i wants nested portlet
I have Google this but didn't find any helping material ,now my question is this scenario is possible in Liferay?
Any helping will be greatly appreciated.
Hi Use nested portlet.
Emded portlet example
or
use web content display portlet inside you can display portlet
or you can use Liferay Portlet Sharing java script code..
i have small following snippet it will render portlet in div but it wont peforn actions because its static content
the following is example snippet to load portlet in div
AUI().use('aui-base','aui-node','aui-dialog','aui-io-request', 'aui-io','liferay-portlet-url','aui-dialog-iframe', function(A) {
var url =Liferay.PortletURL.createRenderURL();
url.setPortletId('signinaction_WAR_WatsonSiginInportlet');
url.setWindowState('pop_up');
var myAjaxRequest=A.io.request(url.toString(), {
dataType: 'html',
autoLoad: false,
on: {
success: function() {
// A.one('#testestDiv').set('innerHTML',"meera");
document.getElementById("login-portlet-content").innerHTML=this.get('responseData');
//A.one('#loginBoxDiv').set('innerHTML',this.get('responseData'));
}
}
});
myAjaxRequest.start();
});

JavaScript only loads once per tab? (Multiple "pages" with tables in single page)

Alright, so I'm creating a script to avoid activating a link in a parent div. I've added an image of the website to give you an idea of what it looks like and to make it easier for me to explain. The white tabs are controlled by Ajax and all of them are loaded when the Orders/Subscriptions page is loaded.
All the rows in the table are clickable, and the blue cogwheel shows a dropdown when you hover over it. This dropdown contains several links that need the javascript/jquery code to not activate the row link instead. The problem is that when you switch tabs, the js code won't run unless you reload the page (the active tab stays when reloaded), but the users of the website shouldn't have to reload the page every time they switch between the tabs.
I have absolutely no idea why the .js file only works on the active tab. Everything is written in Wicket/Java using a lot of Ajax events for this page.
JavaScript:
$(document).ready( function () {
$('.dropdown-menu > li > a').on('click', function(event) {
event.stopPropagation();
alert('Propagination Stopped');
});
EDIT:
Alright, so I now know it works if I add
location.reload();
when the tabs are clicked, but I kinda want to avoid this since that adds unnecessary loading time.
I figured out what the problem was. Since I use Ajax for the tabs I had to add
$(document).ajaxComplete(function { myFunction });
and put the onClick in there. That way it would load properly every time I switched tabs.
The invisible tables in the inactive tabs had display: none; which mean when they are set to display: visible; it isn't part of the DOM. So the script won't run unless page is reloaded.
Don't like answering my own question, but felt like the info should be shared.
Thanks for the help anyways guys!
You haven't shown how your script elements are defined and added to the DOM, so it's hard to be specific.
Once a script element has been added to the DOM (directly, or via markup), it is run once. If you want any functions defined by that script to be run again, you have to run them. So in your tab-switching code, add code to call a function if you want it to be run for that tab.
You also haven't shown how you're loading the tab content, or whether the tab content defines script tags. It's best not to have the tab content contain any more script than necessary. Instead, have a main script file loaded with the page that defines the main functions, and then at most have a single script in the dynamically-loaded tab content that executes a single function call to that already-loaded code. If you're loading via jQuery's load, it'll call the scripts for you unless you use a fragment identifier with load. (If you use a fragment identifier with load, it disregards scripts in the content entirely.)
I think this will help you!
the html code example
<ul id="ajaxContainer">
<li>the default content in your app</li>
</ul>
<nav id="pagination">
<ul>
<li><a class="active" href="/ajaxpath1">1</a></li>
<li>2</li>
<li>2</li>
</ul>
</nav>
<script src="jquerypath/jquery.js"></script>
<script src="appjspath/app.js"></script>
Code in your app.js as bellow
$(function() {
var $ajaxContainer = $('#ajaxContainer'),
CLSA = "active",
DOT = ".",
$pagination = $('#pagination'),
hasElMakeShow = function($el) {
//just make elment show hide
$el.show().siblings().hide();
},
appendNewEl = function($el) {
//new data requested should be append to container element
$ajaxContainer.append($el);
hasElMakeShow($el);
},
initBindEl = function(){
//init bind first active pagination el with its data elment
var $li = $ajaxContainer.find('>li'),
$active = $pagination.find(DOT + CLSA);
$active.data('el', $li);
},
switchNavA = function($el) {
//do some pagination switch active class work
$el.addClass(CLSA).closest('li').siblings().removeClass(CLSA);
};
initBindEl();//first bind current pagination
$pagination.delegate('>li a', 'click.page', function(e){
e.preventDefault();//prevent default jump
var $me = $(this),
isActive = $me.is(DOT + CLSA),
$targetEl = $me.data('el');
if(!isActive) {
if($targetEl.length) {
hasElMakeShow($targetEl);
} else {
var url = $me.attr('href');
$.get(url, function(data){
var $respondEl = $(data);
$me.data('el', $respondEl);
appendNewEl($respondEl);
switchNavA($me);
});
}
}
});
});

show and hide a portlet when clicking on a link inside another portlet

I have three portlets for example: portletA, portletB and portletC.
portletA displays on left side and it has two links linkB and linkC.
If I click on linkB then portletB should be displayed on right side and If I click on linkC then portletB must become hidden and portletC should be displayed.
Please, tell me how I can do this using ICEfaces.
I used this code to hide the portlet but after refreshing the page again portlet is visible can you suggest what I can do so that after refreshing portlet should not visible?
function fun(E)
{
if(E=="Entry")
{
alert("hi");
document.getElementById("p_p_id_ipc_WAR_IPC2portlet_").style.display='none';
document.getElementById("p_p_id_ipc1_WAR_IPC2portlet_").style.display = '';
}
else
{
alert("else");
}
}
</script>
You can do it with simple javascript and css. What you have to do is see what portlet B and C portlet id's are and than using javascript you can alter css "display" property on the portlet boundary div.
Using simple javascript
var p = document.getElementById("p_p_id_YOUR-PORTLET-ID_");
if (p) {
if (p.style.display == "none") {
p.style.display = "block";
} else {
p.style.display = "none";
}
}
Using jQuery
jQuery("p_p_id_YOUR-PORTLET-ID_").show();
//or
jQuery("p_p_id_YOUR-PORTLET-ID_").hide();
Examples are for showing/hiding single portlet. In your case link B should hide C and show B, and link C other way around.
Also take a look at Client-side Inter-Portlet Communication

How to redirect to the same view using ModelAndview in Spring MVC framework

I have a page with a link. On clicking the link a page opens up in a separate window. This new page has a form. On submitting this form, some operation takes place at the server. The result of which needs to be redirected to the same page. However after the operation on using the following:
return new ModelAndView("newUser");
//This view "newUser" actually maps to the popped up window.
A similar new window again pops up and the message gets displayed on this new page.
Any ideas as to why this behavior or how to go about this?
If you open a popup window with a form in it, any submits from here to the server will be handled in the same location, so you will get your response (and any subsequent request-responses) in that popup window.
If I understand this right, you have a page X which opens the popup, you submit in the popup and as a result you want again the content of page X, but in the popup?
If that is the case I thing the behavior is not from Spring but from what you have in the X page. Maybe a JavaScript which gets triggered on load and opens a new popup? Can't really tell without seeing more code.

Categories

Resources