SVG Image www. .com cs-cubed http:// Integrating SVG with AngularJS and JSF http://www.cs-cubed.com

Scalable Vector Graphics (SVG) and AngularJS are client-side applications, and JavaServer Faces is a server-side application. Some preliminary investigations have been made in integrating these. Links to the relevant sections on this page are given, together in some case with links to several examples as follows:

(I) Integrating SVG with JSF - Examples: Tucson bus routes, and Locating items in a store.

(II) Integrating AngularJS with JSF

(III) Integrating SVG with AngularJS - Examples: Analog and digital clocks displaying the current time.

(IV) Integrating SVG with AngularJS and JSF.

(V) A fun application using jQuery to show graphically the calculated date of Easter Sunday for a particular year.

I. INTEGRATING SVG WITH JSF

SVG is a client-side XML language used to display 2D graphics in a browser, and incorporates the capability of animation, in addition to being able to use JavaScript for animation. The display at the top of this page makes use of SVG animation. However, as some versions of Internet Explorer (IE) cannot render animation properly, conditional JavaScript compilation is used to test for IE, and if IE is used, a static image of a screen shot is displayed instead.

JavaServer Faces (JSF) is a server-side framework based on the Java Enterprise Edition used to generate dynamic web pages. Normally SVG is not associated with JSF, and very little documentation on integrating the two appears to be available.

By incorporating SVG with JSF, an extra level of flexibility can be obtained with computer graphics. An example is to produce an interactive map of an urban transport system using buses, trams, metros, trains, etc. Nearly all such maps include curves in the routes, which can be modelled very well using quadratic and cubic Bézier curves. This can easily be done with SVG, which can also be used to animate the position of a public vehicle along its path with time using GPS, if available, otherwise based on a timetable. By using JSF with suitable databases, such a system can be set up for many urban transport systems. Many other applications are possible.

An example of a prototype trial version of the Tucson Suntran bus routes was created by digitizing many of the bus routes used in the August 2014 map, put on a web server, then viewing the generated SVG code in a browser, and copying and pasting this code to the page here. Note that this may not be correctly displayed in Internet Explorer. Another example of prototype code is shown on the page here for locating items in a large store, but again Internet Explorer may not work correctly.

JSF 2.2 has a number of improvements over previous versions, including the ability of making it fully HTML 5 compliant. One particular feature of considerable interest is being able to pass through attributes of HTML 5 tags. Unfortunately, this does not work with SVG tags. However, a method has been developed that can simulate this, so that a block of SVG code can be incorporated in an XHTML file that can be converted to a form that JSF can understand, then is rendered correctly in a browser.

Below is a description of how to integrate SVG with JSF. It assumes that you have Eclipse installed.

1. Setting up SVG with JSF

First create an empty JSF application with a project name, such as "svgwithsjf", and in the \src folder create a package such as "myjavasvg". The default set-up will be:

-svgwithjsf
| -src
| | -myjavasvg
| | | MainSvgToJsf - This Java class contains a main method that is run from the
                     console in Eclipse
| | | JSFClass1 - One or more beans and possibly regular classes used to
| | | JSFClass2   generate dynamic HTML that is rendered on the client.
| | | JSFClass3
| | | .........
|
| +Other resources created by Eclipse.
|
| -WebContent
| | +META-INF - Created by Eclipse
| | -resources - Optional resources that my contain folders for CSS, images and
| | |            JavaScript
| | | -css
| | | -img
| | | -js
| |
| | +WEB-INF - Contains the normal XML files created by Eclipse that may be
| |            edited, and may optionally contain additional libraries.
| |
| | index.html       - Zero or more regular HTML files with no SVG code.
| | index.xhtml      - Zero or more XHTML files that are directly created with
| |                    no SVG code
| | generated1.xhtml - One or more XHTML files containing SVG code that have
| | generated2.xhtml   been generated using MainSvgToJSF above.
| | generated3.xhtml
| | ................
|
| rawsvg1.xhtml      - One or more input XHTML files containing raw SVG code
| rawsvg2.xhtml        that will be read by MainSvgToJSF, and will be converted
| rawsvg3.xhtml        to "generated1.xhtml", etc.

