Sunday, May 1, 2011

Javascript: Dynamically created html elements referencing an instantiated object

(For further background, this relates to the same piece of work as a previous question)

I'm creating a JavaScript based webchat system using jQuery to make life much easier. All the webchat JavaScript code is in an external js file, which is then referenced and instantiated by the html page.

<html xmlns="http://www.w3.org/1999/xhtml">

WebchatV3

        <div style="float:right;width:300px;" >

        <div id="MembersBox">
            Members
            <ul id="MembersList" >
            </ul>
        </div>
        <div id="QuestionsBox">
            Questions
            <div id="QuestionsList" >
            </div>
        </div>        

    </div>

    <div style="margin-right:310px;" id="ChatBox" >
        <div id="ChatData">
            <ul id="ChatDataList"></ul>
        </div>
        <div id="ChatInput">
            <div id="ChatInputCharRemainText">Characters remaining <span id="ChatInputCharRemain" ></span></div>
            <input type="text" maxlength="1000" id="ChatInputTextbox" />
        </div>
    </div> 

</div>

    <script type="text/javascript">

        var webchat;
  webchat = new AvonAndSomerset.WebchatV3(123, 'passcode', false );

 </script>

In the JavaScript there is code to dynamically create a list of active chat members from a JSON query. This code creates a series of html DIVs and then injects this html into the 'QuestionsList' DIV present in the html.

Now here's the question :)

Within each question are elements with JavaScript onclick events that allows actions to be taken against the question shown. How can I create the onclick code without hard coding the reference to 'webchat' - is there an elegent and acceptable way?

My initial thoughts are to pass in the instance name of the 'webchat' instance when it's created, so it can then be used inside the JavaScript when creating dynamic JavaScript...

Example of code with hard coded reference to instantited 'webchat':

<div id="QuestionsBox">
Questions
<div id="QuestionsList">
 <div class="Question">
  <div class="QuestionInnerControls">
   <img src="images/arrow_up.png" alt="" class="ControlIcon" onclick="webchat.Questions.Move(1,1);" >
   <img src="images/arrow_down.png" alt="" class="ControlIcon" onclick="webchat.Questions.Move(1,-1);">
   <img src="images/delete.png" alt="" class="ControlIcon" onclick="webchat.Questions.Delete(1);">
  </div>
  <div class="QuestionInnerText">
   1) <b>Peter Bridger</b>: This is the question text
   <br style="clear: right;">
  </div>
 </div>
</div>

From stackoverflow
  • Your description is a bit in depth and I hope that I am following it correctly but it seems to me that you are trying to attach a click event(s) to all of the items as well as all of the items that will be created in the future. Rather than specifying the onclick event when creating the you should use the new jQuery feature that came out in jQuery 1.3+ that allows you to specify an event for every element that matches the Selector... even future elements like the ones you will be adding via json.

     $("p").live("click", function(){
      $(this).after("<p>Another paragraph!</p>");
    });
    

    http://docs.jquery.com/Events/live

  • While I think the live idea will most likely work for you, my initial thought was to create a template div in the initial stages of the code, and then use the clone(true) method to create dynamic copies of the template and its methods. Then within the javascript "loop" each copy could be customised as needed before being appended into the DOM.

    http://docs.jquery.com/Manipulation/clone#bool

  • Thanks for your input everyone, I've decided to pass in the instance name of the Webchat when instancing it:

            var webchat;
                webchat = new AvonAndSomerset.WebchatV3(123, 'passcode', false , 'webchat' );
    

    Then inside the JavaScript I'm referencing the passed in referenced when dynamically building html with JavaScript in it:

    onclick="' + this.instanceName + '.popupMemberDetailsShow(' + this.Members.collection[i].memberId + ');
    

0 comments:

Post a Comment