Javascript: Dynamically created html elements referencing an instantiated object - javascript

(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">
<head>
<title>WebchatV3</title>
<script type="text/javascript" src="/JavaScript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="WebchatV3.js"></script>
<link rel="stylesheet" href="WebchatV3.css" />
</head>
<body>
<div id="WebchatSurround">
<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>
</body>
</html>
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>
</div>

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

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

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 + ');

Related

how to target an external div in javascript

I have this situation:
<div id="first">
<div>
<p>text</p>
</div>
</div>
<div id="second">
<div>
<button class="button">click</button>
</div>
</div>
...
<div id="first"> ... </div>
<div id="second"> ... </div>
...
and so on, the structure repeats.
This structure is created dynamically so I can't use any specific class nor id for the first div.
I need to retrieve the text in the first div when I hit the button in the second div.
(NOTE: I need a pure javascript solution, not a jQuery solution)
Thanks
Assuming you have an event handler for the button click, you could do this from that event handler:
function buttonClickHandler(e) {
var first = this.parentNode.parentNode.previousSibling;
var paragraphs = first.getElementsByTagName("p");
var text = paragraphs[0].textContent;
}
If you have common and known class names on the the divs marked first and second, then you can make your Javascript code much more insulated from markup changes which is generally a good idea.
P.S. I presume you know that you should't have duplicate id values in your HTML. This code doesn't use them, but you should be using class names instead of id values if you're going to have duplicates.

Selecting a Particular class inside another class and getting the inner html from a DOM using javascript

I am stuck with this thing.May be an immature question.I dont know,I am pretty new to programming.I want to get a particular elements inner html from DOM of the page.The problem is the page is so complex it has so many classes subclasses href,span and all kind of things.Here is what it looks like from the POINT OF VIEW OF MY REQUIRED CLASS(there are a lot of other class and id's but this is the navigation to my required class,I skipped others.)
<html>
<head></head>
<body>
<div class=
<span style=
<iframe class=
#document
<html id=
<body class=
<div class=
<div id=
<div id=
<div class=
<div class=
<span id=
<a class=
<div class= "required class"
</div>
</a>
<span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
</iframe>
</span>
</div>
</body>
<html>
Is there anyway to get the particular element using getelementbyID,getelementsbyClassName or any javascript property ?
Is this the correct one ?
document.getElementById('main').getElementsByClassName('test');
IF so how ?
I am not getting any output so I was was wondering this method is right or not..
Thanks in advance.
Assuming that your iframe is loaded from the same domain and you want to access the contents within this iframe, you will have to do something like:
document.getElementsByTagName('iframe')[0].contentWindow.document.getElementsByClassName('required class');
Take a look at this jsFiddle for example which loads fiddle.jshell.net in its iframe and applies a red color to the first editor found. Code of which is as belows:
document.getElementsByTagName('iframe')[0].contentWindow.document.getElementsByClassName('CodeMirror-scroll')[0].style.backgroundColor="red";
If you want the inner HTML of a DOM element then here is what you can do,
First access the element by it's id and use innerHTML to get the HTML content inside of it as,
var x = document.getElementById("main").innerHTML;
alert(x);
You are not getting proper output because you are not referencing the object and not accessing it's HTML content with innerHTML
EDIT: To access elements by class names you can use below script,
var x = document.getElementsByClassName("main");
for(var i=0;i<x.length;;i++){
alert(x[i].innerHTML);
}

Draggable many elements with same class

I need to be able to drag all the .notes on the page, but when i use draggable() from the jQuery UI, it only works for the first .note. I have jQuery UI downloaded and is working. When I click the page it makes a new .note so I think that this is a cloning problem. Here is the code
HTML:
<body>
<div id="wrapper">
<div id="wrp">
<h1>Click to make a new note!!!</h1>
<hr>
<div class="note">
<p class="remove"><b>X</b>
</p>
<div class="time"></div>
<hr>
<textarea class="item"></textarea>
<div class="saved"><span class="msg"></span>
</div>
</div>
</body>
JS:
$(".note").closest('.note').draggable();
(I will not include all my JS)
Fiddle here: http://jsfiddle.net/cjhind/zfxj3cps/46/
Any advise?
Add this extra line in your onclick function because jquery cannot recognise new items. It is like it has already did target the items with .note and you need to retarget them. Take care because this will load again the script and it will act twice. so as many items you insert you can see by firebug that it is calling script more times. If you need more info let me know.
$('#wrp, #wrapper').click(function showNote() {
$('.note').fadeIn();
$(".note").closest('.note').draggable(); // ADD THIS TO GIVE YOUR NOTE THE ABILTY TO BE DRAGABLE
});
Did this help?

Angular ng-repeat, Jquery fail

So I am using ng-repeat to repeat some divs which show images out of my JSON file. What I want to do is that when I click on that image (whether its desktop or mobile) the image will scale. Now my problem is that when I want to create a click event on my image tag (which is inside that div that holds the ng-repeat), he doesn't do anything. He cant see the click.
I red something on the internet about issues with jquery and angular, but for me as a beginner its hard to understand what I have to do to make it work how I pleased. I just want to be able to put a jquery function on a image tag inside the ng-repeated divs, so I can manipulate the css from there.
I have a piece of the code posted below here, maybe I have to add something to my controller? I dont know, I am clueless at the moment. :-)
<section class="words">
<div class="colored-sidebar"></div>
<!-- content -->
<div class="previous-button"></div>
<div class="word-container" ng-controller="imageController as imageCtrl">
<h1><span>noun</span>words</h1>
<div class="category-body">
<p><span>noun</span>travel</p><hr>
<div class="category-section" ng-repeat="icon in imageCtrl.imageList.travel">
<!-- <div class="category-image" ng-include="icon.src"></div> -->
<div class="category-image">
<img src="{{icon.src}}" />
</div>
</div>
</div>
</section>
The angular file
(function() {
app.controller('imageController', function(){
this.imageList = imageJson;
});
var imageJson = {
//ALOT OF JSON DATA HERE//
};
})();
I hope this piece of code would be enough to help me :-)
Any tips are welcome, I love to learn this language better and also understand it better.
Thanks!
jQuery is not suitable here, because by the time you run your jQuery code inside jQuery.ready(), the elements in "category-image" class are not created yet.
For solution of your problem you can use two methods:
1) Use the "ng-click", as proposed before. You can also pass "$index" to function inside ng-click. This way you will know index of icon in imageList.travel that was clicked. But this way you will have no information about dom element.
2) Create a directive. The main difference between directives and controllers is that directive have information about dom object. You can treat element as typical jQuery object
JS:
app.directive('imageClick', [function () {
return {
link: function (scope, element, attr) {
element.on("click", function(e){
//do some stuff here
})
}
}
}]);
HTML
<section class="words">
<div class="colored-sidebar"></div>
<!-- content -->
<div class="previous-button"></div>
<div class="word-container" ng-controller="imageController as imageCtrl">
<h1><span>noun</span>words</h1>
<div class="category-body">
<p><span>noun</span>travel</p><hr>
<div class="category-section" ng-repeat="icon in imageCtrl.imageList.travel">
<!-- <div class="category-image" ng-include="icon.src"></div> -->
<div class="category-image">
<img image-click src="{{icon.src}}" />
</div>
</div>
</div>
</section>

insertAdjacentHTML inserts <div /> when it should not

I have a main DIV where I would like to insert different DIVs via PHP.
Very simplified my HTML looks like:
<div id="mainDiv">
<div id="invoice1">
....
</div>
<div id="invoice2">
....
</div>
<div id="invoice3">
....
</div>
</div>
The user can then interact by clicking on buttons (ajax) and fx. the div with "invoice2" needs to be given new HTML (cleared out and having inserted the new HTML).
I can do this by using innerHTML but gets very slow with 100's of divs (invoices) and the coding is not nicely done.
To improve this I tried with insertAdjacentHTML but I cannot get it to make HTML like:
<div id="invoice1">
insertAdjacentHTML inserts it as
<div id="invoice1"></div>
And the ending
</div>
is stripped away (making the page look wrong).
So how can I do this in a smart way?

Categories