Portlet.js Fail Query - liferay

When user tries to navigate away to another portal page before current page has finished loading, error message saying - There was unexpected error. Please refresh the current page comes up for the portlets which were loading before the redirection happened.
On debugging, it was found that it comes up from portlet.js and its failed() handler from Ajax call.
Can we restrict it for a specific portlet?
Thanks

As per my observation, failure method has three arguments - event, id, obj.
In some other parts of this JS file (portlet.js), event.portletId is used to fetch portlet ID. Its worth to give a try if you can fetch your portlet ID inside failure method.
Then you can apply condition on portlet ID of your choice to display the message or not.
if (event.portletId == '<your-portlet-instance-id>') {
placeHolder.placeAfter('<div class="portlet-msg-error">' +
Liferay.Language.get('there-was-an-unexpected-error.-please-refresh-the-current-page')
+ '</div>');
}

Related

How To Know When A CS Cart Hook Fires?

I need to confirm if I have selected the right hook from the hooks database. I need to auto order a vehicle on confirming an order. I chose the change_order_status and registered it in my init.php using
fn_register_hooks(
'change_order_status'
);
now in my func.php I have
if (!defined('AREA')) {die('Access denied');}
function fn_dellyman_change_order_status(&$status_to,&$status_from,&$order_info,&$force_notification,&$order_statuses,&$place_order) {
//Getting authentication data to identify user
$auth = $_SESSION['auth'];
var_dump($auth);
}
when I go to orders and switch the order from say open to complete, I expect to see the contents of auth rendered to the page at least as part of the request response. However I see no indication that the hook selected is the right one. How can i ensure the hook called is correct.
depending on your CS-Cart version since 4.6.x is Tygh::$app['session']['auth'] but also depend if is done by AJAX request or normal place/edit order
On AJAX request you will not get any notification.
please try to use for a nicer notification:
fn_print_r(Tygh::$app['session']['auth']);
Use
fn_set_notification('W','Description', var_export($varialble,true) );
this gives a notificcation after the hook fires and I found it very useful for my dev purposes.
The W can also be I and E for information and Error. Basically all it does is change the style of the popup

context.redirectToPage & $$PreviousPage

i have a button that is calling an agent , and i would like to return to the calling page as the last line of the button.
Is there a way to use context.redirectToPage() in conjunction with "$$PreviousPage" instead of capturing the previous page via a before page load scope variable?
Thanks !
If you just want to 'stay on page' use a partial refresh and eventually the standby control. If you want to get to the previous page you can chain simple actions. Action 1 would be 'run code' action 2 the redirect.
You might want to check your response time. Converting your agent to a Java class will most likely give you better response times

XPages: execute context.redirectToPage after client side function?

