Include page javascripts conflicting with outer page javascripts - java

My problem is a little difficult to explain, but I will try.
I have 2 jsp pages Outer.jsp and Inner.jsp
Outer.jsp
Script: src="tabs.js"
var PageTabs = "Tab1"
#include "Inner.jsp"
Inner.jsp
Script: src="tabs.js"
var PageTabs = "Tab2~Tab3~Tab4"
Both the jsp pages use the same tabs.js to render some tab elements on the page. The "PageTabs" variable is one of the many common variables that are used by tabs.js. So what happpens is while rendering, the tabs.js takes the latest "PageTabs" variable i'e var PageTabs = "Tab2~Tab3~Tab4" even while rendeing tabs of Outer.jsp.
Note: The page variables and tabs.js are part of standard elements recieved from client. So they have to be used to give the same look and feel for application.
What I need is a way to isolate the "Inner.jsp" from accessing scripts of "Outer.jsp". This will prevent the tabs element from being confused over which variables to use.
I hope I am somewhat clear. Please let me know if I need to provide any more clarifications. Thanks.

JavaScript is interpreted top-to-bottom inside a page, so your second PageTabs value overrides the first one. One option is to use a different name for the variable (and parameterize tabs.js functions rather than rely on global vars.)

When using jsp include, one of a very useful skill is to make your .js code modular . This is also an important method to encapsulate code and avoid conflict.
tab.js:
var tabModule = (function(my){
var model;
return {
setModel: function(model){/*....*/}
//other api functions
}
})(tabModoule||{});
Outer.jsp:
tabModule.setModel({PageTabs : "Tab1"});
Innder.jsp:
tabModule.setModel({PageTabs : "Tab2~Tab3~Tab4"});

Related

Using EJS without NodeJS

I figured that the latest build release would allow me to use ejs globally without using node so I tried doing so.
Though, when I try to use ejs.renderFile(params...), i get the error:
TypeError: exports.fileLoader is not a function
Which is just another node module. Is there a way to get around this?
Note: This is the only time we use EJS at my company, so, if not, would you kindly point me in a good direction in how to render .ejs files.
Update: You can create an EJS object by running
new EJS({url: some/url/to/file.ejs}).render({dataToPass: data, moreData: secondData});
yet another way you can use render instead of renderFile, and your ejs file can be get as string:
// here using jQuery
$.get(you_ejs_file_path).then(function (str, status, xhr) {
const html = ejs.render(str, your_data)); // str is ejs file
});

Selenium/ Java how to verify the this complex text on page

I want to verify below text(HTML code) is present on page which as // characters , etc using selenium /jav
<div class="powatag" data-endpoint="https://api-sb2.powatag.com" data-key="b3JvYmlhbmNvdGVzdDErYXBpOjEyMzQ1Njc4" data-sku="519" data-lang="en_GB" data-type="bag" data-style="bg-act-left" data-colorscheme="light" data-redirect=""></div>
Appreciate any help on this
I believe you're looking for:
String textToVerify = "some html";
boolean bFoundText = driver.getPageSource.contains(textToVerify)
Assert.assertTrue(bFoundText);
Note, this checks the page source of the last loaded page as detailed here in the javadoc. I've found this to also take longer to execute, especially when dealing with large source codes. As such, this method is more prone to failure than validating the attributes and values and the answer from Breaks Software is what I utilize when possible, only with an xpath selector
As Andreas commented, you probably want to verify individual attributes of the div element. since you specifically mentioned the "//", I'm guessing that you are having trouble with the data-endpoint attribute. I'm assuming that your data-sku attribute will bring you to a unique element, so Try something like this (not verified):
String endpoint = driver.findElement(
new By.ByCssSelector("div[data-sku='519']")).getAttribute("data-endpoint");
assertTrue("https://api-sb2.powatag.com", endpoint);

Redirect with anchor in play 2

