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

Junit - Test fails on French or German string assertion

In my previous post about building a regex to check a text without special characters but allow German and French . I met a problem that the unit test works fine on my machine using Eclipse, but it was fail when running on Jenkins' build job. Here is my test: @Test public void shouldAllowFrenchAndGermanCharacters(){ String source = "ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ"; assertFalse(SpecialCharactersUtils.isExistSpecialCharater(source)); } Production code: public static boolean isExistNotAllowedCharacters(String source){ Pattern regex = Pattern.compile("^[a-zA-Z_0-9_ÄäÖöÜüß áÁàÀâÂéÉèÈêÊîÎçÇ]*$"); Matcher matcher = regex.matcher(source); return !matcher.matches(); } The result likes the following: Failed tests: SpecialCharactersUtilsTest.shouldAllowFrenchAndGermanCharacters:32 null A guy from stackoverflow.com says: "This is probably due to the default encoding used for your Java source files. The ö in the string literal in the J...

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...

Performance of a Data Structure

Why data structures matter The fact is that programs are all about processing data. Data structures are referred to how data is organized which affects the time of executing a program. How to measure the performance of a data structure In order to measure "how fast"/efficiency/performance of a data structure, we measure the performance of its operations. There are four basic operations including reading , searching , insertion , and deletion . A pure time consuming is not used for the measuring because it is not reliable depending on the hardware that it is run on. But instead, we use the term time complexity which refers to how many steps an operation takes. An example of how a single rule can affect efficiency Let's compare two data structures: Array and Set (with N elements). 1. Array - Reading : 1 step (because the computer has the ability to jump to any particular index in the array) - Searching : N steps (the worst case with linear search) - Inserti...

BarcampSaigon 2015

Barcamp Saigon is one of my most expected events of the year. This year, it took place at RMIT university. As usual, it brought many useful topics to the community. Here is all topics that I have attended. Scale it! - Lars Jankowfsky Lars is founder of 8bitrockr.com How do we make a decision correctly? It is hard to know that until we try and measure it. He gave an example about how good an app was. And, most of people thought that the app with nice user interfaces is good at the first look. But it is not correct because it is only true until we try to use it, even the nice GUI app sometime is not good at UX, functionalities, etc. The key of success for working in team is collaboration. We can not only base on the experience of members likes: "In my opinions| As I know.... this is the best way..bla..bla.." but we should test it. Therefore, manually testing as well as automation testing is more and more necessary nowadays. "Don't think, just try...