Using Java Servlet 3.0 file upload, how can I get the names of files when I only know the name of the input?
For instance, I will have several inputs which are type="file", and will have the multiple attribute. At the time I'll need the file names, I'll know the input name, but I won't know the file names. I know how to get a file name from the header with substring, I just don't know how to get it from a specific input. It doesn't matter what order I get the filenames, I just need them from the correct input and put into an array for later processing. I've been stuck on this for about 3 weeks and can't find an answer, which probably means I'm looking for the wrong thing.
My inputs will be like this:
<input type="file" name="pic1" multiple="multiple">
<input type="file" name="pic2" multiple="multiple">
<input type="file" name="pic3" multiple="multiple">
And the code:
function setFileNames(arg, num){
for (c=0; c<=11;c++){
var d = c+1;
var key = arg.getAttribute('id');
var number = key.charAt(key.length-1);
var FileName = document.getElementById("FileName" + d + "-" + number);
var f = document.getElementById("pic" + number);
var name = f.files.item(c).name;
FileName.value = name;
}return;
}
Related
I am new to grails and I am a bit confused about how to use <g:paginate>.
I have a table and I want to set the max number of entrees to 10. Most of the examples I find online have used a List and have a set of jobs and services that help create the navigation. I am confused about this because I did not use a list in my controller. The total number of entrees is going through, but every entree is still displayed. If I click on page 2 or a 'next' button, it seems that my controller loses track of the sourceVolume that the user selected to generate this list.
For context - the first page the user sees prompts them to select a source volume - and from there a table is generated that shows a list of all of the entrees(snapshots) in the source volume.
my selectSnapshotVolume.gsp
<g:form class = "myForm" url="[controller:'Vaultrecovery', action:'doRecoveryConfirmation', method:'post']">
<table class = "content-table">
<thead>
<tr>
<th>Select</th>
<th>Cluster</th>
<th>Vserver</th>
<th>Volume</th>
<th>SnapShot</th>
</tr>
</thead>
<tbody>
<g:each in="${destinationVolumes}" var="destinationVolume">
<tr>
<td><g:radio name="snapshot" value="$destinationVolume.snapshot" required="true"></g: radio></td>
<td>
${destinationVolume.cluster}
</td>
<td>
${destinationVolume.vserver}
</td>
<td>
${destinationVolume.volume}
</td>
<td><b>
${destinationVolume.snapshot}
</b></td>
</tr>
<g:hiddenField name="cluster" value="${destinationVolume.cluster}" />
<g:hiddenField name="vserver" value="${destinationVolume.vserver}" />
<g:hiddenField name="volume" value="${destinationVolume.volume}" />
</g:each>
</tbody>
</table>
<div class = "centerMe">
<div class="pagination">
<g:paginate controller='Vaultrecovery' total="${entreeCount.total[0] ?: 0}" />
</div>
</div>
<div class = "centerMeDescription">
<g:submitButton class="submit " name="submit" value="Submit"/>
</div>
</g:form>
and here is my controller. I do not have any services, jobs, or a domain class. I have also cut out parts of the controller that are irrelevant.
class VaultrecoveryController {
def dataSource_model // netapp_model
def dataSource // dataautomation
def mailService
File testFile = new File("/opt/tomcat/work/TEST")
boolean TEST = testFile.exists()
def index() { }
def selectSourceVolume() {
log.info "Vaultrecovery Controller - selectSourceVolume"
def foo = new Sql(dataSource_model)
String SQL
SQL = "SELECT distinct(name) FROM volume WHERE (name NOT LIKE '%_dest%' AND name NOT LIKE 'MDV%' AND name NOT LIKE '%\\_\\_%') ORDER BY name"
log.info "Getting source volumes: " + SQL
def sourceVolumes = foo.rows(SQL)
[sourceVolumes: sourceVolumes]
} // end selectSourceVolume
def selectSnapshotVolume() {
log.info "Vaultrecovery Controller - selectSnapshotVolume"
def sourceVolume = params.srcvolume
log.info "SOURCE VOLUME IS: " + sourceVolume
def foo = new Sql(dataSource)
String SQL
SQL = "SELECT cluster, vserver, volume, snapshot FROM netapp_vault WHERE volume LIKE '%" + sourceVolume + "%' ORDER BY snapshot"
log.info SQL
def destinationVolumes = foo.rows(SQL)
SQL = "SELECT COUNT(cluster) as total FROM netapp_vault WHERE volume LIKE '%" + sourceVolume + "%' ORDER BY snapshot"
def entreeCount = foo.rows(SQL);
[sourceVolume: sourceVolume, destinationVolumes: destinationVolumes, entreeCount: entreeCount]
} // end selectSnapshotVolume
}
You lost the search criteria because the Prev or the Next button did not POST your Source Volume value back to the controller.
I had the same problem in my project. Took me half the day to figure it out. If you check the HTML what the Prev and the Next button is, they only POST back the Max and Offset values back to the controller. Keep this in mind. This kind of project is state-less. So, your action will reset back to the initial state.
Next
I use a private variable to store my last used search criteria. My action checks if the private variable has anything. If so, it use the criteria from the private variable to run the SQL. So, I will get the same records from the page before. I then apply the Max and Offset to get the correct records.
Something like this:
class BookController {
private String _searchString = ''
def index() {
_searchString = (params.searchString == null) ? _searchString : params.searchString
bookList = Book.findAllByName(_searchString, params)
}
}
params.searchString will be null because the Prev/Next button does not POST back the searchString. If it is null, I grab the searchString from the private variable _searchString and use it in my dynamic finders. I am lucky that Grails did not reset the _searchString variable when the Prev/Next calls the action.
I am using Coded UI for creating some test cases for a web application, while doing the same I have encountered an issue. I am not able to select a Radio Button using their Displayed Text, however if I use the ValueAttribute then its working fine. But, since value attribute is not containing a number which may not be of any logical use for a person creating test data, so I need to do same work using the Displayed Text of the Radio button.
Here is my html code
<td><input id="ContentPlaceHolder1_rbl_NewChanged_0" type="radio" name="ctl00$ContentPlaceHolder1$rbl_NewChanged" value="1131">
<label for="ContentPlaceHolder1_rbl_NewChanged_0">New</label></td>
<td><input id="ContentPlaceHolder1_rbl_NewChanged_1" type="radio" name="ctl00$ContentPlaceHolder1$rbl_NewChanged" value="1132">
<label for="ContentPlaceHolder1_rbl_NewChanged_1">Changed</label></td>
<td><input id="ContentPlaceHolder1_rbl_NewChanged_2" type="radio" name="ctl00$ContentPlaceHolder1$rbl_NewChanged" value="1133">
<label for="ContentPlaceHolder1_rbl_NewChanged_2">Longstanding</label></td>
I have tried the following code. but didn't work
String selectType = data.getType().get(rowCnt);// data reading from excel stored to string variable
List<WebElement> type = driver.findElements(By.xpath("//input[#type='radio']"));
for (int i = 0; i < type.size(); i++) {
if (type.get(i).getText().equals(selectType)) {
type.get(i).click();
}
}
If you are getting the String values pertaining to the text of the <label> tags e.g. New, Changed, Longstanding. etc from excel then you can write a function which will acccept the texts as String as follows:
public void clickItem(String itemText)
{
driver.findElement(By.xpath("//td//label[starts-with(#for,'ContentPlaceHolder1_rbl_NewChanged_')][.='" + itemText + "']")).click();
}
Now you can call the function clickItem() by passing the String argument to click on the relevant Radio Button as follows:
String selectType = data.getType().get(rowCnt); // data reading from excel stored to string variable
clickItem(selectType); // will support clickItem("New"), clickItem("Changed") and clickItem("Longstanding")
Note: As per the HTML you have provided the clickItem() method should work with the implemented Locator Strategy. As an alternative you can also replace the clickItem() function to click on the <input> node as follows:
public void clickItem(String itemText)
{
driver.findElement(By.xpath("//td//label[.='" + itemText + "']//preceding::input[1]")).click();
}
I have a form with a button that will dynamically add a group of inputs of the same form.
I already managed to get it done, except for one issue.
I couldn't pass the parameters from radio input type with the same name to the servlet for everytime I add the fields. It only passed the value to servlet once. Weird thing is I could pass the text input type successfully.
Or is there any other way to pass the value from the radio button to the servlet?
Here's the code:
<script type="text/javascript">
$(document).ready(function(){
var counter = 2;
$("#addDynamicDivs").click(function () {
var newTextBoxDiv1 = $(document.createElement('div'))
.attr("id", 'TextBoxDiv1');
newTextBoxDiv1.attr("style",'float: left;');
var newTextBoxDiv2 = $(document.createElement('div'))
.attr("id", 'TextBoxDiv2');
newTextBoxDiv2.attr("style",'float: left;');
var newTextBoxDiv3 = $(document.createElement('div'))
.attr("id", 'TextBoxDiv3');
newTextBoxDiv3.attr("style",'float: left;');
var newTextBoxDiv4 = $(document.createElement('div'))
.attr("id", 'TextBoxDiv4');
newTextBoxDiv4.attr("style",'float: left;');
newTextBoxDiv1.after().html('<label>Speaker Name : </label>' +
'<input type="text" name="speakername" id="speakername" value="" >');
newTextBoxDiv2.after().html('<label>Speaker Country : </label>' +
'<input type="text" name="speakercountry" id="speakercountry" value="" >');
newTextBoxDiv3.after().html('<label>Speaker Company : </label>' +
'<input type="text" name="speakercompany" id="speakercompany" value="" >');
newTextBoxDiv4.after().html('<label>ID Type: </label>' +
'<ul name="idtype class="forms-list">'+
'<li><input type="radio" name="idtype" id="idtype" value="New ID">'+
'<label for="New ID">New ID</label></li>'+
'<li><input type="radio" name="idtype" id="idtype" value="Old ID">'+
'<label for="Old ID">Old ID</label></li></ul>');
newTextBoxDiv1.appendTo("#TextBoxesGroup");
newTextBoxDiv2.appendTo("#TextBoxesGroup");
newTextBoxDiv3.appendTo("#TextBoxesGroup");
newTextBoxDiv4.appendTo("#TextBoxesGroup");
});
});
From the servlet, the parameters are retrieved by this code:
String[] speakername = request.getParameterValues("speakername");
String[] speakercountry = request.getParameterValues("speakercountry");
String[] speakercompany = request.getParameterValues("speakercompany");
String[] idtype = request.getParameterValues("idtype");
I print out the length of each String array above, and I got 2 for each of the parameters except for idtype which the length is 1.
All the dynamic params are already included inside the form.
Radio buttons will usually only send one value out of the group with the request. By design, only one radio button can be selected out of the group. If you add more radio buttons with the same name to the form, the browser should still pass only one selected value for the group when you submit the form.
If you want to have multiple of this form passed, you will be best off differentiating between the dynamically added forms (it looks like you want all the data to be sent together, so you'll need to add a unique identifier to the name of each <input> element, but otherwise having them in separate <form>s would be preferable). I would not recommend relying on the browser passing multiple <input>s with the same name in the same <form>.
I have an HTML file, a part of which looks like this:
<a name="user_createtime"></a>
<p class="column">
<span class="coltitle">CreateTime</span> <span class="titleDesc"><span class='defPopupLink' onClick='popupDefinition(event, "datetime")'>datetime</span></span> <span class = "spaceandsize">(non-null)<sup><span class='glossaryLink' onclick="popupDefinition(event, '<b>non-null</b><br>The column cannot contain null values.')">?</span></sup></span>
<br>
<span class="desc">Timestamp when the object was created</span>
<a name="user_createuser"></a>
<p class="column">
<span class="coltitle">CreateUser</span> <span class="titleDesc">foreign key to User</span>
<span class = "spaceandsize">(database column: CreateUserID)</span>
<br>
<span class="desc">User who created the object</span>
There are many such Coltitle. titleDesc and desc classes.
Now, if I get an input string like "CreateTime", I want the output to be:
CreateTime, datetime, Timestamp when the object was created
and if I get an input string "CreateUser", I want the output to be:
CreateUser, foreign key to User, User who created the object
I'm using Jsoup for this, and I have gotten this far:
Elements colElements = Jsoup.parse(html).getElementsByClass("coltitle").select("*");
System.out.println("your Col:");
for (Element element : colElements)
{
if(element.ownText().equalsIgnoreCase("CreateTime"))
System.out.println(element.text());
}
which just prints the selected coltitle. How do I parse the related classes and get their values? Or, are they not even related and am I just treading down the wrong path?
Can someone please help me get my desired output?
You are only selecting the <span>-tags, thus, only printing what they values they hold.
You can use the siblingElements()-method to get the siblings of the element that you first select.
Your HTML does not seem to be formatted correctly, but the following should work
System.out.println("your Col:");
for (Element element : colElements) {
if (element.ownText().equalsIgnoreCase("CreateTime")) {
System.out.print(element.text());
for (Element sibling : element.siblingElements()) {
System.out.print(", " + sibling.text());
}
}
if (element.ownText().equalsIgnoreCase("CreateUser")) {
System.out.print("\n"+element.text());
for (Element sibling : element.siblingElements()) {
System.out.print(", " + sibling.text());
}
}
}
This will select the elements of the class 'colTitle'.
The if-case will check if it's either of them, and then print out the element text. It will then move on to it's siblings, and print out their texts.
According to the api docs, you can call children() on colElements.
http://jsoup.org/apidocs/org/jsoup/nodes/Element.html#children()
I can't figure out why i can't get an input value from a jsp. I'm using for cycle to make several input fiels for "choices", but when i'm trying to get values from a mvcportlet, it get nothing.
<aui:form action="<%=addPollURL%>">
<aui:fieldset>
<%
int optionCount = Integer.parseInt(optionCountS);
for (int i = 0; i < optionCount; i++) {
%>
<aui:input label="<%=Integer.toString(i + 1)%>" name="choice<%=i%>"
type="text" />
<%
}
%>
<aui:button-row>
<aui:button value="Add poll" type="submit" />
</aui:button-row>
</aui:fieldset>
</aui:form>
Here goes mvcportlet method
List<String> choices = new ArrayList<String>();
int count = Integer.parseInt(actualChoiceCount);
for (int i = 0; i < count; i++) {
System.err
.println("another choice"
+ ParamUtil
.getString(
actionRequest,
("choice" + i)));
choices.add(new String(ParamUtil.getString(actionRequest,
("choice" + i))));
}
Its really weird... but some ideas or tests
Is AddPollUrl an Action URL with named action and so your action is executed in your generic portlet?
Are you sure text fields are populated with values in the UI (there is no no explicit value in tag)? ParamUtil output would be the same without value that with a blank value
Try without type=text and write it as a single line (input tags)
Try aui:submit instead of aui:button type submit
Try adding an id to form or fields (Ive seen some problems with repeated forms if they dont have namespace)
Why new String(ParamUtil...)?
the most important... whats the output of your System.outs?
That happens because your input field has no value. Or at least it seems so.
You should modify the input to have the value parameter set to "choiceX" like:
<aui:input label="<%=Integer.toString(i + 1)%>" name="choice<%=i%>"
type="text" value="choice<%=i%>" />
Then you'll find it in actionRequest, like Jonny said:
request.getParameter("choice"+i);
This will return you the value of the input field, searching by it's name. So you can have your choice in the processAction method.
Regards !
Try using:
actionRequest.getParameter("choice" + i);
That's not the standard way of getting POST params from the request.