cancel
Showing results for 
Search instead for 
Did you mean: 

how to add event handler into surf template ?

zengqingyi12
Champ in-the-making
Champ in-the-making



        <div class="yui-gd">
            <div class="yui-u first"><label for="${args.htmlid}-addContent">${msg("label.HowToAddContent")}:</label></div>
            <div class="yui-u"> 
              <select id="addContent" name="addContent" onchange="dropdown(this)">
                  <option value="1" selected="selected">${msg("label.generateFromDescription")}</option>
                  <option value="2">${msg("label.uploadFile")}</option>
               </select>  
              </div>  

         </div>
<script type="text/javascript">//<![CDATA[
       function dropdown(sel){
              //if(document.getElementById("addContent").value == "1")
            if(sel.value == "0"){
               document.getElementById('desc').style.display = 'block'
         }
            else {
            document.getElementById('desc').style.display = 'none'
         }
      }       
//]]></script>


I write it because i want to add event handler into select box, it works well in firefox, but in IE it always throw null exception.
Even through i used attachEvent , it still can not work in IE.
If i use document.getElementById("addContent") in <script></script> above, it will always throw null exception!
But all these things work well in Firefox!

Can someone tell me why ?
Thanks in advance !
8 REPLIES 8

mikeh
Star Contributor
Star Contributor
That's more of a generic JavaScript issue rather than having much relation to Surf, but anyway…

An isolated (static HTML) test works fine:
<html>
<head><title>select</title></head>
<body>

<select id="addContent" name="addContent" onchange="dropdown(this)">
   <option value="1" selected="selected">label.generateFromDescription</option>
   <option value="2">label.uploadFile</option>
</select>  
<div id="desc">This is the desc div</div>
<script type="text/javascript">//<![CDATA[
function dropdown(sel)
{
   if (sel.value == "1")
   {
      document.getElementById('desc').style.display = 'block';
   }
   else
   {
      document.getElementById('desc').style.display = 'none';
   }
}      
//]]></script>

Note that MSIE may not have liked your lack of semicolons on the end of the lines. Also, I'm assuming you've got a div with an ID of "desc" somewhere on the page?

Generally, it's a bad idea to code element ids on the page like you've got. Look at the label's "for" attribute (and any other Share element with an id) and you'll see it's prefixed with "${args.htmlid}". This ensures multiple instances of the component on a page won't have clashing ids. It's also much better to attach events to elements via YUI, but I'll ignore that for now.
<select id="${args.htmlid}-addContent" name="addContent" onchange="dropdown(this)">
   <option value="1" selected="selected">${msg("label.generateFromDescription")}</option>
   <option value="2">${msg("label.uploadFile")}</option>
</select>  
<div id="${args.htmlid}-addContent-desc">This is the desc div</div>
<script type="text/javascript">//<![CDATA[
function dropdown(sel)
{
   var descDiv = YAHOO.util.Dom.get('${args.htmlid}-addContent-desc');
   descDiv.style.display = sel.value == "1" ? "block" : "none";
}      
//]]></script>

Hope that helps,
Mike

zengqingyi12
Champ in-the-making
Champ in-the-making

