Adding HTML to Document body not allowing for div click - javascript

When the batman image is clicked on it shows the 'overlay' div however that div is not clickable for some reason thus not allowing the onclick portion of the code to run. Deleting the 'document.body..... ' line of code solves this issue but why?
JS:
window.onload = function()
{
$("#overlay").hide();
}
$(document).ready(function(){
//page is ready
$("#overlay").on("click",function(){
alert("hi");
$("#overlay").fadeOut(500);
});
$('#batman').on("click",function(){
lightboxImg()
});
});
function lightboxImg()
{
var source = $('#batman').attr('src');
var text = "<img src= \"" + source + "\" id=\"lightbox-img\"/>";
document.body.innerHTML = text + document.body.innerHTML;
$("#overlay").fadeIn(0);
}
HTML:
<!DOCTYPE html>
<html>
<head>
<title> Lightbox </title>
<link rel="stylesheet" type="text/css" href="lightboxcss.css">
</head>
<body>
<div id = "overlay"></div>
<img src="batman.jpg" alt="" href="javascript:void(0)" id="batman" >
<br><br><br><br>
<p> RANDOM TEXT STUFF </p><br><br>
<p> 328ueekfuuirgh40t43h8hohro8ht </p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="lightboxjs.js"> </script>
</body>
</html>

Your handlers apply to some elements which are recreated when you append to innerHTML. You need to .prepend to body and have something like this:
window.onload = function()
{
$("#overlay").hide();
}
$(document).ready(function(){
//page is ready
$("body").on("click", "#overlay",function(){
alert("hi");
$("#overlay").fadeOut(500);
});
$('body').on("click", "#batman",function(){
lightboxImg()
});
});
function lightboxImg()
{
var source = $('#batman').attr('src');
var text = "<img src= \"" + source + "\" id=\"lightbox-img\"/>";
$("body").prepend(text);
$("#overlay").fadeIn(0);
}

document.body.innerHTML = ... overrides the element inside the body with new elements. The new elements won't have any event listeners. So clicking them won't fire any functions. So instead of ovveriding the body content with new elements use insertBefore like:
function lightboxImg()
{
var source = $('#batman').attr('src');
var text = "<img src= \"" + source + "\" id=\"lightbox-img\"/>";
//insertBefore
$(text).insertBefore($("#overlay"));
$("#overlay").fadeIn(0);
}

