Saving Custom Attribute in Liferay Portal 6.1 - liferay

I have written a liferay portlet to learn expando/custom attributes. I have a custom attribute named nick for every user. I have this form in jsp
<form action='<portlet:actionURL></portlet:actionURL>' method="post">
<liferay-ui:custom-attribute className="<%=User.class.getName()%>"
classPK="<%=user.getPrimaryKey()%>" name="nick" editable="true" label="Nick">
</liferay-ui:custom-attribute>
<input type="submit" value="Save" />
</form>
When I try to get this value in processAction using
String nick = request.getParameter("nick");
Or
String nick = ParamUtil.get(request, "nick", "no nick given");
It gives me nothing. I checked the name of this textbox comes as _testexpandoportlet_WAR_testexpandoportlet_ExpandoAttribute--nick--
How to get this in processAction?

Try to use PortalUtil.getExpandoValue(...)
String expandoValue = (String)PortalUtil.getExpandoValue(request, "nick", ExpandoColumnConstants.STRING, ExpandoColumnConstants.PROPERTY_DISPLAY_TYPE_TEXT_BOX);

This code section will work
String nick = "";
nick = (String) PortalUtil.getExpandoValue(request,
"ExpandoAttribute--" + "nick" + "--",
ExpandoColumnConstants.STRING, ExpandoColumnConstants.PROPERTY_DISPLAY_TYPE_TEXT_BOX);
For help of others I have uploaded the portlet on Sourceforge. Link for test-expando-portlet

Related