I'm looking for possibility to add anchor to url returned in controller:
public static Result open(String id) {
// here I want to add acnhor like #foo to the produced url
return redirect(routes.MyPage.show(id));
}
I found that it was possible in play 1 using addRef method, but I couldn't find any replacement of the method in play 2.
Of course I can use concatenation like:
public static Result open(String id) {
// here I want to add acnhor like #foo to the produced url
return redirect(routes.MyPage.show(id).url + "#foo");
}
But it seems ugly.
Thank you for any help! Have a good day!
Before trying to answer that question.
I should recommend you change whatever behavior you're currently setting.
Because, an URL fragment's purpose is client side only. Such fragment is never sent to the server, so that it's cumbersome to do the opposite.
However, here is the embryo of a (quite?) elegant solution that you could follow.
What I'll try to do is to leave the browser deal with the fragment, in order to keep potential behaviors (f.i. go to ID or even deal with history...).
To do so, you could add an implicit parameter to your main template which will define the fragment that the URL should have:
#(title: String)(content: Html)(urlFragment:Option[UrlFragment] = None)
As you can see I wrapped the parameter in an Option and default'ed it to None (in order to avoid AMAP pollution).
Also, it simply wraps a String but you could use String alone -- using a dedicated type will enforce the semantic. Here is the definition:
case class UrlFragment(hash:String)
Very simple.
Now here is how to tell the browser to deal with it. Right before the end of the head element, and the start of body, just add the following:
#urlFragment.map { f =>
<script>
$(function() {
//after everything is ready, so that other mechanism will be able to use the change hash event...
document.location.hash = "#Html(#f.hash)";
});
</script>
}
As you can see, using map (that is when the urlFragment is not None) we add a script block that will set the hash available in urlFragment.
This might be a start, however... Think about another solution for the whole scenario.
As of Play 2.4, it's possible to use Call.withFragment().
routes.Application.index.withFragment("some-id").absoluteURL(request)
This was added by PR #4152.

JSP like templating for simple text