Why does context.redirectToPage behave differently when executed in a view root-event instead of an event handler?
This question came up when I tried to set the language of an xpages application to the language saved in the user profile, once the user is logged in. I use a properties-file with translated strings in a resource bundle, and retrieve the strings like this:
<xp:text value="${langString['WELCOME_TEXT']}" />
When the language is changed and so a different properties-file is loaded, the page needs to be refreshed in order to update those strings. This worked fine when I added a full-refresh event handler to the login button, that executed a server side context.redirectToPage(). No luck with client side refreshes like location.reload or window.location.href=window.location.href (the login-function itself is a client side function though).
But of course the user expects that he is also logged in when he presses the enter key instead of the button after he has entered his credentials. So I added an onkeypress-event to the username and password input fields, and checked for the enter key (if (thisEvent.keyCode==13) dosomething...) before executing the login function.
But now the event handler is called every time a key is pressed and of course I do not want the context.redirectToPage to be executed all the time.
Thus I removed the server side event handlers and changed the login function so that it terminated with a partial refresh of the div containing the whole page:
var p = {"execLogin":"true"}; XSP.partialRefreshPost( '#{id:wholePage}', {params: p} );
The parameter sent via the partial refresh now triggers an event in which our context.redirectToPage is executed:
<xp:this.beforeRenderResponse><![CDATA[#{javascript:if (param.containsKey('execLogin') && param.get('execLogin').toString().equals('true')) {
print("test");
context.redirectToPage(context.getUrl().toSiteRelativeString(context),true);
}}]]></xp:this.beforeRenderResponse>
The page is refreshed and "test" is printed out, but I still see the old language strings. I have to refresh the page manually again to make the new user language take effect.
Any idea how to execute a genuine full refresh this way, or maybe another way to update the strings retrieved from the property bundle?
Thanks in advance. Regards,
Sarah
EDIT
I now have:
<xp:inputText id="cc_login_panel_login_username" styleClass="span2">
<xp:eventHandler event="onkeypress" submit="true" refreshMode="complete">
<xp:this.script><![CDATA[if (thisEvent.keyCode!=13) {
return false;
} else {
doLogin();
return true;
}]]></xp:this.script>
<xp:this.action><![CDATA[#{javascript:context.redirectToPage(context.getUrl().toSiteRelativeString(context));}]]></xp:this.action>
</xp:eventHandler>
Because context.reloadPage() didn't even log me in somehow (strange) I got back to using redirectToPage. The server side event is fired once and at the right time *thumbs up*, but the language properties-bevaviour is still the same.
$ is only set on page load, whereas # is set each time during the partial refresh.
I don't think a partial refresh will work at all though. This will refresh the computed field. However, it will need a full refresh to refresh the part of the XPage that includes the properties file. In other words, you would be refreshing the computed field, but using the same properties file.
I wonder if context.redirectToPage or context.reloadPage is somehow going to the same page but with the cached properties files.
If you're always wanting to come back to the same page, a full refresh instead of partial refresh may be the best option.
I think this has something to do with using the $ parameter. this tells the runtime to retrieve the language file the first time the current page is created in the back-end. When a user does a refresh it is actualy retrieving a saved version of the page you are viewing.
I see you're calling "context.redirectToPage(context.getURL().toSiteRelativeString(context)))" within an xp:this.action tag for the xp:eventHandler.
Try using xp:this.onComplete in place of xp:this.action.
According to the Designer tooltip for the action, the expected return is a string to be passed to the navigation handler. So instead giving the onComplete will execute the redirect command when it's done with the eventHandler group of events.
Thanks for all the helpful answers, in fact all of them did work, the problem turned out to be my misunderstanding of when the properties-file is loaded. It is loaded in an early phase, long before my new language is set to the sessionScope (that sessionScope variable is then used as a part of the name of the properties-file to be loaded, via the VariableResolver).
Now I use a double full refresh to load the new file. When the login function terminates successfully, it executes:
window.location.href = window.location.href + "?doRefresh=true";
And to the view root element I added the following event:
<xp:this.beforeRenderResponse><![CDATA[#{javascript:
if (context.getUrlParameter("doRefresh")!=null&&context.getUrlParameter("doRefresh").equals("true")) {
var url = context.getUrl().toSiteRelativeString(context);
url = url.replace("?doRefresh=true","");
context.redirectToPage(url);}
}]]></xp:this.beforeRenderResponse>
This is not a very sophisticated solution, but at least it works :-)

Xpages partial refresh trigger full refresh