where the package or packages in the \src folder contain the Java class MainSvgToJsf, raw input XHTML files containing SVG code are placed in the root folder, and any HTML or XHTML files that do not contain SVG code are placed in the default \WebContent folder.

2. Raw SVG files with XHTML code

When MainSvgToJsf is executed via the Eclipse console, it will read the required raw SVG files and convert them to the required XHTML files, which will be written to the \WebContent folder. Note that Eclipse will flag the SVG tags in the input files as errors, as these tags are not recognised, but these errors should be ignored.

The raw SVG files must conform to the following rules:

A. The start of the file and the head are exactly as a regular XHTML file, including the required namespaces for JSF. All regular HTML, XHTML, comments and JavaScript, etc. in the head and the body are left unchanged, and are passed through to the output file.

However, optionally if Facelet tags (prefixed by "ui:") are otherwise not used, its namespace can optionally be added to the HTML opening tag as:

xmlns:ui="http://java.sun.com/jsf/facelets"

which will affect the output from (B) below.

B. If data are being passed to a bean property in sections (D4) to (D6) with SVG tags, see section (D), then the bean name must be specified in the input XHTML code at any point before the first occurrence of an SVG tag as:

<!-- {beanName} -->

where "beanName" is the name of the bean that SVG uses in this file. If the ui namespace is omitted in (A), then this line will be copied over to the output XHTML file and will be visible in the browser's source. If the ui namespace is present, then the comment will be embedded between ui:remove opening and closing tags as:

<ui:remove><!-- {beanName} --></ui:remove>

which will cause the comment not to be sent out to the browser, so will not be seen, but will still be present in the XHTML output source.

Note that if the bean name is not specified when data are to be passed to it via an SVG tag, an error will be flagged and the program will end. As stated above, this can be omitted if no data are to be passed to a bean via SVG tags.

C. The first line of SVG code is written as would be in a regular HTML or XHTML file, e.g. as:

<svg width='300' height='250'>

and will be converted to XHTML output as in (D2). Alternatively, it could be used to pass arguments to a bean property, see (D4) and later.

D. Subsequent lines of SVG code can be written in one of several forms as follows:

1) A simple SVG tag without any attributes:
   a) <tag>
      This will be converted to:
   b) <h:outputText value="&lt;tag&gt;" escape="false" />
      The browser's source will display the code converted back to (a).
				
   Example:
   c) <g>
   d) <h:outputText value="&lt;g&gt;" escape="false" />
      and (d) will be displayed as (c) in the browser's source.
   Nothing is passed to a bean, so the bean name is not referenced.

2) An SVG tag with SVG attributes:
   a) <tag svg_at1='s1' svg_at2='s2' ...>
        This will be converted to:
   b) <h:outputText value="&lt;tag svg_at1='s1' svg_at2='s2' ... &gt;"
         escape="false" />
   As with (1), the browser's source will display the original code in (a),
   and nothing is passed to a bean.
	 
   Example:
   c) <circle id='myId' cx='50' cy='95' r='50' style='fill:green'/>
      This will be converted to:
   d) <h:outputText value="&lt;circle id='myId' cx='50' cy='95' r='50'
         style='fill:green'/&gt;" escape="false" />
   The output code in (1) and (2) avoids Eclipse complaining that it does not
   recognize the SVG tag, as it is now embedded in the <h:outputText ... />
   tag.  However, the SVG tag could still be directly inserted in the final
   XHTML file if one can put up with the error flagged by Eclipse.
	 
3) For the sake of completeness, XHTML attributes in addition to possible SVG
   attributes can be passed to the <h:outputText .../> tag in addition to the
   value and escape attributes.  Any SVG attributes are passed as in (2) above,
   thus:
   a) <tag |xhtml_at1='x1' xhtml_at2='x2' ... | svg_at1='s1' svg_at2='s2' ... >
      This will be converted to the following code:
   b) <h:outputText xhtml_at1='x1' xhtml_at2='x2' ...
        value="&gt;tag SVG_at1='s1' SVG_at2='s2' ... &gt;" escape="false" />.
   However, this is not particularly useful as most of the attributes are placed
   in a <span> tag surrounding the rendered SVG code, and as this tag is part of
   HTML but not SVG, this will not be understood by the browser.  An exception
   is the JSF render attribute, which will determine if the component is
   rendered.
   
   Nevertheless, an example is:
   c) <circle |id='jsfId' class='myClass'| id='myId1' cx='250' cy='100' r='45'
        style='fill:orange'/>
      which is converted to the XHTML code as:
   d) <h:outputText id="jsfId" class="myClass" value="<circle id='myId1'
        cx='250' cy='100' r='45' style='fill:orange'/>" escape="false" />
      However, the browser's source displays:
   e) <span id="jsfId" class="myClass"><circle id='myId1' cx='250' cy='100'
        r='45' style='fill:orange'/></span>
      but the orange circle here will not be displayed because the HTML <span>
      tag is placed in a block of SVG code.  Although the <foreignObject> tag
      can be used to embed HTML code in a block of SVG code, see (F), this will
      not work in this case.
			
   Note that for options (1), (2) and (3), the bean name is not used, so (B) can
   be omitted if it is not used elsewhere, as stated earlier.

