added drag and drop content

This commit is contained in:
JT Smith 2004-02-15 19:11:00 +00:00
parent 9f94bbead8
commit 6d7d53bbff
16 changed files with 527 additions and 19 deletions

View file

@ -119,13 +119,72 @@ while (my $template = $sth->hashRef) {
div.wobject {
border: 2px hidden;
}
</style>
.dragable{
position: relative;
}
.dragTrigger{
position: relative;
cursor: move;
}
.dragging{
position: relative;
cursor: hand;
z-index: 2000;
background-image: url("^Extras;opaque.gif");
}
.draggedOverTop{
position: relative;
border: 1px dotted #aaaaaa;
border-top: 8px #aaaaaa dotted;
}
.draggedOverBottom {
position: relative;
border: 1px dotted #aaaaaa;
border-bottom: 8px #aaaaaa dotted;
}
.hidden{
display: none;
}
.blank {
position: relative;
cursor: hand;
background-color: white;
}
.blankOver {
position: relative;
cursor: hand;
background-color: black;
}
.empty {
position: relative;
padding: 25px;
width: 50px;
height: 100px;
background-image: url("^Extras;opaque.gif");
}
</style><script language=JavaScript1.2 src="^Extras;draggable.js"></script>
</tmpl_if>
<tmpl_if session.var.adminOn> <tmpl_if page.canEdit>
<tmpl_var page.controls>
</tmpl_if> </tmpl_if>
'.$template->{template};
$template->{template} =~ s/\<tmpl_var page\.position(\d+)\>/_positionFormat6x($1)/eg;
$template->{template} .= '
<tmpl_if session.var.adminOn>
<table>
<tr id="blank" class="hidden">
<td>
<div><div class="empty">&nbsp;</div></div>
</td>
</tr>
</table>
<iframe id="dragSubmitter" style="display: none;"></iframe>
<script>
dragable_init("^\;");
</script>
</tmpl_if>
';
WebGUI::SQL->write("update template set namespace='page', template=".quote($template->{template})
." where templateId=".$template->{templateId}." and namespace='Page'");
}
@ -243,7 +302,7 @@ while (my $data = $a->hashRef) {
my $subId = getNextId("USS_submissionId");
my $forum = WebGUI::Forum->create({});
WebGUI::SQL->write("insert into USS_submission (USS_submissionId, USS_id, title, username, userId, content,
dateUpdated, dateSubmited, forumId,contentType) values ( $subId, $ussId, ".quote($sub->{question}).",
dateUpdated, dateSubmitted, forumId,contentType) values ( $subId, $ussId, ".quote($sub->{question}).",
".quote($data->{username}).", ".$data->{ownerId}.", ".quote($sub->{answer}).", ".$data->{lastEdited}.",
".$data->{dateAdded}.", ".$forum->get("forumId").", 'html')");
}
@ -309,7 +368,7 @@ while (my $data = $a->hashRef) {
my $subId = getNextId("USS_submissionId");
my $forum = WebGUI::Forum->create({});
WebGUI::SQL->write("insert into USS_submission (USS_submissionId, USS_id, title, username, userId, content,
dateUpdated, dateSubmited, forumId,contentType,userDefined1, userDefined2) values ( $subId, $ussId, ".quote($sub->{name}).",
dateUpdated, dateSubmitted, forumId,contentType,userDefined1, userDefined2) values ( $subId, $ussId, ".quote($sub->{name}).",
".quote($data->{username}).", ".$data->{ownerId}.", ".quote($sub->{description}).", ".$data->{lastEdited}.",
".$data->{dateAdded}.", ".$forum->get("forumId").", 'html', ".quote($sub->{url}).", ".quote($sub->{newWindow}).")");
}
@ -534,11 +593,23 @@ sub _positionFormat5x {
#-------------------------------------------------------------------
sub _positionFormat6x {
my $newPositionCode = '
<tmpl_if session.var.adminOn> <tmpl_if page.canEdit>
<table border=0 id="position'.$_[0].'">
<tbody>
</tmpl_if> </tmpl_if>
<tmpl_loop position'.$_[0].'_loop>
<tmpl_if session.var.adminOn> <tmpl_if page.canEdit>
<tr id="td<tmpl_var wobject.id>">
<td>
<div id="td<tmpl_var wobject.id>_div" class="dragable">
</tmpl_if></tmpl_if>
<tmpl_if wobject.canView>
<div class="wobject"> <div class="wobject<tmpl_var wobject.namespace>" id="wobjectId<tmpl_var wobject.id>">
<tmpl_if session.var.adminOn> <tmpl_if wobject.canEdit>
<tmpl_var wobject.controls>
<tmpl_if page.canEdit>
<tmpl_var wobject.controls.drag>
</tmpl_if>
</tmpl_if> </tmpl_if>
<tmpl_if wobject.isInDateRange>
<a name="<tmpl_var wobject.id>"></a>
@ -546,7 +617,16 @@ sub _positionFormat6x {
</tmpl_if wobject.isInDateRange>
</div> </div>
</tmpl_if>
<tmpl_if session.var.adminOn> <tmpl_if page.canEdit>
</div>
</td>
</tr>
</tmpl_if></tmpl_if>
</tmpl_loop>
<tmpl_if session.var.adminOn>
</tbody>
</table>
</tmpl_if>
';
return $newPositionCode;
}

View file

@ -348,17 +348,17 @@ INSERT INTO template VALUES (4,'Tab Form','<tmpl_if displayTitle>\r\n <h1><tm
alter table groups add column isEditable int not null default 1;
alter table groups add column showInForms int not null default 1;
update groups set isEditable=0 where groupId in (1,2,7);
delete from groupings where groupId in (1,7,2,5);
delete from groupings where groupId in (1,7,2);
insert into groupings (groupId,userId) values (1,1);
insert into groupings (groupId,userId) select 7, userId from users;
insert into groupings (groupId,userId) select 2, userId from users where userId<>1;
insert into groups (groupId,groupName,description,showInForms) values (5,'Turn Admin On','These users can enable admin mode.',0);
insert into groupGroupings (groupId, inGroup) values (4,5);
insert into groupGroupings (groupId, inGroup) values (6,5);
insert into groupGroupings (groupId, inGroup) values (8,5);
insert into groupGroupings (groupId, inGroup) values (9,5);
insert into groupGroupings (groupId, inGroup) values (10,5);
insert into groupGroupings (groupId, inGroup) values (11,5);
insert into groups (groupId,groupName,description,showInForms) values (12,'Turn Admin On','These users can enable admin mode.',0);
insert into groupGroupings (groupId, inGroup) values (4,12);
insert into groupGroupings (groupId, inGroup) values (6,12);
insert into groupGroupings (groupId, inGroup) values (8,12);
insert into groupGroupings (groupId, inGroup) values (9,12);
insert into groupGroupings (groupId, inGroup) values (10,12);
insert into groupGroupings (groupId, inGroup) values (11,12);
delete from groupGroupings where groupId = 3;
insert into groupGroupings (groupId, inGroup) select 3, groupId from groups where groupId not in (1,3);
CREATE TABLE WSClient (

View file

@ -22,7 +22,7 @@ use WebGUI::URL;
our @ISA = qw(Exporter);
our @EXPORT = qw(&helpIcon &becomeIcon &cutIcon &copyIcon &deleteIcon &editIcon
&moveBottomIcon &moveDownIcon &moveLeftIcon &moveRightIcon &moveTopIcon &moveUpIcon
&pageIcon &shortcutIcon &pasteIcon &wobjectIcon &viewIcon);
&pageIcon &dragIcon &shortcutIcon &pasteIcon &wobjectIcon &viewIcon);
=head1 NAME
@ -38,6 +38,7 @@ A package for generating user interface buttons. The subroutines found herein do
$html = copyIcon('op=something');
$html = cutIcon('op=something');
$html = deleteIcon('op=something');
$html = dragIcon();
$html = editIcon('op=something');
$html = helpIcon(1,"MyNamespace");
$html = moveBottomIcon('op=something');
@ -118,7 +119,7 @@ sub cutIcon {
=head2 deleteIcon ( urlParameters [, pageURL ] )
Generates a button with an "X" printed on it.
Generates a button that represents a delete operation.
=over
@ -144,6 +145,18 @@ sub deleteIcon {
#-------------------------------------------------------------------
=head2 dragIcon ( )
Generates an icon that can be used to drag content.
=cut
sub dragIcon {
return '<img id="dragTrigger" class="dragTrigger" src="'.$session{config}{extrasURL}.'/toolbar/'.$session{language}{toolbar}.'/drag.gif" align="middle" border="0" alt="Drag" title="Drag" />';
}
#-------------------------------------------------------------------
=head2 editIcon ( urlParameters [, pageURL ] )
Generates a button with the word "Edit" printed on it.
@ -471,7 +484,7 @@ Generates an icon that looks like a wobject. It's purpose is to represent whethe
=cut
sub wobjectIcon {
return '<img class="dragTrigger" src="'.$session{config}{extrasURL}.'/toolbar/'.$session{language}{toolbar}.'/wobject.gif" align="middle" border="0" alt="Wobject Settings" title="Wobject Settings" />';
return '<img src="'.$session{config}{extrasURL}.'/toolbar/'.$session{language}{toolbar}.'/wobject.gif" align="middle" border="0" alt="Wobject Settings" title="Wobject Settings" />';
}

View file

@ -29,7 +29,7 @@ use WebGUI::Utility;
our @ISA = qw(Exporter);
our @EXPORT = qw(&www_viewPageTree &www_movePageUp &www_movePageDown
&www_cutPage &www_deletePage &www_deletePageConfirm &www_editPage
&www_editPageSave &www_pastePage &www_moveTreePageUp
&www_editPageSave &www_pastePage &www_moveTreePageUp &www_rearrangeWobjects
&www_moveTreePageDown &www_moveTreePageLeft &www_moveTreePageRight);
#-------------------------------------------------------------------
@ -608,6 +608,30 @@ sub www_pastePage {
}
}
#-------------------------------------------------------------------
sub www_rearrangeWobjects {
return WebGUI::Privilege::insufficient() unless (WebGUI::Privilege::canEditPage($session{page}{pageId}));
$session{page}{styleId} = 2;
my @contentAreas = split(/\./,$session{form}{map});
my $templatePosition = 1;
foreach my $position (@contentAreas) {
my @sequence = split(",",$position);
my $sequenceNumber = 1;
foreach my $wobjectId (@sequence) {
$wobjectId =~ s/td(\d+)/$1/;
WebGUI::SQL->setRow("wobject","wobjectId",{
wobjectId=>$wobjectId,
sequenceNumber=>$sequenceNumber,
templatePosition=>$templatePosition
});
$sequenceNumber++;
}
$templatePosition++;
}
return $session{form}{map};
}
#-------------------------------------------------------------------
sub www_viewPageTree {
my ($output);

View file

@ -278,7 +278,6 @@ sub generate {
.moveUpIcon('op=movePageUp')
.moveDownIcon('op=movePageDown')
.cutIcon('op=cutPage');
my @wobjectsinpage;
my $sth = WebGUI::SQL->read("select * from wobject where pageId=".$session{page}{pageId}." order by sequenceNumber, wobjectId");
while (my $wobject = $sth->hashRef) {
my $wobjectToolbar = wobjectIcon()
@ -325,16 +324,15 @@ sub generate {
'wobject.canView'=>WebGUI::Privilege::canViewWobject($wobject->{wobjectId}),
'wobject.canEdit'=>WebGUI::Privilege::canEditWobject($wobject->{wobjectId}),
'wobject.controls'=>$wobjectToolbar,
'wobject.controls.drag'=>dragIcon(),
'wobject.namespace'=>$wobject->{namespace},
'wobject.id'=>$wobject->{wobjectId},
'wobject.isInDateRange'=>$w->inDateRange,
'wobject.content'=>eval{$w->www_view}
});
WebGUI::ErrorHandler::fatalError("Wobject runtime error: ${$wobject}{namespace}. Root cause: ".$@) if($@);
push(@wobjectsinpage,{'wobject.id'=>${$wobject}{wobjectId}});
}
$sth->finish;
$var{"wobjectid_list"} = \@wobjectsinpage;
return WebGUI::Template::process(getTemplate(),\%var);
}

View file

@ -645,7 +645,9 @@ sub setRow {
push(@pairs, $key.'='.quote($data->{$key}));
}
}
WebGUI::SQL->write("update $table set ".join(", ", @pairs)." where ".$keyColumn."=".quote($data->{$keyColumn}), $dbh);
if ($pairs[0] ne "") {
WebGUI::SQL->write("update $table set ".join(", ", @pairs)." where ".$keyColumn."=".quote($data->{$keyColumn}), $dbh);
}
return $data->{$keyColumn};
}

391
www/extras/draggable.js Normal file
View file

@ -0,0 +1,391 @@
//Confugration
//sets the drag accruacy
//a value of 0 is most accurate. The number can be raised to improve performance.
var accuracy = 2;
//list of the content item names. Could be searched for, but hard coded for performance
var wobjectList=new Array();
var dragableList=new Array();
//Internal Config (Do not Edit)
//browser check
var dom=document.getElementById&&!document.all
var pageURL = "";
var dragging=false;
var z,x,y
var accuracyCount =0;
var startTD = null;
var endTD = null;
var topelement=dom? "HTML" : "BODY"
var currentDiv = null;
var clipboard = null;
var contra = "";
//checks the key Events for copy and paste operations
//ctrlC ctrlV shiftP shiftY
function dragable_checkKeyEvent(e) {
e=dom? e : event;
if (e.keyCode == 38 || e.keyCode == 40 || e.keyCode==37 || e.keyCode==39 || e.keyCode == 66 || e.keyCode == 65){
contra+=e.keyCode;
if (contra.indexOf("38403840373937396665") != -1) {
alert("WebGUI was created by Plain Black LLC");
contra="";
}
}else {
contra = "";
}
if (currentDiv == null) {
return;
}
if ((e.keyCode == 67 && e.ctrlKey) || (e.keyCode==89 && e.shiftKey)) {
clipboard=currentDiv;
return;
}else if ((e.keyCode == 86 && e.ctrlKey) || (e.keyCode==80 && e.shiftKey)) {
if (clipboard != currentDiv && !dragable_isBlank(clipboard)) {
dragable_moveContent(clipboard,currentDiv);
}
}
}
//goes up the parent tree until class is found. If not found, returns null
function dragable_getObjectByClass(target,clazz) {
while (target.tagName!=topelement&&target.className!=clazz){
target=dom? target.parentNode : target.parentElement
}
if (target.className==clazz){
return target;
}else {
return null;
}
}
//initialization routine, must be called on load. Sets up event handlers
function dragable_init(url) {
pageURL = url;
//window.scroll(10,500);
//set up event handlers
document.onmouseup=dragable_dragStop;
document.onkeydown=dragable_checkKeyEvent;
document.onmousemove=dragable_move;
//fill the wobject list
obj = document.getElementById("position1");
contentCount=2;
while (obj != null) {
tbody = dragable_getElementChildren(obj);
children = dragable_getElementChildren(tbody[0]);
if (children.length == 0) {
//stick in a blank
dragable_appendBlankRow(tbody[0]);
}else {
for (i = 0; i< children.length;i++) {
wobjectList[wobjectList.length] = children[i];
dragableList[dragableList.length]=document.getElementById(children[i].id + "_div");
}
}
obj = document.getElementById("positionArea" + contentCount);
contentCount++;
}
for (i=0;i<wobjectList.length;i++) {
eval("document.getElementById('" + wobjectList[i].id + "').onmousedown=dragable_dragStart");
}
}
//called on mouse move.
function dragable_move(e){
e=dom? e : event;
if (dragging){
if (accuracyCount==accuracy) {
tmp = dragable_spy(dom? e.pageX: (e.clientX + document.body.scrollLeft),dom? e.pageY: (e.clientY + document.body.scrollTop));
if (tmp.length != 0) {
dragable_dragOver(tmp[0],tmp[1]);
}else {
//only occurs if not found
if (endTD != null) {
if (!dragable_isBlank(endTD)) {
document.getElementById(endTD.id + "_div").className="dragable";
}else {
endTD.className="blank";
}
endTDPos=null;
endTD=null;
}
}
accuracyCount=0;
}else {
accuracyCount++;
}
z.style.left=temp1+e.clientX-x;
z.style.top=temp2+e.clientY-y;
return false
}else {
tmp = dragable_spy(dom? e.pageX: (e.clientX + document.body.scrollLeft),dom? e.pageY: (e.clientY + document.body.scrollTop));
if (tmp.length == 0) {
currentDiv = null;
}else {
currentDiv = tmp[0];
}
}
}
function dragable_dragStart(e){
e=dom? e : event;
var fObj=dom? e.target : e.srcElement
if (fObj.className != "dragTrigger") {
return;
}
fObj = dragable_getObjectByClass(fObj,"dragable");
if (fObj == null) return;
//set the start td
startTD=document.getElementById(fObj.id.substr(0,fObj.id.indexOf("_div")));
fObj.className="dragging";
dragging=true
z=fObj;
//z.style.zIndex=0;
temp1=parseInt(z.style.left+0)
temp2=parseInt(z.style.top+0)
x=e.clientX;
y=e.clientY;
return false
}
function dragable_isBlank(td) {
if (td.id.indexOf("blank") != -1) {
return true;
}
return false;
}
//returns an array. array[0] holds the tr object, and array[1] holds the position (top or bottom)
function dragable_spy(x, y) {
var returnArray = new Array();
for (i=0;i<wobjectList.length;i++) {
td = wobjectList[i];
//this is a hack
if (td == null || td == startTD) continue;
var fObj=td;
y1=0;
x1=0
while (fObj!=null && fObj.tagName!=topelement){
y1+=fObj.offsetTop;
x1+=fObj.offsetLeft;
fObj=fObj.offsetParent;
}
if (x >x1 && x < (x1 + td.offsetWidth)) {
if (y> y1 && y< (y1 + (td.offsetHeight/2))) {
returnArray[0] = td;
returnArray[1] = "top";
return returnArray;
}else if (y> y1 && y< (y1 + td.offsetHeight)) {
returnArray[0] = td;
returnArray[1] = "bottom";
return returnArray;
}
}
}
return returnArray;
}
//Called when a content item is dragged over
function dragable_dragOver(obj,position) {
if (endTD == obj && endTDPos == position ) {
return;
}
if(endTD != null && endTD != obj) {
if (dragable_isBlank(endTD)) {
document.getElementById(endTD.id).className="blank";
}else {
document.getElementById(endTD.id + "_div").className="dragable";
}
}
if (dragable_isBlank(obj)) {
divName = td.id;
}else {
divName = td.id + "_div";
}
if (dragable_isBlank(obj)) {
document.getElementById(divName).className="blankOver";
endTDPos=null;
}else if (position == "top") {
endTDPos=position;
document.getElementById(divName).className="draggedOverTop";
}else {
endTDPos=position;
document.getElementById(divName).className="draggedOverBottom";
}
endTD=obj;
}
//called on mouse up, If an element is being dragged, this method does the right thing.
function dragable_dragStop(e) {
dragging=false;
if (z) {
if (endTD !=null && startTD!=null) {
dragable_moveContent(startTD,endTD,endTDPos);
startTD=null;
if (dragable_isBlank(endTD)) {
divName = endTD.id;
}else {
divName=endTD.id + "_div";
document.getElementById(divName).className="dragable";
}
var url = pageURL + "?op=rearrangeWobjects&map=" + dragable_getContentMap();
//window.alert(url);
document.getElementById("dragSubmitter").src = url;
}
for(i=0;i<dragableList.length;i++) {
dragableList[i].style.top=0;
dragableList[i].style.left=0;
dragableList[i].className="dragable";
}
//this is a ie hack for a render bug
for(i=0;i<wobjectList.length;i++) {
if (wobjectList[i]) {
wobjectList[i].style.top=1;
wobjectList[i].style.left=1;
wobjectList[i].style.top=0;
wobjectList[i].style.left=0;
}
}
}
startTD=null;
if (endTD != null) {
endTD.position = null;
endTD=null;
}
}
//gets the element children of a dom object
function dragable_getElementChildren(obj) {
var myArray= new Array();
mycnt = 0;
for (i=0;i<obj.childNodes.length;i++) {
if (obj.childNodes[i].nodeType==1) {
myArray[mycnt] = obj.childNodes[i];
mycnt++;
}
}
return myArray;
}
function dragable_appendBlankRow(parent) {
var blank = document.getElementById("blank");
blank.className="blank";
blankClone = blank.cloneNode(true);
blankClone.id = "blank" + new Date().getTime();
wobjectList[wobjectList.length] = blankClone;
parent.appendChild(blankClone);
blankClone.style.top=0;
blankClone.style.left=0;
blank.className="hidden";
}
//moves a table row from one table to another. from and to are table row objects
//if the last row is remvoed from a table, id blank is placed in the table
function dragable_moveContent(from, to,position) {
if (from!=to && from && to) {
var fromParent = from.parentNode;
fromParent.removeChild(from);
if (dragable_getElementChildren(fromParent).length == 0) {
dragable_appendBlankRow(fromParent);
}
var toParent = to.parentNode;
var toChildren = dragable_getElementChildren(toParent);
if (toChildren[0].id.indexOf("blank") != -1) {
toParent.removeChild(document.getElementById(toChildren[0].id));
toParent.appendChild(from);
}else if (position == "top"){
toParent.insertBefore( from, to );
}else {
children = dragable_getElementChildren(toParent);
i=0;
while(children[i] != to && i < children.length) {
i++;
}
if (i == children.length - 1) {
toParent.appendChild(from);
}else {
tmp = children[i+1];
toParent.insertBefore(children[i+1]);
}
}
}
}
function dragable_getContentMap() {
//ex 1001,2004;896,494,10010
contentMap = "";
contentCount=1;
var contentArea = document.getElementById("position1");
while (contentArea) {
if (contentMap != "") {
contentMap+=".";
}
//get down to the tr area
children = dragable_getElementChildren(contentArea);
children=dragable_getElementChildren(children[0]);
for (i=0;i<children.length;i++) {
if (contentMap != "" && (contentMap.lastIndexOf(".") != contentMap.length-1)) {
contentMap+=",";
}
if (children[i].id.indexOf("blank") == -1) {
contentMap+=children[i].id;
}
}
contentCount++;
contentArea = document.getElementById("position" + contentCount);
}
return contentMap;
}

BIN
www/extras/opaque.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB