Skip to main content

4 Remarkable Notes for JSF Apps Using HTML5


In the previous post, I've already shared with you how my team consults clients by using a HTML prototype. This post is about the used technologies for reusing the provided HTML template and communicating with backend.

What is the issue when using HTML elements with Primefaces components?

Primefaces is a great extension for developing JSF web apps. However, it is really frustrating in case we have to make it work with an existing HTML template. Why?
- Primefaces has its own theme for styling.
- Primefaces changes the HTML structure.
Therefore, that would be a huge effort to use the Primefaces' components to replicate the elements of the HTML template; especially it is impossible for images drawing by "canvas" tag.

That requires us to find a better approach. Since Java EE 7 (introducing JSF 2.2 included), it supports to use HTML5 elements. The idea is that JSF components don't effect the style and HTML structure, so we can easily reuse the provided HTML template. Moreover, we're still able to use Primefaces "No-GUI" components such as "p:ajax", "p:remoteCommand'.

1. JSF Alternatives for HTML5 elements

We can choose to use JSF components, HTML5 elements, or both. Take a look the table "How Facelets Renders HTML5 Elements" of the following link for more detail.
https://docs.oracle.com/javaee/7/tutorial/jsf-facelets009.htm
For example:
<html ... xmlns:jsf="http://xmlns.jcp.org/jsf"
...
    <input type="email" jsf:id="email" name="email"
           value="#{reservationBean.email}" required="required"/>

2. Radio button or How to make a trick for events

There is no JSF component for radio elements. We have to build an alternative by our own. For example:
<div id="gender">
 <div class="control">
  <input type="radio" name="option" checked="true"
   onclick="document.getElementById('gender-hidden-input').setAttribute('value', '0'); onGenderChange();" value="0"></input>
  <label class="control__label" for="optionone">Option One</label>
 </div>
  
 <div class="control">
  <input type="radio" name="option" 
    onclick="document.getElementById('gender-hidden-input').setAttribute('value', '1'); onGenderChange();" value="1"></input>
  <label class="control__label" for="optiontwo">Option Two</label>
 </div>
  
 <h:inputText value="#{data.dataModel.gender}" styleClass="hidden" type="text" id="gender-hidden-input" />
 <p:remoteCommand name="onGenderChange" actionListener="#{logic.onGenderChange}" update="growl"></p:remoteCommand>
</div>

3. Dialog or How to custom Ajax requests

For dialogs/pop-ups, we can use a JQuery library like basicLightbox. We can use "p:remoteCommand" to call ajax  requests to backend. The following is an idea for passing a javascript function as param when executing from different places.
...
okElem.forEach(function (elem) {
 elem.onclick = function (e) {
  
  if(elem.classList.contains("mf-ui-disabled")){
   return false;
  }
  
  var ajaxRequestor = elem.getAttribute('data-ajax-requestor');
  if(ajaxRequestor){
   executeFunction(ajaxRequestor); //ajaxRequestor is a javascript function name which can make by "p:remoteCommand"
  }
  
  instance.close();
  e.preventDefault();
 };
});

...

function executeFunction(functionStr){
 var fn = window[functionStr];
 if (typeof fn === "function") fn();
}

4. Images Exporting

So far, html2Canvas has been the only one library can help us satisfy the requirements of exporting images from client side for all supported browsers including Chrome, Firefox and IE11. Almost other libraries for "html and canvas conversion" won't work with IE due to IE does not support SVG <foreignObject> tag. A fun fact here is this library even has not been released at the time we applied it for our project.
function exportProductChart(){
 
 var productHouse = document.querySelector("#overallPdfExportHouseWrapper");
 
 html2canvas(productHouse, {
   scale: 3,
      onrendered: function(canvas) {
       var productHouseImg = canvas.toDataURL("image/png");
       onClickExportPdfDialogOkBtn = function() {//override the function "onClickExportPdfDialogOkBtn" because this function can be called in another place.
     PrimeFaces.ab({
      s:"onClickExportPdfDialogOkBtn",
      f:"mainForm",
      p:"pdfExportDialog",
      u: "pdfExportDialog",
      onco:function(xhr,status,args){
       $('[id$=downloadPdf]').click();
      },
      pa:[{name: "mfDialogAction", value: "productChartExport"},
          {name: "productChoiceHouse", value: productHouseImg}]
     });
    }
    onClickExportPdfDialogOkBtn(); //p:remote command
    }
 });
}

