change name of calendar export from "liferay.ics" - properties

Someone know how to change the filename of the liferay calendar event before export?
The default one is "liferay.ics".
Thanks
Sabrina

You can alter the name by writting an hook.
Override the export_import.jspf file located at %liferay_folder%\%your_server%\webapps\ROOT\html\portlet\calendar
<aui:fieldset label="export">
<aui:input cssClass="lfr-input-text-container" label="" name="exportFileName" type="text" value="liferay.ics" />
</aui:fieldset>
Changing the value attribute should do the trick.
Owk after looking a bit closer to the calendar portlet it appears that my above solution is only visible on the export/import tab and not when you export an event from the summary tab.
The endpoint who is responsible for creating the file: http://www.jarvana.com/jarvana/view/com/liferay/portal/portal-impl/6.1.0/portal-impl-6.1.0-sources.jar!/com/liferay/portlet/calendar/action/ExportEventsAction.java?format=ok
It appears that when no portlet parameter with the name exportFileName is set the action will automaticly name it liferay.ics:
Short And Easy fix:
Add (in event_action.jsp):
<portlet:param name="exportFileName" value="<%= event.getTitle() %>" />
to :
<c:if test="<%= CalEventPermission.contains(permissionChecker, event, ActionKeys.VIEW) %>">
<portlet:actionURL windowState="<%= LiferayWindowState.EXCLUSIVE.toString() %>" var="exportURL">
<portlet:param name="struts_action" value="/calendar/export_events" />
<portlet:param name="redirect" value="<%= currentURL %>" />
<portlet:param name="eventId" value="<%= String.valueOf(event.getEventId()) %>" />
</portlet:actionURL>
<liferay-ui:icon
image="export"
url='<%= exportURL %>'
/>
</c:if>
Write an wrapper arround the ExportEventsAction. (For more Advance senarios)
Use this method when more advance operations are required in the future.
http://www.liferay.com/web/mika.koivisto/blog/-/blogs/7132115
https://github.com/liferay/liferay-plugins/blob/master/hooks/sample-struts-action-hook/docroot/WEB-INF/src/com/liferay/samplestrutsaction/hook/action/SampleStrutsPortletAction.java
Wrapper basic concepts:
In your hook xml:
<?xml version="1.0"?>
<!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.1.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_1_0.dtd">
<hook>
<custom-jsp-dir>/WEB-INF/jsps/</custom-jsp-dir>
<struts-action>
<struts-action-path>/calendar/export_events</struts-action-path>
<struts-action-impl>aiao.liferay.strutsactions.ExportEventActionWrapper</struts-action-impl>
</struts-action>
</hook>
Your wrapper looks like this:
public class ExportEventActionWrapper extends BaseStrutsPortletAction {
#Override
public void processAction(StrutsPortletAction originalStrutsPortletAction, PortletConfig portletConfig, ActionRequest actionRequest, ActionResponse actionResponse) throws Exception {
_logger.info("Call To Wrapper");
//do your magic here...
originalStrutsPortletAction.processAction(portletConfig, actionRequest, actionResponse);
}
private Log _logger = LogFactoryUtil.getLog(ExportEventActionWrapper.class);
}

Related

How do I display a delete confirmation dialog before deleting a row in a DevExtreme DataGrid on a Razor page?

I am using DevExtreme and razor pages in a Asp.NetCore web application.
I would like to inject client side delete confirmation dialog when deleting a row.
Currently I'm using an asp-action on the controller to make the call to do the delete.
I'm not sure how/where to do this in client side (cshtml file).
I assume that I'd be somehow using javascript/jquery for this?
Are there existign 3rd party open source libraries that I should use for client side dialogs/message boxes?
DevExtreme DataGrid definition in cshtml file.
#(Html.DevExtreme().DataGrid<Customer>()
.DataSource(Model)
.Columns(columns => {
columns.AddFor(m => m.CustomerName);
columns.AddFor(m => m.CustomerId).CellTemplate(
<form asp-action="DeleteCustomer" method="post">
<input type="hidden" value="<%- data.CustomerId %>" name="CustomerId" />
<input type="image" src="/icon/close.png" />
</form>
</text>).Caption("");
});
Server side control action code:
[HttpPost]
public async Task<IActionResult> DeleteCustomer(Guid customerId)
{
// Call WebApi Service to delete row
return RedirectToAction("Index");
}
I believe the datagrid has a built-in function for confirming the delete action on the client side. Might not be exactly what you were looking for but it could be a good start.
Here is the link to the demo page: https://demos.devexpress.com/ASPNetCore/Demo/DataGrid/RowEditingAndEditingEvents/

using Microsoft.Web.MVC on View

