3

I am using j2html to create render html pages via Java, if the html called any javascript function I was putting the Javascript into a separate .js file. However it seems sensible to only include functions is the main application javascript file if they are general purpose functions used by multiple pages. A function written specifically for one page shod be stored somewhere else, creating separate .js files for each page is an administrative nightmare so I want to put them into the html itself near the calling code.

I can do this easily enough, and below is an example created by copying function directly from .js file and wrapping within j2htmls script and rawHtml tags. My problem is that the Javascript code within my Java code is not as readable as it is when within the seperate js file.

Is there any way I can write it in a neater more readable way ?

private Tag artwork()
{
  return script(rawHtml("function artwork() {\n" +
          "    \n" +
          "    select   = document.getElementById('fsArtwork');\n" +
          "    selected = select.options[select.selectedIndex].value;\n" +
          "    if(selected==0)\n" +
          "    {\n" +
          "    \tdocument.getElementById('saveArtworkFilename').disabled = true;\n" +
          "    }\n" +
          "    else\n" +
          "    {\n" +
          "    \tdocument.getElementById('saveArtworkFilename').disabled = false;\n" +
          "    }\n" +
          "}"));
}

In the comments below I keep getting asked why I don't want to use templates , there are a number of reasons:

My webpages are not currently created with templates so it would seem if I wanted a html page with some javascript in it and used templates as suggested I would have to redo the whole page using templates

Since I wouldnt want to write my html in multiple different ways I would be duty bound to redo all my pages in templates

So why didn't I used templates in the first place ?

First of all the main advantage of templates is to separate what the web-developer does from the server developer. I am doing both so there is not an advantage for me. I use a separate stylesheet so if at a later date I want a web-designer to improve the look by modifying the style then they can do that, templates dont help.

Another advantage is code readability, this what certainly true when comparing jsps to servlet code but is not true when comparing to j2html. This lib ensures I can only create wellformed code, and that I can take advantage of Java for creating dynamic and data based pages much more easily then templates.

Using templates would require learning their esoteric ways

Using templates would complicate build and deployment

Webpages generated from templates is considerably slower than pure Java, from j2html website You think template engines are too slow. This index page was rendered 100 000 times in less than a second on an i5-4670. That's about a thousand times faster than Apache 'Velocity' (hah!)

Trying Tipsy's answer

When I try to generate the page it complains

Couldn't find file with path='javascript/artwork.js'

My code contains the existing external files initilization and a location within the main classpath (newly added). Is it okay to have both.

    staticFiles.externalLocation(Platform.getPlatformReportFolder().getPath());
staticFiles.location("");

scriptWithInlineFile_min("javascript/artwork.js"),

Within the main jar file (songkong-4.13.jar) that contains the manifest the javascript file is located within javascript folder which is top level folder within the jar.

I do notice that within the manifest songkong-4.13.jar itself is not listed in the Class-path, this have never been an issue but could that be the issue now ?

Also within my Intellij project itself the javascript folder is in src/main/resources, this seemed to be the default but it would not work running within IntelliJ either.

Now working in Dev

The problem was that I was using a relative path

scriptWithInlineFile_min("javascript/artwork.js")

instead of

   scriptWithInlineFile_min("/javascript/artwork.js")

So it now works in dev.

But when I build it and run outside of dev it is not finding the file again, even though it there in the main jar file directly as /javascript/artwork.js

Further Update

It was a bug in j2html https://github.com/tipsy/j2html/issues/84 but was fixed in 1.2.1 and I was using 1.2.0, now everything is working.

In Summary

I don't know if you would call this templating or not but works perfectly for me. The page specific javascript can be written in file, but then embedded into the rendered html file , and because in main jar no additional deployment issues that you would have if actually deployed as standard files.

29
  • Yeah, don't write HTML in Java. Put it in a template. Commented Jan 25, 2018 at 15:05
  • 1
    Html is not the issue, j2html works great and is much better than templating solutions, the issue is specific to javascript within the html Commented Jan 25, 2018 at 15:27
  • Irrelevant; it's still going to the browser, it doesn't matter which it is. You put it in a template. As to whether or not h2html is "much better than templating solutions", that's an opinion, one I don't share: I'd rather write HTML in an HTML-aware editor with HTML attribute completion etc. Neither here nor there--any time you're trying to write one language in another you'll end up with an impedance mismatch. Put the JS in a file and send the file contents. Commented Jan 25, 2018 at 15:35
  • Html editor fine for basic static webpages but when you are creating dynamic pages then j2html is much beter than any templating solution I have tried, you should try it. Anyway what is irrelvant is diuscussing html as my answer is specifically about Javascript, Commented Jan 25, 2018 at 18:55
  • Still belongs in a file. Every page I make is dynamic-but there are much easier Solutions available. ¯_(ツ)_/¯ Commented Jan 26, 2018 at 0:26

2 Answers 2

3

I think you should write your JavaScript in .js files. Include them either via script().withScr("/path/to/file.js") (if the file is hosted), or via scriptWithInlineFile_min("/path/to/file.js") (if you want to read the file from the classpath/file-system).

Sign up to request clarification or add additional context in comments.

5 Comments

So if I understand you right as long as your .js is within your main jar and its path is valid within that jar relative to the staticFiles.location() then the generated html page will contain the contents of the javascript directly within the html page (rather than a link to an external js file) without me having to directly put the javascriupt within the j2html java page itself. Sounds perfect, cant get it working at the moment though, Im updating my question to show the error.
Ive marked as correct as seems like right answer, but still cannot get it to work
If you're using scriptWithInlineFile_min(...) you don't need to use staticFiles.location(...). scriptWithInlineFile_min(...) reads the file from the classpath/file-system and returns it as a String. You can have a look at the tests for this method to see how it works: github.com/tipsy/j2html/blob/master/src/test/java/j2html/tags/…
The problem I was using a relative path scriptWithInlineFile_min("javascript/artwork.js") instead of scriptWithInlineFile_min("/javascript/artwork.js"), it now works. Files are stored under resources in my maven project)
Also I was using j2html 1.2.0 that has a bug that prevents reading resources from jar file so that prevented working in production, updating to 1.2.2 fixed the issue.
0

(Delta I barely remember Java, and I know you don't need some sort of StringUtils to join anymore.)

private Tag artwork() {
  String[] js = [
    "function artwork() {",
    "  select   = document.getElementById('fsArtwork');",
    "  selected = select.options[select.selectedIndex].value;",
    "  if (selected === 0) {",
    "    document.getElementById('saveArtworkFilename').disabled = true;",
    "  } else {",
    "    tdocument.getElementById('saveArtworkFilename').disabled = false;",
    "  }",
    "}"
  ];

  return script(rawHtml(StringUtils.join(js, "\n")));
}

But I'd still put it in a template, load and populate, and ship that to the client. The code generated by any reasonable template engine will end up being almost this anyway.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.