4) Passing SVG attributes to a bean property:
   a) <#prop.tagx svg_at1='s1' svg_at2='s2' ... >
      where the characters have the following meanings:
      i)   "#" - Indicates that data will be passed to a bean property.
      ii)  prop - The bean property name, the bean name is added, see below.
      iii) x - Specifies optional additional information.
      iv) svg_at1 svg_at2 etc. - The SVG attributes and 's1', 's2' etc. are
            their corresponding respective values.
      The character or characters, as x, immediately following the tag name can
      be used for formatting and sending additional data.  By default rendered
      SVG code in the browser's source does not include new lines, so this can
      be used to clean that up.  The following options are available:
      Nothing - No additional information is sent to the bean.
      '[' - The SVG tag starts on a new line.
      ']' - A new line is added after the end of the SVG tag.
      '+' - The SVG tag starts on a new line and a new line is added after the
            end of the tag.
      '[d', ']d' or '+d' - One of the last three above plus one or more
            characters, most likely digits, that can be used to pass additional
            information to a bean, such as being able to sort SVG tags in an
            array.
       '!d' - As the precious option, but no new lines are generated.
      This will be converted to the output XHTML file as:
   b) <h:outputText value="#{beanName.prop('tag','svg_at1=|s1| svg_at2=|s2|'
          ...','x')}" escape="false" />
      The attribute values here are placed between pairs of "|" symbols as sent
      to the bean property rather than quotes, as both single and double quotes
      are already used, and this is in preference to escaping quotes.  If the
      bean property returns the values as given in first two arguments of prop,
      then the source rendered by the browser will be of the form:
   c) <tag svg_at1='s1' svg_at2='s2' ...>
			 
   Example:
   d) <#circprop.circle[ cx='120' cy='85' r='60' style='fill:red'/>
      This will be converted to:
   e) <h:outputText value="#{svg.circprop('circle','cx=|120| cy=|85| r=|60|
         style=|fill:red|/','[')}" escape="false" />
      where the bean name, "svg", has been picked up from (B), and "circprop"
      has 3 arguments picked up from (d), namely the SVG tag "circle", the
      attributes of the circle tag, and the formatting character '['.
      In the browser's source this will be rendered as:
   f) <circle cx='120' cy='85' r='60' style='fill:red'/>
      except that now the values of cx, cy, r and style have been passed to a
      bean property, and can be processed for scaling, etc.  Note that because
      of the formatting character '[' this starts on a new line.  If immediately
      following the formatting character there are additional characters, such
      as "[pqr", the string "pqr" will be passed to the bean property where it
      can be used for tagging SVG components in the bean, or particularly if
      digits are used, can be used to sort SVG components in a list.

