Firing Javascript on dynamic <div> load - javascript

I'm working on adding page title notifications for an install of AJAXchat. I'm using a jQuery plugin called jquery-titlealerts to achieve this. If I assign the method on the onclick event it works as correctly and changes the page title. But that doesn't work as I need. I need it to change the page title each time a new div is created. Here is the js that dynamically creates a new div every time someone submits a message:
return '<div id="'
+ this.getMessageDocumentID(messageID)
+ '" class="'
+ rowClass
+ '">'
+ this.getDeletionLink(messageID, userID, userRole, channelID)
+ dateTime
+ '<span class="'
+ userClass
+ '"'
+ this.getChatListUserNameTitle(userID, userName, userRole, ip)
+ ' dir="'
+ this.baseDirection
+ '" onclick="$.titleAlert(\'Error!\');">'
+ userName
+ '</span>'
+ colon
+ this.replaceText(messageText)
+ '</div><script>$.titleAlert(\'Error!\');</script>';
return
As you can see I've tried creating a <script> block to load just below the div - and it does but for some reason isn't changing the document title. If you click on a message generated in the chat it will work though because it is being fired from the onclick event..
I'm not sure what else to try to get it to work when each div is loaded.

In the place where you're calling the function that has this return statement, after you call that function you should update the page title. If you don't want to do it that way, you can have the function that returns your new Div content update the page title right before it returns.
Alternatively, consider using jQuery's $.ajax() method with a complete (or success) callback to do the title modification. Honestly, this would be my preferred approach if I were to be given this problem to solve.
You can read all about $.ajax() here.

Inserting a script block programmatically almost never works in modern browsers for obvious security reasons.
Instead, make the script that receives this HTML do the alerting, possibly based on part of the content of the HTML; say, a hidden span containing the message to pull out and use as the title.

Related

Dynamically creating an HTML link that passes a list to a JavaScript function

I have an HTML link that calls a JavaScript function that in turn makes a NEW link. This new link calls the same JS function when clicked, making another link etc. The function also creates a new div where the next link is added.
function displayChildren(displayLocation, myList) {
innerHtml = "";
for (item in myList) {
name = myList[item];
newDisplayLocation = displayLocation + "/" + name;
innerHtml += "<a href='#' onclick='displayChildren(\"" + newDisplayLocation + "\", " + myList + ");'>" + name + "</a>";
innerHtml += "<div id='" + newDisplayLocation + "'></div>";
}
document.getElementById(displayLocation).innerHTML = innerHtml;
}
{{myList.0}}<br />
<div id="{{myList.0}}"></div>
However, I want to pass this JS function a list as a parameter. The first HTML link made is not dynamically created and therefore can pass that list easily, but subsequent links will not give the JS function the list. The onclick tag will call the JS function and pass other parameters fine, but lists are turned into a string.
So the list [["apple", []]] will turn into apple,. This makes sense because I am putting this entire <a> tag into a string. But I still need that link to pass a list, or just in some way get this JS function a list. Any ideas how to do this?
Additional Information:
I am using this to create a tree structure that will show all of a node's
children when clicked.
The list is changed each time it is passed to the JS function. It actually passes the list of the node's children.
The page is not refreshing.

Insert html element into a previously dynamically inserted element?

