Liferay Auto Fields how to set limit of repetitions - java

I'm using Liferay AutoFields for first time, everything's ok, but the problem is that I can't set a limit in the "clone" event to get up to six fields only, and seems like documentation not exists, just found examples.
I'm using Liferay 7.0, this my aui:form:
<aui:form action="<%= addURL %>" name="<portlet:namespace />addForm">
<div id="auto-fields-container">
<div class="lfr-form-row lfr-form-row-inline sku-input-container">
<aui:input name="skuIdSave" label="Registrar SKU" helpMessage="Se consultará el SKU ingresado"></aui:input>
</div>
</div>
<aui:button-row>
<aui:button type="submit"></aui:button>
</aui:button-row></aui:form>
and this is my Liferay Auto Fields code fragment:
new Liferay.AutoFields({
contentBox: '#auto-fields-container',
fieldIndexes: '<portlet:namespace />rowIndexes',
on: {
'clone': function(event) {
console.log('Clone event');
console.log(event);
console.log('Cloned node');
console.log(event.row);
},
'delete': function(event) {
console.log('Delete event');
console.log(event);
}
},
sortable: true,
sortableHandle: '.lfr-form-row'
}).render();
There is a native way in the plugin to set a repetition limit? Or only can be done by the clone "event" logic? Because I found the way to get the number of fields by clicking the add and remove buttons, and I tried something like this, without exit:
if(AUI().all('.sku-input-container:visible').size() >= 6)
delete(event);
Although I found a way (with JQuery) to delete the created row when the number of fields is the limit I want, I guess it could affects to the "undomanager" logic ("undomanager" renders by default as a div in the form)
Undomanager:
<div id="yui_patched_v3_18_1_1_1665078696121_520" class="yui3-widget component undomanager"><div id="yui_patched_v3_18_1_1_1665078696121_522" class="undomanager-content helper-clearfix alert alert-info lfr-undo-queue"><a class="lfr-action-undo" href="javascript:;">Deshacer <span class="lfr-items-left" id="yui_patched_v3_18_1_1_1665078696121_2775">(2)</span></a><a class="lfr-action-clear" href="javascript:;">Eliminar el historial</a></div></div>
Many thanks in advance.

Related

Multiple Submit Buttons Security Risk

For some reasons, I need to create a form with two submit buttons which are going to call different actions after submission.
I found the following example in Multiple Submit Buttons:
<s:form method="post" action="mySubmitAction">
<s:submit value="Submit"/>
<s:submit value="Clear" action="myClearAction"/>
</form>
As my project is using Struts 2.3.16.3, struts.mapper.action.prefix.enabled = true is needed.
However, is there any risk to enable it back in struts 2.3.16.3?
Will it share the same security problem in 2.3.15.2?
If yes, would you mind providing some alternatives to make the multiple submit buttons work on single form? if-else solution is not preferred.
The vulnerabilities discovered in versions Struts 2.0.0 - Struts 2.3.15.2 related to the OGNL injection attack. In fact the action: prefix opens a door for this kind of attacks.
Previously it's discovered in S2-016, the fixed version was 2.3.15.1. Lately S2-018 was introduced and they disabled the action: prefix. Recommended upgrade was 2.3.15.3.
This means that using action: prefix is discouraged and you can enable in on your own risk. In S2-019 the DMI was disabled by default too, so you can't use method: prefix because it works only if DMI is enabled.
These restrictions made side effect on multiple button usage where action or method attributes used to bind s:submit buttons to the action other than in the s:form action attribute. To use multiple buttons to execute its own methods of the action class you can pass a parameter that holds a method name. It could be a hidden field or submit field, etc.
When execute method is called this information should be already available and you can use Java to call the method by the name. Another approach is most popular to use javascript to modify the form's action attribute in the onclick event handler before the form is submitted.
<s:form name="myForm" method="post" action="mySubmitAction" >
<s:submit value="Submit"/>
<s:submit value="Clear" onclick="myClearAction()"/>
</form>
<script>
function myClearAction(){
document.forms["myForm"].action = "<s:url action='myClearAction' />";
}
</script>