References:
[1]. http://www.oracle.com/technetwork/articles/java/enterprise-html5-2227136.html
[2]. https://docs.oracle.com/javaee/7/tutorial/jsf-facelets009.htm
[3]. https://github.com/tsayen/dom-to-image

Comments

  1. Chào anh Hương, em là sinh viên mới tiếp cận Java và CNTT nên không biết nhiều. Em đang định dùng lại code mã nguồn mở của SweetHome 3D nhưng mò mẫm mãi vẫn không xem được code của họ. Mong anh chỉ giáo

    ReplyDelete
    Replies
    1. Chào bạn!
      Tôi chưa có kinh nghiệm lập trình với SweeHome 3D, nên tôi sẽ chỉ có thể cho lời khuyên:
      1. Bạn nên làm theo hướng dẫn này Developer Guide. (phải cái bạn nỏi không??)
      2. Bạn xem source code của file jar (Download) bằng java decompiler (vd: JD) hoặc cài plugin decompiler trên Eclipse.

      Không biết bạn đã tham gia cộng đồng này Dạy Nhau Học chưa, nếu chưa thì bạn có thể lên đây đặt câu hỏi và chia sẻ lại với mọi người.

      Delete

Post a Comment

Popular posts from this blog

My must-have apps for daily work

There is no doubt that cool apps can help us be more productive and enjoyable at work. For the time being, I really love the following apps which are used by me almost every day. 1. A personal Kanban In fact, a personal kanban is the most useful app for me. Why does it matter? It is not just a to-do list, but it keeps me motivated every day because it helps me be able to know what my "big picture" is. I usually set up my plans together with a path to reach them.  KanbanFlow  is my preferred tool. KanbanFlow 2. A terminal Needless to say, a terminal is a must-have app for every developer, especially the ones use macOS/Linux. Due to its importance, I love to decorate and enhance it to be super exciting with various tools such as  iTerm ,  oh-my- zsh , and  thefuck . ;) iTerm + oh-my-zsh 3. A documentation "ecosystem" As a developer, I can not remember all things that I have experimented a day. Moreover, a document is really useful for sharing an...

Monday vhandit #1

This is the first post in a series of articles called "Monday vhandit". You can go to the original post by clicking on each head title. Character encodings: essential concepts This article points out why Unicode matters and differentiates among concepts: character sets, coded character set (unit is code points), and character encoding. Explained from First Principles: the Internet The very structural and well-explained article contains almost concepts of the Internet. I really appreciated the author's effort put on that post. Dev Community - DevDojo I just joined this community. DevDojo is really a developer-oriented platform. It is very nice, easy, fast, and sufficient to write (Markdown supported) and search for a post. The best of it, you also have a personal blog for your posts at "<your_username>.devdojo.com". My username is vnnvanhuong Everything you need to know about HTTP security headers A good collection of HTTP security-related headers. Moreover...

Selenium - Override javascript functions to ignore downloading process

I have got an issue with downloading process on IE 8. This browser blocks my automatic-download functionality on my app so that I could not work with my test case any more after that. In my case, I didn't care about the file is downloaded or not, I just focus on the result after downloading process finished successfully. Therefore, I found a solution to ignore this process so that I can work normally. I use Primefaces, here is the remote command to trigger the download process <p:remoteCommand name="cmdGenerateDocument" actionListener="#{logic.onGenerateDocument}" update="xrflDocumentCreationPanel" oncomplete="clickDownloadButton();"/> The following is my test case: @Test public void shouldUpdateStep6ToWarningIfStep1IsValidAfterFinished(){ MainPage mainPage = new MainPage(); waitForLoading(mainPage.getDriver()); EmployeeDetailPage empDetailPage = new EmployeeDetailPage(); waitForLoading(empDetailPage.getDriver()); e...

My 2017 Review

Passion for System Design After finishing a one year project, my longest stable team (lasted for 3 years) was separated into two smaller teams. Sadly, but that was a good chance for me to become a key member in my new team. My preferred skills were about system architectures; therefore most of the tasks of building the application structures were handled by me. In order to enhance my design system skills, I have spent much my time for reading books closely after work. These following books help me a lot. - Object-Oriented Thought Process | Matt Weisfeld - Head First Design Pattern  | Elisabeth Freeman and Kathy Sierra - Java 8 in Action: Lambdas, Streams, and Functional-style Programming | Alan Mycroft and Mario Fusco Junior Technical Architect I was requested to join a technical architect team (aka Team. Alpha) where I actually had gained experiences almost on interviewing candidates for my company (lol). Besides, I noticed myself must improve the skills of convinci...