13 Replies Latest reply on Feb 27, 2011 6:53 PM by Tim Evers

    insert content into the <head> element

    Jonny B Newbie

      Hi Guys!


      I'm looking for a way to add elements into the head tag of a page.


      The .xhtml page looks like this:




      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
           xmlns:s="http://jboss.com/products/seam/taglib"
           xmlns:ui="http://java.sun.com/jsf/facelets"
           xmlns:f="http://java.sun.com/jsf/core"
           xmlns:h="http://java.sun.com/jsf/html"
           xmlns:rich="http://richfaces.org/rich"
           xmlns:a="http://richfaces.org/a4j"
           template="../../layout/solverTemplate.xhtml">
      
           <ui:define name="body">
                <div id="mygraph"></div>
                <input type="button" value="Naechster Knoten"></input>
           </ui:define>
           
      </ui:composition>



      It is based on a template page solverTemplate.xhtml which brings the basic functionaliy of the page.


      Now i need to import a JavaScript library:



      <script  language="javascript" src="jsdot/core/jsdot-dev.js" ></script>



      and a simple function which is to be started after the page has been loadad.


      <script  language="javascript">
      function graph(){
              j = new JSDot("mygraph", {mode: "editor"});
      }
      </script>




      Unfortunately nothing i tried so far worked.


      I searched the net, this forum and the books i have of this topic but couldn't find any solution.

        • 1. Re: insert content into the <head> element
          Jonny B Newbie

          ok i tried importing the library in two different ways:
          like it's done usually:


          <script  language="javascript" src="jsdot/core/jsdot-dev.js" ></script>



          and with the loadScript tag:


          <a4:loadScript type="text/javascript" src="resource:///jsdot/core/jsdot-dev.js"></a4:loadScript>



          The first one hasn't been recognized by the parser at all. The loadScript Tag actually imports the library but somehow in a wrong way so i can't get the library to work properly.


          The following errors have been listed in Firebug:




          uncaught exception: [Exception... "Component returned failure code: 0x80070057... 
          
          element.dispatchEvent is not a function
          
          element.dispatchEvent is not a function
          
          a is undefined
          http://localhost:8080/easy-Student/rfResscripts/jsdot.min.js?org.jboss.portletbridge.NAMESPACE=jbpns_2feasy_2fStudent_2fStudentOverviewPortletWindowsnpbj
          Line 2




          Please, if anybody has a clue what i'm doing wrong...i am grateful for any hint. I'm just a beginner with seam and am kind of lost right now because i need to get this to work for my final thesis at the university.


          Thanks in advance!

          • 2. Re: insert content into the <head> element
            Tim Evers Master

            Hi Jonny,


            You are missing the most important piece of information here to allow us to help you.


            WHERE are you trying to put the line:


            <script  language="javascript" src="jsdot/core/jsdot-dev.js" ></script>
            



            Show the full example not just one liners.

            • 3. Re: insert content into the <head> element
              Tim Evers Master

              I did a small test and this works fine for me.


              testImport.xhtml


              <?xml version="1.0" encoding="UTF-8"?>
              <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                  xmlns:ui="http://java.sun.com/jsf/facelets"
                  xmlns:h="http://java.sun.com/jsf/html"
                  template="/layout/template.xhtml">
                  <ui:define name="body">
                      <script
                          language="javascript"
                          src="test.js"
                          type="text/javascript" />
                          
                      <h:outputText value="HELLO WORLD!"/>
                          
                      <script>
                          testImport();
                      </script>
                  </ui:define>
              </ui:composition>
              



              test.js


              function testImport() {
                   alert('Working');
              }
              



              Of course the downside to this approach is that the import is not in the header...but, it works.


              I'll have a quick stab at getting it into the header and let you know.

              • 4. Re: insert content into the <head> element
                Tim Evers Master

                OK, putting it into the headers is just as simple...I just had to make sure it worked. :P



                In your template in the header section you want to do this.


                template.xhtml


                <html
                    .......all your stuff>
                
                    <head>
                        ....bunch of header stuff script/meta/link tags
                        <ui:insert name="extraHeaders"/>
                    </head>
                    <body>
                        ....you already have this anyways.
                    </body>
                </html>
                



                The main point was the line


                <ui:insert name="extraHeaders"/>
                



                located in the head tag.


                Then your xhtml page will look something like this.


                <?xml version="1.0" encoding="UTF-8"?>
                <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                    xmlns:ui="http://java.sun.com/jsf/facelets"
                    xmlns:h="http://java.sun.com/jsf/html"
                    template="/layout/template.xhtml">
                    <ui:define name="extraHeaders">
                        <script
                            language="javascript"
                            src="test.js"
                            type="text/javascript" />
                    </ui:define>
                    <ui:define name="body">
                        <h:outputText value="HELLO WORLD!"/>
                            
                        <script>
                            testImport();
                        </script>
                    </ui:define>
                </ui:composition>
                

                • 5. Re: insert content into the <head> element
                  Jonny B Newbie

                  Hi Tim! First of all, thank you very much for your time!


                  I tried the same thing you did. I imported a very simple .js file and started it after pageload. What i observed is following:



                  • it works with the loadScript tag, but the normal script tag seems just to be ignored

                  • after importing the libraries i need i get JavaScript errors



                  This is the template file


                  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                  <f:view xmlns="http://www.w3.org/1999/xhtml"
                       xmlns:ui="http://java.sun.com/jsf/facelets"
                       xmlns:f="http://java.sun.com/jsf/core"
                       xmlns:h="http://java.sun.com/jsf/html"
                       xmlns:rich="http://richfaces.org/rich"
                       xmlns:a="http://richfaces.org/a4j"
                       xmlns:s="http://jboss.com/products/seam/taglib"
                       contentType="text/html" >
                       
                       <a:loadStyle src="resource:///stylesheet/theme.xcss" />
                       <a:loadStyle src="/stylesheet/theme.css" />
                       <ui:insert name="head" />
                       <ui:include src="menu.xhtml">
                            <ui:param name="projectName" value="easy-Editor" />
                       </ui:include>
                       <h:form>
                            <div id="content1column">
                            <div id="message-container"><a:outputPanel ajaxRendered="true">
                                 <h:messages id="messages" globalOnly="true" styleClass="message"
                                      errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg"
                                      rendered="#{showGlobalMessages != 'false'}" />
                            </a:outputPanel></div>
                            <div id="d">
                            <ui:include id="controller"
                                 src="/solver/solverController.xhtml" /></div>
                            <div id="moduleContentRight">
                            
                            <rich:simpleTogglePanel     opened="true" label="#{messages['Task Assignment']}" switchType="client" rendered="#{not empty currentAssignment.task}">
                                 <h:outputText escape="false" value="#{currentAssignment.task}" id="task-assignment" />
                            </rich:simpleTogglePanel>
                                      
                            <ui:insert name="body" />
                            </div>
                            <div class="clear"></div>
                            </div>
                       </h:form>
                  </f:view>



                  and this is the actual solver.xhtml i need to import the javascript into. I forgot to mention that JQuery is a dependency of the actual jsdot library.




                  <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                  <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                       xmlns:s="http://jboss.com/products/seam/taglib"
                       xmlns:ui="http://java.sun.com/jsf/facelets"
                       xmlns:f="http://java.sun.com/jsf/core"
                       xmlns:h="http://java.sun.com/jsf/html"
                       xmlns:rich="http://richfaces.org/rich"
                       xmlns:a="http://richfaces.org/a4j"
                       xmlns:a4="http://richfaces.org/a4j"
                       template="../../layout/solverTemplate.xhtml">
                       
                       <ui:define name="head">
                            
                            <a:loadScript type="text/javascript" src="/scrips/jquery-ui-1.8.2.custom.min.js"></a:loadScript>
                            <a:loadScript type="text/javascript" src="/scrips/jquery-1.4.2.min.js"></a:loadScript>
                            <a:loadScript type="text/javascript" src="/scrips/jsdot.min.js"></a:loadScript>
                            
                            <a:loadStyle src="/style/ui-lightness/jquery-ui-1.8.2.custom.css" />
                            <a:loadStyle src="/style/jsdot/editor.css" />
                            <a:loadStyle src="/style/jsdot/shapes.css" />
                  
                            <style type="text/css">
                                  #mygraph {height:400px; width:600px; overflow:hidden}
                            </style>
                            <script type="text/javascript">
                                 function graph(){
                                      var j = new JSDot("mygraph", {mode: "editor"});
                  
                                 }
                            </script>
                            
                            
                       </ui:define>
                       
                  
                       <ui:define name="body">
                            <body onload="graph()">
                            <h:outputText style="FONT-WEIGHT: bold; font-size: 1.4em" value="#{studentModulesAdaptorTreeStructure.solverModule.tsAssignment.assignmentText}" />
                            <div id="mygraph"></div>
                            <input type="button" value="Naechster Knoten"></input>
                            </body>
                       </ui:define>
                       
                  </ui:composition>




                  Maybe this dependency is causing problems? I'm running out of ideas... :(


                  Thank you in advance for your efforts!!

                  • 6. Re: insert content into the <head> element
                    Jonny B Newbie

                    Now i'm confused again. Neither the script nor the a:loadScript tag seem to work any more. After loading the page i get the following error message in Firebug:


                    JSDot is not defined
                    http://localhost:8080/portal/auth/portal/easy/Student/StudentOverviewPortletWindow?action=e&windowstate=normal&javax.faces.portletbridge.STATE_ID=96d0bf34-88a7-48e1-963f-92bf1ade8b59%3Aview%3Aa4dcc696-3b02-4859-a70e-9260363b1591&mode=view
                    Line 136



                    The awkward thing here is that if i create a single page, with normal html tags everything works perfectly fine. Like here:




                    <?xml version="1.0" encoding="utf-8"?>
                    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
                                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                    <html xmlns="http://www.w3.org/1999/xhtml"
                          xmlns:s="http://jboss.com/products/seam/taglib"
                          xmlns:h="http://java.sun.com/jsf/html"
                          xmlns:f="http://java.sun.com/jsf/core">
                    
                       <head>
                          <title>Register New User</title>
                              
                          <link type="text/css" rel="stylesheet" href="jsdot/style/ui-lightness/jquery-ui-1.8.2.custom.css"/>
                          <link type="text/css" rel="stylesheet" href="jsdot/style/jsdot/shapes.css"/>
                          <link type="text/css" rel="stylesheet" href="jsdot/style/jsdot/editor.css"/>
                          <script type="text/javascript" src="jsdot/scripts/jquery-1.4.2.min.js"></script>
                          <script type="text/javascript" src="jsdot/scripts/jquery-ui-1.8.2.custom.min.js"></script>
                          <script type="text/javascript" src="jsdot/scripts/jsdot.min.js"></script>
                    
                          <script type="text/javascript">
                    
                          var json_graph = '{"nodes":[{"name":"29","position":[50,150]},{"name":"32","position":[85,150]},{"name":"2","position":[120,150]}],"edges":[]}';
                           var j = 0;
                    
                              function graph(){
                                        j = new JSDot("mygraph", {mode: "editor"});
                                        j.importJSON(json_graph);
                              }
                                    
                          </script>
                               
                               <style type="text/css">
                                    #mygraph {height:400px; width:600px; overflow:hidden}
                               </style>
                       </head>
                       <body onload="graph()">
                          <div id="mygraph"></div>
                       </body>
                    
                    </html>
                    



                    • 7. Re: insert content into the <head> element
                      Tim Evers Master

                      You need to read my examples more carefully. You also need to go read some documentation on templates and how they work. Start by reading This Page



                      But, for the sake of the problem at hand.


                      You need to take a step back and look at what you are doing.


                      You are having a hard time because you are not doing things right.


                      Let's take a look at the template.


                      For starters your not defining your header or body at all. Essentially you are creating a html page without head or body tags. <h:head><h:body> need to be used. Well, to be exact you did create a body, the problem was it was not where it should be. It was defined inside your form.


                      Next, get rid of the a:load stuff. Keep the page simple and only use special tags when you understand what they do.


                      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                      <f:view xmlns="http://www.w3.org/1999/xhtml"
                           xmlns:ui="http://java.sun.com/jsf/facelets"
                           xmlns:f="http://java.sun.com/jsf/core"
                           xmlns:h="http://java.sun.com/jsf/html"
                           xmlns:rich="http://richfaces.org/rich"
                           xmlns:a="http://richfaces.org/a4j"
                           xmlns:s="http://jboss.com/products/seam/taglib"
                           contentType="text/html" >
                           
                          <h:head> <!--HEADER DEFINED!!!!-->
                              <link 
                                  href="#{facesContext.externalContext.requestContextPath}/stylesheet/theme.xcss" <!--fix this to whatever it is for you -->
                                  rel="stylesheet"
                                  type="text/css" />
                              <link
                                  href="#{facesContext.externalContext.requestContextPath}/stylesheet/theme.css" <!--fix this to whatever it is for you -->
                                  rel="stylesheet"
                                  type="text/css" />
                              <ui:insert name="head" /> <!--INSERT EXTRA HEADERS-->
                          </h:head>
                           
                          <h:body> <!--BODY DEFINED HERE -->
                              <!--Why isn't this inside the form? Should it? -->
                           <ui:include src="menu.xhtml">
                                <ui:param name="projectName" value="easy-Editor" />
                           </ui:include>
                      
                           <h:form>
                                <div id="content1column">
                                <div id="message-container"><a:outputPanel ajaxRendered="true">
                                     <h:messages id="messages" globalOnly="true" styleClass="message"
                                          errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg"
                                          rendered="#{showGlobalMessages != 'false'}" />
                                </a:outputPanel></div>
                                <div id="d">
                                <ui:include id="controller"
                                     src="/solver/solverController.xhtml" /></div>
                                <div id="moduleContentRight">
                                
                                <rich:simpleTogglePanel     opened="true" label="#{messages['Task Assignment']}" switchType="client" rendered="#{not empty currentAssignment.task}">
                                     <h:outputText escape="false" value="#{currentAssignment.task}" id="task-assignment" />
                                </rich:simpleTogglePanel>
                                          
                                <ui:insert name="body" />
                                </div>
                                <div class="clear"></div>
                                </div>
                           </h:form>
                          </h:body>
                      </f:view>
                      



                      So, now we do the actual page.


                      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                          "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                           xmlns:s="http://jboss.com/products/seam/taglib"
                           xmlns:ui="http://java.sun.com/jsf/facelets"
                           xmlns:f="http://java.sun.com/jsf/core"
                           xmlns:h="http://java.sun.com/jsf/html"
                           xmlns:rich="http://richfaces.org/rich"
                           xmlns:a="http://richfaces.org/a4j"
                           xmlns:a4="http://richfaces.org/a4j"
                           template="../../layout/solverTemplate.xhtml">
                           
                           <ui:define name="head">
                                <!--fix all these to be normal link/script tags please -->
                                <a:loadScript type="text/javascript" src="/scrips/jquery-ui-1.8.2.custom.min.js"></a:loadScript>
                                <a:loadScript type="text/javascript" src="/scrips/jquery-1.4.2.min.js"></a:loadScript>
                                <a:loadScript type="text/javascript" src="/scrips/jsdot.min.js"></a:loadScript>
                                
                                <a:loadStyle src="/style/ui-lightness/jquery-ui-1.8.2.custom.css" />
                                <a:loadStyle src="/style/jsdot/editor.css" />
                                <a:loadStyle src="/style/jsdot/shapes.css" />
                      
                                <style type="text/css">
                                      #mygraph {height:400px; width:600px; overflow:hidden}
                                </style>
                                <script type="text/javascript">
                                     function graph(){
                                          var j = new JSDot("mygraph", {mode: "editor"});
                      
                                     }
                                </script>
                                
                                
                           </ui:define>
                           
                      
                           <ui:define name="body">
                                  <h:outputText 
                                      style="FONT-WEIGHT: bold; font-size: 1.4em" 
                                      value="#{studentModulesAdaptorTreeStructure.solverModule.tsAssignment.assignmentText}" />
                               <div id="mygraph"></div>
                               <input type="button" value="Naechster Knoten"></input>
                                  <!--There is a better way to do this but, for now just do this -->
                                  <script>
                                      graph()
                                  </script>
                           </ui:define>
                           
                      </ui:composition>
                      



                      One thing to always remember is when dealing with problems like this simplify your problem first. Get rid of unknowns. If you don't know exactly how a:loadXXXX works then don't use it. Drop down to standard html and work back up.


                      Secondly, you are using richfaces which INCLUDES jQuery. So, unless your jQuery scripts have been setup to not conflict with richfaces you may end up finding out that trying to load the jQuery .js files is going to cause you problems. The Richfaces jQuery library is accessible by the jQuery variable.


                      eg.


                      '
                      jQuery('input').forEach(function(){})  //You get the idea
                      '


                      The fact that a normal straight html page worked for you should have triggered the solution for you. You should be checking the actual generated html (In browswer View -> Source) and making sure it represents what you expect. Sure you have to get used to the fact that there will be a lot of noise in the generated html, but you should be able to find the important parts.


                      Please take the time to read through the examples I posted carefully I have put comments in there on some things so make sure you read it.


                      But, my guess is that your actual problem is a combination of invalid usage of facelets and more then likely a conflict loading the jQuery libs for a second time due to richfaces already loading it. As you can see on your pure html file that worked you did not include richfaces so this could very well be something else to consider.

                      • 8. Re: insert content into the <head> element
                        Jonny B Newbie

                        Tim thank you so much for your help. You gave me the crucial advices. I was able to localize the errors and i'm working on a fix. And i will definitely follow your general advices when i encounter the next errors. They have been of great help.


                        About the errors:


                        The thing is that i am not developing an application from ground up but a module in order to extend the funcionality of an already existing system for E-Assessment.
                        I've been given the xhtml templates i posted here. Consequently i can't change them in order to fix my errors because all the other modules would be affected.


                        The main errors had been caused - like you guessed - by a conflict of different JavaScript libraries. jQuery interfered with JavaScript libraries which had been loaded by Seam in the background. Firebug reported an error with the library prototype.js.
                        I was able to circumvent that by using the jQuery.noConflict() function (for anyone who encounters similar problems: http://docs.jquery.com/UsingjQuerywithOtherLibraries) but my actual jsdot library wouldn't work with that correctly even after i adjusted the $(function) shotcut to jQuery(function).


                        So now i'm looking for an other solution. I am thinking to externalize my module into a separate portlet (without any additional javascript functionality) and load the necessary xhtml files through an iframe into the portal. Maybe not the most sophisticated solution, but if it works...


                        Many thanks to you again!

                        • 9. Re: insert content into the <head> element
                          Tim Evers Master

                          Glad I could be of some help.


                          I am surprised that you couldn't get it working once you made the changes for your javascript libs. Out of curiosity what was happening?


                          Hope you get it all sorted soon. :)

                          • 10. Re: insert content into the <head> element
                            Jonny B Newbie

                            hi again :)


                            Well after i configured the jQuery shortcut i found myself dealing with tons of other problems which occured in the JavaScript application (JsDot) i was actually trying to load. I tried to fix those errors by adjusting $(... to jQuery(... everywhere in the application.
                            Through that i was able to load JsDot but unfortunately this was causing more errors during the execution. In the end i wasn't able to trace the final reasons of those errors because i don't understand the underlying JavaScript totally.


                            Now i'm trying to find a plan B. My idea was to develop my module as an more or less independent application so i can use html files without any additional javascript libraries included. The problem is that i curently have no idea how to communicate on the application layer...
                            Maybe webservices would be one possible solution, though a clumsy one.


                            Do you have any idea if there is a possibility to connect two projects with each other so the seam components could communicate directly? That would just be awesome...

                            • 11. Re: insert content into the <head> element
                              Tim Evers Master

                              Hmm, I just did a little quick test and maybe you could do this.


                              So, here's my theory. Scripts are not shared between frames, sooooo.


                              How bout you do all your JsDot work in an iFrame that way you wont have any jQuery compatibility issues. You can leave the jQuery lib loaded with richfaces alone and load the version of jQuery you want in your iFrame and viola!


                              Here is my little test.


                              test.html


                              <html>
                                   <head>
                                        <script 
                                             language="javascript"
                                             src="testScript.js"
                                             type="text/javascript">
                                        </script>
                                        <script>
                                             function test() {
                                                  alert('test function called');
                                             }
                                        </script>
                                   </head>
                                   <body>
                                        <iframe id="iFrame" width="800" height="400" border="1" src="test2.html">
                                        </iframe>
                                        <button onclick="test();">TEST()</button>
                                        <button onclick="test2();">TEST2()</button>
                                        <button onclick="test3();">TEST3()</button>
                                   </body>
                              </html>
                              



                              test2.html (this is what is loaded in the iFrame)


                              <html>
                                   <head>
                                        <script 
                                             language="javascript"
                                             src="testScript2.js"
                                             type="text/javascript">
                                        </script>
                                   </head>
                                   <body>
                                        <button onclick="test()">TEST()</button>
                                        <button onclick="test2()">TEST2()</button>
                                        <button onclick="test3()">TEST3()</button>
                                   </body>
                              </html>
                              



                              testScript.js (loaded in test.html)


                              function test2() {
                                   alert('test2 function called');
                              }
                              



                              testScript2.js (loaded in test2.html)


                              function test3() {
                                   alert('test3 function called');
                              }
                              



                              Now, on the main page the TEST and TEST2 buttons work but TEST3 fails.


                              In the iFrame TEST and TEST2 buttons fail and TEST3 works.


                              So....in theory, you should be able to use this to your advantage and eliminate the conflicts while still maintaining complete connection to your underlying Seam beans.

                              • 12. Re: insert content into the <head> element
                                Jonny B Newbie

                                Hey Tim!


                                Thanks for your idea. I thought about pretty much the same thing. Unfortunately it doesn't work because JsDot needs to communicate with the backbean over the @WebRemote interface and the problem is that i need to call this interface from within a xhtml page for security reasons. I tried to access it from within the html page but it gives me a java.lang.IllegalAccessException. When i change the file to xhtml the system wraps a complete portalpage around my actual page so in the end i am back at zero.


                                Little by little i'm running out of time so i decided to concentrate on finishing my module as a standalone application and to deal later with the integration into the portal.


                                Thanks again for all your suggestions and advices. They have been greatly appreciated. :)

                                • 13. Re: insert content into the <head> element
                                  Tim Evers Master

                                  BAH!! I thought we were onto a winner there!


                                  Oh well, best of luck!



                                  I'd still be banging my head getting those js libs to play nicely with each other myself :P. Which mind you I have done on the app I'm on (different libs etc of course) and now I'm concerned that I've gone so far down that path that my js is hanging together by a tiny thread...time will tell I guess lol So, maybe your solution is a better one for the long term.