<div id="${args.htmlid}-dialog" class="create-folder" >
<script type="text/javascript">//<![CDATA[
function dropdown(sel)
{
   var descDiv = YAHOO.util.Dom.get('desc');
   descDiv.style.display = sel.value == "1" ? "block" : "none";
}      
//]]></script>
   
   <div class="hd">${msg("title")}</div>
   <div class="bd">
      <form id="${args.htmlid}-form" action="" method="post">
         <div class="yui-g">
            <h2>${msg("header")}:</h2>
         </div>
         <div class="yui-gd">
            <div class="yui-u first"><label for="${args.htmlid}-name">${msg("label.name")}:</label></div>
            <div class="yui-u"><input id="${args.htmlid}-name" type="text" name="name" tabindex="1" /> *</div>
         </div>
         <div class="yui-gd">
            <div class="yui-u first"><label for="${args.htmlid}-title">${msg("label.title")}</label></div>
            <div class="yui-u"><input id="${args.htmlid}-title" type="text" name="title" tabindex="2" /></div>
         </div>



        <div class="yui-gd">

            <div class="yui-u first"><label for="${args.htmlid}-addContent">${msg("label.HowToAddContent")}:</label></div>
            <div class="yui-u"> 
              <select id="${args.htmlid}-addContent" name="addContent" onchange="dropdown(this)">
                  <option value="1" selected="selected">${msg("label.generateFromDescription")}</option>
                  <option value="2">${msg("label.uploadFile")}</option>
               </select>  
              </div>  

         </div>
         <div class="yui-gd" id = "desc">
            <div class="yui-u first"><label for="${args.htmlid}-description">${msg("label.description")}:</label></div>
            <div class="yui-u"><textarea id="${args.htmlid}-description" name="description" rows="16" cols="150" tabindex="3" ></textarea></div>
         </div>
         <div class="yui-gd" id="${args.htmlid}-privilegetype-field">
            <div class="yui-u first"><label for="${args.htmlid}-privilegetype">${msg("label.privilegetype")}:</label></div>
            <div class="yui-u">
               <select id="${args.htmlid}-privilegetype" name="privilegetype" tabindex="4">
                  <option value="Normal">${msg("label.Normal")}</option>
                  <option value="Confidential">${msg("label.Confidential")}</option>
                  <option value="Public">${msg("label.Public")}</option>
               </select>             
         </div>

         <div class="yui-gd" id="${args.htmlid}-mywidth-field">
            <div class="yui-u first"><label for="${args.htmlid}-mywidth">${msg("label.doctype")}:</label></div>
            <div class="yui-u">
               <select id="${args.htmlid}-mywidth" name="mywidth" tabindex="5">
                  <option value="PT">PT</option>
                  <option value="OTH">OTH</option>
               </select>             
         </div>
         </div>
         <div class="bdft">
            <input type="button" id="${args.htmlid}-ok" value="${msg("button.ok")}" tabindex="6" />
            <input type="button" id="${args.htmlid}-cancel" value="${msg("button.cancel")}" tabindex="7" />
         </div>
      </form>
   </div>

</div>


The whole page's code is this, but when i add the onchange="dropdown(this)" , IE will throw "miss object" error.   even through the only content in the dropdown function is alert('t'), it will also throw such error.   It seems that the javascript onchange can not find the function dropdown.


Really Thank you very much, Mike !!

mikeh
Star Contributor
Star Contributor
Ah ok - I'm going to assume you're loading this in via an ajax call? That would have been useful to know at the start  :wink:
I also going to assume you've copied the onNewFolder() function, which calls Alfresco.util.Ajax.request() without setting execScripts to true.

Firefox will parse inline <script> blocks, but for MSIE we must execute them manually.

So, to fix it, find the Alfresco.util.Ajax.request() parameters and add: execScripts: true to it.

That's just another reason why it's better to add event handling in the main .js file rather than inline.

Thanks,
Mike

zengqingyi12
Champ in-the-making
Champ in-the-making
is toolbar-min.js

           this.modules.createFolder = new Alfresco.module.SimpleDialog(this.id + "-createFolder").setOptions(
            {
               width: "80em",
               templateUrl: Alfresco.constants.URL_SERVICECONTEXT + "modules/documentlibrary/create-folder",
               actionUrl: actionUrl,
               doSetupFormsValidation:
               {
                  fn: doSetupFormsValidation,
                  scope: this
               },
               firstFocus: this.id + "-createFolder-name",
               onSuccess:
               {
                  fn: function DLTB_onNewFolder_callback(response)
                  {
                     var folder = response.json.results[0];
                     YAHOO.Bubbling.fire("folderCreated",
                     {
                        name: folder.name,
                        parentPath: folder.parentPath,
                        nodeRef: folder.nodeRef
                     });
                     Alfresco.util.PopupManager.displayMessage(
                     {
                        text: this._msg("message.new-folder.success", folder.name)
                     });
                  },
                  scope: this
               }
            });
         }
         else
in simple-dialog.js:

     show: function AmSD_show()
      {
         if (this.dialog)
         {
            this._showDialog();
         }
         else
         {
            var data = {
                htmlid : this.id
            };
            if (this.options.templateRequestParams)
            {
                data = YAHOO.lang.merge(this.options.templateRequestParams,data);
            }
            Alfresco.util.Ajax.request(
            {
               url: this.options.templateUrl,
               dataObj:data,
               successCallback:
               {
                  fn: this.onTemplateLoaded,
                  scope: this
               },
               failureMessage: "Could not load dialog template from '" + this.options.templateUrl + "'.",
               scope: this,
               execScripts: true
            });
         }
         return this;
      },