5) Handling XHTML attributes in addition to passing SVG attributes:
   Several XHTML attributes can be handled in the same way as (3) by placing
   them between a pair of "|" characters, except that the first "|" must follow
   "#prop.tagx " in (4) including a space.  The same restrictions as in (3)
   apply.  However, a more useful case is when one XHTML attribute, and only
   one is allowed, is passed to a bean property in addition to the SVGattributes
   in the following form:
   a) <#prop.tagx |xhtml_at='#{xt}'| svg_at1='s1' svg_at2='s2' ... >
      where xhtml_at is the xhtml attribute, and xt is a bean property.  This
      will be converted in the output XHTML file as:
   b) <h:outputText xhtml_at="#{beanName.xt}" value="#{beanName.prop('tag'
        'svg_at1=|s1| svg_ar2=|s2| ... ','x')}" escape="false" />
      When this is rendered in the browser's source, the output could be:
   c) <tag svg_at1='s1' svg_at2='s2' ...>
      but depending on xhtml_at, it may be modified.  Note that as with (3),
      several attributes are rendered in an enclosing <span> block, which is
      invalid SVG.

   Example:
   d) <#circprop.circle[xyz |rendered='#{render}'| cx='30' cy='30' r='30'
         style='fill:blue'/>
      This is written as the xhtml output file as:
   e) <h:outputText rendered="#{svg.render}" value="#{svg.circprop('circle',
         'cx=|30| cy=|30| r=|30| style=|fill:blue|/','[xyz')}" escape="false" />
      and depending on the boolean value returned by render getter in the svg
      bean, this will either be displayed as a blue circle in the browser with
      the source as:
   f) <circle cx='30' cy='30' r='30' style='fill:blue'/>
      or nothing.
    Note that in the case the SVG tag starts on a new line when it is displayed
    in the browser's source and "xyz" are passed to the bean.
			
6) The final option is the omission of the name of the bean property, and use
   the SVG tag name as the property name.  Thus:
   a) <#.tagx svg_at1='s1' svg_at2='s2' ... >
      becomes:
   b) <h:outputText value="#{beanName.tag('tag','svg_at1=|s1| svg_at2=|s2|
         ...','x')}" escape="false" />
      where the property of the bean is the same as the tag name.
   The rules as specified for (4) and (5) are otherwise the same. 
E. Closing tags:
At the end of the SVG block of code, it must be closed using:
   a) </svg>
      This will be converted to:
   b) <h:outputText value="</svg>" escape="false" />
      which will be rendered as (a) in the browser's source.

Likewise all other closing SVG tags are treated in the same way. Nothing is passed to a bean property, even xhtml attributes.

F. Embedding HTML and XHTML code in a block of SVG code:

For this the embedded code must be placed between the opening and closing <foreignObject> tag. This tag can be treated as any other SVG tag, and can take attributes that can be passed to a bean property, as discussed above.

An example is:
   a) <#circprop.foreignObject[abc x='150' y='150' width='100' height='150'>
      which will be converted to:
   b) <h:outputText value="#{svg.circprop('foreignObject','x=|150| y=|150|
         width=|100| height=|150|','[abc')}" escape="false" />
      and in the browser's source will be shown as:
   c) <foreignObject x='150' y='150' width='100' height='150'>
	 
   Following the opening tag, any regular HTML and XHTML code can be placed,
   including CSS and JavaScript.
	 
   The foreignObject tag should be closed with:
   d) </foreignObject>
      which will be converted to:
   e) <h:outputText value="</foreignObject>" escape="false" />
      then in the browser's source will be dislayed as (d).
G. Handling other code:
1) Everything between <!-- and --> is treated as a comment, so is passed to the
   output XHTML file without any changes, except as noted in (B).
	 
