Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

JavaScript doesn't prevent an object from being dropped on top of another object

Posted on 2013-11-22
8
Medium Priority
?
250 Views
Last Modified: 2013-11-28
This program is a jigsaw puzzle. You drag the pieces of the puzzle from the right side of the page and drop them on the grid on the left side of the page. The problem is that the program allows you to drop one piece on top of another piece, causing the second piece to be covered.  I want to prevent this so that if a  user tries to drop Piece 1 on top of Piece 2, Piece 1 "sticks" to the cursor, which prevents it from dropping on top of Piece 2. Only when Piece 1 is dragged away from Piece 2 should JavaScript let the user drop it.

The functions  mouseMove(), attached to the mousemove event,  and mouseDrop(), attached to the mouseup event,  control the drag-and-drop feature.  A function invoked from within mouseDrop() named dropValid() tests if the piece which is about to be dropped is hovering over another piece. If yes, mouseMove() and mouseDrop() are detached from the mousemove and mouseup events to prevent the user from dropping the piece.

The dropValid() function uses the withinIt(object1, object2) function to test if the piece that is about to be dropped is hovering over another piece. Parameter object1 is the piece to be dropped, and parameter object2 is any other piece in the puzzle. The withinIt() function looks at every piece in the puzzle to get each one's top and left coordinates from the style sheet. It then uses these coordinates to determine if object1 (piece to be dropped) is over object2 (any other piece).

I think the problem is that the function withinIt() isn't working. JavaScript lets me drop one piece on top of another piece, allowing the second piece to be covered.

All files are included in the attached .zip file.
Jigsaw-Puzzle.zip
0
Comment
Question by:MBarongan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
8 Comments
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39670518
Hover is of no value to you.  the piece that is already in place is being covered by the second piece so the mouse cannot "see" it.  You need to look at the grid and determine if a piece is already in the position where the user is trying to drop.

Cd&
0
 

Author Comment

by:MBarongan
ID: 39672039
Doesn't the withinIt(object1, object2) function ultimately make the mouse see the second Piece?

function withinIt(object1, object2) {
   var within = false;
   var x1 = parseInt(object1.style.left);
   var y1 = parseInt(object1.style.top);

   var left = parseInt(object2.style.left);
   var top = parseInt(object2.style.top);
   var width = parseInt(object2.style.width);
   var height = parseInt(object2.style.height);

   var bottom = top + height;
   var right = left + width;

   if ((x1 > left && x1 < right) && (y1 > top && y1 < bottom)) {  
     within = true;
   }

   return within;
}


If mousePiece is the puzzle piece currently being dragged, I thought I was forcing the mouse to see the positions of all the other pieces ("pieces\[i\]") no matter where those pieces are located on the page. So no matter if any puzzle piece pieces\[i\] is on or off the left grid, I can determine of mousePiece  is hovering over pieces\[i\] bycalling withinIt(object1, object2) inside dropValid(object) like this:

  function dropValid(object) {  
    for (var i = 0; i < pieces.length; i++){
      if (withinIt(mousePiece, pieces\[i\]))    
       return false;
   }        
  return true;
  }

As the for loop iterates through all stationary puzzle pieces, the if(withinIt(mousePiece, pieces\[i\])) tests if the top and left coordinates of  mousePiece are within the top and left coordinates of each pieces\[i\]. If so, function dropValid(object) returns false and passes this false value to the if statement in the event handler mouseDrop(e).

  function mouseDrop(e) {  
   if (dropValid(mouseDrop)){
    removeEvent(document, "mousemove", mouseMove, false);
    removeEvent(document, "mouseup", mouseDrop, false);    
   }    
 }

So if the test if(dropValid(mouseDrop)) evaluates to false, then  removeEvent() does not remove the handler mouseMove from event "mouseMove", and removeEvent() does not remove the handler mouseDrop from the event "mouseup". As a result, releasing the mouse button will not cause mousePiece to be dropped on top of pieces\[ i \], no matter where pieces \[i\] happens to be on the page. The only thing JavaScript tests if whether mousePiece is hovering over pieces\[i\].

That's the logic I'm trying to tell JavaScript to follow. Do the functions above correctly code that logic into the program?
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39672106
The function merely creates variable that the window object is aware of, but the mouse cannot see them.  However the mouse can determine its co-ordinates and based on position trigger a window event. If an ocuppied grid cannot have a second element dropped

Then disable the drop event for a cell as soon as it becomes occupied.

Cd&
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:MBarongan
ID: 39672228
How can I mark a cell as occupied?
0
 
LVL 53

Accepted Solution

by:
COBOLdinosaur earned 2000 total points
ID: 39672756
An array with flags representing the current state of each cell come to mind.  I don't know what it looks like because I don't download zip files from unknown sources; so if you post a link I will look at it to see how you have it structured and maybe have some additional ideas.

Cd&
0
 

Author Comment

by:MBarongan
ID: 39679382
Your suggestion worked. I created a new array with true/false flags to mark a grid as false if a piece occupies it. Now no one can drop a second piece on a grid marked to false by the first piece. But I still need help because I can't figure out how to un-mark a grid back to true if the user moves the piece off of it. This is necessary because solving a puzzle involves a lot of shuffling around of pieces. As it stands now, once a piece has been placed on a grid, that grid is no longer useable.

I'd to post a link to my web page for you to access it, but I don't know where I can do it. Is there an Experts Exchange web server that hosts members' websites for others to review?
0
 

Author Closing Comment

by:MBarongan
ID: 39683976
I'll work on the other part of the problem for a while and open another a question later if I need help. Thanks for helping me resolve my main issue.
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39684237
On the drag event to remove the piece, you should be able to set the flag for that grid to true.

EE does not have a facility for hosting member pages.  If you do not have a hosted site you can always just sign up with a free site, so you can put pages on the internet.  You need an ability to see how your pages work in a hosted environment anyway.  There is all kinds of free hosting available.

Cd&
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
In this tutorial viewers will learn how to style a decorative dropcap for the first letter in a paragraph using CSS. In CSS, create a new paragraph class by typing "p.fancy": Then, to style only the first letter of the first sentence, include the ps…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Suggested Courses

618 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question