Sendkeys to a GXT integerSpinnerField in Selenium

I have been trying to "sendkeys" to a IntegerSpinnerField but it is not working. The IntegerSpinnerField has a id but I can't use the "sendkeys" on it. I opened up the html the ID is there but the IntegerSpinnerField is 3 widgets in 1. So is there anyway i can give an id to the 3 widgets that make up the IntegerSpinnerField.
html-code
<div __gwtcellbasedwidgetimpldispatchingfocus="true" __gwtcellbasedwidgetimpldispatchingblur="true" id="maximumfrequencySpinnerField" class="GJCAMDBBOPB" title="Enter an maximum frequency value within the allowable range. The allowed range is 776 to 787 MHz" style="width: 100px;"><div style="width: 100px;" class="GJCAMDBBAW"><table width="100%" cellpadding="0" cellspacing="0"><tbody><tr><td><input style="width: 75px;" type="text" value="" class="GJCAMDBBCV GJCAMDBBJV" id="x-auto-229-input" tabindex="0" disabled=""></td><td><div class="GJCAMDBBKV"></div><div class="GJCAMDBBNV"></div></td></tr></tbody></table></div></div>
Id of the textfield which is autogenerated
Don't go with id's for ExtJs Applications those were dynamically generated at runtime and prone to change everytime.So you have to write a relative xpath for every element.And ExtJS elements follow some pattern So you have to write xpaths for that and you can reuse them.
Refer any-suggestions-for-testing-extjs-code-in-a-browser-preferably-with-selenium
For your case and for most input element you can find it using label.The immediate input of the label might be the element you are looking for
I have tested the spinner field named Revenue %: in this demo site using the following xpath
//label[text()='Revenue %:']//following::input
The script for the above site.Hope it helps
WebDriver driver = new FirefoxDriver();
driver.get("https://www.sencha.com/examples/#ExamplePlace:dashboard");
WebElement element=driver.findElement(By.xpath("//label[text()='Revenue %:']//following::input"));
element.clear();
element.sendKeys("67.67");

JSP send data to Java class

I'm looking to send information after each link click to my java class to help increment a counter and to change an object which is held in my bean (myGame) which holds an array of 'cases'. I understand that I can increment a counter using JS, but i'd like to keep all game logic within the bean if possible.
I have considered using forms and changing the anchor to a submit button, however, I'd like to keep that the player can no longer click the link after it the case is eliminated.
The printCase(int) function works by finding the corresponding case in the array, checking the value of a boolean (is the case is eliminated from the game [deal or no deal]) and then prints the amount of money held in the case if eliminated; the case number if it is not.
I have about a dozen cases.
<jsp:useBean id="myGame" scope="session" class="dealOrNoDeal.GameLogic"/>
<table border="1" id="dndTable">
<form action="/../doStuff.jsp" method="post">
<tr>
<td> <%= myGame.printCase(0) %> </td>
</tr>
</form>
</table>
I've also considered changing my bean to a servlet. Does that work? Can you have a bean in a servlet?
Thanks all.
Update: I've made printCase now print the tag that it's within now, as well. Prints as a submit button if the case is not opened, prints as a <p> if it is (I need it to use the class). Attempted putting the <td>s in there as well, but it somehow messes up the formatting.
I'm now looking to get the name of the one button that was clicked, any ideas?
I'm not sure about understand completely your qestion. But i'll try:
U have 2 ways:
You have to build a jquery where on each button click u call a servlet where u send information to your java class;
Using DWR: http://directwebremoting.org/dwr/index.html

Angularjs UI Bootstrap Popover Prevents input submit

