jsf validation before js and js before bean action - javascript

JSF / PrimeFaces 3.5
I need when clicking on p:commandButton to check the validation first of all (input text required=true)
if validationFail == false then
Call the popup dialog from js :
else
show requiredMessage from inputText (this field is mandatory...)
I have tried with oncomplete but it calls my bean and after the js popup dialog. I dont want it.
I need in this order : click p:button -> check validation -> if not fails -> show primefaces dialog.
if fails after validation-> render message
My xhtml :
<p:commandButton id="btnSalvar"
value="abc"
action="#{notaFiscalManagedBean.salvar}"
oncomplete="if (args.validationFailed) return true; else return showPF_DiagBox()"
in my showPF dialog I call bean method. if OK clicked by user.

It is better to user RequestContext of primefaces which allows user to execute javascript which is set from managed bean. You can use it by modifying your method at #{notaFiscalManagedBean.salvar} as shown below.
public String salvar(){
boolean valid=true;
//Do your validation here
if(valid){
RequestContext.getCurrentInstance().execute("showPF_DiagBox()");
}
}
If you want to do the validation on client side before submitting the request to the server then just do the following change in your code,
<p:commandButton id="btnSalvar"
value="abc"
action="#{notaFiscalManagedBean.salvar}"
onclick="if(validationFailed()){return false}"
oncomplete="showPF_DiagBox()"/>
Also write down a javascript function to do validations
function validationFailed(){
//Check various conditions based on component validations and return whether validatoin failed or not
}

Try this:
<p:commandButton id="btnSalvar"
value="abc"
action="#{notaFiscalManagedBean.salvar}"
update="#form"
render="#form"/>
By adding 'render' and 'update' attributed your form will have to reload, and then process all the validations inside of it's form.
Hope this can help you, good luck!

In my oncomplete commandButton I got what I wanted getting from #BalusC answer (How to find indication of a Validation error (required="true") while doing ajax command) and #Tuukka Mustonen (JSF 2.0 AJAX: Call a bean method from javascript with jsf.ajax.request (or some other way)) and making some adjustments to fit my needs.
This way, if there are any validation errors or any converters do be validated, they are rendered at screen first of all. If there are not validation errors so I execute my js function and inside it I fire my bean method if needed.
thanks for everybody ! :)

Related

Disable a button without changing its appearance