2) JavaScript code between the opening <script> and </script> tags is passed
   through to the output XHTML file without any changes in a block of HTML or
   XHTML code.  However, inside a block of SVG code, but outside any
   <foreignObject> tag, a CDATA block surrounds the JavaScript code between the
   opening and closing <script> tag.  Thus given the following code in the input
   file:

   <script>
     // Lines of JavaScript code.
   </script>
	 
   This will be written to the output XHTML file as:
	 
   <script><![CDATA[
     // Lines of JavaScript code.
   // ]]></script>
	 
3) All other code, including CSS, and anything else is passed through without
   any changes.
H. Ending the Input File

Any HTML or XHTML file should have the closing </html> tag. In addition, this application uses it to indicate the end of the input data, so anything after it is ignored. This can be used to add comments or notes after the closing tag in the input file which will not be copied to the output file.

3. Running the Application

After setting up the files in Eclipse as given in section (1), and creating raw SVG files as given in section (2), the following steps need to be performed:

A. With the Java class containing the main() method, in the application here it is called MainSvgToJsf, run it as a Java application, and it will start a console session.

B. The console will prompt for the input file name, so enter its name and MainSvgToJsf will read that file from the root of the project. If the file is not found, it will end with an error.

C. The console will then prompt for the output file name, so enter its name or enter "." to use the same name as the input file. The output file will be written to the \WebContent folder, so it will not overwrite the input file. Files in the \WebContent folder are read by the JSF framework, which ignores any files in the project's root folder.

D. To view the output XHTML file in the \WebContent folder, refresh the project by clicking on the project's folder name, then press the F5 key or right click and select "Refresh" from the menu.

E. If the server is already running, stop it then restart it so that it picks up the output XHTML file.

F. Open a browser window and go to http://localhost:port/projectName (usually the port number is 8080), and if there are no errors the browser should display the graphics generated by the SVG code. On looking at the browser's source, the SVG code itself should be visible. If there are any errors, stop the server edit the input file, and repeat the steps from (B). The previous output XHTML file will be overwritten. Of course the output file can also be edited, but in that case care has to be taken not to overwrite it.

G. Once any errors have been corrected, a war file can be created using Eclipse by right clicking the project's root folder, selecting Export -> WAR file, then type the destination folder. Note that the war file will not contain any input XHTML files that are in project's root folder in the Eclipse application. However, it will contain the compiled class containing the main method for the console application, as well as the source code, if on generating the war file the source code option had been selected.

As the console application is not used in a deployed web application, it can be removed using the following steps in Windows:

a) Rename the war file to a zip file.

b) Uncompress the zip file.

c) Delete the compile console application class file in the path below the
   \WEB-INF folder.  If the source code is also present, delete it.
	 
d) Recompress the project folder back to the zip file.

e) Rename the zip file back to the war file.
4. Example of a Test Application

A. Directory setup in Eclipse

An example is given here for a minimal test application using Eclipse. The Eclipse project folder \svgtojsf contains the following structure:

-svgtojsf
| -Java Resources         - Generated by Eclipse.
| | -src                  - Generated by Eclipse.
| | | -svgtoxhtml         - Package
| | | | MainSvgToJsf.java - This class contains the main method to run the
| | | |                     console application.
| | | | Svgbean.java      - The bean used to handle the XHTML and SVG code.
| | +Libraries            - Generated by Eclipse.
| +JavaScript Resources   - Generated by Eclipse.
| +build                  - Generated by Eclipse.
| -WebContent             - Generated by Eclipse.
| | +META-INF             - Generated by Eclipse.
| | -WEB-INF              - Generated by Eclipse.
| | | +lib                - Generated by Eclipse but by default is empty.
| | | faces-config.xml    - Generated by Eclipse.
| | | glassfish-web.xml   - Generated by Eclipse.
| | | web.xml             - Generated by Eclipse.
| | index.html            - An optional HTML starter page that redirects the
| |                         URL to index.face, which is index.xhtml.
| | index.xhtml           - An XHTML page containing a form and a button used
| |                         to initialize the bean.  On clicking the button
| |                         the svgtest.xhtml is rendered.
| | svgtest.xhtml         - The page containing the XHTML, HTML and SVG code,
| |                         and renders the SVG graphics using Svgbean, and is
| |                         output file generated by MainSvgToJsf.
| svgtest.xhtml           - The input XHTML file containing the raw SVG code
|                           that is read by MainSvgToJsf.  Note that as stated
|                           above, it is not written to the war file.

B. Input XHTML file containing raw SVG code

Note that all the code here and in the following sections has been reformatted to fit the width of the text above. In some cases new lines have been added and some spacing has been altered, but otherwise there are no other changes.

