Following problem:
I would like to build a little clipboard with jQuery. I have tried several times to store an object in the data of a javascript object with $(object).data(‘id’,objectToStore). Objects can be stored there that works fine. The problem is if I try to insert the stored data I only get a reference to that object. So when I am editing one copy also the others are changed. I need a way to copy the html code into a global variable and then to insert the code individually from the stored one. Hope u guys understand my problem! Thx!
Here the code:
Object
/**
* Objectdefinition
*/
Clipboard = {
//PROPERTIES
itemcount: 0,
maxItems:10,
//Templates
tplClipboard:"<div id='GUI_clipboard'><a href='' title='clear clipboard' id='GUI_clipboardClose' class='gritter-close'></a><ul></ul></div>",
tplItem:"<li><a href='' class='[[type]] clipboardItem' id='[[id]]'><span class='hidden'>[[text]]</span></a></li>",
tplItemHover:"<div class='GUI_clipboard_itemhover' style='width:[[offsetW]]px;height:[[offsetH]]px'><a href='' title='delete container' class='GUI_containerDelete'><span class='hidden'>Delete</span></a></div>",
//Clipboarditem
item:{
id:null,
type:null,
content:'',
offsetWidth:0,
offsetHeight:0
},
//FUNCTIONS
addItem:function(id,type,text,content,offsetH,offsetW){
if(this.itemcount>=this.maxItems){
return $.gritter.add({
title:'Clipboard',
text:'You cannot store more than '+ this.maxItems +' Elements!',
image:'warning',
});
}
var item = {};
item.id=id,
item.type=type,
item.content=content,
item.offsetHeight=offsetH,
item.offsetWidth= offsetW;
this.verify();
if (!this.checkRed(id)) {
this.itemcount++;
var tmp = this.tplItem;
tmp = this.str_replace(['[[type]]', '[[id]]', '[[text]]'], [type, id, text], tmp);
$('#GUI_clipboard ul').append(tmp);
var $item = $('a#'+id);
var number = this.itemcount;
$item.hide().fadeIn('slow',function(){
Clipboard.redraw();
});
this.saveItem(item);
var config = {
over:function(){Clipboard.hoveringItem($('a',this))},
out:function(){Clipboard.unhoveringItem($('a',this))},
timeout:1
};
$item.parent().hoverIntent(config);
$item.draggable({
connectToSortable:'.column',
helper:'clone',
revert:'invalid',
cursor:'move', //Cursor
start:function(){
$('body').unbind('mouseover',Content.showContainerMenu);
$('body').unbind('mouseout',Content.hideContainerMenu);
$('#GUI_clipboard li').trigger('mouseout');
},
stop:function(){
$('body').bind('mouseover',Content.showContainerMenu);
$('body').bind('mouseout',Content.hideContainerMenu);
}
});
}else{
$('#'+id,'#GUI_clipboard').effect("bounce", { times:3 }, 300);
}
},
saveItem:function(item){
$(this).data(item.id,item);
},
removeItem: function(id){
$('#GUI_clipbaord').data(id,null);
$('a[id='+id+']','#GUI_clipboard').parent().slideUp('slow',function(){$(this).remove()});
this.itemcount--;
if(this.itemcount==0)this.remove();
},
verify:function(){
if($('#GUI_clipboard').length == 0){
$('body').append(this.tplClipboard);
$('#GUI_clipboard')
.css({
top:$(window).height()/2+'px'
})
.animate({
left:0
}).children('.gritter-close').capture({cssClass:'GUI_clipboardClose'});
}
},
checkRed:function(id){
if($('a[id='+id+']').length==0)return false;
else return true;
},
remove:function(){
$('#GUI_clipboard').animate({
left:'-60px'
},function(){
$(this).remove();
});
this.itemcount=0;
},
hoveringItem:function(el){
var item = $(this).data($(el).attr('id')),
content=item.content,
oH=item.offsetHeight,
oW=item.offsetWidth,
tmp = this.tplItemHover;
tmp = this.str_replace(['[[offsetW]]', '[[offsetH]]'], [oW,oH], tmp);
$(el).after(tmp);
var $element = $('.GUI_clipboard_itemhover').append(content).prepend("<div class='GUI_clipboardArrow'></div>");
$element.position({ my: 'left center', at: 'right center', of: $(el),offset:'14 0',collision:'none fit'});
$('.GUI_clipboardArrow',$element).position({ my: 'left center', at: 'right center', of: $(el),offset:'-2 0',collision:'none fit'});
$('#'+item.id,'#GUI_clipboard').removeClass('borderContainer editable');
$('a.GUI_containerDelete',$element).click(function(){
Clipboard.removeItem($element.children('.container').attr('id'));
$element.fadeOut().remove();
}).capture({cssClass:'GUI_clipboardItemClose'});
},
unhoveringItem:function(el){
//Preview entfernen
$(el).next().remove();
},
redraw:function(){
if(this.itemcount>1){
$('#GUI_clipboard').animate({
top: '-=20px'
});
}
},
str_replace: function(search, replace, subject, count) {
var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0,
f = [].concat(search),
r = [].concat(replace),
s = subject,
ra = r instanceof Array, sa = s instanceof Array;
s = [].concat(s);
if (count) {
this.window[count] = 0;
}
for (i=0, sl=s.length; i < sl; i++) {
if (s[i] === '') {
continue;
}
for (j=0, fl=f.length; j < fl; j++) {
temp = s[i]+'';
repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0];
s[i] = (temp).split(f[j]).join(repl);
if (count && s[i] !== temp) {
this.window[count] += (temp.length-s[i].length)/f[j].length;}
}
}
return sa ? s : s[0];
}
}
That was the object! As you see when I hover over an element the Object gets it from the internal store. But when I am inserting the object with following into the content area
var item = $(Clipboard).data($(ui.sender).attr('id')),
newItem = $.extend(true, {}, item);
content=newItem.content;
and then hover the clipboard to drag it and insert it again the object (html-code) from the contentarea disappears and is inserted in the preview of the clipboard.
Any ideas!
Please!
Got the solution on my own! Thanks to the awesome JavaScript Tutorial from Leigh Kaszick: “The Basics of Object-Oriented JavaScript”. Check it out: http://net.tutsplus.com/tutorials/javascript-ajax/the-basics-of-object-oriented-javascript/
Literal objects are always referenced while functional are not 😉 That’s the trick.
Literal Object:
functional Object:
To solve my problem I created a new instance of the storage object each time when I pass data to the clipboard. And it works! 😉