I need to add tooltip for tabs. Is there way to add tooltip for CTabView tabs in yii?
I've done it by extending the functionality of the jQuery object thru the fn property.
In view file:
<?php
Yii::app()->clientScript->registerScript('jquery-tooltip', '
$.fn.tooltip = function(tooltip_text)
{
// Mouse enters the target element
$(this).on("mouseenter", function()
{
// Make the tooltip visible
$("#tooltip").css("display", "inline");
// Set custom text
$("#tooltip").text(tooltip_text);
// Start listening to the mousemove event, memory is allocated for it
$(this).on("mousemove", function(event) {
var x = event.pageX; // get mouse X position relative to the page (screen)
var y = event.pageY; // get mouse Y position
x = x + 32; // move it to the right from the cursor
y = y - 16; // move it up
$("#tooltip").css( {left: x, top: y} );
});
});
// Mouse leaves the target element
$(this).off("mouseout", function()
{
// Stop listening to the mousemove event, memory is released
$(this).off("mousemove");
});
$(this).on("mouseout", function()
{
// Hide the tooltip
$("#tooltip").css("display", "none");
});
}
$(document).ready(function()
{
$("a[href=\'#tab1\']").tooltip("tooltip text1");
$("a[href=\'#tab2\']").tooltip("tooltip text2");
});
' , CClientScript::POS_END );
?>
<div id = "tooltip" '></div>
Some CSS:
#tooltip {
position: absolute;
width: auto;
display: inline;
padding: 8px;
font-family: Arial;
font-size: 14px;
color: #777777;
font-weight: bold;
border: 1px solid silver;
background: #FFFFEE; /* Slightly yellow background */
border-radius: 5px; /* Rounded corners */
box-shadow: 5px 5px 10px #DDD; /* Tooltip shadow */
z-index: 30000; /* A very large z-index ensures
it's "always on top" */
}
The working demo. The only thing: i've changed in the code in that i've replaced 'mouseover' with 'mouseenter' event.
Related
So I was wondering how to make the menu item that has been clicked, shown as 'active'/'highligted', so the user can see which page they are on?
I've made this menu bar.
/* Add a black background color to the top navigation */
.topnav_menu {
background-color: #333;
overflow: hidden;
display: flex;
align-items: center;
}
/* Style the links inside the navigation bar */
.topnav_menu a {
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
cursor: pointer;
}
/* Change the color of links on hover */
.topnav_menu a:hover,
.engine_dropdown:hover .engine_dropbtn {
background-color: #ebebeb;
color: black;
}
<div class="topnav_menu">
<!-- # will be removed for enable redirect -->
Profile
Test Runs
Dashboard
TRT Tools
</div>
After the item has been clicked it should appear highlighted.
EDIT
So I created a solution, but is that the best way?
Created this function to check which page in on, and then if im on that page, I would set the class to active
function active($currect_page){
$url = basename(getcwd())."/".str_replace(".php", "", basename($_SERVER['PHP_SELF'])); // If filename is just "name" or "name.php"
// Also checks which directory the file is in, to avoid highlighting multiple menu items with same name
// $currect_page == $url :: parentFolder/fileName == parentFolder/fileName (without .php here)
if($currect_page == $url || $currect_page == basename(getcwd())."/".basename($_SERVER['PHP_SELF'])){
echo 'active'; // class name in css
}
}
<div class="topnav_menu">
<div id="imgDiv"></div>
Test Runs
Dashboard
TRT Tools
</div>
active class would look like this
/* Active menu item */
.topnav_menu a.active,
.topnav_menu a:focus {
/* When a-tags inside this class has been clicked */
background-color: #ffffff;
color: black;
}
Based on how you have written the HTML, bellow js will solve the problem.
//JS
let a = document.querySelectorAll('a')
for(let i =0; i< a.length; i++){
a[i].onclick = function(){
a.forEach(function(item){
item.classList.remove("active");
});
this.classList.add("active");
}
}
i want to display the following Post in 3 different sections. The first section is the table of content. The second is the summary and the third is the theory. Is like a multipage post but each page has a section, as I don't want to show all the information in a single page.
Thanks in advance
The way I have come up with this is this way.
I'm only posting these because I have it all setup so I can basically copy and paste it in. Next time I want to see more effort on your part.
Create a new JS file. well call it mytabs.js in that file put this:
;( function( $, window, document, undefined ) {
"use strict";
$( document ).ready( function() {
var loadTabOrder = function(id){
// Define friendly data store name
var dataStore = window.sessionStorage;
var oldIndex = 0;
// Start magic!
try {
// getter: Fetch previous value
oldIndex = dataStore.getItem(id);
} catch(e) {}
return oldIndex;
};
var saveTabOrder = function(id, currentIndex){
// Define friendly data store name
var dataStore = window.sessionStorage;
// Start magic!
try {
dataStore.setItem( id, currentIndex );
} catch(e) {}
};
$('.ui-tabs-vertical').each(function(){
var id = $(this).prop('id');
if(!id) $.error('.ui-tabs-vertical requires an id');
var element = $( "#"+id );
var options = {
active: loadTabOrder(id),
activate: function(event, ui) {
saveTabOrder(id, ui.newTab.parent().children().index(ui.newTab));
}
};
element.tabs(options).addClass( "ui-helper-clearfix" );
var nav = element.find('> .ui-tabs-nav > li');
nav.removeClass( "ui-corner-top" ).addClass( "ui-corner-left" );
var height = 0;
nav.each(function(){
height += $(this).outerHeight();
});
element.find('> .ui-tabs-panel').css(
'min-height',
height+'px'
);
});
} );
} ) ( jQuery, window, document );
Somewhere in your theme/pllugin put this:
//ui css
wp_enqueue_style('jquery-ui');
//jquery
wp_enqueue_script('jquery');
//jquery-ui
wp_enqueue_script('jquery-ui');
//you only need to do the above it you dont have them included already
//add our JS page.
wp_enqueue_script('mytabs', plugin_dir_url(__FILE__).'mytabs.php', ['juery-ui']);
//in my case this is in a plugin file, obviously use your path to your JS file
In your CSS file add these, make sure your CSS loads after jQuery UI
.ui-tabs.ui-tabs-vertical {
padding: 0;
height: 100%;
width: calc(100% - 15px);
position: relative;
}
.ui-tabs.ui-tabs-vertical .ui-widget-header {
border: none;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav {
float: left;
width: 10em;
background: #EEE;
border-radius: 4px 0 0 4px;
border-right: 1px solid gray;
position: absolute;
top : 0;
bottom: 0;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li {
clear: left;
width: 100%;
margin: 0.2em 0;
border: 1px solid gray;
border-width: 1px 0 1px 1px;
border-radius: 4px 0 0 4px;
overflow: hidden;
position: relative;
right: -2px;
z-index: 2;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a {
display: block;
width: 100%;
padding: 0.6em 1em;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a:hover {
cursor: pointer;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active {
margin-bottom: 0.2em;
padding-bottom: 0;
border-right: 1px solid white;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li:last-child {
margin-bottom: 10px;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-panel {
float: left;
margin-left: 150px;
width: calc(100% - 200px);
min-width: 600px;
border-radius: 0;
position: relative;
left: -1px;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-panel .panel-title{
padding: 0px;
margin: 0px;
margin-bottom: 10px;
font-size: 22px;
}
In your HTML add something like this
<div id="myttabs" class="ui-tabs-vertical">
<ul>
<li>General</li>
<li>Foo</li>
</ul>
<div id="settings-panel">
<p>Here is some settings</p>
</div>
<div id="foo-panel">
<p>Here is some foo</p>
</div>
</div>
Overview
How it works. In the above HTML you will notice ui-tabs-vertical class. Then in our mytabs.js we do this:
$('.ui-tabs-vertical').each(function(){ ... }
In short what this does is any element that has the ui-tabs-vertical class will get the ui-tabs added automagially. This is especially nice for wordpress as we can get into a real mess trying to put JS in a post (for example). So we want it as clean an free as possible. This trick with some variation can be used on any of the UI elements that create similar stuff, same type of popup, or anything we can normalize to a common format, so we don't have too many arguments.
Pass options -via- data attributes
One way to pass options to the JS, that I didn't need here is to simply put them in a data- attribute on the main element or any element that makes sense. For example you can set .tabs({hide:true}) to hide the tabs.
So if I wanted to do that I would do something like this:
//in our HTML add the data attribute to the main element
<div id="myttabs" class="ui-tabs-vertical" data-hide="true" >
//in myscript.js - change the options object.
var element = $( "#"+id )
var options = {
hide: element.data('hide') | false,
active: loadTabOrder(id),
activate: function(event, ui) {
window.saveTabOrder(id, ui.newTab.parent().children().index(ui.newTab));
}
};
The active tag will be remembered by the users browser by making use of some simple Session Storage stuff in there. These are keyed off the ID of the main HTML element for the tabs. This makes that ID required, so there is a bit of code to issue an error to the console, for development purposes. Its important to use the tabs ID, because that way each tab will have it's own settings remembered. If we mixed them we would probably get some errors for missing tab indexes etc..
There are also some modifications to the vertical CSS to expand the area behind the Tabs. I probably spent the most time on this piece and its a relatively minor visual issue. But I cant have that in my work. This is actually quite tricky to do, as you will see below. It looks way better with the full width background.
You can see this issue even on the jQuery example page.
The way I fixed it was
position:absolute on the navigation box with a top:0 and bottom:0, the parent element should be position:relative. This alone basally solves the 100% height issue, now we have to deal with the side effects of absolute positioning.
A few tricks like this width: calc(100% - 200px); to dynamically get the width set up. Absolute elements are not part of the Box Model of the DOM, so it's very hard to account for them with just CSS as they don't hold any space in the container.
Now all we need to do is set the min-height. The only reason we need to do this is everything goes janky if you have a lot of menu item (absolute) but no content in the tab (height is smaller then the nav). Which will bust it out of the bottom of the ui-tabs container because its absolute positioned. This is because with the top:0 and bottom:0 we are tying the width of the navigation menu to the main ui-tabs container. When the panel is empty that container will be shorter then the menu, which is a problem with many menu items and tiny panels. It can also cause some issues if you load content -via- AJAX, as you may see this error for second while the request goes.
4 So with the last bit of JS we just need to set min-height to apx the same height as the navigation's height. Because the navigation is absolute and tied to the parent container (as I said above, its height is dependent on .ui-tabs), so we can't simply get the height of that. The only option I saw was to sum the height of it's contents, the li elements themselves. This is a bit harder but we only need to do it one time for each ui-tabs.
The absolute position stuff will dynamically adjust the height (with just CSS) if the tab height changes, such as loading content via AJAX or other dynamic stuff.
The .ui-tabs-panel are set to float:left with a margin apx the width of the tab navigation. This accounts for the horizontal space the navigation takes up. Then to get something resembling a proper 100% width, we can use width: calc(100% - 200px); again because the nav is absolute we are sort of stuck manually offsetting for it. So This has 150px for the menus width offset, (or the left-margin on the panel, about the same width as the nav) and an extra 50 for things like the margin on the right and some other padding etc. We could have used negative margins for some of these (but I didn't think about that tell now)
Now having the panel width dynamic and like a real 100% width, all we need to do to make the panel smaller is adjust the width of the container around the main UI-Tabs element. This way we can adjust it without sending any arguments to .tabs() or changing any thing with JS.
As I said that menu thing is a hard problem to solve, this is mainly due to the fact were limited in what we can do structure wise, or we will just break the ui-tabs. So we cant really change that, and that leave only JS and CSS. CSS is preferable because then we don't have to write yet more JS, and we would need to keep watch on the contents changing to resize it. Even then there would be some lag in the change. For example using an setInterval to keep an eye on it, this is something we want to avoid as it can affect performance too, and is more of a headache then the minor visual problem that this is.
Summery
I basically just pasted this from my own plugin, so I can't grantee that I covered everything. I cant stand little quirky things like the images above so I always fix that stuff. And I try to make my life easier later so now we just make the HTML and add the ui-tabs-vertical and mytabs.js takes care of the rest. Lastly we should never have to mess with mytabs.js and anytime we want a tab setup we just add the HTML with that class.
There is probably a tiny performance penalty to this (maybe) but in Wordpress it can be really hard to call JS from posts or other content in a "clean" way. So this just encapsulates all that code and make it a lot cleaner and easier to maintain IMO because, you are not mixing HTML and JS and CSS etc.
Hope it helps:
PS if the way I start my JS looks funny please see this question:
What advantages does using (function(window, document, undefined) { ... })(window, document) confer?
And this one:
How does this JavaScript/JQuery Syntax work: (function( window, undefined ) { })(window)?
Basically its a self executing function that keeps our global JS space clean, so we don't get any conflicts from other plugins, or scripts that may use the same variable names as we are.
I do a fair amount of plugin development, so its a bit more common to use it for that, but I just basically copy and paste it now, so... Also I feel I should mention this is part of a much larger script that dynamically adds a bunch of UI stuff for me. That way when I'm working on HTML, I can just work on HTML etc...
For the final result check this out:
;( function( $, window, document, undefined ) {
"use strict";
$( document ).ready( function() {
var loadTabOrder = function(id){
/*// Define friendly data store name
var dataStore = window.sessionStorage;
var oldIndex = 0;
// Start magic!
try {
// getter: Fetch previous value
oldIndex = dataStore.getItem(id);
} catch(e) {}
return oldIndex;*/
};
var saveTabOrder = function(id, currentIndex){
/*// Define friendly data store name
var dataStore = window.sessionStorage;
// Start magic!
try {
dataStore.setItem( id, currentIndex );
} catch(e) {}*/
};
$('.ui-tabs-vertical').each(function(){
var id = $(this).prop('id');
if(!id) $.error('.ui-tabs-vertical requires an id');
var element = $( "#"+id );
var options = {
active: loadTabOrder(id),
activate: function(event, ui) {
saveTabOrder(id, ui.newTab.parent().children().index(ui.newTab));
}
};
element.tabs(options).addClass( "ui-helper-clearfix" );
var nav = element.find('> .ui-tabs-nav > li');
nav.removeClass( "ui-corner-top" ).addClass( "ui-corner-left" );
var height = 0;
nav.each(function(){
height += $(this).outerHeight();
});
element.find('> .ui-tabs-panel').css(
'min-height',
height+'px'
);
});
$('#expand').click(function(){
$('#'+$( "#mytabs li.ui-tabs-active" ).attr('aria-controls')+' p').css({"height":'300px'});
});
$('#shrink').click(function(){
$('#'+$( "#mytabs li.ui-tabs-active" ).attr('aria-controls')+' p').css({"height":''});
});
} );
} ) ( jQuery, window, document );
.ui-tabs.ui-tabs-vertical {
padding: 0;
height: 100%;
width: calc(100% - 15px);
position: relative;
}
.ui-tabs.ui-tabs-vertical .ui-widget-header {
border: none;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav {
float: left;
width: 10em;
background: #EEE;
border-radius: 4px 0 0 4px;
border-right: 1px solid gray;
position: absolute;
top : 0;
bottom: 0;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li {
clear: left;
width: 100%;
margin: 0.2em 0;
border: 1px solid gray;
border-width: 1px 0 1px 1px;
border-radius: 4px 0 0 4px;
overflow: hidden;
position: relative;
right: -2px;
z-index: 2;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a {
display: block;
width: 100%;
padding: 0.6em 1em;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li a:hover {
cursor: pointer;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active {
margin-bottom: 0.2em;
padding-bottom: 0;
border-right: 1px solid white;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-nav li:last-child {
margin-bottom: 10px;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-panel {
float: left;
margin-left: 150px;
width: calc(100% - 200px);
min-width: 600px;
border-radius: 0;
position: relative;
left: -1px;
}
.ui-tabs.ui-tabs-vertical .ui-tabs-panel .panel-title{
padding: 0px;
margin: 0px;
margin-bottom: 10px;
font-size: 22px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<div id="mytabs" class="ui-tabs-vertical">
<ul>
<li>General</li>
<li>Foo</li>
</ul>
<div id="settings-panel">
<p>Here is some settings</p>
</div>
<div id="foo-panel">
<p>Here is some foo</p>
</div>
</div>
<div style="margin-top: 20px">
<button id="expand" >Click here to expand the panel</button>
<button id="shrink" >Click here to shrink the panel</button>
</div>
The only notes here, is I added the buttons to showcase how the gray nav background resizes automatically and Stack Overflow wont let me use the sessionStorge here. So I had no choice but to comment it out.
Sense there is so much code, most of it is pretty simple stuff really, I didn't want it all in the snip-it windows, as its a bit harder to read there. So forgive the lengthy post, but I wanted it to all make sense.
Enjoy!
I want to add a text and link to both the sign boards here in this image (separately for both). I am trying to use the <map> <area> rule and I need to place the coordinates of the two rectangle boxes there so that once a user clicks on that board or text he will be redirected to some another page. Now the problem is that I am not sure from where to find the exact coordinates of the image here and how? If anyone can help then please help.
Here is the code I am using
<img src="image link here" usemap="#mapname">
<map name="mapname">
<area shape="rect" coords="" href="http://www.google.com" alt="TEST">
</map>
I'm working on something similar, but I wanted to make it responsive - not if you zoom in, image will be bigger and areas too. I didn't use <map>, because the coords are absolute. I used this:
<div id="mapdiv">
<img src="link" id="imgmap" alt="" />
<div id="box1">Here is the text</div>
<div id="box2" onclick="alert('You can use js too')"></div>
</div>
And CSS:
#imgmap {
width: 100%;
}
div#mapdiv {
position: relative; /* thanks to this... */
}
div#menu div {
position: absolute; /* ...and this are boxes positioned relatively inside the imgdiv */
border: 1px dashed blue; /* for finding coords, remove after you are done */
}
div#box1 {
left: 21%; /* my coords, make your own by trying and trying... */
top: 26.5%;
height: 5%;
width: 6.5%
}
div#box2 {
left: 7.5%;
top: 66.2%;
height: 24.5%;
width: 31.5%;
}
if you want to add text, then you better use real links and set them on top of your areas wich are quiet good rectangle.
example:
.map {
position: relative;
}
.map img {
display: block;
width: 100%;
}
.map a {
position: absolute;
top: 48.6%;
left: 9.118%;
width: 19.8%;
height: 19%;
transform: rotate(-1.375deg);
border-radius: 50% 50% 0px 0 / 0.25vw;
transition: 0.5s;
color:#3F4754;
display:flex;
align-items:center;
justify-content:center;
font-size:4vw;
font-weight:bold;
font-family:courier;
font-variant:small-caps;
text-decoration:none;
text-shadow:-2px -2px 2px black
}
.map a + a {
top: 48%;
left: 70%;
transform: rotate(3deg);
transform-origin: bottom right
}
a:hover {
color: white;
background:linear-gradient(to bottom left, rgba(0, 0, 0, 0.5), transparent);
text-shadow:2px 2px 2px black
}
<div class="map">
<img src="https://i.stack.imgur.com/mDEuy.jpg" />
hover me
or me
</div>
use your own style and ids or class
I use a chrome extension I got called Page Ruler. What I do is use the extension to draw a rectangle from the pixel with the coordinate 0,0 to a target pixel. The bar at the top shows the width and height of the rectangle. There are also other tools, such as Meazure, which can do the same thing.
You can use the mouse events clientX, clientY https://www.w3schools.com/jsref/event_clientx.asp
When you use onmousemove it shows the coordinates
<!DOCTYPE html>
<html>
<body>
<img src="https://i.stack.imgur.com/mDEuy.jpg" usemap="#mapname"
onmousemove="showCoords(event)">
<map name="mapname">
<area shape="rect" coords="" href="http://www.google.com" alt="TEST">
</map>
</img>
<p id="demo"></p>
<script>
function showCoords(event) {
var x = event.clientX;
var y = event.clientY;
var coords = "X coords: " + x + ", Y coords: " + y;
document.getElementById("demo").innerHTML = coords;
}
</script>
</body>
</html>
$(document).ready(function() {
$("img").on("click", function(e) {
bounds=this.getBoundingClientRect();
var l = bounds.left;
var t = bounds.top;
var x = e.pageX - l;
var y = e.pageY - t;
var cw = this.clientWidth;
var ch = this.clientHeight;
var nw = this.naturalWidth;
var nh = this.naturalHeight;
var px = x/cw*iw;
var py = y/ch*ih;
});
});
I have a "news" div and a "banner" div.
I want user to see the "banner" div when page loads. This "banner" div should show over the "news" div, exactly over the position, covering the "news" div. So:
How should I do to detect position of "news" div and show the "banner" div over, floating, without affecting the grid structure?
Any jQuery plugin that allows user to hide that div and never show again? w/ cookie?
Hope you've understood my idea. I leave an image:
use the jquery's offset
http://api.jquery.com/offset/
and the jquery's show and hide
http://api.jquery.com/show/
you can use hte negative margin for the banner to come over to the news...div.
Let me know if you need anything...
use absolute postioning for news banner.
I've written a script for you which should help.
It uses the Cookie plugin for jQuery.
I've put some comments in the code so hopefully it should be pretty self-explanatory.
Feel free to come back with other questions you may have.
Usage
You should see a banner on first load, then click run again and it should dissapear.
The banner will be positioned exactly above the news-list using absolute positioning, the width/height and the top/left offset of the newslist.
I realise this question has already been answered, but I thought I'd offer a slight alternative, using CSS, jQuery and the jQuery cookie plugin:
html:
<div class="container">
<div class="news">
<p>Lorem ipsum dolor sit amet...</p>
</div>
<div class="banner">
<p>Yet more text, this time it's the banner.</p>
<span class="close">X</span>
</div>
</div>
<div id="clear">Remove the cookie</div>
css:
.container {
width: 80%;
min-height: 400px;
position: relative;
border: 4px solid #000;
}
.news {
width: 100%;
height: 100%;
}
.banner {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #f00;
}
.close {
position: absolute;
top: 0;
right: 0;
border-left: 2px solid #fff;
border-bottom: 2px solid #fff;
width: 2em;
line-height: 2em;
text-align: center;
display: block;
cursor: pointer;
}
#clear {
width: 80%;
text-align: right;
color: #fff;
background-color: #999;
border: 4px solid #000;
border-top-width: 0;
font-family: arial, sans-serif;
cursor: pointer;
}
jQuery:
$(document).ready(
function(){
if ($.cookie('closed')){
$('.banner').remove();
}
$('.close').click(
function(){
$(this).closest('.banner').remove();
$.cookie('closed',true, {expires: 30});
});
$('#clear').click(
function(){
$.cookie('closed',false, {expires: -200});
});
});
JS Fiddle demo.
A slightly more pleasing demo, with animate():
$(document).ready(
function(){
if ($.cookie('closed')){
$('.banner').remove();
}
$('.close').click(
function(){
$(this)
.closest('.banner')
.animate(
{
'top':'120%'
}, 1500,
function(){
$(this).remove();
}
);
$.cookie('closed',true, {expires: 30});
});
$('#clear').click(
function(){
$.cookie('closed',false, {expires: -200});
});
});
Demo at JS Fiddle
Edited with an afterthought, assuming that you get repeat visitors, it might be worth re-setting the cookie in the initial if check, to ensure that they don't see the banner ever again (unless they leave more than 30 days between visits), changing it to:
if ($.cookie('closed')){
$('.banner').remove();
$.cookie('closed',true,{expires: 30});
}
Hey guys I have a drag and drop function that does not fully work. What I want to do is be able to drag and drop a picture into a div and have that picture pop up in the div. I have a list of 2 pictures right now, so I have the following function echoed for each picture. Both pictures are draggable and droppable, but the first one is the only one that appears in the div, regardless of which picture gets dragged in. I am not sure what is wrong because the jquery function seems to be unique to each picture. If any one has any suggestions I would appreciate it greatly.
while ($row = mysql_fetch_assoc($query)) {
$image=htmlentities($row['image']); //image name
$uniqid=uniqid(); //unique id for jquery functions
$dirname = "usercontent/$user/images/$image";
echo "<img id=\"$uniqid\" src=\"$dirname\" width=\"75\" height=\"75\"/>";
echo "<script>
$(function() {
$(\"#$uniqid\").draggable({ scroll: true, scrollSensitivity: 10, scrollSpeed: 10, revert: true, helper: 'clone', cursorAt: { cursor: 'move', top: 27, left: 27 } });
$(\"#droppable2, #droppable-background , #droppable2-innerer\").droppable({
greedy: true,
activeClass: 'ui-state-hover',
hoverClass: 'ui-state-active',
drop: function(event, ui) {
$(this).addClass('ui-state-highlight').find('> p').html('Dropped!');
$('#droppable-background').css(\"background-image\",\"url($dirname)\");
}
});
});
</script>";
}
Don't use the ID to set up a draggable item, it is best to just use a class you can put on all of them. From the code above it appears that you are using a single ID, maybe that's why only one picture works? And are you setting up 3 drop zones?
I set up a working demo and I added a bunch of comments to help you see how this could be done.
CSS
#draggable { width: 250px; height: 500px; padding: 0.5em; float: left; margin: 10px; background: #ddd; }
#droppable { width: 250px; height: 500px; padding: 0.5em; float: left; margin: 10px; background: #ccc; }
.dragme { background: #999; text-align: center; width: 100px; padding: 5px; }
.fade { opacity: 0.3 }
.ui-state-highlight { border: #333 1px solid; }
HTML
<div class="demo">
<div id="draggable" class="ui-widget-content">
<p>Drag from here</p>
<div class="dragme"><img src="image1.gif"><br><span class="caption">Drag me to my target</span></div>
<div class="dragme"><img src="image2.gif" height="100"><br><span class="caption">Drag me to my target</span></div>
</div>
<div id="droppable">
<p>Drop here</p>
</div>
</div>
Script
$(document).ready(function(){
// set up the draggable items
$(".dragme").draggable({
helper : 'clone', // you will drag a copy of the item around
revert : true, // draggable returns home if released
start: function(e,ui){
$(this).addClass('fade'); // fade out original item while dragging the clone
ui.helper.find('.caption').text("I'm being dragged!"); // message in clone
},
stop: function(e,ui){
$(this).removeClass('fade'); // remove fade if dragged item is released
}
});
$("#droppable").droppable({
drop: function(e, ui) {
$(this).addClass('ui-state-highlight'); // add drop box highlight (border)
ui.draggable.appendTo($(this)).removeClass('fade') // move item to drop box & un-fade
.find('.caption').text("I've been dropped"); // change caption
ui.helper.remove(); // remove clone
}
});
})
Edit: Hiya, if you look at the overview page of the Draggable and Droppable document page, you will see that the plugin defines extra variables (actually they are jQuery objects) for you: "ui.draggable" is the selected draggable element & "ui.helper" is the clone of the object.
I have updated the demo with what you requested.. it should now place the image as the background of the drop box. Here is just the updated portion of the script:
$("#droppable").droppable({
drop: function(e, ui) {
$(this).addClass('ui-state-highlight'); // add drop box highlight (border)
var src = ui.draggable.find('img').attr('src'); // get img URL
$('#droppable')
.css({
backgroundImage : 'url(' + src + ')', // set background image
backgroundPosition : 'center center', // position background image
backgroundRepeat : 'no-repeat' // don't repeat image
});
ui.helper.remove(); // remove clone
}
});