I implemented a dynamic enable/disable function in a page thanks to a javascript function calling a backing java bean method that sets to true/false a boolean, which is then used to disable (or not) a primefaces commandLink button.
Everything works fine, but I wanted to know if instead of changing the appearance of the button when is it disabled, I could keep the regular appearance (and even better, printing an alert message when trying to click it without having to render another web element).
Here are the simplified pieces of code:
Javascript function:
function enableSubmit(){
jQuery(element).click(function(){
if (condition){
rc_enable();
} else {
rc_disable();
}
});
}
And the primefaces commandButton together with the remoteCommands:
<p:remoteCommand name="rc_disable" update="submitButton" actionListener="#{mappenBean.setDisabled}" />
<p:remoteCommand name="rc_enable" update="submitButton" actionListener="#{mappenBean.setEnabled}" />
<h:commandLink id="submitButton" action="#{mappenBean.updateFund}" styleClass="FormButton" rendered="#{!sitzungBean.gedruckt}" disabled="#{!mappenBean.enabled}">
...[action listeners etc.]
<h:outputText value="Eingaben übernehmen" />
</h:commandLink>
The java bean functions simply set the boolean to true or false.
It seems that I cannot implement a javascript click() function to display an alert if the disabled button is clicked, because once disabled it is not recognized anymore.
The primefaces version is 2.2.1 (i know...) and JSF is 2.1
Any help will be welcome, thanks a lot!
you can add css class to the button to be disabled and disable mouse events
.disabled-button{
pointer-events: none;
}
it wont change the appearance but it will do the trick
You can put a validate function (client side) to check if the condition is true/false and then show the message or submit the action.
First remove the disabled="#{!mappenBean.enabled}"
The button will be always enable. But it will not be submitted if the condition is false.
Add an onclick="return validate();" to your commandLink
Create a javascript function and a dialog for the message.
<script type= "text/javascript">
function validate(){
if(condition){
dialogMessage.show(); // or an alert
return true;
}else{
return false;
}
</script>
Your xhtml will be something like this:
<h:commandLink id="submitButton" action="#{mappenBean.updateFund}" styleClass="FormButton" rendered="#{!sitzungBean.gedruckt}" onclick="return validate();" >
...[action listeners etc.]
<h:outputText value="Eingaben übernehmen" />
</h:commandLink>
I finally managed to do so by adding a click handler on the commandLink with the following code:
onclick="if(#{!mappenBean.enabled}) {alert('test'); return false;}"
However, as Kukeltje pointed out:
But keep in mind that this is a fake and insecure way of disabling. People with a browser developer tool can easily circumvent this. There is a very good and valid reason JSF does all this serverside (never trust the client). It might better be done the other way around. Disable it server side and via css 'enable' it visually and clickable client side!!!
I will keep it running that way for now as it was urgent and I will try and implement the right way of doing it.
Thanks a lot to everyone for your help!

How do I pass in postback argument from JS to VB?

I am trying to pass in an image from an image editor to a function in VB. I have it setup as the following:
JS
var canvas = document.getElementById("canvas_minipaint");
var img = canvas.toDataURL("image/jpeg");
__doPostBack('SaveImage', img);
ASPX
<asp:LinkButton ID="SaveImage" runat="server" Visible="true"></asp:LinkButton>
VB
Private Sub SaveImage_Click(sender As Object, e As EventArgs) Handles SaveImage.Click
Call GetSession()
End Sub
When I click the SaveImage button right now i get the following error:
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
How do I register the onClick for the button for the validator? Or am I missing something else?
Turn off event validation for this page. You can turn it off at page level by adding
Page EnableEventValidation="false"
to the top of your .aspx page. I would recommend doing that in this case, since you are doing a manual postback using JavaScript. It is not possible to turn it off for individual controls.
EDIT:
You could always store the value of the image in a hidden field, and that would prevent the need to disable event validation. You'd need a way of storing the image data (base64 string maybe?) in the field, but it would work.
I would suggest not disabling the EventValidation to avoid malicious users to mess with the form. You could store the data in an input hidden or override the page event and handle it.
protected override void RaisePostBackEvent(IPostBackEventHandler sourceControl, string eventArgument)
{
if (sourceControl is yourControl)
{
//sanitize data
}
}

Oncomplete JavaScript does not re-evaluate EL expression at time of execution

I have a Primefaces dialog that contains a 'Save' button with the following oncomplete rules:
<p:dialog id="dialogId" widgetVar="dialogWidget">
...
<p:commandButton value="Save" async="true"
oncomplete="if (!args.validationFailed && #{xp:hasNoMessagesToDisplay(dialogId)}) dialogWidget.hide()"
partialSubmit="true" process="dialog"/>
</p:dialog>
#{xp:hasNoMessagesToDisplay} is a custom EL function that checks to see if there are any FacesMessages associated for the dialogId specified. The problem is that the evaluation of this function only takes place when HTML is rendered for the dialog (e.g. on initial page load). I need the function to be evaluated when the oncomplete Javascript is evaluted (i.e. on the fly).
Is it possible to extend the Primefaces "args" Javascript object to include additional info, or what are alternative approaches?
Got an idea from this post which gave me a solution:
Use FacesContext.getCurrentInstance().validationFailed(); when the FacesMessages for the dialog are created to indicate JSF validation failure so
oncomplete="if (!args.validationFailed) dialogwidget.hide()"
is sufficient. I'm not sure what implications this has, guess I'll just have to wait and see....

Attaching a callback to html generated by JSF - Primefaces

I've got a Primefaces command button that I need to add a callback to in jQuery on document.ready. Basically what I've been trying to do is get a reference to the existing function and then call it in a new function that I wrote:
var existingFunction = jQuery("[id~='submit']").live("click");
jQuery("[id~='submit']").live("click", function(){
existingFunction();
alert('test');
updateControlPanel(buildControlPanelUrl(getUrlVars()));
});
It seems simple enough to me but for some reason this will not work. When I load the page and click the submit button it doesn't even reach the alert.
I've checked the error console and found that it's throwing the following errors:
((f.event.special[s.origType] || {}).handle || s.handler).apply is not a function
There is existing jQuery functions on the page that I did not write but I'd like to make sure this error is not related to the way I'm approaching this.
I'm using tomcat 6 with an older version of JQuery (1.3 or 1.4 ).
Thanks and let me know if you guys need any more info.
Edit
I've put up an example of what I'm trying to do on JS Fiddle: http://jsfiddle.net/anSXH/2/
Here is some further clarification:
I've built the button as a project in JSF 2.0 (MyFaces) using the latest Primefaces component library. I've then taken that button and embedded it into an existing web page. The button submits the form and then calls a JavaScript function to show the result on the page after an ajax request is complete. This all works when I embed the button onto the page but I now need to update something on the client side after the button calls the function. That's why I'm looking at adding a callback to the existing onclick function.
As a side note, because I'm using Primefaces I can attach a JavaScript function to run after the ajax request is complete. My plan B is to try and access this function and somehow override it.
Edit part 2
Here is the generated control from primefaces:
<button
id="topsaveform:submittop"
name="topsaveform:submittop"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
onclick="PrimeFaces.ab({source:'topsaveform:submittop',process:'topsaveform OEIMeasurementsTable',update:'errorMessages submittedPopup',onstart:function(cfg){jQuery('#loadingBar').show('fast');;},oncomplete:function(xhr,status,args){postSubmit();;}});return false;"
type="submit">
<span class="ui-button-text">Save</span>
</button>
Did you try making the original function die (ref)?
jQuery("[id~='submit']").die("click");
jQuery("[id~='submit']").live("click", function(){
alert('test');
updateControlPanel(buildControlPanelUrl(getUrlVars()));
});
The problem was that I was trying to do this with a primefaces button. When I switched to a standard JSF button I was able to affix the function to it no problem.

javascript confirm asp.net button never submits?

i have a regular asp:button. I am working in .Net 3.5. I've tried adding a js confirm to the button with the OnClientClick attribute as well as adding in code-behind and the result is the same. No matter what the user clicks in the confirm pop-up the form will not submit??
BtnDeleteSelected.Attributes.Add("onclick", "return confirm('Are you sure you want to delete?');");
The confirm dialog appears and if i select "OK" it still does not submit.. Any ideas? thanks.
That's because you should not be returning in all cases. If you view the source of the page and look for the button markup, you are likely to see this...
onclick="return confirm('Ok?'); __doPostback();"
The __doPostback invocation is inserted automatically by the ASP.NET framework in some cases. Since you return immediately regardless of the result of confirm, the postback never fires. The ultimate solution would be to not to set the onclick attribute, but instead use an unobtrusive approach. However, if there is pressing reason to control this on the server-side via onclick, you can use a simple if statement and only return when they press "Cancel"...
string js = "if(!confirm('Are you sure you want to delete?')) return false;";
BtnDeleteSelected.Attributes.Add("onclick", js);
I had this problem too. I was using adding the client side javascript in the OnItemCreated code of a datagrid like this:
myTableCell = e.Item.Cells(iDeleteColumnNumber) 'Delete Button Column
myDeleteButton = myTableCell.Controls(1)
If myDeleteButton.UniqueID = "lbtnDelete" Then
myDeleteButton.Attributes.Add("onclick", "if(!confirm('OK to Delete?'))return false;")
End If
For some reason that didn't work. I then moved the JavaScript to the <asp:linkbutton> in the design view like this:
<asp:LinkButton id="lbtnDelete" runat="server" CssClass="link-text" Text="<img border=0 src=../images/icons/icon-delete.gif alt=Delete>"
CommandName="Delete" CausesValidation="false" OnClientClick="if(!confirm('OK to Delete?'))return false;"></asp:LinkButton>
And that worked for me.
Do you have to return TRUE if validation passes? Meaning, if confirm() returns false I don't think the form will submit.
Your code looks OK on the surface. Do you have any validators that might be preventing it being submitted? Try adding BtnDeleteSelected.CausesValidation = false to prevent the delete button calling any client-side validators.
Please try calling doPostBack function ;)
I mean:
BtnDeleteSelected.Attributes.Add("onclick", "CheckConfirm();");
<script language="javascript">
function CheckConfirm()
{
if ( confirm('Are you sure you want to delete?') )
__doPostBack('BtnDeleteSelected','');
else
return false;
return true;
}
</script>
Hope that helps,

Categories