I am following an online example for creating a wizard control. It involves in serializing the model on the view, then pass it to the controller which Deserialize the model and use. Below is the code for the View,
#using Microsoft.Web.Mvc
#model Sample.Models.RegisterWizardViewModel
#{
var currentStep = Model.Steps[Model.CurrentStepIndex];
ViewBag.Title = "Register";
}
#using (Html.BeginForm())
{
#Html.Serialize("wizard", Model)
#Html.Hidden("StepType", Model.Steps[Model.CurrentStepIndex].GetType())
#Html.EditorFor(x => currentStep, null, "")
if (Model.CurrentStepIndex > 0)
{
<input type="submit" value="Previous" name="prev" />
}
if (Model.CurrentStepIndex < Model.Steps.Count - 1)
{
<input type="submit" value="Next" name="next" />
}
else
{
<input type="submit" value="Finish" name="finish" />
}
}
Now at first I was not finding [Deserialize] attribute in the controller and for that I have installed the MvcContrib package from the NuGet.
The problem I am facing is that #Html.Serialize("wizard", Model) is not found. Also the namespace Microsoft.Web.Mvc could not be resolved. If in the Controller file I use Microsoft.Web.Mvc then it work without a problem but when I use the same namespace in the view then it could not be resolved. What is the difference between System.Web.MVC and Microsoft.Web.MVC? How to resolved the namespace error?
I have also read that #Html.Serialize is not available and it can be accessible through MVC Futures. I have added the package but how to use it to Serialize the model on the View?
Edit: Just like to mention that I have installed the nuget package Microsoft.AspNet.Mvc.Futures 5.0.0' but I am unable to see any reference in the references folder. There is no Microsoft.AspNet.Mvc or Microsoft.AspNet.Mvc.Futures reference in the references folder. Where did it go I wonder?

How can I react to a finished upload with <h:inputFile>?

I'm using Richfaces-4.3.5 on Wildfly-8.0.0.CR1 here, migrating from <rich:fileUpload> which doesn't work with JSF-2.2/Servlet-3.0. I'm replacing it with this snippet:
<rich:popupPanel id="testPop" autosized="true">
<h:form id="uploadF" enctype="multipart/form-data">
<h:inputFile value="#{bean.file}">
<a4j:ajax listener="#{bean.storeFile()}" render="#form,:fileListTbl"
oncomplete="#{rich:component('testPop')}.hide();" />
</h:inputFile>
</h:form>
</rich:popupPanel>
This works fine in that the storeFile method is called and I can access bean.file just fine. However, I'd like to close the rich:popupPanel when I'm done uploading, so I need to react to the success/complete events of the ajax request. But that doesn't seem possible - the popup stays visible and the response is clearly incomplete (indented for better readability):
<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
<changes>
<update id="j_id1:javax.faces.ViewState:0">
<[CDATA[-1186354868983349335:-5499969782208038164]]>
</update>
<extension id="org.richfaces.extension"><render>#component</render></extension>
</changes>
</partial-response>
Though the richfaces debug messages indicate the handlers are being called:
RichFaces: Received 'success' event from <input id=uploadF:j_idt1136 ...>
RichFaces: Received 'complete' event from <input id=uploadF:j_idt1136 ...>
So, simple question: how can I get the popup to close and the components to be re-rendered?
i'm not sure if the problem is directly related to a4j:ajax or what's needed to be done to make it work with a4j:ajax, but the code below seems to work with f:ajax.
<h:form id="formId">
<h:commandLink value="popup"
onclick="#{rich:component('testPop')}.show(); return false;" />
</h:form>
<rich:popupPanel id="testPop" autosized="true">
<h:form id="uploadF" enctype="multipart/form-data">
<h:inputFile value="#{bean.file}">
<f:ajax listener="#{bean.storeFile()}" render="#form :fileListTbl"
onevent="eventHandler"/>
</h:inputFile>
</h:form>
</rich:popupPanel>
<script>
function eventHandler(event)
{
if (event.status == 'success')
{
#{rich:component('testPop')}.hide();
}
}
</script>

Google script HTML api can´t process file upload field

I am trying to create a simple web app in google scripts with the HTML api.
code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function processForm(formObject) {
var formBlob = formObject.myFile;
var driveFile = DriveApp.createFile(formBlob);
return driveFile.getUrl();
}
index.html
<script>
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
<form id="myForm">
<input name="myFile" type="file" />
<input type="button" value="Submit"
onclick="google.script.run
.withSuccessHandler(updateUrl)
.processForm(this.parentNode)" />
</form>
<div id="output"></div>
The form fails to submit. I´m using google chrome Versión 30.0.1599.101 m
This appears in the console: Uncaught NetworkError: Form submission failed.
Here is the app: https://script.google.com/d/1yrgM20n1ZI99bChN2qtQWgGck36OccLN3A16Gn7tCPvsJw0EcK_ql7C5/edit?usp=sharing
Maybe you should add encoding="multipart/form-data" attribute to form tag.
If not solved already – did you try changing the input type from "button" to "submit"? On top of that I'd also try giving it another value than "Submit" since that might interfere with the actual submit parameter.