<?xml version="1.0" encoding="UTF-8"?>   
<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
  <h:head>
    <title>Code Test</title>
  </h:head>
  <h:body>
    <h1>Here is an example of SVG in an xhtml page</h1>
    <h:outputText value="This is a test"/>
    <!-- Here is a comment outside svg -->
    <script>
    // This is a script outside svg
    </script>
    <h:form id="myForm" prependId="false">
    <!-- {svg} -->
      <svg width='300' height='250'>
        <circle id='myId' cx='50' cy='95' r='50' style='fill:green'/>
   <!-- <circle |id='jsfId' class='myClass'| id='myId1' cx='250' cy='100' r='45'
          style='fill:orange'/> -->
        <#circprop.circle[ cx='120' cy='85' r='60' style='fill:red'/>
        <#circprop.circle[xyz |rendered='#{render}'| cx='30' cy='30' r='30'
          style='fill:blue'/>
        <#circprop.circle+pqr cx='45' cy='45' r='10' style='fill:yellow'/>
        <#circprop.rect[ x='150' y='150' width='100' height='150'
          style='fill:yellow'/>
        <#circprop.foreignObject[abc x='150' y='150' width='100' height='150'>
          <div id='myId'>
            Here is a <strong>paragraph</strong> that requires <em>word wrap
              </em>
          </div>
          <!-- Here is a comment inside a foreignObject tag -->
          <script>
           // Here is a comment inside a script tag inside a foreignObject tag
          </script>
        </foreignObject>
        <!-- Here is a comment inside svg -->
        <script>
          // This is a script inside svg
        </script>
      </svg>
      <h:commandButton id="clickMe" value="Click Me" action="#{svg.update}" />
    </h:form>
  </h:body>
</html>

C. Console Application

As with the code, the text has been reformatted to fit the page width.