Hi Thanks Mike,
So system have set the execSCript to ture, but actually the <script> are still not work.

That's just another reason why it's better to add event handling in the main .js file rather than inline.
which .js file should i add the event handling ?
I have tried to add event handling in toolbar-min.js 
it wouldn't throw out error, but it didn't take action, what's the reason ?

mikeh
Star Contributor
Star Contributor
which .js file should i add the event handling ?
The one where you load your "add content" dialog. Maybe you need to back-up and describe exactly what you're trying to achieve and what you've done so far.

It doesn't matter that much - the solution I gave above would still work.

I have tried to add event handling in toolbar-min.js
Don't edit the -min.js files. Edit the uncompressed ones and then run them through the YUI Compressor to produce the -min.js version.

Mike

zengqingyi12
Champ in-the-making
Champ in-the-making
which .js file should i add the event handling ?
The one where you load your "add content" dialog. Maybe you need to back-up and describe exactly what you're trying to achieve and what you've done so far.

It doesn't matter that much - the solution I gave above would still work.

I have tried to add event handling in toolbar-min.js
Don't edit the -min.js files. Edit the uncompressed ones and then run them through the YUI Compressor to produce the -min.js version.

Mike

Thanks, I just change the name of *-min.js to *.js and change *.js to *-min.js,     since it is convenient for developping

zengqingyi12
Champ in-the-making
Champ in-the-making
is toolbar-min.js

           this.modules.createFolder = new Alfresco.module.SimpleDialog(this.id + "-createFolder").setOptions(
            {
               width: "80em",
               templateUrl: Alfresco.constants.URL_SERVICECONTEXT + "modules/documentlibrary/create-folder",
               actionUrl: actionUrl,
               doSetupFormsValidation:
               {
                  fn: doSetupFormsValidation,
                  scope: this
               },
               firstFocus: this.id + "-createFolder-name",
               onSuccess:
               {
                  fn: function DLTB_onNewFolder_callback(response)
                  {
                     var folder = response.json.results[0];
                     YAHOO.Bubbling.fire("folderCreated",
                     {
                        name: folder.name,
                        parentPath: folder.parentPath,
                        nodeRef: folder.nodeRef
                     });
                     Alfresco.util.PopupManager.displayMessage(
                     {
                        text: this._msg("message.new-folder.success", folder.name)
                     });
                  },
                  scope: this
               }
            });
         }
         else
in simple-dialog.js:

     show: function AmSD_show()
      {
         if (this.dialog)
         {
            this._showDialog();
         }
         else
         {
            var data = {
                htmlid : this.id
            };
            if (this.options.templateRequestParams)
            {
                data = YAHOO.lang.merge(this.options.templateRequestParams,data);
            }
            Alfresco.util.Ajax.request(
            {
               url: this.options.templateUrl,
               dataObj:data,
               successCallback:
               {
                  fn: this.onTemplateLoaded,
                  scope: this
               },
               failureMessage: "Could not load dialog template from '" + this.options.templateUrl + "'.",
               scope: this,
               execScripts: true
            });
         }
         return this;
      },

Hi Thanks Mike,
So system have set the execSCript to ture, but actually the <script> are still not work.

That's just another reason why it's better to add event handling in the main .js file rather than inline.
which .js file should i add the event handling ?
I have tried to add event handling in toolbar-min.js 
it wouldn't throw out error, but it didn't take action, what's the reason ?


So can you tell me why this happens ? I am afraid that you miss this post, so i quote it again, sorry.

zengqingyi12
Champ in-the-making
Champ in-the-making
I add this code into
onNewFolder: function DLTB_onNewFolder(e, p_obj)

         alert(this.id);
         var addcontent = YAHOO.util.Dom.get(this.id + "-addContent");
         alert(addcontent.value);
         function fnCallback(e) { alert("click"); };
         YAHOO.util.Event.addListener(addcontent, "change", fnCallback);  

and it works now, system can take action when item changed.
But i don't know whether it is good to add javascript in this function.
Again, Thanks mike very much!!