Solved

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

Posted on 2013-11-22
8
244 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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 

Author Comment

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

Accepted Solution

by:
COBOLdinosaur earned 500 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

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

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

CSS is a visual language used to classify objects and define rules about how they should be displayed. CSS skills aren’t restricted to developers anymore, there is a big benefit to having a basic understanding of the language, regardless of your occ…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
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 this tutorial viewers will learn how to style rounded corners for elements in CSS using the border-radius property Begin with a normal styled element such as a div: To style all four corners of the div to be the same degree of roundness, use the …

726 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