Avoid multiple form submission - jsf-2

In JSF2, is there any way to handle the multiple form submit (user clicks submit button multiple times)? Now we are getting the below exception in server
java.lang.IllegalStateException: Response already committed
java.lang.IllegalStateException: Response already committed
javax.faces.FacesException: socket write error: Connection aborted by peer

That depends on how you're submitting the form. If you're using <f:ajax> or any other Ajax based tag to perform the submit by Ajax, then your best bet is to use jsf.ajax.addOnEvent() to add a function which disables the button when the Ajax request is about to be sent and re-enables it after the Ajax response is retrieved.
E.g. as follows, which you include after the JSF Ajax scripts are included, e.g. inside a <script> or <h:outputScript> referring a .js file in <h:head>.
jsf.ajax.addOnEvent(function(data) {
if (data.source.type != "submit") {
return; // Ignore anything else than input type="submit".
}
switch (data.status) {
case "begin":
data.source.disabled = true; // Disable input type="submit".
break;
case "complete":
data.source.disabled = false; // Re-enable input type="submit".
break;
}
});
If you're not using Ajax to perform the submit, then one of the ways is to throw in a setTimeout() function in onclick which disables the button a few ms after click.
Basically,
<h:commandButton
id="foo"
value="submit"
action="#{bean.submit}"
onclick="setTimeout('document.getElementById(\'' + this.id + '\').disabled=true;', 50);"
/>
The setTimeout() is mandatory, because when you disable it immediately, then the name=value pair of the button won't be sent along with the request which would cause JSF to be unable to identify the action to be executed. You can of course refactor it to some DOM ready or window onload function which applies this for all submit buttons (jQuery would be tremendously helpful in this).

You can add a disabled button on the page which does nothing and show it when the submit button is clicked.
<div id="disabled" style="display:none;">
<span class="disabled-button"/>
</div>
<div id="enabled" style="display:block;">
<span class="enabled-button">
<h:commandLink id="submit"/>
</span>
</div>
$('#submit').live("click", function() {
$('#enabled').hide();
$('#disabled').show();
});

Related

how to display pop up on another page on success of post method in mobile jquery?