Use extended jQuery format like:
$(document).on('click', $(#....), function(){});
Check jQuery API for extended .on() parameters.

Related

How to display viewbag elements in Javascript?

How to call the Method in Jquery's Append Method ?
I have the HTML code in which I use the append method() on click of a button.
I want to append the HTML with viewbag data using loop.
here is my code , is that right ?
<html>
<body>
<div class="row-fluid" id="MyCode">
</div>
<button name="AddCode"></button>
</body>
</html>
<script type="text/javascript">
$(document).ready(function ()
{
$('#AddCode').click(function () {
$('#MyCode').append("<di ><div class='span2'>" +
//I want to call the function here...
AddDivs()
);
});
function AddDivs()
{
var ht="";
#foreach (var item in ViewBag.LocationList)
{
ht += "<div id='"+item.Id+"_"+item.Name+"'></div>";
}
}
});
</script>
Its showing undefined.
Change foreach loop with following:
#foreach (var item in ViewBag.LocationList)
{
// these lines are client codes that is in server codes
<text>ht += "<div id='" + #item.Id + "_" + #item.Name + "'></div>";</text>
}
if you dont write your js codes in <text>, razor assume that ht is an server variable.
script tag must be inside of body tag
<script type="text/javascript">
...
</script>
</body>
</html>

wrapping a text url with <a> tags via jquery find and replace

I am pulling in tweets through a getJSON and writing them to a Google map infowindow with javascript. The problem is, these tweets come with text links but no formatting (and no ids/classes/anything for which to narrow a find and replace). This is the mash of code I'm using right now to find the text, but I can't get it to wrap whatever it finds in <a> tags to properly display the links:
function wrap( str ) {
return '<a href="' + str + '">' + str + '<\/a>';
};
function replaceText() {
var jthis = $(this);
$("*").each(function () {
if (jthis.children().length == 0) {
jthis.text(jthis.text().replace(/\bhttp[^ ]+/i, wrap));
}
});
}
$(document).ready(replaceText);
$("html").ajaxStop(replaceText);
Did I overlook something or does anyone know a better way to do this?
If i understand your problem right, this should work.
not sure why you are iterating through elements as regexp will scan all the text anyway.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js" type="text/javascript"></script>
<script>
function wrap( str ) {
return '<a href="' + str + '">' + str + '<\/a>';
};
function replaceText() {
$(".tweet").each( function(){
$(this).html($(this).html().replace(/\bhttp[^ ]+/ig, wrap));
})
}
$(document).ready(replaceText);
</script>
</head>
<body>
<div class="tweet"> test 1 http://example.com/path </div>
<div class="tweet"> test 2 http://example.com/path </div>
</body>
</html>

JSon and Jquery Accordion

This is driving me freaking BATTY as hell.
This is essentially what I am trying to accomplish.
You'll see the Json there are a 2 different departments "Office" and "Stockroom"
What I am trying to accomplish is to arrange everyone by the department they are in. The problem with this is that the HTML needs to look something like this
<h3>Section 1</h3>
<div>
<p>
First Paragraph
</p>
<p>
Second Paragraph
</p>
<p>
Third Paragraph
</p>
</div>
But unfortunately I cannot seem to get the </div> tag in the right spot at the end of the last paragraph of each section
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="http://jqueryui.com/themes/base/jquery.ui.all.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="http://jqueryui.com/ui/jquery.ui.accordion.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var contacts = [{"displayname":"Bruce Lee","email":"Bruce.lee#karate.com","department":"stockroom"},
{"displayname":"Your Momma","email":"Your.Momma#Yourmom.com ","department":"stockroom"},
{"displayname":"Bob","email":"Bob#bob.com ","department":"Office"},
{"displayname":"Cathy","email":"Cathy#Cathy.com ","department":"Office"},
{"displayname":"mike","email":"mike#Cathy.com ","department":"Office"},
{"displayname":"scott","email":"scott#Cathy.com ","department":"Office"}
];
var contacts2 = contacts;
var r = 1;
var lastvalue = 'blah';
for(var i=0; i <=contacts.length; i++)
{
if(contacts[i].department != null)
{
if(lastvalue != contacts[i].department)
{
if(i<1)
{
$('#accordion').append('</div><h3>' + contacts[i].department + '</h3>');
$('#accordion').append('<div><p>' + contacts[i].displayname + '</p>');
}else{
$('#accordion').append('<h3>' + contacts[i].department + '</h3>');
$('#accordion').append('<div><p>' + contacts[i].displayname + '</p>');
}
}else{
$('#accordion').append('<p>' + contacts[i].displayname + '</p>');
}
lastvalue = contacts[i].department;
r++;
}
}
});
$(function() {
$( "#accordion" ).accordion();
});
</script>
</head>
<body>
<div id="contactlist">
<div id="accordion">
</div>
</div>
</body>
</html>
You might want to change this to a jquery each loop and work with json objects directly inside it. The reason you were getting an accordion level each time was due to your loop inserting a h3 every time. I've supplied code to get you pretty much what you need.
edit:
Here is a link to my forked jsfiddle => http://jsfiddle.net/TTV6d/12/
Hope this helps
var departmentlist=new Array();
$.each(contacts, function(i,contact) {
//insert the departments
if (contact.department != null && $('#' + contact.department).length == 0) {
$('#accordion').append('<h3 id='+ contact.department +'>' + contact.department + '</h3>');
departmentlist.push(contact.department);
}
//insert contacts in the accordion
$('#' + contact.department).after('<p>' + contact.displayname + '</p>');
});
$.each(departmentlist, function(i,list) {
$("#" + list).nextUntil("h3").wrapAll("<div></div>");
});
First, be aware that browsers will generally attempt to normalize markup appended to the document: (http://jsfiddle.net/EVjaq/)
$('#container').append('<div><p>Testing</p>'); // no `</div>`
console.log($('#container').html()); // `<div><p>Testing</p></div>`
So, the open <div> in this line will be closed at the end for you, before the next <p> is appended:
$('#accordion').append('<div><p>' + contacts[i].displayname + '</p>');
To avoid this, you can store all of the HTML in a variable, concatenating segments together, and append it to the DOM only once it's done. Or, you can store the <div> and append to that, which can make the conditionals a bit simpler:
var lastvalue = null,
lastdiv = null;
for (var i = 0; i <= contacts.length - 1; i++) {
if (contacts[i].department != null) {
if (lastvalue != contacts[i].department) {
$('#accordion').append('<h3>' + contacts[i].department + '</h3>');
// remember `<div>`
lastdiv = $('<div>').appendTo('#accordion');
}
// append to the `<div>` directly rather than `#accordion`
// also, skip the `else` so you don't have to type this twice
lastdiv.append('<p>' + contacts[i].displayname + '</p>');
lastvalue = contacts[i].department;
r++;
}
}

jQuery text to input?

I have a simple layout with a textblock and one <a>, like:
text1 edit
When I click on the <a>, I want this textblock to become text input. How is that possible with jQuery?
Use jQuery replaceWith():
$(document).ready(function(){
$("a").click(function(e){
e.preventDefault();
$(this).parent().replaceWith("<input />");
});
});
http://jsfiddle.net/Dqkyg/1/
Furthermore, you can fill the textbox with the text outside the link like so:
$(document).ready(function(){
$("a").click(function(e){
e.preventDefault();
var txt = $(".text").html();
$(".text").replaceWith("<input value='" + txt + "' />");
});
});
http://jsfiddle.net/Dqkyg/5/
The following will replace the edit with Save & Cancel options:
<div>
<span class="text">testing</span> <a href='#'>test</a>
</div>
$(document).ready(function(){
$("a").click(function(e){
e.preventDefault();
var txt = $(".text").html();
$(".text").replaceWith("<input value='" + txt + "' />");
$(this).replaceWith("<a href='#'>Save</a> | <a href='#'>Cancel</a>");
});
});
http://jsfiddle.net/Dqkyg/6/
There are plenty of plugins that you can use... No need to reinvent the wheel
http://www.appelsiini.net/projects/jeditable
Hmm ... ur a bit unclear... but
http://jsfiddle.net/mMYrf/4/
<div class="dataGrid">
<span>test</span>
edit
</div>
And
$('.dataGrid a').click( function(e) {
e.preventDefault();
var EditGrid = $(this).parent().children('span');
var DataTxt = EditGrid.text();
var InputHtml = '<input type=text" value="'+DataTxt +'" />';
$(this).text('Save?');
EditGrid.html(InputHtml);
});
<div class="editable">This is the content.</div>
<script type="text/javascript">
$(function() {
$('.editable').each(function() {
var a = $('edit');
(function(link, parent) {
link.click(function() {
link.remove();
var textField = $('<textarea/>').val(parent.html());
parent.replaceWith(textField);
delete parent, link;
});
})(a, $(this));
$(this).append(" ").append(a);
});
});
</script>
Working example: http://jsfiddle.net/BnH29/

How to catch creation of DOM elements and manipulate them with jQuery

I'm trying to devise a method of when adding a simple div element with a class and some data-* in it, it will replace it or add into it some other elements. This method should not be called manually, but automatically by some kind of .live() jQuery method, a custom event or some kind like $('body').bind('create.custom'), etc.
I need it this way since I wouldn't know in advance what elements will be created since they will be served through ajax like single empty div's or p's .
<!DOCTYPE html>
<html>
<head>
<title >on create</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" ></script>
<script type="text/javascript" >
jQuery(function($){
$("div.fancyInput").each(function(index,element){
var $div = $(this);
var dataId = $div.attr("data-input-id");
var inputId = '';
var labelId = '';
if(!!dataId){
inputId = 'id="' + dataId + '"';
labelId = 'id="' + dataId + 'Label"';
} // if
var dataValue = $div.attr();
$(
'<p class="fancyInput" >' +
' <label ' + labelId + ' for="' + inputId + '" >A fancy input</label>' +
' <input ' + inputId + ' name="' + inputId + '" value="A fancy input" />' +
'</p>'
).appendTo($div);
}); // .each()
}); // jQuery()
</script>
<script type="text/javascript" >
jQuery(function($){
var counter = 2;
var $form = $('#form');
$('#add').click(function(event){
$('<div class="fancyInput" data-input-id="fancyInput' + counter + '" ></div>').appendTo($form);
counter++;
}); // .click
}); // jQuery()
</script>
</head>
<body>
<a id="add" href="#" > add another one </a>
<form id="form" action="#" >
<p class="normalInput" >
<label id="normalInputLabel" for="normalInput" >A normal input</label>
<input id="normalInput" name="normalInput" value="A normal input" />
</p>
<div class="fancyInput" ></div>
</form>
</body>
</html>
Update:
I checked liveQuery beforehand, it's that kind of functionality that I need, but with the ability to modify DOM elements while the event callback is executed. So it's not just that I need events attached, but the ability to modify the DOM upon element creation. For example: whenever a new is created, it should be filled in (even better if replaced) with the p, label and input tags
You could use a DOM Level 3 Event, like DOMNodeInserted. This could look like:
$(document).bind('DOMNodeInserted', function(event) {
// A new node was inserted into the DOM
// event.target is a reference to the newly inserted node
});
As an alternative, you might checkout the .liveQueryhelp jQuery plugin.
update
In referrence to your comment, have a look at http://www.quirksmode.org/dom/events/index.html, only browser which do not support it are the Internet Explorers of this this world (I guess IE9 does at least).
I can't say much about the performance, but it should perform fairly well.

Categories

Resources