Can we have custom permissions defined for the portal?

Environment: Liferay 6.1 GA3 EE
Can we have custom permissions defined for the portal?
We can create custom permissions in our plugin portlet through creating an XML with <portlet-resource> tag and defining the <action-key> within it.
And when I go to define permissions for a Role in Control Panel my portlet appears in the section Site Applications, now what I want is to create custom permissions (not through EXT) in a portlet or hook that should have a separate category as My Custom and should have custom permissions like <action-key>ACCESS_EMAIL</action-key>, <action-key>ACCESS_TOOLSET<\action-key> etc.
In short my custom category should appear within section Portal as shown in the following figure while I define the permission for a custom Portal (regular) role:
I would like to use this permission not for a specific portlet but need to use it inside jsp-hooks or any other of my custom portlets. Just like we have ADD_SITE, ADD_USER etc permissions in Portal --> General, I want to have these permissions as generic.
Edit
To make the portlet appear in any of the section I created a simple custom-portlet, so the portlet appeared in the Site Application section and if I want I can make it appear in the Control Panel sections as well.
But now the problem is I don't have any view nor any implementation in this portlet so I make it hidden by updating the liferay-display.xml and putting it under category.hidden. This also hides it from the Define Permission drop-down.
And if I don't use the lifeay-display.xml liferay puts it under the Undefined category while accessing it from +Add menu in dockbar. :-(
Thank You
This is how we achieved it:
Create a custom portlet with the permissions file for this portlet like /resource-actions/custompermission.xml to specify the different custom permissions we want. The full steps are identical to this wiki.
Make this portlet a hidden portlet so that it won't appear in the Add menu in dockbar, neither in Control-panel nor in the Define Permissions drop-down.
Now create a JSP hook (you can either create a separate plugin or include the hook in the custom-portlet defined in point no. 1) and modify the /docroot/html/portlet/roles_admin/edit_role_permissions_navigation.jspf to include our custom category:
<aui:form action="<%= currentURL %>" name="resourceSelection">
<aui:fieldset>
<aui:select changesContext="<%= true %>" name="add-permissions" onchange='<%= renderResponse.getNamespace() + "addPermissions(this);" %>'>
<aui:option label="" />
<%-- Our customization starts here --%>
<%--
We have added our very own option group but this is not required just the <aui:option> will do
--%>
<optgroup label="<liferay-ui:message key="custom" />">
<%
if (_isCustomPermissionsPortlet(CUSTOM_PERMISSIONS_PORTLET)) {
editPermissionsURL.setParameter("portletResource", CUSTOM_PERMISSIONS_PORTLET);
editPermissionsURL.setParameter("showModelResources", "0");
%>
<%--
and here we add our own Permission category drop-down option
--%>
<aui:option label="custom-permissions"
selected="<%= _isCurrent(editPermissionsURL.toString(), portletResource, showModelResources) %>"
value="<%= editPermissionsURL.toString() %>" />
<%
}
%>
</optgroup>
<%-- Our customization ends here --%>
<c:choose>
<c:when test="<%= role.getType() == RoleConstants.TYPE_SITE %>">
<optgroup label="<liferay-ui:message key="administration" />">
<% // Other liferay stuff continues ...
and at the end of the JSP we have:
// ... other liferay stuff
private boolean _isOrganizationPortlet(String portletId) {
return ArrayUtil.contains(_ORGANIZATION_PORTLETS, portletId);
}
private boolean _isPortalPortlet(String portletId) {
return ArrayUtil.contains(_PORTAL_PORTLETS, portletId);
}
// Our customization starts here
// portlet's ID
public static final String CUSTOM_PERMISSIONS_PORTLET = "CustomPermissions_WAR_CustomPermissionsportlet";
private static final String[] _CUSTOM_PERMISSIONS_PORTLET = {
CUSTOM_PERMISSIONS_PORTLET,
};
private boolean _isCustomPermissionsPortlet(String portletId) {
return ArrayUtil.contains(_CUSTOM_PERMISSIONS_PORTLET, portletId);
}
// Our customization ends here
This is how it looks in the Control Panel:
We can move the permissions in the Portal section as well by moving our customized code to that place in the JSP.
The advantage of having it above is that it will be displayed when we want to set Define Permissions for Site Role.
Hope this helps somebody.