Trigger full refresh when logged out in 8.5.3. I don't care if the data is lost, I just want to trigger full refresh if partial refresh fails in case user is logged out or session has timed out.
I have two windows open. If I press the logout button on window 2, and then come back onto window 1 and try to do a partial refresh, it returns nothing (just blank value for that control). So how can I trigger a full refresh when the user is logged out?
I tried onComplete, onStart and onError client side events, but cannot figure out how I could find out when this logout has happened, I tried the following code:
var strUserName = '#{javascript: #Name("[CN]", #UserName());}';
alert("Start: " + strUserName);
It always returns the username rather than anonymous in window 1, even when user is logged out in window 2!
onError event never fires when partial refresh fails or returns blank value.
Any ideas or help would be greatly appreciated.
Did you try to lock the database down (Anonymous = NoAccess)? Then you should get an 404 and the error routine fires.
Update
You can:
add a redirect meta header to the page that kicks in when a session expires (cheapo solution, but might catch already most used cases)
Still lock down the database but give Anonymous the right "view public pages" and then have the page(s) that anonymous is allowed to see marked with the attribute "available for public access"
Make sure your partial refresh checks if nothing comes back and reloads the page then (most work since you need to alter business logic) - some sample of your code would be needed
onComplete has one weakness. The value bindings are evaluated when the page is rendered, not after a partial refresh, as you might think. This is due to the way the request works. When a request is sent, the callbacks for the request are bound (onStart,onComplete, etc.). Therefore the client side handler code has to be available before the refresh happens.
If the partial refresh doesn't refresh the item with the event handler(onComplete/onStart/onError), I think the value binding is only updated on page load.
There are several ways to solve this.
Have a client side function that does partial refresh on a hidden (by CSS) xp:text/etc. that shows the current user name. Fetch the content using theNodeReferenceVariable.innerHTML. If Anonymous is the current user:
document.location.href = document.location.href
You could also do document.location.reload(), but that might result in submits being resent.
Use the XPages Extension Library REST services. Same as above, if Anonymous, reload page.

ASP.NET MVC 2 JQuery POST not displaying the model state errors

I have been using asp.net mvc for a bit (but I'm still a beginer). I want to have the ability to update two views as a result of a jquery postback.
Basically I have a list and a details view. The details view is presented using a jquery popup (using jquery-UI popup). I only want to update the list if the details save is successful (i.e. there are no validation errors on the details view). However, if there are any validation errros in the details view, I want to update the details view so that the user sees the validation errors.
so I thought in my controller, I return a JsonResult instead of a View.
[HttpPost]
public ActionResult SavePersonInfo(Person p) {
if(ModelState.Valid) {
return View("PersonList");
}
return Json({Error = true, View = PartialView("PersonDetails", p)});
}
As you can see if there are no errors I return the person list view, but if there are any validation errors, I have return the details view. The reason that I'm returning a JsonResult is I need to tell my view there is an error so that the view (jquery) knows which section to update (as in whether to update the person list 'div' or the popup dialog 'div').
So, in my view, the jquery is as follows (please assume that there is a form for entering in the person details and "SubmitPersonForm();" function is called upon clicking on the "Save" button):
<script type="text/javascript>
$('#btnSave').click(function (event) {
onBegin();
$.ajax(
{
type: "POST",
url: "/Person/Save",
data: $('form').serialize(),
success: function (result) {
if(result.Error) {
$('#dvDetails').html($(result).View));
}
else {
$('#dvPersonList').html($result);
}
}
});
});
</script>
So the problem that I have now, is that when there is a validation error, I do see the correct, 'div' being updated, but I lose the asp.net mvc validation messages. I do not see any validation errors in red, as if ASP.NET MVC is completely ignored them. However, my ModelState does have those errros, just not displayed in the details view. I do have valication summary and Html.ValidationFor(m => ...) statements put in my details view.
Could someone tell me why I'm not seeing the validation errors? although I'm using a JSonResult, I do use the right property which is a valid view when I render the 'dvDetails'. Am I doing something that I'm not suppose to in asp.net mvc? Btw I'm using asp.net mvc2 RC with Visual Studio 2010 RC.
Thank you.
The Url does not match the Action name ... not sure if you maybe are calling the wrong Method on the controller ... just an idea. :-)
ASP.NET MVC code processes the response to display validation errors stored in the ModelState during a postback. Because you are using an Ajax Post, the postback code is not rebuilding the page and displaying the validation errors. If you want to display validation errors, you have to handle it yourself.
I've done it by passing the ModelState errors as an array in the response. I process my Ajax response to update the validation error placeholder elements in the form with corresponding error messages in the response.
A warning, though: the keys in the ModelState may have their case changed, so an element ID string in the form doesn't exactly match the string that's used for the key. ModelStateDictionary is case-insensitive, but DOM ID's are not.

Resources