This is a console application that takes an input file containing html, xhtml and svg tags, and embeds the svg tags inside <h:outputText /> tags to be rendered as svg tags. The svg tags can also be used to pass arguments to a bean. This application is used to convert a file containing svg code into a form suitable for use by JavaServer Faces. Note that html, xhtml and comments tags are not affected. Code between <script> and </script> tags are also not affected, but when these tags are inside an svg block, the script is enclosed between <![CDATA[ and // ]]> tags

The input file is read from the project root, and the output file is written to the \WebContent folder. When the jsf application is run, it is this file that is rendered, and should have an html or xhtml extension

Type input filename:                                    svgTest.xhtml
Type output filename, or '.' to use the input filename: .
The bean name is: svg
Execution has ended successfully with 43 lines read

D. Output XHTML file containing processed SVG code

After running the console application, the output XHTML file is produced, as listed here, and it is this code that JSF then processes.

<?xml version="1.0" encoding="UTF-8"?>   
<!DOCTYPE html>
<html lang="en"
      xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
  <h:head>
    <title>Code Test</title>
  </h:head>
  <h:body>
    <h1>Here is an example of SVG in an xhtml page</h1>
    <h:outputText value="This is a test"/>
    <!-- Here is a comment outside svg -->
    <script>
    // This is a script outside svg
    </script>
    <h:form id="myForm" prependId="false">
    <ui:remove><!-- {svg} --></ui:remove>
      <h:outputText value="<svg width='300' height='250'>" escape="false" />
        <h:outputText value="<circle id='myId' cx='50' cy='95' r='50'
           style='fill:green'/>" escape="false" />
   <!-- <circle |id='jsfId' class='myClass'| id='myId1' cx='250' cy='100' r='45'
           style='fill:orange'/> -->
        <h:outputText value="#{svg.circprop('circle','cx=|120| cy=|85| r=|60|
           style=|fill:red|/','[')}" escape="false" />
        <h:outputText rendered="#{svg.render}" value="#{svg.circprop('circle'
           'cx=|30| cy=|30| r=|30| style=|fill:blue|/','[xyz')}"
           escape="false" />
        <h:outputText value="#{svg.circprop('circle','cx=|45| cy=|45| r=|10|
           style=|fill:yellow|/','+pqr')}" escape="false" />
        <h:outputText value="#{svg.circprop('rect','x=|150| y=|150|
           width=|100| height=|150| style=|fill:yellow|/','[')}"
           escape="false" />
        <h:outputText value="#{svg.circprop('foreignObject','x=|150| y=|150|
           width=|100| height=|150|','[abc')}" escape="false" />
          <div id='myId'>
            Here is a <strong>paragraph</strong> that requires
              <em>word wrap</em>
          </div>
          <!-- Here is a comment inside a foreignObject tag -->
          <script>
           // Here is a comment inside a script tag inside a foreignObject tag
          </script>
        <h:outputText value="</foreignObject>" escape="false" />
        <!-- Here is a comment inside svg -->
        <script><![CDATA[
          // This is a script inside svg
        // ]]></script>
      <h:outputText value="</svg>" escape="false" />
      <h:commandButton id="clickMe" value="Click Me" action="#{svg.update}" />
    </h:form>
  </h:body>
</html>

E. Displayed SVG Generated Images

After starting the server and opening a browser window, the image here is displayed. The "Click Me" button toggles the display/not display of the blue circle, as the blue circle uses a read-only boolean bean property that is toggled by the button.

SVG Image

Note that the yellow rectangle has been produced by SVG, but the text in it has been produced by HTML code embedded between <foreignObject> opening and </foreignObject> closing tags.

F. Source Code in the Browser

The source code corresponding to the view (E) from the browser is shown here.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"><head id="j_idt2">
    <title>Code Test</title></head><body>
    <h1>Here is an example of SVG in an xhtml page</h1>This is a test
    <!-- Here is a comment outside svg -->
    <script>
    // This is a script outside svg
    </script>
<form id="myForm" name="myForm" method="post" action="/svgtojsf/svgtest.faces"
  enctype="application/x-www-form-urlencoded">
<input type="hidden" name="myForm" value="myForm" />
<svg width='300' height='250'><circle id='myId' cx='50' cy='95' r='50'
  style='fill:green'/>
<!--   <circle |id='jsfId' class='myClass'| id='myId1' cx='250' cy='100' r='45'
  style='fill:orange'/> -->
<circle cx='120' cy='85' r='60' style='fill:red'/>
<circle cx='30' cy='30' r='30' style='fill:blue'/>
<circle cx='45' cy='45' r='10' style='fill:yellow'/>

<rect x='150' y='150' width='100' height='150' style='fill:yellow'/>
<foreignObject x='150' y='150' width='100' height='150'>
  <div id="myId">
    Here is a <strong>paragraph</strong> that requires
      <em>word wrap</em>
  </div>
  <!-- Here is a comment inside a foreignObject tag -->
  <script>
    // Here is a comment inside a script tag inside a foreignObject tag
  </script></foreignObject>
  <!-- Here is a comment inside svg -->
  <script><![CDATA[
    // This is a script inside svg
  // ]]></script></svg><input id="clickMe" type="submit" name="clickMe"
     value="Click Me" /><input type="hidden" name="javax.faces.ViewState"
     id="j_id1:javax.faces.ViewState:0"
     value="7469415835050163830:2951350506012832615" autocomplete="off" />
</form></body>
</html>

As noted above, the code here has been reformatted for presentation, but is otherwise unchanged.

5. Java Source Code

The files containing the Java source code for the console application and the bean are not given here, as they have not been fully tested and debugged. However, my contact details are given on the home page for any questions or comments.

II. INTEGRATING ANGULARJS WITH JSF

So far only a very preliminary investigation of integrating AngularJS with JSF has been carried out. In using Eclipse with JSF it is possible to have an HTML tag with an AngularJS attribute, such as:

<div ng-app='myApp'>

in an XHTML file, although Eclipse will complain as the attribute is non-standard HTML, but it will work. However, an XHTML tag such as:

<h:body ng-app='myApp'>

will fail, as JSF will not recognise this tag as having valid attributes.

A simple solution to this is to make a small modification of the code used for processing SVG tags discussed above, so that the tag is embedded in an <h:outputText .../> tag. Accordingly, given the raw code of the form:

1) <-div ng-app='myApp'>

it will be converted to:

2) <h:outputText value="&lt;div ng-app='myApp'&gt;" escape="false" />

which in the browser's source will be rendered as:

3) <div ng-app='myApp'>

The "-" inserted between "<" and the tag name in (1) indicates that the tag will be processed. This can be applied to any HTML tag that has non-standard attributes. Unlike the case for SVG, where the processing code is placed in the SVG mode and processes all SVG tags accordingly until the terminating </svg> tag is encountered, this applies only for the tag itself.

To close the tag in (1), the raw code should be of the form:

4) <-/div>

with the "-", and will be converted to:

5) <h:outputText value="&lt;/div&gt;" escape="false" />

which in the browser's source will be rendered as:

6) </div>

Note that also unlike processing SVG code, the whole tag here between "<" and ">" must be on the same line, and no other code must follow on that line, not even comments.

A possible extension is to pass values to a bean in a way similar to the SVG code. A possible implementation is to have raw code of the form:

<=div prop.tag attr='myApp'>

where "myApp" is a value that can be passed to a bean with the property "prop", but this is not currently implemented.

A potentially substantial improvement to this simple application is to use http://angularfaces.com/, which fully integrates JavaServer Faces with AngularJS, but is still in its early stages of development, there are a number of bugs, and the documentation is not very clear and is incomplete. However, a test application from this website has been successfully run. It makes use of 4 jar files for AngularFaces, PrimeFaces, BootsFaces and Bootstrap. Some comments on this will be added at a later date.

III. INTEGRATING SVG WITH ANGULARJS

In this case no server-side code is directly involved. We can either embed the whole SVG block of code between HTML opening and closing tags, such as a <div>, but bearing in mind the comments in section (II) if Eclipse is being used, or inside the SVG block of code by adding the AngularJS attributes to a <g> tag, but in some cases we have no choice but to embed inside an SVG block. As HTML tags cannot be placed directly in an SVG block of code, tags such as <div> cannot be used, and although the SVG <g> tag is normally used for grouping SVG tags, it can also be used as an equivalent to a <div> tag.

The first example at this link is based on code substantially improved from a German website that uses SVG with AngularJS to display and animate an analog clock. In this case the ng-app and ng-controller attributes are placed together in the <div> tag immediately after the <body> tag, two ng-repeat attributes have been placed in <g> tags, and several ng-attr-transform attributes have been placed in other SVG tags. Note that by placing ng-app in a <div> tag rather than the <body> tag, text further down in the page can use the literal "{{" and "}}" after the corresponding closing </div> tag without AngularJS trying to process it.

The second example at the same link is a digital clock and an interactive counter simulating a 7 segment display inside a second SVG block. An individual segment is generated using the SVG <polygon> tag, then 7 polygons are put together to create a digit, which is scaled and skewed, then AngularJS is used to generate 8 digits. Likewise the hours/minutes and minutes/seconds separators and the decimal point are scaled and skewed. Extensive use of styling is made to switch on and switch off parts of the display, but unlike the analog clock which is controlled by AngularJS, this is controlled by jQuery after AngularJS has set it up.

IV. INTEGRATING SVG WITH ANGULARJS AND JSF

Most of the material covered in sections (I), (II) and (III) apply here. The SVG code can be pre-processed exactly as in section (I), and that includes any AngularJS attributes added to the SVG tags in the raw code. AngularJS attributes can also be added directly to HTML tags, but Eclipse will complain, so it is preferable in the raw code to place a "-" between "<" and the tag name to tell the pre-processor to process this tag as in section (II). In this case the closing tag should also be processed. As JSF does not recognise XHTML tags with non-standard attributes out of the box, AngularJS attributes cannot be placed in tags such as <h:body>. Although it is possible to extend JSF tag handling, but this is not considered here. As most HTML tags cannot be placed directly in an SVG block of code, in order to make use of AngularJS attributes in SVG code, the <g> tag is used in place of the <div> tag as mentioned in section (III).

We can pass a string containing SVG attributes, including AngularJS attributes to a bean as discussed in section (I). First we must include the bean name in the raw code before the SVG code block, such as adding the line:

<!-- {svg} -->.

Then given the raw SVG code:

1) <#tagprop.line[ x1='200' y1='15' x2='200' y2='2' ng-attr-transform=
     'rotate({{$index*30}} 200 200)' style='stroke:#aaa' />

This will be converted to:

2) <h:outputText value="#{svg.tagprop('line','x1=|200| y1=|15| x2=|200| y2=|2|
     ng-attr-transform=|rotate({{$index*30}} 200 200)| style=|stroke:#aaa| /',
     '[')}" escape="false" />

Then the browser's source will be displayed as:

3) <line x1='200' y1='15' x2='200' y2='2' ng-attr-transform=
     'rotate({{$index*30}} 200 200)' style='stroke:#aaa' />

We have passed the string:

'x1=|200| y1=|15| x2=|200| y2=|2| ng-attr-transform=|rotate({{$index*30}}
   200 200)| style=|stroke:#aaa| /'

to the bean "svg" with the property name "tagprop", which is available to be processed on the server, if required. In this case the public method "tagprop" just returns the string that is rendered by the browser as (3), but it is easy to see that anything can be returned, or the server can generate a completely new string based on some internal logic.

There are many other possibilities in combining JSF with SVG and AngularJS that can be explored, including AngularFaces.



Click here to return to the main selection page.