I´m trying to use auto-fields in the configuration of my portlet, but I´m getting desperate with an issue: in the action, I can retrieve the datafields but not the fields indexes in the controller. When I get it from the action request, it´s an empty String :(
Here´s the code from the jsp corresponding to the fields:
<div id="fyhespecials">
<div class="lfr-form-row lfr-form-row-inline">
<div class="row-fields">
<aui:input id='fecha0' name="fecha0" label="Fecha" />
<aui:input id='horario0' name="horario0" label="Horario" />
</div>
</div>
</div>
Here´s the script:
<aui:script use="liferay-auto-fields">
AUI().ready('liferay-auto-fields', function(A) {
new Liferay.AutoFields(
{
contentBox: '#fyhespecials',
fieldIndexes: '<portlet:namespace/>indexes'
}
).render();
});
</aui:script>
And in the controller, I just can´t get the indexes from the actionRequest, but I can get the fields "fecha(index)" and "horario(index)". However, I need the indexes to get the fields properly, so I´m stuck right now. Maybe is saved within the actionRequest, but named in a different way.
Would appreciate some help :)
Thanks in advance,
Luis.
PS: just for providing additional info (in case it was useful), the portlet is running in a Liferay 6.0
EDIT: As requested, here is the code in the controller that tries to catch de String of indexes. Note that, in the syso made below, this String comes empty, while the fields (fecha0, fecha1...) are shown correctly:
public class ListadoMuseoConfigurationActionImpl extends
DefaultConfigurationAction {
public void processAction(PortletConfig portletConfig,
ActionRequest actionRequest, ActionResponse actionResponse)
throws Exception {
String portletResource = ParamUtil.getString(actionRequest,
"portletResource");
PortletPreferences preferences = PortletPreferencesFactoryUtil
.getPortletSetup(actionRequest, portletResource);
//...
String indicesString= actionRequest.getParameter("indexes");
String fechaEspecial = ParamUtil.getString(actionRequest, "fecha0");
String fechaEspecial1 = ParamUtil.getString(actionRequest, "fecha1");
//...
System.out.println("=============Indices autofields======="+indicesString);
System.out.println("=============fechaEspecial======="+fechaEspecial);
System.out.println("=============fechaEspecial1======="+fechaEspecial1);
Hope this helps to get to a solution.
Related
I am trying to post a string array to the post action in an Razor Pages project. For this, I thought about using a hidden <select> tag. The user would enter text into a text box, press a button and I would then add a new option to the <select> then post the whole thing with a submit button. However, after everything is posted, the array property of my model is empty.
Does anyone know if there is a better way of doing this or what I am doing wrong?
Razor:
<form method="post">
<input id="string-value" />
<input type="button" id="add-item" value="Add item" />
<select asp-items="#Model.Model.ArrayOfStrings" id="hidden-select"></select>
<table id="table-items">
</table>
<input type="submit" value="Submit" />
</form>
public class ArrayModel
{
public List<SelectListItem> ArrayOfStrings { get; set; } = new List<SelectListItem>();
}
public class IndexModel : PageModel
{
[BindProperty]
public ArrayModel Model { get; set; }
public void OnGet()
{
Model = new ArrayModel();
}
public void OnPost()
{
System.Diagnostics.Debugger.Break();
}
}
JS:
$('#add-item').on('click', function () {
debugger;
var value = $('#string-value').val();
$('#hidden-select').append(new Option(value, value));
$('#table-item tr:last').after('<tr><td>' + value + '</td></tr>')
});
Repository can be found here.
The options of the select will not be posted so this will not work.
The easiest way to do this is append the results to a hidden input with a separator char, then do a string split on the server side.
Another, maybee more elegant way, would be to add hidden inputs with the same name. Each input with it's own value. You should then be able to get this as a List or Array on the server.
Razor:
<input value="#String.Join(",", Model.Model.ArrayOfStrings)" id="tags"></select>
JS
$('#tags').val($('#tags').val() + ',' + value);
Controller
public void OnPost(string tags)
{
var tagsArray = tags.split(',');
}
I have created a controller with following code.
**I am not using any model in this example.
public ActionResult PersonalDetails()
{
return View();
}
[HttpPost]
public ActionResult Thanks(FormCollection formcol)
{
return View();
}
also a view is added for PersonalDetails action with following markup.
#{
ViewBag.Title = "PersonalDetails";
}
<h2>PersonalDetails</h2>
#{
ViewBag.Title = "PersonalDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>PersonalDetails</h2>
#using (Html.BeginForm("Thanks", "DemoForms", FormMethod.Post))
{
#Html.ValidationSummary()
<p>
Your Name : #Html.TextBox("FirstName")
</p>
<br />
<p>
Your Name : #Html.TextBox("LastName")
</p>
<p> Your Phone : #Html.TextBox("Phone")</p>
<p> #Html.RadioButton("Gender", "Male", true) Male</p>
<br />
<p>#Html.RadioButton("Gender", "Female", false) Female </p>
<p> #Html.CheckBox("Reading", true) Reading</p><br />
<p> #Html.CheckBox("Cooking", false) Cooking</p><br />
<p> #Html.CheckBox("Cooking", false) Painting</p><br />
<p>
Would you like to participate in Survey?
#Html.DropDownList("ddlResponse", new[]
{
new SelectListItem() {Text="Yes", Value="Yes"},
new SelectListItem() {Text="No", Value="No"}
}, "Choose an Option")
</p>
<input type="submit" value="Submit Invite" />
}
when user enter the information in above view and click on submit button, it will redirect to Thanks action.
I want to create a Thanks view that will show this information.
Please let me know how I can show/ access the information on Thanks view.
Thank you in advance.
A typical way to do this is to simply send the data to the new view on the server. There are a lot of different patterns. For model binding, do something like this:
[HttpPost]
public ActionResult Thanks(FormCollection formcol)
{
ThanksViewModel model=new ThanksViewModel();
//add the data to the model
return View(model); //return the model with the view
}
If you're not using the model-binding functionality in your view pages, you can always pass data using the ViewBag:
[HttpPost]
public ActionResult Thanks(FormCollection formcol)
{
ViewBag.ThanksData="data"; //add data as properties of ViewBag
return View();
}
The ViewBag is just a built-in dynamic type that you can store any data on. You can then render this data in the view using the standard razor syntax. Eg in the razor page:
#{
ViewBag.Title = "PersonalDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>PersonalDetails</h2>
<p>#ViewBag.ThanksData</p>
We can use TempData also
In Controller:
[HttpPost]
public ActionResult Thanks()
{
TempData["Thanksdata"] = "data";
return View();
}
In View:
<h2>#TempData["Thanksdata"]</h2>
we can use Viewdata also
in controller:
ViewData["Thanksdata"] = "data";
View:
<h2>#ViewData["Thanksdata"]</h2>
Difference between ViewData ViewBag TempData
http://www.c-sharpcorner.com/Blogs/14947/difference-between-viewdata-viewbag-and-tempdata.aspx
I have a model with properties declared, Controller actions. and View with Viewmodel specified. I fill data in the form and submit, but model has only null values for all properties. If i try with view model i get same null values in HttpPost action.
My Model:
public class Supplier
{
public string SupplierSequenceNumber { get; set; }
public string SupplierName { get; set; }
public string SupplierActive { get; set; }
}
My Controller:
[HttpGet]
public ActionResult Add()
{
SupplierVM objSupplierVM = new SupplierVM();
return View(objSupplierVM);
}
[HttpPost]
public ActionResult Add(Supplier objSupplier)
{
return View();
}
My View:
#model AIEComm.ViewModel.SupplierVM
#using (Html.BeginForm("Add", "Supplier", FormMethod.Post, new { id = "formAddSupplier" }))
{
<div class="control-group">
#Html.LabelFor(m=>m.objSupplier.SupplierName, new{#class = "control-label"})
<div class="controls">
#Html.TextBoxFor(m => m.objSupplier.SupplierName, new { placeholder = "Swatch Style" })
#Html.ValidationMessageFor(m=>m.objSupplier.SupplierName)
</div>
</div>
<div class="control-group">
#Html.LabelFor(m=>m.objSupplier.SupplierActive, new{#class = "control-label"})
<div class="controls">
#Html.DropDownListFor(m=>m.objSupplier.SupplierActive,new SelectList(AIEComm.Models.Utilities.YesNoSelectList,"Value","Text"),new{#class=""})
#Html.ValidationMessageFor(m=>m.objSupplier.SupplierName)
</div>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" class="btn btn-primary" id="btnSubmit" value="Add"/>
</div>
</div>
}
The reason for this is the following code:
m => m.objSupplier.SupplierName
You're generating HTML elements with a model that is inside a ViewModel. This is a good approach, and your problem can be solved quite easily.
It's a good approach because you're keeping things organised, but it's not working because the above code is saying:
Ok, using the ViewModel object (m), take the objSupplier object and then use the SupplierName property.
This is fine, but then when you're submitting data, you're saying (to the action):
Hi, I have a SupplierName property. Please put this into the objSupplier object which you can find inside the ViewModel object.
To which the action says "Well, I am expecting an objSupplier object, but what's this ViewModel you speak of?"
A simple solution is to create a new partial view to generate your form. It's model type should be:
_SupplierForm.cshtml
#model Supplier
#* // The Form *#
In your View, continue to use the same ViewModel, but pass in the correct supplier model:
#model AIEComm.ViewModel.SupplierVM
#Html.Partial("_SupplierForm", Model.objSupplier)
I am starting an adventure with Apache Tapestry5. I am trying to make simple component (for tests), consisting of pair of Textfields. Component is named "TestComp". I have following elements:
testComp.tml
<t:container
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<p>
<input t:type="TextField" t:id="testOne" t:value="testOne.input"/><br/>
<input t:type="TextField" t:id="testTwo" t:value="testTwo.input"/><br/>
</p>
</t:container>
TestComp.java
public class TestComp {
private DataContainer testOne;
private DataContainer testTwo;
#SetupRender
public void setup(){
testOne = new DataContainer();
testTwo = new DataContainer();
}
public String getContentOfTestOne() {
return testOne.getInput();
}
public String getContentOfTestTwo() {
return testTwo.getInput();
}
public DataContainer getTestOne() {
return testOne;
}
public void setTestOne(DataContainer testOne) {
this.testOne = testOne;
}
public DataContainer getTestTwo() {
return testTwo;
}
public void setTestTwo(DataContainer testTwo) {
this.testTwo = testTwo;
}
}
And then I am trying to use it in other place, for example in index.tml:
<form t:type="form" t:id="out">
<t:testComp />
<br/><input type="submit" value="Component"/>
</form>
According to dozens of materials and examples I've found (to be honest non of it refereed to case similar to mine) such implementation should result of showing testComp element in the form, but unfotrunately there is nothing rendered above the button (though tapestry is not crashing). What am I missing? And will I be able to put in Index.java property of TestComp type and bind it with my
<t:testComp />
in Index.tml by id (or it requires something more to implement in my custom component?)
Did you provide the full index.tml file? If so, you are missing the tapestry namespace as well as a correctly setup html document. Try the following:
Index.tml
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<head>
<title>My page</title>
</head>
<body>
<form t:type="form" t:id="out">
<div t:id="testComp" />
<br/><input type="submit" value="Component"/>
</form>
</body>
</html>
In your Index.java you can use this to access your component.
#component(id="testComp")
private TestComp testComp;
If this does not work there is probably something wrong in your configuration or setup and you might just be looking at a static tml file not handled by tapestry at all. In this case follow the step-by-step guide on the Getting Started page.
I have defined a configuration-action-class for loading the configuration of an existing portlet based on drools (liferay-portlet.xml):
<configuration-action-class>com.liferay.drools.action.ConfigurationActionImpl</configuration-action-class>
This class is processAction class:
public class ConfigurationActionImpl extends DefaultConfigurationAction {
#Override
public void processAction(
Now, I want to add another form with rows (inside the same config.jsp page). Exactly I want to call a different class from all of this rows (A call to SelectRules.java class):
<%
ResultRow row = (ResultRow)request.getAttribute(WebKeys.SEARCH_CONTAINER_RESULT_ROW);
IRRule myRule = (IRRule)row.getObject();
String name = IRRule.class.getName();
String primKey = String.valueOf(myRule.getPrimaryKey());
%>
<liferay-ui:icon-menu>
<portlet:actionURL name="selectRule" var="selectURL">
<portlet:param name="resourcePrimKey" value="<%=primKey %>" />
</portlet:actionURL>
<liferay-ui:icon image="checked" message="SelectRule" url="<%=selectURL.toString() %>" />
</liferay-ui:icon-menu>
In my portlet.xml I defined the following portlet-class:
<portlet-class>com.myown.oriol.selectrules.portlet.SelectRules</portlet-class>
As you see, the main problem is that actionURL is looking to the configuration-action-class but what I exactly want is to call to the portlet-class(SelectRules.java) function called selectRules.
And the defined class selectRules that I want to call starts this way:
public class SelectRuleClass extends MVCPortlet {
public void selectRule(
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse)
Do you know what I need to solve this?? I don't know how I can merge this two classes with two different extensions considering that configurationActionImpl.java is already defined by another person.
In resume.. I need to call the function selectRule from configuration.jsp while selecting a Rule to be used. But the configuration-action-class is another one required for loading this existing portlet. And while selecting a rule I get this error...
86 does not have any paths specified
Thank you so much,
Oriol
Since the configuration.jsp is rendered by a liferay portlet with name 86 you would need to use <liferay-portlet:actionURL> instead of the simple <portlet:actionURL> since you would need to specify the portlet-name whose action method you need to call from configuration.jsp, something like this:
<liferay-ui:icon-menu>
<liferay-portlet:actionURL name="selectRule" var="selectURL" portletName="SelectRules_WAR_SelectRulesportlet">
<liferay-portlet:param name="resourcePrimKey" value="<%=primKey %>" />
</liferay-portlet:actionURL>
</liferay-ui:icon-menu>
If you have defined <portlet-name>SelectRules</portlet-name> than the attribute portletName of the tag would have value portletName="SelectRules_WAR_SelectRulesportlet", this is the portlet-id which is generated by liferay once you deploy the portlet.
This is liferay's convenient way to call one portlet (SelectRules) from another (86).