I have used Angularjs with ui.bootstrap popover feature in following manner,
<form name="frm1" role="form" ng-submit='myFunc()' novalidate="novalidate">
.... other inputs go here...
<input type="number" ng-pattern="/^[0-9]+$/" name="testNo" ng-model='testNo' required popover="Locate number here" popover-trigger="focus">
<input type="submit" ng-model='funcBtn' value="Submit" ng-click="submitted = true" ng-disabled="value.length=0">
</form>
The issue is because of popover="Locate number here" popover-trigger="focus" code when I check after submitting the form the value for the input testNo is not passed to controller.
The Controller is as follows,
app.controller('myCtrl', ['$scope','$location','$log', function($scope,$location,$log)
{
$log.log('testNo', $scope.testNo);
}]);
And If I remove the popover code from this input it works fine. I like to know whether there's a specific way in using popover into inputs.
Used resource ui.bootstrap example, input trigger: http://angular-ui.github.io/bootstrap/
The problem is that the current version of AngularJS can only have one scope for a given DOM element, and the popover creates a child scope that then gets inherited by the other directives. Fortunately, the solution is simple. Just refer to $parent.my_var in the directive, in your case ng-model="$parent.$model".
Here is the popover FAQ on this problem.
I ran into this problem in the bowels of my own custom directive, but fortunately the solution is simple there as well: rather than refer to $scope.var, refer to $scope.parent.var. Simple solution, but hours of debugging!

dijit.form.Select re-appears unpopulated?

This is a continuation of an issue I was having yesterday so if it looks familiar, thats why :) It IS a different question tho!
So I have another dijit.form.Select initially created on the page like so;
<c:set var="clazzId" value="${verification.clazz.id}" />
<div id="clazzOptions">
<select id="clazz" name="clazz" style="width:22em" dojoType="dijit.form.Select" maxHeight="140">
<option value="-1" label=" " />
<c:forEach items="${requestScope.clazzes}" var="clazzItem">
<c:choose>
<c:when test="${clazzId eq clazzItem.id}">
<option value="${clazzItem.id}" selected = "true">${clazzItem.name}</option>
</c:when>
<c:otherwise>
<option value="${clazzItem.id}">${clazzItem.name}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</select>
</div>
I then have some javascript that I'm trying to use to swap the contents of the div "clazzOptions" depending on the value chosen from a different drop down (not seen here). If its a certain value, replace the div with a text message, if its any other value, re-show the original dijit.form.Select;
<script type="text/javascript">
var classDropDown;
var classPhDMessage = "PhD's do not require a Class or Grade";
dojo.addOnLoad(function() {
classDropDown = dojo.byId('clazzOptions').innerHTML;
});
function checkForPHD() {
var awardOption = dijit.byId('qualification').attr('displayedValue');
if(awardOption == "PhD"){
dojo.byId('clazzOptions').innerHTML = classPhDMessage;
} else {
dojo.byId('clazzOptions').innerHTML = classDropDown;
}
}
</script>
As you can see I'm trying to capture the innerHTMLof the div as it is when the page loads and then depending on the value chosen in the other drop down (not seen) change between a predefine message and the captured div contents.
The issue is that after the original div contents have been replaced with the message and then the selection changes again away from "PhD" and the original div innerHTML is placed back into the div, the dijit.form.Select re-appears but is completely empty and in fact doesn't appear usable at all? If I remove the dijit.form.Select dojoType and just leave it as a normal select this whole operation works perfectly but I kinda need it to be a dijit.form.Select.
Why won't dijit.form.Select work in this case whereas a normal select does?
You shouldn't use innerHTML to add/remove dijits, especially if you're trying to re-use them.
A dijit is a combination of HTML and Javascript and can be thought of as 'more complex' than simply the contents of a specific node.
You have a number of options:
Disable your dijit.form.Select and add a small note under it (or set it's value) explaining why it's disabled (this is generally a better UI paradigm than removing controls). Depending on your UI this is what I'd try and do
Create a <span> as a sibling of your dijit.form.Select and use CSS to show/hide one of them at a time.
Obviously you'll still get the value of the dijit.form.Select when you submit your form, but because you do server side validation as well as client side validation (I hope :) this won't be a problem
Use the dojo.data API to create a datastore from your "${requestScope.clazzes}" iterator. Use this store when you (programatically) create the dijit.form.Select. Keep track of the current value of said Select somewhere. When you don't need it, call yourSelect.destroy() to properly destroy it, then when you need it again create a new one and set it's value to the saved value from before.
This seems unnecessarily expensive to me tho.

Categories