Here is my first question here, I've been looking for an small clue on many researches but didn't found any piece of answer, hope it's not a silly thing.
I'll try to be straight: I'm working on a website dealing with xml files (data is stored in an array then displayed and fully editable).
Until now and despite some troubles I figured out, everything works fine.
I loop on my array to get all the required string then create jQuery object (such as $("<input id='xxx' value='yyy' />") that I appendTo a specific div).
At first start, I have an empty #insertXml div (written in my html).
One my xml files parsed and my array ready, I dynamcically create a #content div appended to my #insertXml, then for each index I'll have its key written in a #keyInput" div (dynamic insert, only once), then 1st value in a #lang1 div (still dynamic insert), 2nd in #lang2 div, etc.
lang1, lang2, etc are variables, so it's written:
$("<input .../>").appendTo("#"+langN);
where langN changes on each loop.
Everything works FINE!... at 1st display :/
The trouble is, when I'm using my function that creates new data.
I work first on a modal window, to retrieve user values through the listener function, then pass it to another function that pushes it in my array.
I debugged it, that works, my array is correctly updated.
Then I want to simply refresh my page, so I try, the same way I did previously for my whole data, to append a few inputs.
It works then correctly on my #keyInput div, but NOT on my #lang divs !?!?!
No matter how I try (even forgetting jQuery and using html document.xxx functions), no way.
While debugging, all my variables are OK, it just does nothing when doing the "appendTo", except once for the keyInput div.
I tried then to remove the #content div and relaunch the whole displayInit() method (heavy operation but, just to see) and same damn problem: only the #keyInput is correctly refreshed.
The only thing I've read that may be interesting, is that dynamically created elements (through script) are not registered in the DOM, so it can't be found.
BUT in that case, none of my display attempts should work, so?
In advance, THANK YOU very much for taking care about my nightmare.
Attached: my html + JS function.my DOM
function displayInsert() {
var firstLang = stripXmlExtension(paths[0]); // same keys on every language, so we grab the 1st one
var lastKeyIndex = mapXml[firstLang].key.length - 1;
var keyToInsert = mapXml[firstLang].key[lastKeyIndex]; // == last insertion
var inputKey = "<input size=35 type=text id=k" + lastKeyIndex + " value=" + stripHTML(keyToInsert.replace(/ /g, " ")) + " readonly />";
// while appending tag to the HTML content page, we add a dblclick listener that will morph the input into a textarea when double dblclicked
$(inputKey).css("margin-bottom", "15px").dblclick(function (e) {
e.preventDefault();
tempEditId = $(this).attr('id');
$(".modal-body").html("<textarea cols='65' rows='10' id='txt" + $(this).attr('id') + "'>" + $(this).val() + "</textarea>");
$("#modalEdit #btn-correct").css("display", "none");
$("#modalEdit").modal({backdrop: "static"});
}).appendTo("#keyInput");
for (var i = 0; i < paths.length; i++) {
var lang = stripXmlExtension(paths[i]);
var lastValueIndex = mapXml[lang].value.length - 1;
var valueToInsert = mapXml[lang].value[lastValueIndex]; // == last insertion
var inputValue = "<input size=35 type=text id=" + lang + "---" + lastValueIndex + " value=" + stripHTML(valueToInsert.replace(/ /g, " ")) + " readonly />";
// while appending tag to the HTML content page, we add a dblclick listener that will morph the input into a textarea when double clicked
$(inputValue).css("margin-bottom", "15px").dblclick(function (e) {
e.preventDefault();
tempEditId = $(this).attr('id');
$(".modal-body").html("<textarea cols='65' rows='10' id='txt" + $(this).attr('id') + "'>" + $(this).val() + "</textarea>");
$("#modalEdit #btn-correct").css("display", "none");
$("#modalEdit").modal({backdrop: "static"});
}).appendTo("#" + lang);
}
}
OMG, I'm ashamed.
My problem came from an input generated in a modal window that took the same id that was duplicated...
I was hoping it would be a little more complicated ^^
Solved!

PHP echo appears to work but doesnt show up in HTML