Component attributes do not support complex content (mixed C# and markup) error message

I am working on validation on a form in a blazor server application.
I created the component below that I am using
#* Inherits from the original InputText component *#
#inherits InputText
#* Bind the oninput event *#
<input #attributes="AdditionalAttributes"
class="#CssClass"
value="#CurrentValue"
#oninput="EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
#code {
}
I am using the inputTextOnInput in this form
<EditForm EditContext="#EditContext">
<DataAnnotationsValidator />
<div class="mb-5">
<label for="projectnameinput" class="form-label">Name your project*</label>
<InputTextOnInput class="form-control form-control-lg cust #pNameValidation" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
</div>
</EditForm>
since I created this I started getting the error message below
Component attributes do not support complex content (mixed C# and markup). Attribute: 'class', text: 'form-controlform-control-lgcustpNameValidation
Do you have an idea of what this implies?
You cannot use the class attribute in your new component if you have declared a specific parameter for that.
<InputTextOnInput class="form-control form-control-lg cust #pNameValidation" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
you need to remove class from above and pass it via CssClass.
For some reason Blazor/Razor don't let you mix text literals and variables within an attribute value. So when you try and do
<InputTextOnInput class="form-control form-control-lg cust #pNameValidation" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
the class statement is invalid because it contains literals "form-control", "form-control-lg" and "cust" and also a variable "#pNameValidation".
My solution to this problem was to create a little method on a component base class which allows mixing the two things.
public string Class(string classStr, params string[] objStrs)
{
var output = new StringBuilder();
output.Append(classStr);
output.Append(' ');
output.AppendJoin(' ', objStrs);
return output.ToString();
}
now all I have to do is to write my line like this
<InputTextOnInput class="#Class("form-control form-control-lg cust", pNameValidation)" id="projectnameinput" #bind-value="projectModel.ProjectName" #onkeyup=KeyboardEventHandler />
and by using params, you can also just add as many string variables as you want.

Cannot read checkbox when not ticked

I am trying to check if a checkbox is ticked but when the checkbox is not ticked it wont work and gives the error: "TypeError: Cannot read property 'PrivateCheck' of undefined" and points to the line with this code:
let isprivare = req.body['PrivateCheck'];
This is the check box I am trying to get input from
<form class="fileupload" action="upload" method="post" enctype="multipart/form-data">
<input type="checkbox" id="PrivateCheck" name="PrivateCheck" />
</form>
Thank you.
According to the HTML documentation the value of a checkbox is sent with the form only if it is checked. Otherwise nothing is sent for that checkbox.
In your particular case you can fix it like this:
let isprivate = req.body && req.body['PrivateCheck'];

TYPO3 Indexed Search not working

I'm using the TYPO3 version 8, I have installed the indexed_search form box with typoscript
50 = COA
50 {
stdWrap {
wrap = <div id="searchcontainer">|</div><div class="clearboth"></div>
required = 1
}
10 = TEXT
10 {
wrap = <form id="searchbox" name="searchbox" action="|" method="post">
typolink.parameter = {$searchPID}
typolink.returnLast = url
if.isTrue = {$config.tx_realurl_enable}
}
20 = TEXT
20 {
value = <form id="searchbox" name="searchbox" action="/" method="post">
if.isFalse = {$config.tx_realurl_enable}
}
30 = COA
30 {
10 = TEXT
10{
wrap = <input type="hidden" name="id" value="|" />
value = {$searchPID}
if.isFalse = {$config.tx_realurl_enable}
}
20 = TEXT
20 {
wrap = <input type="text" id="swords" name="swords" value="|" size="20" onfocus="this.value='';" />
value = {$searchTEXT}
}
30 = TEXT
30 {
wrap = <input type="submit" id="searchbutton" value="" />
}
}
40 = TEXT
40 {
value = </form>
}
}
When I click on search, I'm redirected to my search page wich contain the search plugin installed, but no search results or even the keyword is showing. The pages are well indexed and in the backend indexing searched keyword it appears, but not in the frontend, what I'm mising here ? please help!
user2714261 shows, how to deactivate the cHash check for all elements. That might a bit risky in deed. But you can deactive it only for the indexed_search plugin. That won't be any problem, because the indexed_search should not cache anyway. So you jsut can write in your plugin-Setup:
plugin {
tx_indexedsearch {
features.requireCHashArgumentForActionArguments = 0
}
}
That worked fine in TYPO3 8.7.9.
Martin
You can use <f:form> in a FLUIDTEMPLATE to generate a Quicksearch-Form. This way an essential cHash-parameter will be generated and appended to the action-URL, automatically.
TypoScript (Constants)
plugin.tx_indexedsearch.settings.targetPid = 35
TypoScript (Setup)
lib.quicksearch = FLUIDTEMPLATE
lib.quicksearch{
file = fileadmin/Quicksearch.html
settings.targetPid = {$plugin.tx_indexedsearch.settings.targetPid}
}
Quicksearch.html
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<div id="quicksearch">
<f:form action="search" method="post" controller="Search" extensionName="indexedsearch" pluginName="pi2" pageUid="{settings.targetPid}">
<f:form.textfield name="search[sword]" value="{sword}" class="quicksearch-sword" />
<f:form.submit name="search[submitButton]" value="Search" class="quicksearch-submit" />
</f:form>
</div>
</html>
Edit: i found the solution. You have to add something to the typolink ts (my result plugin has _pi2 btw)
wrap = <form id="searchbox" name="searchbox" action="|" method="post">
typolink.parameter = 25
typolink.additionalParams = &tx_indexedsearch_pi2[action]=search&tx_indexedsearch_pi2[controller]=Search
typolink.returnLast = url
typolink.useCacheHash = 1
First Posting:
I don't have the solution right now, but i found something that could help.
I'm having a similar problem with TYPO3 8 and a searchbox. I adapted my HTML of the searchbox, that it fits to the embedded plugin, like this:
<form action="searchresult.html?tx_indexedsearch_pi2%5Baction%5D=search&tx_indexedsearch_pi2%5Bcontroller%5D=Search" method="post" name="searchform" id="searchform">
<input name="tx_indexedsearch_pi2[search][sword]" type="text"/>
<input name="tx_indexedsearch_pi2[search][submitButton]" type="submit" id="submitbutton" value="submit"/>
...
As you can see i have a fixed setup here in my template. What i noticed is, that the embedded plugin obviously doesn't run if you don't send the chash in the action url. Probably you can generate it with your typoscript.
I'm just sure that this is the problem, at least for my case, because when i turn the chash requirements for extbase off, it works ...
config.tx_extbase.features.requireCHashArgumentForActionArguments = 0
but i believe that is a little bit risky and should not be used in production
so generating the chash should be the way to do make it work. just wanted to share what i found out.

How to check in CODED UI if text field is a required field?

I am new in coded UI, I just want to ask if there's any way to check if the text field in a web application is required?
HTML:
<div class="col-sm-7">
<input id="txt_title" type="text" name="Title" value="#Model.Asset.Title" class="form-control" required>
</div>
I would suggest doing this in two steps:
Get the control based on its ID
Ensure that the definition of the control contains "required"
Here's a code example:
HtmlTextArea requiredInput = new HtmlTextArea(browserWindow);
requiredInput.SearchProperties.Add("Id", "txt_title");
string controlDef = requiredInput.ControlDefinition;
Assert.IsTrue(controlDef.Contains("required"), "Test Failed: Input should be required");
Please mark as the answer if it accomplishes what you're saying. Thanks!

Disable empty search

I have a photography site driven in part by the 'Photoshelter' service, and I put an embedded search bar in my nav.
<form action="http://brettcole.photoshelter.com/search" method="get">
<input type="text" placeholder="search library" size="15" name="I_DSC">
<input type="submit" value="go">
<input type="hidden" name="I_DSC_AND" value="t">
<input type="hidden" name="_ACT" value="search">
</form>
It allows for a search to be executed with the no search term present, which then returns all 12,000 photos in my archive. Is there a best practice for preventing this, such that the user has to type something or nothing will happen when they click search?
It's also present on my advanced search page. This is generated by a search widget shortcode in the Photoshelter back end. I'd like to apply the same thing here, but not sure how the widgetization of it might affect the process.
Many thanks
You can use the onsubmit attribute of the form element to check if the user has entered information in any fields and then prevent submit based on that.
<script>
function checkValues() {
searchBox = document.getElementById("SearchField");
return searchBox.value != ""; // True will allow submission and false will prevent it
}
</script>
With this...
<form onsubmit="checkValues();" action="http://brettcole.photoshelter.com/search" method="get">
<input type="text" id="SearchField" placeholder="search library" size="15" name="I_DSC">
<input type="submit" value="go">
<input type="hidden" name="I_DSC_AND" value="t">
<input type="hidden" name="_ACT" value="search">
</form>
Should do what you need.
See also this answer: How to grab the onSubmit event for a form?
The actual search isn't working
From the contact page for example, it returns this
http://brettcolephotography.com/contact.html?I_DSC=red&I_DSC_AND=t&_ACT=search
the formula for my search returns is
http://brettcole.photoshelter.com/search?I_DSC=red&I_DSC_AND=t&_ACT=search
this search bar is present on all three of my web properties, personal site, blog, and photoshelter site, all three are tightly integrated to where you can't tell when you're switching between them. It needs to work regardless of where the search is being executed from. Thanks
Here is a function I wrote to disable the search form submitting if the search field is empty. It also focuses the cursor on the search field if the form is not submitted so that the user does not think that search is broken.
This is assuming that jQuery is loaded. Hope this helps!
var preventSearchIfEmpty = function() {
$('form[method="get"]').on( 'submit', function( ev ){
var query = $('input[type="text"]').val(),
queryLength = query.length;
if ( 0 === queryLength ) {
// Make the cursor blink so user is aware it's not broken, they need input to search
$('input[type="search"]').focus();
ev.preventDefault();
return;
}
});
}();

Resources