i am working on a project which is based on jquery Mobile. i am a biggner in this field, so sorry for the silly question. the question is -- i have a page 'Page1' and i am using post method to fetch data from database. On success i am showing a notification to user through a notification dialog(without cancel and ok button). now what i want this success message on another page "page2", and the message should be there up to 2 sec and then disappear automatically. i have tried
function sendAddGuest(data, dialog) {
$.post("/GuestsList/AddGuest", data, function (response) { //using the post method
//alert(JSON.stringify(response));
$('.error').html("");
hideLoading();
if (response.result == 'success') { //if the process done
$.mobile.changePage('/GuestsList/Index', { dataUrl: "/GuestsList/Index", reloadPage: false, changeHash: true }); //To another page "page2"
// window.setTimeout('showToastMessage("Guest added successfully with window");',2000); //i have tried this
setTimeout(function () { showToastMessage("Guest added successfully test2"); }, 100); //and this also i want to show this message on other page "page2"
}
}
I am also beginning with Jquery Mobile, based in the toy project I am working with I would suggest the following:
Use popup from jquerymobile instead of showToast, then you could call
the .close() of the element in the settimeout function.
This is the div you create for your popup (you put it in the page 2):
<div data-role="popup" id="myPopup" class="ui-content" data-theme="e">
<p>Guest added successfully</p>
</div>
This is how you could call the function to open once in the new page (use the pageload event):
$('#myPopup').popup('open');
This is how you could call the function to close (in the same pageload event):
window.setTimeout(function(){ $('#myPopup').popup('close'); }, 2000)
Sorry I have no time to code a complete example, but I think this is the way to go.
Hope this helps!:-)

how to submit a php/html form loaded into a dialod using .load()

Am trying to understand jquery. Am a bit slow, maybe cause I come from a COBOL background.
I learn as i do, instead of just reading. php, jquery are all just hobbies for me
I used to have these update form pages. I wanted to try and put them in dialogs.
I trying using Dialog with an I frame, I did not like it, The iframes were very slow to load, of of the pages being loaded contained jquery tabs, which where even slower to load. And several other problems.
So I trying moving away from iframes. I stripped the pages and kept the meat(the body of my php/html file)(minus the body tag), So now I load a short version of my Form onto the dialog, It loads beautifully and looks good.
So next I wanna submit my for data, this is where I am a bit lost....
I am guesting I have to use Ajax, but on returning from Ajax with a OK/Fail message I am lost again.
My submit buttons were not jquery dialog buttons, Must they be so?
Must I use buttons:
{
"Save" : function () {
.....
"Close" : function () {
$(this).dialog("close");
.....
}
These are ugly and I have less control on where to place them and how the look.
All you need to do is make sure you have a form in your dialog box.
The, add a listener on your form. Let's say you have
<form id="myForm">
<input id="myInput" name="myName" type="text" />
</form>
Then you would add a listener :
$("#myForm").die().live('submit',function(e) {
e.preventDefault();
$.ajax({
type : POST,
url : localhost:8080/myUrl,
dataType : 'json',
cache: false,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
data : $("#myForm").serialize(),
success : function(){ //do what you want here, like displaying validation errors...},
error:function (xhr, ajaxOptions, thrownError){ //manage ajax errors}
});
return false;
});
So your Save button is just a plain input type="submit"
Have fun !

Can you pick a browser target server-side?

I have a form that lets users select checks, and when submitted, creates a PDF, which opens in a new browser tab. It doesn't have any branding, and will probably open in a plugin anyway, so I don't want it taking over my site's tab. So I set the form's target to _blank.
But it's possible for the user to submit the form without enough information to create the PDF, in which case I flag the error (server-side) and re-render the form. But because I set the form's target, this re-render opens in a new tab as well, and that's not what I want - in this case, I want it to behave as if target were _top.
So the question is: Can I change the browser's rendering target server-side?
Yes, I know that this can be done with client-side JavaScript, but JS annoys me, and I have to do the validation server-side anyway. I may end up having to use it, but please don't suggest it as an answer - I'm more curious if what I'm attempting can even be done.
PS: I'm on Ruby on Rails 2.3.8, in case anyone knows a framework-specific solution.
A workaround on this problem would be to use the content-disposition header on the pdf, in order to force the file to be downloaded, and avoid the whole "target" approach..
Content-type: application/pdf
Content-Disposition: attachment; filename="downloaded.pdf"
No. This is a purely client-specific feature. As a matter of fact, it's quite possible to get a browser that supports only one window and where the target attribute would have simply no effect. There were even efforts to make this attribute disappear from future HTML standards completely (for instance, the XHTML branch had no such attribute).
The only overlap that I can think of between HTML and HTTP are the <meta http-equiv> tags (where HTML can affect otherwise HTTP-controlled behavior). HTTP is a transfer protocol, designed to work with about just any kind of data. Letting it control presentation would be a pretty terrible mix of concerns.
Fortunately, we live in a JavaScript-enabled world. It is rather easy to validate a form using an AJAX request, especially with libraries like jQuery.
For instance, this script performs a POST request to an URL (in this case, /pdf/validate) and expects the page to send back "ok" (if everything's good) or something else if there was an error.
<form method="post" action="/pdf/send" id="pdf-form">
<!-- form stuff here -->
</form>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
// set to true if we are to bypass the check
// this will happen once we've confirmed the parameters are okay
var programmaticSubmit = false;
// attach an event handler for when the form is submitted
// this allows us to perform our own checks beforehand; we'll do so by
// cancelling the event the user triggered, and do the submit ourselves if
// we detect no error
$('#pdf-form').submit(function(event)
{
if (!programmaticSubmit)
{
// first off, cancel the event
event.preventDefault();
// do an AJAX request to /pdf/validate
$.ajax("/pdf/validate", {
type: "POST",
data: $(this).serialize(), // send the form data as POST data
success: function(result)
{
// this gets called if the HTTP request did not end
// abnormally (i.e. no 4xx or 5xx status);
// you may also want to specify an "error" function to
// handle such cases
if (result == "ok")
{
// since the server says the data is okay, we trigger
// the event again by ourselves, but bypassing the
// checks this time
programmaticSubmit = true;
$(this).submit();
}
else // something went wrong! somehow display the error
alert(result);
}
});
}
});
});
</script>

jQuery UI dialog form, not sending correct variable

I'm loading a customer info page using jQuery. There's a list of customers with a link next to it:
View
That triggers this function:
function load_customer(id) {
$("#dashboard").load('get_info/' + id);
}
That works perfectly. On the page I'm loading, I have a jQuery UI modal dialog form for adding new information.
<div id="addinfo">
<form><input type="hidden" name="customer_id" value="<?php echo $c->id; ?>" /></form>
</div>
My javascript:
$("#addinfobutton").click(function(){
$("#addinfo").dialog("open");
return false;
});
$("#addinfo").dialog({
autoOpen:false,
width:400,
height:550,
modal: true
});
When you select a customer the first time, it populates the hidden field correctly, but then it stays the same even after selecting other customers.
I thought that by loading a new customer page, the form would reset as well... but apparently it's being stored/cached somewhere. If I echo the ID anywhere else in the page, it shows correctly... just not in the "addinfo" div.
Any help/suggestions would be appreciated! Thanks!
JQuery dialog's dont reload the content for you when you open them. I tend to have an AJAX call replacing the content of the div that the dialog is on (or tweakng some values in it) when the dialog is opened.
If you want a hidden field, then I wouldn't put it within the dialog, you should be able to retrieve the value from outside the dialog.
After some more researching, it seems the dialog is being cached client-side after it's called. So to get around that, I just added the customerId to the end of the popup div's ID name... so each customer page will have a unique dialog ID.
However, if it's caching each of those dialogs, won't there be a performance loss if you open quite a few? How can you clear them without having to do a full page refresh?
I guess if the #addinfo div is updated it should capture the new content...anyway this would destroy the dialog after closing it to insure a new instance will be created:
$("#addinfobutton").click(function(){
openDialog('#addinfo');
return false;
});
function openDialog(elm) {
$(elm).dialog({
autoOpen:true,
width:400,
height:550,
modal: true,
close: function() {
$(this).dialog('destroy');
}
});
}

Running a js function after ajax call puts incoming data to an element

I have an ajax link in my application:
<head>
<script type="text/javascript">function GoFurther() { ... }</script>
</head>
...
<%= Ajax.ActionLink("Go", "SomeAction", "SomeController", new AjaxOptions() { UpdateTargetId = "someDiv" }) %>
<div id="someDiv"></div>
I want to execute GoFurther() after ajax request completes AND someDiv is filled with its content so that it can bind some events on some buttons that've come from server. OnCompleted and OnSuccess seem to work after the ajax answer is received but before someDiv is filled. So they do not work for me.
To be clear, some div will be filled with some content after ajax call:
<someDiv><input type="button" value="Click" class="someButton" /></someDiv>
GoFurther makes some bindings using $(".someButton").click(...); so it must run once someDiv is completely filled. How can I make sure it runs after someDiv is filled?
OnSuccess is supposed to run after the DOM element has been updated [according to the source code for the Mvc Ajax Helpers - see OnComplete method]. Is there a particular problem that is occurring when you use OnSuccess?

Resources