I've got a program that currently has a mass of code that I would like to design away. This code takes a number of text files and passes it through an interestingly written interpreter to produce a plain text file report that goes on to other systems. In theory this allows a non-programmer to be able to modify the report without having to understand the inner workings of Java and the interpreter. In practice, any minor change likely necessitates going into the interpreter and tweaking it (and the domain specific language isn't exactly friendly even to other programmers).
I would love to redesign this code. As a primarily web programmer the first thing that came to mind when thinking of "non-programmer being able to modify the report ..." I replaced report with web page and said to myself "ah ha! Jsp." This would give me a nice What You See Is Almost What You Get approach for people along with taglibs and java scriptlets (as undesirable as the later may be) rather than awkwardly written DSL statements.
While it is possible to use jspc to compile a jsp into java (another part of the application runs ejbs on a jboss server so jspc isn't too far away), the boilerplate code that it uses tries to hook up the output to the pagecontext from the servletcontext. It would involve tricking the code into thinking it was running inside a web container (not an impossibility, but a kluge) and then removing the headers.
Is there a different templateing approach (or library) for java that could be used to print to a text file? Every one that I've looked at so far appears to either be optimized for web or tightly coupled to a particular application server (and designed for web work).
So you need a slim down version of JSP.
See if this one (JSTP) works for you
http://jstp.sourceforge.net/manual.html
Give Apache Velocity a try. It is incredibly simple and does not assume it is running in the context of a web application.
This is totally subjective, but I would argue it's syntax is easier for a non-programmer to understand than JSP and tag libraries.
If you want to be a real tread setter in your company, you could create a Grails application to do it and use Groovy templating (maybe in combination with the Quartz plugin for scheduling), it might be a bit of a hard sell if there is alot of existing code to be replaced but I love it...
http://groovy.codehaus.org/Groovy+Templates
If you want the safe bet, then (the also excellent) Velocity has to be it:
http://velocity.apache.org/
Probably you want to check Rythm template engine, with good performance (2 to 3 times faster than velocity) and elegant syntax (.net Razor like) and designed specifically to Java programmer.
Template, generate a string of user names separated by "," from a list of users
#args List<User> users
#for (User user: users) {
#user.getName() #user_sep
}
Template: if-else demo
#args User user
#if (user.isAdmin()) {
<div id="admin-panel">...</div>
} else {
<div id="user-panel">...</div>
}
Invoke template using template file
// pass render args by name
Map<String, Object> renderArgs = ...
String s = Rythm.render("/path/to/my/template.txt", renderArgs);
// or pass render arguments by position
String s = Rythm.render("/path/to/my/template.txt", "arg1", 2, true, ...);
Invoke template using inline text
User user = ...;
String s = Rythm.render("#args User user;Hello #user.getName()", user);
Invoke template with String interpolation mode
User user = ...;
String s = Rythm.render("Hello #name", user.getName());
ToString mode
public class Address {
public String unitNo;
public String streetNo;
...
public String toString() {
return Rythm.toString("#_.unitNo #_.streetNo #_.street, #_.suburb, #_.state, #_.postCode", this);
}
}
Auto ToString mode (follow apache commons lang's reflectionToStringBuilder, but faster than it)
public class Address {
public String unitNo;
public String streetNo;
...
public String toString() {
return Rythm.toString(this);
}
}
Document could be found at http://www.playframework.org/modules/rythm. Full demo app running on GAE: http://play-rythm-demo.appspot.com.
Note, the demo and doc are created for play-rythm plugin for Play!Framework, but most of the content also apply to the pure rythm template engine.
Source code:
Rythm template engine: https://github.com/greenlaw110/rythm/
Play Rythm Plugin: https://github.com/greenlaw110/play-rythm

How to set the Locale Value based on the country the user belongs to

Currently my J2EE Application supports these below countries
MessagesBundle_en_GB.properties (United Kingdom )
MessagesBundle_en_US.properties (United States )
MessagesBundle_it_IT.properties (Italy )
MessagesBundle_pt_BR.properties (Brazil )
MessagesBundle_sv_SE .properties (Sweden)
So i made a properties files for all these countries above and defined the Key value pairs in it .
I am using Resource Bundle for this concept .
And the way i will be accessing the key name is this way
bundle.getString("userName"));
bundle.getString("Mobile"));
Now my question is ,
How can i set the Locale value inside the JSP Page , because the user might belong any of the country as mentioned above
Please let me know , thank you very much
// This one is hardcoded , how can i set this dynamically ??
ResourceBundle bundle = ResourceBundle.getBundle("MessagesBundle", Locale.UK);
use ResourceBundle.getBundle(BUNDLE_NAME).getString(key); to access the Strings.
when updating the Default Locale e.g. via Locale.setDefault(<REQUIRED_LOCALE>); clear the Resourcebundle cache: ResourceBundle.clearCache();
the next call of ResourceBundle.getBundle(BUNDLE_NAME).getString(key); should the return the localized String of the chosen Locale.
The simplest way to do it is to implement HttpFilter. Call it for example LocaleHttpFilter. It should be mapped to/*` in your web.xml, so it will be called every time the request arrives to your application.
The filter will discover your request and decide what should be the current locale. It may base its decision on URL parameters, HTTP headers, GeoIP lookup etc. Once it decided about the locale it should call:
Locale.setDefault(locale)
Then you can use
ResourceBundle.getBundle("MessageBundle").getString("hello");
at any place in your code. This line will return value of string "hello" according to the current locale that was set into the filter.
First thing first: you may use ResourceBundle.getBundle(Locale) in your back-end code. However, you should never use this in the JSP Page directly. You should use JSTL instead. Now, let's get into details.
There are two reasons why it is not necessary the good idea to use ResourceBundle directly. One is related to this:
<%
try {
ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
} catch (MissingResourceException mre) {
// LOG THIS!
}
%>
This looks pretty ugly, doesn't it? That's because you have to beware of MissingResourceException that will be thrown if there is no bundle for base name you are looking for. To make matters worse, the same exception might be thrown if there is no key in the given scenario:
rb.getString("key");
So you also need to take this into account:
<%
try {
rb.getString("key");
} catch (MissingResourceException mre) {
// LOG THIS!
}
%>
How does it look?
Of course you can derive from ResourceBundle and override these methods so they won't throw an exception, but this is substantially more work than just this:
<fmt:setLocale value="fr_CA" scope="session"/>
<fmt:bundle basename="com.taglib.weblog.Greeting">
<fmt:message key="com.taglib.weblog.Greeting.greeting">
This is the reason you should use JSTL with JSP. Read more about how to use JSTL for i18n in this article.
Now, your original question was about language negotiation (W3C term), or Locale detection if you prefer. How to do that in JSP application?
The easiest and most typical scenario is to read the contents of HTTP's Accept-Language header. In Java Servlet world that means calling ServletRequest's getLocale() or getLocales() method and assign to variable in HttpSession object, which is accessible from JSP page. If you wonder how to access HttpSession on the servlet side, there is a getSession() method.
That works if you have direct access to Servlet. If you don't you need to create (or assign existing) Locale filter which will do all that for you. As you may imagine, this is fairly common scenario. That's the reason people already written (long time ago) necessary classes. You can find in few frameworks, let me notably mention Spring Framework.
I know it might sound strange, but if you are looking for simple solution, learning and using common web framework (i.e. Spring MVC) is better that re-inventing the wheel. I know that learning curve might be a bit steep, but it is worth it.

Categories