First of all I am not very good in designing but with some help I am able to acheive this code
My main issue is that when a user opens a div it becomes the target div, so if I have five divs open at the same time it doesn't matter which I type in because the text gets appended to the last opened div. I can also open an unlimited amount of the same div, which should not happen.
The small issue I have is that I'm unable to close the div and minimize it(much like fb when we click on the chat box it gets minimized).
Fiddle
HTML
<div id="contact">
<header>Users</header>
<main>
<ul>
<li id="Prashant">Prashant</li>
<li id="Katrina">Katrina</li>
<li id="Priyanka">Priyanka</li>
<li id="Kareena">Kareena</li>
<li id="Anushka">Anushka</li>
</ul>
</main>
</div>
<div id="chat"></div>
CSS
* {
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
body{margin:0;padding:0;}
#contact {
height: auto;
background: #ececec;
position:absolute;
right:0;
bottom:0;
width:100px;
}
#contact header {
padding: 10px;
background: #333;
color: #FFF;
}
#contact main {
padding: 10px
}
#chat {
position: fixed;
bottom: 0;
left: 0;
right: 100px;
height: auto;
}
#chat .user {
border: 1px solid #333;
background: #fff;
width: 200px;
height: 100%;
float: left;
margin-right: 5px;
}
.user header {
position: relative;
background: #4b67a8;
border: 1px solid #2e4588;
}
.user header .status {
position: absolute;
top: 36%;
left: 10px;
width: 8px;
height: 8px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
background: green;
}
.user header .header-text {
color: #fff;
font-weight: bold;
padding: 8px;
margin: 0 0 0 15px;
font-size: 12px;
text-shadow: 0 -1px rgba(0, 0, 0, .25);
}
.user header .close {
position: absolute;
right: 5px;
top: 7px;
color: #fff;
}
.message-area {
background: #fff;
height: 120px;
padding: 5px;
color: #333;
overflow: scroll;
}
.user .input-area {
border-top: 1px solid #333;
padding: 3px;
}
.user .input-area input {
padding: 5px;
width: 100%;
font-size: 12px;
border: none;
outline: none;
}
Javascript
var username = 'user201';
$(document).ready(function() {
$('a').click(function(e) {
e.preventDefault();
var targetUser = ($(this).html());
$(document).data('chat.targetUser', targetUser);
var user = '<div class="user open" id="' + targetUser + '"><header><div class="status"></div><div class="header-text">' + targetUser + '</div><div class="close">×</div></header><div class="message-area"></div><div class="input-area"><input type="text" id="input" /></div></div>';
$('#chat').append(user);
});
$('#chat').on('keydown', '#input', function(event) {
if (event.keyCode == 13) {
var targetUser = $(document).data('chat.targetUser');
var txt = $(this).val();
$('#' + targetUser + ' .message-area').append(username + ': ' + txt + '<br/>');
$(this).val('');
}
});
});
I edited div.close and added a div.mini like
<div class="mini" title="MINIMIZE">-</div>
<div class="close" title="CLOSE">×</div>
Css for .mini
.user header .mini {
position: absolute;
right: 25px;
top: 7px;
color: #fff;
cursor:pointer;
}
JS code for them to work
$(document).on("click", "div.close", function(){
$(this).parent().parent().remove();
});
$(document).on("click", "div.mini", function(){
var elem = $(this).parent().parent().children().not("header");
elem.slideToggle();
});
Also added this js code to prevent add the div if it's already opened and make it append to last section of chat
if ($("div#" + targetUser).length > 0) {
$("div#" + targetUser).appendTo("#chat");
return false;
}
FIDDLE
EDIT
Edited div.mini click function for -/+ Minimize/Maximize
$(document).on("click", "div.mini", function(){
var elem = $(this).parent().parent().children().not("header");
elem.slideToggle();
$(this).text($(this).text() == "-" ? "+" : "-");
$(this).attr("title", $(this).attr("title") == "MINIMIZE" ? "MAXIMIZE" : "MINIMIZE");
});
UPDATED FIDDLE
The text you enter will appear in the last opened div because your var targetUser is changed every time you click on one of the users. The best way to solve this I think is to find the parent of the input field and search for the previous .message-area.
Like this:
$('#chat').on('keydown', '#input', function(event) {
if (event.keyCode == 13) {
var txt = $(this).val();
$(this).parent().prev(".message-area").append(username + ': ' + txt + '<br/>');
$(this).val('');
}
});
Working JSFiddle
Here is the fix for your code:
http://jsfiddle.net/afzaal_ahmad_zeeshan/36pcu/14/
I have updated the code in your fiddle, and I have added a fix so that the divs don't open up twice.
I just added a class to the link of the user, to show that this user is now active. Here is the code
if($(this).attr('class') != 'active') {
var targetUser = ($(this).html());
$(document).data('chat.targetUser', targetUser);
var user = '<div class="user open" id="' + targetUser + '"><header><div class="status"></div><div class="header-text">' + targetUser + '</div><div class="close">×</div></header><div class="message-area"></div><div class="input-area"><input type="text" id="input" /></div></div>';
$('#chat').append(user);
}
$(this).attr('class', 'active');
Then the div thing was handled using this code:
if (event.keyCode == 13) {
var txt = $(this).val();
$(this).parent().prev(".message-area").append(username + ': ' + txt + '<br/>');
$(this).val('');
}
This was the fix for your code, now it works.
According to your statement "...Also I am able to open an unlimited amount of the same divs, which should not happen**..." this can be prevented if you know what are the boxes opened
please check the Fiddle
var id = '#Box' + targetUser;
var existent = $('#chat').find(id)[0];
// This will ensure that you can only open one box at each time
if(existent != null){
alert('There is already one chat to user "' + targetUser + '" open');
}
else
{
your code...
}
Also the fix proposed by speetje33 helps you prevent to write always in the last box.
I've added some comments to the code for your better understanding.
Related
I've decided to try and make a Notes program as a learning experience. The point was to problem-solve on my own, but I'm pretty clueless as to why this won't work.
When I Shift + Double Click a note to rename it the note changes from a <div> to <input>, but the CSS stays the same. When I press enter (which submits the input) the changes back to <div>, and the CSS is there, but it is very small and doesn't take the shape of the text. Any idea why? Thanks!
Code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button class="newList" onclick="newNote()">Create a new note</button>
<br></br>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script>
function clickNote(){
if(event.shiftKey){
$( "div" ).click(function() {
$( this ).replaceWith( "<tr><td><form'><input class='rename' placeholder='Type here' onkeydown='enter(event)' id='newListName' autofocus>" + "</input></form></td></tr>" );
});
} else {
location.href='list.html';
}
}
function enter(event){
var enter = event.which;
if (enter == 13){
var input = document.getElementById("newListName");
$( "input" ).keyup(function() {
$( this ).replaceWith( "<tr><td><div class='list' id='list' onclick='clickNote()'>" + input.value + "</div></td></tr>" );
});
}
}
function newNote(){
var newNt = document.createElement("DIV");
var text = "Rename with Shift + Double Click"
newNt.textContent = text;
newNt.setAttribute('class', 'list');
newNt.setAttribute('id', 'list');
newNt.setAttribute("onclick", "clickNote()");
document.body.appendChild(newNt);
}
</script>
</body>
</html>
CSS:
:root {
--main-color: #FFE033;
--secondary-color: #FEC82A;
}
.newList {
height: inherit;
width: 10%;
padding: .4%;
position: relative;
border-bottom: 4px solid var(--secondary-color);
background: var(--main-color);
}
.list {
height: inherit;
width: 10%;
padding: .4%;
position: relative;
border-bottom: 4px solid var(--secondary-color);
background: var(--main-color);
}
.rename {
height: 2.5em;
width: 116%;
padding: .4%;
position: relative;
border-bottom: 4px solid var(--secondary-color);
background: var(--main-color);
}
#list {
cursor: pointer;
}
Am not sure why you are doing this, but you are adding td tr around the div which make it insde a table and create this issue as the width is defined with 10%. Remove it and it should work fine. You need also to correct the input tag.
function clickNote() {
if (event.shiftKey) {
$("div").click(function() {
$(this).replaceWith("<input class='rename' placeholder='Type here' onkeydown='enter(event)' id='newListName' autofocus>");
});
} else {
location.href = 'list.html';
}
}
function enter(event) {
var enter = event.which;
if (enter == 13) {
var input = document.getElementById("newListName");
$("input").keyup(function() {
$(this).replaceWith("<div class='list' id='list' onclick='clickNote()'>" + input.value + "</div>");
});
}
}
function newNote() {
var newNt = document.createElement("DIV");
var text = "Rename with Shift + Double Click"
newNt.textContent = text;
newNt.setAttribute('class', 'list');
newNt.setAttribute('id', 'list');
newNt.setAttribute("onclick", "clickNote()");
document.body.appendChild(newNt);
}
:root {
--main-color: #FFE033;
--secondary-color: #FEC82A;
}
.newList {
height: inherit;
width: 10%;
padding: .4%;
position: relative;
border-bottom: 4px solid var(--secondary-color);
background: var(--main-color);
}
.list {
height: inherit;
width: 10%;
padding: .4%;
position: relative;
border-bottom: 4px solid var(--secondary-color);
background: var(--main-color);
}
.rename {
height: 2.5em;
width: 100%;
padding: .4%;
position: relative;
border-bottom: 4px solid var(--secondary-color);
background: var(--main-color);
}
#list {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="newList" onclick="newNote()">Create a new note</button>
Assume that i have two pages:
Client page
Items page
in both pages i have an Add buttons, is it possible to create a shortcut keys like ctrl + A will click on the Add button and ctrl + B will be for submitting and ctrl + E for new Entity ?
A simple way to detect multiple keydowns to use as shortcuts:
let keysDown = {};
window.onkeydown = function(e) {
keysDown[e.key] = true;
if (keysDown["Control"] && keysDown["a"]) {
//do what you want when control and a is pressed for example
console.log("control + a");
}
else if( keysDown["Control"] && keysDown["b"] ){
console.log("control + b");
}
}
window.onkeyup = function(e) {
keysDown[e.key] = false;
}
Yes, this is definitely possible!
You can build the code yourself, but there is no point in reinventing the wheel, so try one of pre-build libraries. For example:
https://craig.is/killing/mice
You can create custom shortcuts and bind them to javascript functions.
These functions will than process the action.
Good luck!
Also see: How can I add a JavaScript keyboard shortcut to an existing JavaScript Function?
I have developed custom script to achieve this feature by just adding class
Example: <button type="button" class="ctrl-p">Custom Print</button>
Here Check it out https://jsfiddle.net/RaviMakwana/k6zL1q9t/
// find elements
var banner = $("#banner-message")
var button = $("button")
// handle click and add class
button.on("click", function(){
if(banner.hasClass("alt"))
banner.removeClass("alt")
else
banner.addClass("alt")
})
$(document).ready(function(){
$(document).on('keydown', function (e) {
if (e.ctrlKey) {
$('[class*="ctrl-"]:not([data-ctrl])').each(function (idx, item) {
var Key = $(item).prop('class').substr($(item).prop('class').indexOf('ctrl-') + 5, 1).toUpperCase();
$(item).attr("data-ctrl", Key);
$(item).append('<div class="tooltip fade top in tooltip-ctrl alter-info" role="tooltip" style="margin-top: -61px; display: block; visibility: visible;"><div class="tooltip-arrow" style="left: 49.5935%;"></div><div class="tooltip-inner"> CTRL + ' + Key + '</div></div>')
});
}
if (e.ctrlKey && e.which != 17) {
var Key = String.fromCharCode(e.which).toLowerCase();
if( $('.ctrl-'+Key).length == 1) {
e.preventDefault();
if (!$('#divLoader').is(":visible"))
$('.ctrl-'+Key).click();
console.log("You pressed ctrl + "+Key );
}
}
});
$(document).on('keyup', function (e) {
if(!e.ctrlKey ){
$('[class*="ctrl-"]').removeAttr("data-ctrl");
$(".tooltip-ctrl").remove();
}
})
});
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#banner-message {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
#banner-message span {
padding: 20px;
font-size: 15px;
text-align: center;
margin: 0 auto;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#banner-message.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#banner-message.alt button {
background: #fff;
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div id="banner-message">
<p>Hello World</p>
<button class="ctrl-s" title="s">Change color</button><br/><br/>
<span>Press CTRL+S to trigger click event of button</span>
</div>
I am working on one task for school, I want to display a menu from an XML file.
Here is the XML file:
<?xml version="1.0" encoding="UTF-8"?>
<menus>
<menu text="Subjects">
<menu text="English">
<school text="English A" image="E_A.png" />
<school text="English B" image="E_B.png" />
</menu>
<menu text="Maths">
<school text="Maths A" image="M_A.jpg" />
<school text="Maths B" image="M_B.jpg" />
</menu>
</menu>
<menu text="Teachers">
<school text="Sara" image="phones/sara.jpg" />
<school text="Maya" image="phones/maya.jpg" />
</menu>
</menus>
My HTML markup looks like that:
<section class="intro">
<div class="inner">
<div class="content">
<h1>Welcome</h1>
</div>
</div>
</section>
<footer id="footer">
<nav id="nav">
</nav>
</footer>
I am using jQuery and JavaScript to read data from XML file and display in the navigation bar. The JavaScript and jQuery code for that is given.
$(document).ready(function() {
$.ajax({
type: "GET",
url: "record.xml",
dataType: "xml",
success: function(xml) {
html = generateMenu(xml);
}
});
});
function generateMenu(xml) {
var mainMenu = $("<ul />");
$(xml).find('menu').each(function() {
if ($(this).children().length) {
var subMenu = $("<ul />");
$(this).children().each(function() {
subMenu.append('<li id="' + $(this).attr("text") + '">' + $(this).attr("text") + '</li>');
});
var li = $('<li id="' + $(this).attr("text") + '">' + $(this).attr("text") + '</li>');
mainMenu.append(li.append(subMenu));
} else {
mainMenu.append('<li id="' + $(this).attr("text") + '">' + $(this).attr("text") + '</li>');
}
});
$("#nav").append(mainMenu);
}
The CSS you will help you to understand the logic going on.
html, body {
background-color: #f0efed;
margin: 0;
padding: 0;
height: 100%;
width: 100%;
font-family: 'Oswald', sans-serif;
}
.intro {
height: 90%;
width: 100%;
margin: auto;
top: 0;
display: table;
}
.intro .inner {
display: table-cell;
vertical-align: middle;
width: 100%;
max-width: none;
}
.content {
max-width: 90%;
margin: 0 auto;
text-align: center;
padding: 20px 20px 40px 20px;
}
.content h1 {
font-family: 'Raleway', sans-serif;
text-shadow: 0px 0px 300px #000;
padding-bottom: 10px;
font-size: 225%;
}
#footer {
position: fixed;
bottom: 0;
margin: 0;
padding: 0;
left: 0;
right: 0;
width: 100%;
height: 10%;
font-family: Arial;
text-shadow: 1px 1px 1px black;
border-top: 1px solid #dbdbdb;
background-color: #ffffff;
box-shadow: inset 0 1px rgba(255,255,255,0.3), inset 0 10px rgba(255,255,255,0.2), inset 0 10px 20px rgba(255,255,255,0.25),inset 0 -15px 30px rgba(255,255,255,0.3);
}
nav {
width: 100%;
background: #ffffff;
padding: 0;
margin: 0;
height: 60px;
position:relative;
}
nav ul {
background: #ffffff;
list-style:none;
padding:0 20px;
margin: 0;
height: 60px;
}
nav ul li {
display: inline-block;
}
nav ul li a {
color:#333333;
display:block;
padding:0px 40px;
text-decoration:none;
float: left;
height: 50px;
line-height: 50px;
}
nav ul li:hover {
background: #205791;
border-radius: 20px;
}
nav ul li:hover > a{
color:#ffffff;
}
nav ul li:hover > ul {
display:block;
}
nav ul ul {
background: #ffffff;
padding:0;
display:none;
width: 100%;
position: absolute;
top: -61px;
left: 0px;
}
Display: Then menu looks like that
In case if you want to see the code in action here is the link to jsfiddle
Issue: As you can see the English and Math are showing in the parent node, and at the same time it is showing in the child node. When I mouse over on Egnlish which is in parent node it shows English A, English B. I want it in the proper order.
I also want to fire an event to display image in content div base on mouse over on the last node.
The structure flow will be something like that.
I will appreciate your help. Thank you!
You have used find, which has ignored the structure of child nodes.
Also your script is missing iteration through Sub-menu level 2
Here is corrected JS code:
$(document).ready(function() {
generateMenu();
});
function generateMenu(xml) {
var emptySubMenu = $("<ul />");
var mainMenu = $("<ul />");
$('menus').children('menu').each(function() {
var li = generateLiNode($(this).attr("text"));
//get subMenu level 1
var subMenuLvl1 = $("<ul />");
$(this).children().each(function() {
var li2 = generateLiNode($(this).attr("text"));
//get subMenu level 2
var subMenuLvl2 = $("<ul />");
$(this).children().each(function() {
subMenuLvl2.append(generateLiNode($(this).attr("text")));
});
if (subMenuLvl2.html() != emptySubMenu.html())
li2.append(subMenuLvl2);
//subMenu level 2 is prepared.
subMenuLvl1.append(li2);
});
if (subMenuLvl1.html() != emptySubMenu.html())
li.append(subMenuLvl1);
//subMenu level 1 is prepared.
mainMenu.append(li);
});
$("#nav").append(mainMenu);
}
function generateLiNode(text)
{
return $('<li id="' + text + '">' + text + '</li>')
}
and also a working JSFiddle:
http://jsfiddle.net/c5ghc80s/8/
Your second question can be solved by 3 steps:
Pass 2nd parameter to generateLiNode, the same way you are passing "text" right now but this time with "image"
Print the image attribute next to "id" attribute
In document ready function, after generateMenu(), register onhover event
where you will do whatever you want with the image attribute of current li node.
For example you can take it out from li element and put into src attribue of img node which can be placed in your main div:
$("li").mouseover(function() {
$('div > img').attribute("source", $("this").attribute("image"));
});
*this question has been updated.
I have a set of boxes which, when clicked open a div called #expander. In my code, after #expander is opened, and if another box is clicked, I check if the new box clicked is the same as the last box clicked. If it is the same, I close #expander, else I briefly close it and then open it again.
This is demonstrated with the this jsfiddle
Here is the same code, in stackoverflow:
$(document).on('click', '.box', function(e) {
if (!$('#expander').hasClass('active')) {
$('#expander').addClass('active');
$('.basic-info').css('border-left', '1px solid black');
activeBox = $(this).attr('id');
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
return;
}
if ($('#expander').hasClass('active')) {
$('#expander').removeClass('active');
$('.basic-info').css('border-left', '0px solid black');
if ($(this).attr('id') !== activeBox) {
setTimeout(function() {
$('#expander').addClass('active');
}, 256);
}
activeBox = $(this).attr('id');
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
return;
}
});
#expander{
height: 100%;
width: 0%;
float: left;
visibility: hidden;
overflow: hidden;
background-color: grey;
transition: .75s ease-out;
}
#expander.active{
height: 100%;
width: 50%;
z-index: 1;
visibility: visible;
}
#closer{
padding: 4px;
margin: 0px;
background-color: #707070;
color: white;
font-size: 1.5em;
text-align: center;
cursor: pointer;
}
#closer:hover{
background-color: #606060;
font-size: 2em;
padding: 0px;
}
.box{
width: 32px;
height: 32px;
padding: 5px 0px;
margin: 0px 4px;
display: inline-block;
background-color: grey;
overflow: hidden;
font-size: 1em;
font-weight: bold;
text-align: center;
border: 1px solid transparent;
border-radius: 2px;
cursor: pointer;
}
.basic-info{
padding: 8px 16px;
color: white;
background-color: #47a;
border-top: 1px solid black;
border-right: 1px solid black;
border-bottom: 1px solid black;
transition: .5s ease-out;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="expander">
<div id="closer" title="Close"><span>×</span></div>
<div id="main"></div>
</div>
<div class="basic-info">
<div id="box1" class="box">1</div>
<div id="box2" class="box">2</div>
<div id="box3" class="box">3</div>
</div>
The above code works (although it does not look exactly how it looks in my final layout) BUT what it does not do run this: $('.basic-info').css('border-left', '1px solid black'); after the first time a box is clicked (when it opens the #expander
I realize the reason this is not working is that the JS code first adds the classes and styles, but then the next if statement removes the classes and styles. Also, I have to paste the following code two times:
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
return;
Does anyone know a better way to layout my if statements so that code does not conflict? Also, is there a way to not need to use return;s?
P.S. does anyone have a link to a good if statement tricks tutorial so that I can learn these things for the future?
Thank you.
UPDATE:
I have updated the code based on the current answers and have changed the JS to this:
$(document).on('click', '.box', function(e) {
if ($('#expander').hasClass('active')) {
$('#expander').removeClass('active');
if ($(this).attr('id') !== activeBox) {
setTimeout(function() {
$('#expander').addClass('active');
}, 256);
activeBox = $(this).attr('id');
console.log('activeBox = ' + activeBox);
return;
}
$('.basic-info').css('border-left', '0px solid white');
return;
}
$('#expander').addClass('active');
$('.basic-info').css('border-left', '1px solid white');
activeBox = $(this).attr('id');
console.log('activeBox = ' + activeBox);
}
(it does the same thing, just laid out differently). All I am trying to figure out now is just how I can write this without any of the return;s and also so I do not have to write activeBox = $(this).attr('id'); console.log('activeBox = ' + activeBox); twice (unless these things are impossible/unavoidable)
thank you.
for the clean up part and get rid of repeated data, you can convert your js code to this
Updated
jsFiddle
// target the #expander
var Expander = $('#expander'),
activeBox = '';
$(document).on('click', '.box', function(e) {
//toggleClass means if #expander hasClass, remove it, if it
//doesn't have the class, add it.
Expander.toggleClass('active');
// same for .basic info, we use toggle class, instead of
// CSS hardcoded, thus we can toggle
$('.basic-info').toggleClass('black-border-left');
if ($(this).attr('id') !== activeBox) {
Expander.removeClass('active');
// to get rid of the delay for when one .box div is clicked for the first time
// when activeBox = ''.
if(activeBox !== ''){
setTimeout(function() {
Expander.addClass('active');
}, 500);
}else{
Expander.addClass('active');
}
activeBox = $(this).attr('id');
}
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
});
$(document).on('click', '.box', function(e) {
if (!$('#expander').hasClass('active')) {
$('#expander').addClass('active');
$('.basic-info').css('border-left', '1px solid black');
activeBox = $(this).attr('id');
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
} else if ($('#expander').hasClass('active')) {
$('#expander').removeClass('active');
$('.basic-info').css('border-left', '0px solid black');
if ($(this).attr('id') !== activeBox) {
setTimeout(function() {
$('#expander').addClass('active');
}, 256);
}
activeBox = $(this).attr('id');
$('#main').text(activeBox);
console.log('activeBox = ' + activeBox);
}
});
I'm creating a website where I have a series of images with different dimensions that are being placed in a lightbox gallery.
Sorry for the long read in advance.... the code is as follows:
http://jsfiddle.net/djtiii/Sas94/1/
HTML
<div id="wrapper">
<h1>simple lightbox w/ slideshow (images only)</h1>
<p>those image links i was talking about:</p>
<ul id="paintings">
<li> <a title="The Hills" href="http://www.artmajeur.com/files/oksana-veber/images/artworks/100x100/6683281_the-hils-100-100-cm-acrilic-on-canvas-1998-thumb.jpg" class="lightboxTrigger">
on
</a>
</li>
<li> <a title="Pixelisa" href="http://piq.codeus.net/static/media/userpics/piq_2313_400x400.png" class="lightboxTrigger">
two
</a>
</li>
<li> <a title="Vase" href="http://andyinoman.files.wordpress.com/2013/01/story-no-5-the-loosing-battle.jpg?w=500" class="lightboxTrigger">
three
</a>
</li>
</ul>
</div>
CSS
/* page styles */
body {
margin: 0;
padding: 0;
background: #efefef;
}
#wrapper {
width: 600px;
margin: 0 auto;
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-radius: 0 0 5px 5px;
background: #fff;
border: 1px solid #ccc;
padding: 25px;
border-top: none;
box-shadow: 0 0 5px #ccc;
-moz-box-shadow: 0 0 5px #ccc;
-webkit-box-shadow: 0 0 5px #ccc;
text-align: left;
}
/* lightbox styles */
#lightbox {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#lightbox p {
text-align: right;
color: #fff;
margin-right: 20px;
font-size: 12px;
}
#lightbox img {
max-width: 940px;
}
/* slideshow styles */
#slideshow {
position: relative;
z-index: 100;
width: 600px;
height: 350px;
margin: 0 auto;
padding: 10px;
background-color: #fff;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
}
#slideshow ul > li {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
list-style: none;
}
.nav {
display: none;
}
.prev, .next {
position: absolute;
top: 50%;
background: rgba(100, 100, 100, .5);
padding: .25em .5em;
color: #fff;
text-decoration: none;
}
.next {
right: 10px;
}
.prev {
left: 10px;
}
JavaScript
jQuery(document).ready(function ($) {
var current, size;
$('.lightboxTrigger').click(function (e) {
e.preventDefault();
var slideNum = $('.lightboxTrigger').index(this);
if ($('#lightbox').length > 0) {
$('#lightbox').fadeIn(300);
$('#content').html('<img src="' + href + '" />');
} else {
var hgt = $(this).attr('height');
var wid = $(this).attr('width');
var lightbox =
'<div id="lightbox">' +
'<p>X</p>' +
'<div id="slideshow">' +
'<ul></ul>' +
'<div class="nav">' +
'<' +
'>' +
'</div>' +
'</div>' +
'</div>';
$('body').append(lightbox);
$('#paintings').find('.lightboxTrigger').each(function () {
var href = $(this).attr('href');
var title = $(this).attr('title');
$('#slideshow ul').append(
'<li>' +
'<img src="' + href + '">' +
'<h5>' + title + '</h5>' +
'</li>');
});
$('#lightbox').hide().fadeIn(300);
}
size = $('#slideshow ul > li').length;
$('#slideshow ul > li').hide();
$('#slideshow ul > li:eq(' + slideNum + ')').show();
current = slideNum;
});
$('body').on('click', '#lightbox', function () {
$('#lightbox').fadeOut(300);
});
$('body').on({
mouseenter: function () {
$('.nav').fadeIn(300);
},
mouseleave: function () {
$('.nav').fadeOut(300);
}
}, '#slideshow');
$('body').on('click', '.slide-nav', function (e) {
e.preventDefault();
e.stopPropagation();
var $this = $(this);
var dest;
if ($this.hasClass('prev')) {
dest = current - 1;
if (dest < 0) {
dest = size - 1;
}
} else {
dest = current + 1;
if (dest > size - 1) {
dest = 0;
}
}
$('#slideshow ul > li:eq(' + current + ')').fadeOut(750);
$('#slideshow ul > li:eq(' + dest + ')').fadeIn(750);
current = dest;
});
});
The issue with this code is that the div id=slideshow's dimensions are not dynamic to the dimensions of the images. I'm fairly certain that I need some sort of Javascript that stores the dimensions of each image piece as it loads, then adjusts the dimensions of the div to those dimensions. I'm not experienced enough in Javascript to achieve this, however.
Thank you to all who take a crack at this!
To adjust the dimension of lightbox you can use additional function to find the height, width of the image being displayed and can apply these to the lightbox window.
I have created a fiddle for this, please see here:
function to calculate and apply dimensions:
function adjustDimensions(current){
var H = $('img','#slideshow ul > li:eq(' + current + ')').height();
var W = $('img','#slideshow ul > li:eq(' + current + ')').width();
if($('h5','#slideshow ul > li:eq(' + current + ')').length>0){
H = H+20;
}
$('#slideshow').animate({width:W+'px',height:H+'PX'},1000);
}
http://jsfiddle.net/lokeshpahal/yX4NP/2/