I am trying to use a php script to generate HTML in order to save lines and what not. I am using jQuery to call my php and then put the result into a specified div as shown below:
function createSidebarRow(div, cellNum, rowName, rowDesc) {
$("#" + div).load("createIndexSidebarRow.php?cellNum=" + cellNum + "&rowName=" + rowName + "&rowDesc=" + rowDesc);
}
However, when this is executed the HTML is not updated on the page, I can see that the code has worked because the browser network activity confirms it. I am trying to figure out what is causing it to not update.
This is the network activity confirming the echo'd HTML.
Sorry for stating the obvious, but the div you are trying to fill up does exist with that particular id right?
If so, try this:
$("#" + div).load("createIndexSidebarRow.php?cellNum=" + cellNum + "&rowName=" + rowName + "&rowDesc=" + rowDesc, function() {
alert('success');
});
If the id does exist (and it's unique) and you get an alert there should be no reason for it not to work.
It might be so, that the div is not yet created in the DOM. (the div that should received the html).
Are you calling createSidebarRow directly on page load?
If so, put the function call in a document ready:
jQuery(document).ready(function(){
createSidebarRow (... );
});
Turns out jQuery doesn't play ball when you include spaces in the POST URL. I removed the space and used %20 instead and all is well now. Thanks for any advice.

prevent execution of innerHTML

I have a Chrome extension in which I'm fetching tab title and url, and putting them into one single line. Same as Chrome History. I want to separate them visually, dark title, lighter url.
and for that I'm using this code
nodeTitle.innerHTML = tabs[j].title + "<span id='url'>" + ' - ' + tabs[j].url + "</span>" ;
CSS for #url is set and everything works fine, unless page title have some actual HTML code/tag in it, and title get messed (ofc. innerHTML works as it supposed to).
example page...look at title
innerText doesn't help in this situation, because I need < span > treated as it is.
Is there any way to cancel HTML execution for that first part (which can be any variable) or I have to separate them into two different elements and style them?
(and I'm really trying to avoid that)
...maybe check for tags and insert space if any exist??!... relized while writing this question, span tag in pointy brackets :)
You can use createTextNode as an easy (though perhaps not very efficient) way to do this:
function textToHtml(str) {
return document.createTextNode(str).innerHTML;
}
nodeTitle.innerHTML = textToHtml(tabs[j].title) + "<span id='url'>" + ' - ' + textToHtml(tabs[j].url) + "</span>" ;

Why i am unable to bind a method on onClick event of div?

I am trying to create div elements dynamically, and at the time of creation i am using onClick = 'showDimension();'. It shows the correct html on alert box but when DIV is created you can see that div is not having any onClick method attached [ firebug ]. Instead of that it is having a stray string 'showDimension();'. Why it is happening ? How to resolve it?
http://jsbin.com/inoqi3/3
Also, you can see that i am using
var eventDe = " onClick='showDimension("+i +");'";
and then, later this i will be used to find out the div id. Quite obvious it is not correct approach. How to use the event.target or event.srcElement to get the div from which the event is fired? I tried but unable to use that.
You messed up with quotes. Sometimes you use " and sometimes '.
If you go to the route of generating your HTML by strings you may use ' to build your string in Javascript and the " for the HTML attributes as it should be. Like below:
var style = [' style="background-color: ' + getRandomColor(),
'position:absolute;border: thick solid',
'height: ' + height,
'width: ' + width,
'left: ' + left,
'top: ' + top,
'" '].join(';');
var eventDe = 'onclick="showDimension(this);"';
var innerText = 'DIV:' + i + '<br/> height: ' + height + '<br/>';
var html = '<div id="div' + i + '" ' + style + ' ' + eventDe + '>' +
innerText + '</div>';
Note few things:
Instead of the += you can use an Array and join
You don't have to camelize onclick as attributes are not case sensitive
The showDimension(this), this will give you the reference of the clicked DIV.
You can get it with:
function showDimension(div){
alert($(div).height());
}
Something you may consider to avoid all these string manipulations is to use a javascript template engine. I contribute to PURE but there are plenty of others available.
Update:
$('#element_id').live('click', function(event){
var trget = event.target;
});
The jQuery has the live() method you can use to apply click event to dynamic elements.
Example:
$('#element_id').live('click', function(){
// your code...
});
Why don't you try the div class name approach.
Giv a class name to the div so that you can have a separate click handler
('.clasname').live(click,function()) like...this
If you don't want to use jQuery binders (live, bind, click) but the attribute onclick instead, make sure you add javascript: to indicate JS call and event as a parameter to your event handler so that you can access event.target and other data inside your function::
var eventDe = " onlick='javascript:showDimension(event, " + i + ");'";
I'd still recommend using jQuery. Remember that even if you are generating the HTML in your JS (such as in response for AJAX request), you can still do that using jQuery API and attach events to newly created nodes before you add them to parents (via methods like after).

Categories

Resources