I'm trying to communicate between two portlets by rendering the URL.
One portlet shows the table containing the list of available options. When one of the options is clicked, a javascript function renders the URL and in the second portlet should appear the detailed info about the clicked project.
However, it is not working: the URL is rendered correctly, with the proper id of the row in the URL but the method of the second portlet, set with #RenderMapping(params) is never called.
Thanks in advance
First portlet view.jsp:
<%#page import="java.util.List"%>
<%#page import="pl.spot.vorange.model.Project"%>
<%# taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<div id="projectListDiv" style="width: 100%;"></div>
<script type="text/javascript">
var pids = new Array();
var pnames = new Array();
var projectId = "${p.id}";
<%
List<Project> all = (List<Project>) request.getAttribute("all");
if(all!=null && !all.isEmpty()) {
int i = 0;
for(Project project : all) {
out.println("pids[" + i + "]='"+project.getId()+"';\n");
out.println("pnames[" + i + "]='"+project.getName()+"';\n");
i++;
}
} else {
out.println("brak projektów w zasięgu requestu");
}
%>
function createProjectList() {
var tags = "<table width='100%'>";
for(var i=0; i<pids.length; i++) {
tags += "<tr class='projectTr'>";
tags += "<td class='orangeArray' onClick='firePortletEvent2(" + pids[i] +
")'> </td>";
if(pids[i]!=projectId) {
tags += "<td class='orangeTableItem' onClick='firePortletEvent2(" +
pids[i] + ")'>";
} else {
tags += "<td class='orangeTableItemSel'
onClick='firePortletEvent2(" + pids[i] + ")'>";
}
tags += pnames[i] + "</td></tr>";
}
tags += "</table>";
el = document.getElementById("projectListDiv");
if(el!=null) {
el.innerHTML = tags;
}
}
function firePortletEvent2(projectId) {
var url ="<portlet:renderURL />";
prefix = "&_offer2_WAR_vorange_";
url += prefix+"a=getproject";
url += prefix+"page=expiring";
url += prefix+"tab=expiringOffers";
url += prefix+"pid="+encodeURI(projectId);
location = url;
}
createProjectList();
</script>
Clicking on one of the projects renders the URL.
Second portlet controller:
#RenderMapping(params = "a=getproject")
public String getProject(RenderResponse response, RenderRequest request) {
String pid = request.getParameter("pid");
Project p = null;
if (pid != null) {
long id = Long.parseLong(pid);
p = projectService.searchById(id);
request.getPortletSession().setAttribute("project", p);
}
p = (Project) request.getPortletSession().getAttribute("project");
request.setAttribute("p", p);
return "view";
}
I don't know if it's working correctly because this method is never called.
I know the code is messy but I haven't written it. I just obtained it and I must fix it.
I wouldn't be surprised if this code will never work but I have just started developing on Liferay and don't know many things.
Related
I have this method which tries to count the images that don't have any alt attribute (not even alt='').
private int countImagesWithoutAlt(String page){
int nbImages = 0;
int nbImagesWithoutAlt = 0;
try {
Document dom = Jsoup.connect(page).get();
Elements images = dom.getElementsByTag("img");
nbImages = images.size();
for (Element image : images) {
if(image.attr("alt") == null){
nbImagesWithoutAlt ++;
}
}
return nbImagesWithoutAlt ;
} catch (IOException e) {
System.out.println("Problem on " + page + " : " + e);
return 0;
}
}
The problem is, even if I have <img src="blabla"/>, the condition image.attr("alt") == null is false. How come? And how can I fix this code?
Thanks a lot.
For the ones who want to know why I want to differenciate with no "alt" and with empty "alt" attribute. In my context (accessibility testing), it doesn't always matter if the "alt" attribute is empty. It may mean that the image is only decorative does not need a description. But, if there is no "alt" attribute at all, the screen reader is likely to say "image", which is not relevant for the one using it.
Alright I found a way to do it!
private String countImagesWithoutAlt(String page){
try {
Document dom = Jsoup.connect(page).get();
Elements images = dom.getElementsByTag("img");
int nbImages = images.size();
Elements imagesWithoutAlt = dom.getElementsByTag("img").not("[alt]");
int nBImagesWithoutAlt = imagesWithoutAlt.size();
return page + "," + nbImages + "," + nBImagesWithoutAlt;
} catch (IOException e) {
System.out.println("Problem on " + page + " : " + e);
return null;
}
}
The interesting part is :
Elements imagesWithoutAlt = dom.getElementsByTag("img").not("[alt]");
I am using Jsoup to crawl data.
Part of page source looks like this:
<script> var uitkformatter = { dependency: ['uitk_localized_dateApi', 'uitk_localized_priceApi', 'uitk_localized_config'] }; </script><script async defer src="//www.expedia.com/i18n/28/en_US/JPY/currencyFormats.js?module=exp_currencyformats_JPY"></script><script> define('exp_currencyformats', [ 'exp_currencyformats_JPY' ], function() { return window.uitkformatter; }); </script><script async defer src="//b.travel-assets.com/uitoolkit/2-164/3542359672ff5cd9d827c16bd754bf539fd383b1/core/js/uitk-localize-bundle-min.js"></script>
<script language="javascript" type="text/javascript">
OlAltLang = 'en-us.';
</script>
<script type="text/javascript">
'use strict';
require('infositeApplication', function(infositeApplication) {
infositeApplication.start();
});
define('infosite/env', function() {
return {
isJP: true,
isVN: false,
isVSC:false,
isTD:false
};
});
define('infositeData', [], function() {
var infosite = {};
infosite.hotelId = '5522663';
infosite.guid = '59ad4387-979f-477a-901a-6070f3879ce6';
infosite.token = '6a06f2f73106c754340f7a459f5d75d588637caa'; <--This I need to fetch
If I want to fetch infosite.token then what should I do ?
Sample code:
//Fetch HTML code
Document document = Jsoup.connect(URL).get();
//Parse the HTML to extract links to other URLs
Elements linksOnPage = document.select("QUERY TO FETCH infosite.token");
I am not able to figure out what should I write at "QUERY TO FETCH infosite.token"
I tried
Element linksOnPage = document.select("script:contains(infosite.token)").first();
But not working.
You can find all script elements like so:
Elements scriptElements = doc.getElementsByTag("script");
You can then walk through the script elements and use regular expressions to find the variable assignments (such as infosite.token = '6a06f2f73106c754340f7a459f5d75d588637caa';) and then grab the right hand side of the relevant variable assignment.
For example, the following code will print out '6a06f2f73106c754340f7a459f5d75d588637caa':
String html =
"<html><script> var uitkformatter = { dependency: ['uitk_localized_dateApi', 'uitk_localized_priceApi', 'uitk_localized_config'] }; </script><script async defer src=\"//www.expedia.com/i18n/28/en_US/JPY/currencyFormats.js?module=exp_currencyformats_JPY\"></script><script> define('exp_currencyformats', [ 'exp_currencyformats_JPY' ], function() { return window.uitkformatter; }); </script><script async defer src=\"//b.travel-assets.com/uitoolkit/2-164/3542359672ff5cd9d827c16bd754bf539fd383b1/core/js/uitk-localize-bundle-min.js\"></script>\n" +
"<script language=\"javascript\" type=\"text/javascript\">\n" +
"OlAltLang = 'en-us.';\n" +
"</script>\n" +
"<script type=\"text/javascript\">\n" +
"'use strict';\n" +
"require('infositeApplication', function(infositeApplication) {\n" +
"infositeApplication.start();\n" +
"});\n" +
"define('infosite/env', function() {\n" +
"return {\n" +
"isJP: true,\n" +
"isVN: false,\n" +
"isVSC:false,\n" +
"isTD:false\n" +
"};\n" +
"});\n" +
"define('infositeData', [], function() {\n" +
"var infosite = {};\n" +
"infosite.hotelId = '5522663';\n" +
"infosite.guid = '59ad4387-979f-477a-901a-6070f3879ce6';\n" +
"infosite.token = '6a06f2f73106c754340f7a459f5d75d588637caa'; </script></html>";
Document doc = Jsoup.parse(html);
Elements scriptElements = doc.getElementsByTag("script");
// the script elements have no identifying charateristic so we must loop
// until we find the one which contains the "infosite.token" variable
for (Element element : scriptElements) {
if (element.data().contains("infosite.token")) {
// find the line which contains 'infosite.token = <...>;'
Pattern pattern = Pattern.compile(".*infosite\\.token = ([^;]*);");
Matcher matcher = pattern.matcher(element.data());
// we only expect a single match here so there's no need to loop through the matcher's groups
if (matcher.find()) {
System.out.println(matcher.group(1));
} else {
System.err.println("No match found!");
}
break;
}
}
After trying few variations I got my answer.
Elements linksOnPage = document.select("script");
Matcher matcher = null;
Pattern pattern = Pattern.compile("infosite\\.token = \'(.+?)\'");
for (Element element : linksOnPage){
for (DataNode node : element.dataNodes()){
matcher = pattern.matcher(node.getWholeData());
while (matcher.find()){
System.out.println(matcher.group());
System.out.println(matcher.group(1));
}
}
}
I have the unenviable task of editing a 2000 line javascript file inorder to maintain and add some new feature to a web app written in JSP, Json-RPC, jQuery and Java. I do not possess any deeper knowledge of jQuery and Json-RPC except basic Javascript knowledge and the original developer is not there anymore.
There is a JS function which accepts a few params, and calls a Json-RPC and here I am getting the error
arg 1 could not unmarshal
Can someone please tell me what this error means?
Here is my code
function distributeQuantityNew(pReportId, pDecimalPlaces, pRun) {
try {
alert('distributeQuantityNew: ' + pReportId + ', ' + pDecimalPlaces + ', ' + pRun);
var fieldValue = $("#distribution_quantity_" + pReportId).val();
if (fieldValue.length == 0) {
showErrorDialog(resourceBundleMap["error.no.distribution.quantity"]);
return;
} else {
$("#distribution_quantity_" + pReportId).val("");
}
var affectedRowIds = [];
var rows = $("#tableBody_" + pReportId + " tr:visible").has("input[type=text]").filter(function(index) {
var voucherType = this.cells[getVoucherColumnIndex()].innerHTML;
if ((voucherType == 'TRANSFER_CS') || (voucherType == 'PAYOUT_CS') || (voucherType == 'SOURCE_BON') || (voucherType == 'PAYOUT_BON')) {
return false;
}
affectedRowIds.push(parseInt(this.id.split("_")[3]));
return true;
}
);
var affectedReportRows = $.extend(true, {}, foreignReportMap[pReportId]);
$.each(affectedReportRows.map, function(i, row) {
if ($.inArray(row.partnerReportBillNr, affectedRowIds) == -1) {
delete affectedReportRows.map["row_" + row.partnerReportBillNr];
}
});
var report = getLoadedReportByRunId(pReportId);
var productType = report.partnerProductType;
SessionManager.extend();
var resultRows = jsonrpc.foreignReportObject.distributeQuantity(affectedReportRows, fieldValue, pDecimalPlaces, pRun);
alert('back after RPC');
$.each(resultRows.map, function(i, row) {
foreignReportMap[pReportId].map["row_" + row.partnerReportBillNr] = row;
updateForeignReportRow(row, true, productType);
});
updateSummaryRow(pReportId);
toggleApproveAllLink(pReportId);
sortForeignReportTable(pReportId, true);
} catch (e) {
handleError("Failed to distribute quantity: ", e);
}
}
I have peppered it with alerts so that I know whether RPC call was succesful, but I get the error arg 1 could not unmarshal before that from the catch block. Thanks for any hints
OK, got it solved. The first parameter to the remote function is expecting a list of Map<String, SomeBO>. SomeBO is a bean with several BigDecimals. I had another JS function which had set the values passed into the Map. This function was setting a BigNumber where I had a setter of String only. I wish the error I had gotten back from JSON unmarshaller was a bit more descriptive...Below is the code where I added .toString() to solve the issue
foreignReportMap[pReportId].map["row_" + pRowId].clientQuantity = clientQuantity.toString();
foreignReportMap[pReportId].map["row_" + pRowId].totalClientQuantity = totalClientQuantity.toString();
I am new to JSP and servlet for 1 month, and there are many things that I am still unsure off.. Inside a JSP, I have a dropdownlist(the values inside are grab from database) and it would be dynamically created on the number that the user keyed in. Example, the user key in 3, this digit would store in session, and 3 dropdownlist would be generated.
I am able to do this, however I am unable to grab the value of all the 3 dropdownlist in a servlet. and instead of getting 3 diff values, the output repeat the value of the first dropdownlist. Example "john,john,john" instead of "john, ken, andy".
JSP code:
<form action="Adding" method="post">
<%
session = request.getSession();
ProjectGroup projGrp1 = (ProjectGroup)session.getAttribute("PROJECTNAME");
//getMaxMember is the int that user keyed in
int staff =projGrp1.getMaxMember();
for(int i = 0; i < staff; i++) {
%>
<select name="list1" >
<%#page import="sit.bean.*,sit.data.*"%>
<%
GroupTaskManager mgr3 = new GroupTaskManager();
GroupTask[] at3 = mgr3.getCheckBox();
for(int g = 0; g < at3.length; g++) {
%>
<option><%=at3[g].getStaffName()%></option>
<%
}
%>
</select>
<%
}
%>
<input type="submit" name="submit">
</form>
In servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
ProjectGroup projGrp = (ProjectGroup)session.getAttribute("PROJECTNAME");
int member = projGrp.getMaxMember();
String total = null;
for(int i=0; i< member; i++)
{
String names = request.getParameter("list1");
total += names + " , ";
}
PrintWriter pw = response.getWriter();
pw.write("<HTML><BODY>");
pw.write(total);
pw.write("</HTML></BODY>");
pw.close();
}
Can i set the downdownlist name like "list<%i%>", to set different id to each downdownlist? therefore i can retrieve each of them seperately???
In servlet you are getting same parameter every time which is list1 in loop.
and also in JSP creating dropdownlist with same name attribute,
that's why you are getting john,john,john instead of john, ken, andy.
Yes you can use list<%i%> to set different id as well as name
change your select with below in JSP
<select name="list<%=i%>" >
and for loop in servlet with below
for(int i=0; i< member; i++)
{
String names = request.getParameter("list1"+i);
total += names + " , ";
}
I have a java servlet that passes an array to a jsp page, on that jsp page it displays a bunch of results. What I am trying to do is when it prints out it prints a link so I can use it as a parameter. In my case it prints out a bunch of lab classes, what i want to happen is they click the link related to that lab then i click the link and can use that lab.id in a sql statement.
here is the code for the array being printed out
here is the servlet
private void sendBack(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(true);
//Set data you want to send back to the request (will be forwarded to the page)
//Can set string, int, list, array etc.
//Set data you want to send back to the request (will be forwarded to the page)
//Can set string, int, list, array etc.
String sql = "SELECT s.name, l.time, l.day, l.room" +
" FROM lab l, subject s, user_lab ul" +
" WHERE ul.user_id=" + (Integer)session.getAttribute("id") +" AND ul.lab_id ="+ "l.id"+" AND l.subject_id ="+"s.id";
try{
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/wae","root","");
System.out.println("got boobs");
System.out.println(session.getAttribute("id"));
Statement stmt = con.createStatement();
ResultSet res = stmt.executeQuery(sql);
System.out.println(res);
ArrayList<String> list1 = new ArrayList<String>();
if (res.next()){
do{
list1.add(res.getString(1) + " " + res.getString(2) +" "+ res.getString(3) + " " + res.getString(4));
System.out.print(res.getString(1) + res.getString(2));
}while(res.next());
System.out.println("Outside");
String[] arr = list1.toArray(new String[list1.size()]);
request.setAttribute("res", arr);
}
}catch (SQLException e) {
}
catch (Exception e) {
}
//Decides what page to send the request data to
RequestDispatcher view = request.getRequestDispatcher("Lecturer_labs.jsp");
//Forward to the page and pass the request and response information
view.forward(request, response);
and here is the jsp page
<h3>Manage Labs</h3>
<table>
<% String[] list1 = (String[])request.getAttribute("res");
if(null == list1){%>
<%
}else{
for(int i=0; i<list1.length; i++)
{ %>
<tr><%out.println(list1[i] + "<br/>");%></tr>
<% }
}
%>
</table>
so how can I get it to print the results as a link that passes a parameter
To display the results as a link that pass the parameter id, each link could look like:
Link <%out.println(list1[i]);%>
but look how clunky this looks.
JSTL tags can eliminate all this scriptlet code:
<c:forEach items="${res}" var="id">
<tr><td>Link ${id}</td></tr>
</c:forEach>