Introduction
This code has been stripped out of a much larger application I am currently writing, on the basis that I thought it might be helpful to others, and to show what can be achieved with just a little DHTML and AJAX (or SJAX in this instance; the code is actually synchronous although there's no particular requirement for that).
I was asked to provide the users of my application with the ability to add notes to certain pages. These notes had to be flexible, and ideally should be capable of being placed wherever the user wanted. In practice, it looked like DHTML would be the only real choice. The next problem was how to make the notes persistent. There's lots of code available on the web to show you how to implement moveable and resizeable DIVs; none of it addresses the fact that as soon as you close the browser window, all your creative positioning is lost. I also didn't want to interrupt the user by forcing them to refresh the page just to get the note saved to the database. The answer, as it turned out, was AJAX.
AJAX and persistence
The term has been bandied around enough already, and is all over CodeProject, so there's no point in talking about it here. Suffice it to say that AJAX allowed me to store the position and size of a note without requiring a round-trip to the server and a page refresh. This was important as there is no way any computer user is going to put up with that sort of behaviour when all he/she wants to do is resize or move an element in a window.
When the mouse-down event is fired anywhere in the page, the JavaScript checks to see which element the mouse pointer is in. If it's in one of our notes, and not in the resize hotspot at the bottom right, the note is marked as moveable, and any subsequent mouse-move event moves the note around the page. When the mouse-up event is fired, something a bit cleverer happens. The current position of the note is sent in an AJAX request to the server, and routines on the server save the position of the note in a database. Because the position of the note is only tracked on mouse-up, and not during mouse-move or on mouse-down, the drag action is kept nice and smooth.
The resize functionality is accomplished in the same way, except that the note is marked as resizeable when the mouse-down event occurs in the resize hotspot. On mouse-up, a request is sent to the server to record the new size.
Because the positional data is stored in a database and no longer solely held on the client, this data is now persistent, and the next time the page is loaded, all the notes will be in the right place.
Saving the note text
The text of the note is more problematic. There's simply no event we can fire to automatically store the text that doesn't radically affect the page's performance. At first, I sent the request on the key-up event, reasoning that every time a key was released, there was something new to send to the database. Unfortunately, this blocked input in a fairly disastrous way. I didn't want to do the request asynchronously, as I was afraid of swamping my server with what could be a very long string of requests.
I decided there was no real harm in creating a button to do the job, within the note itself. This meant I had a nice, simple on-click event to use. The button (or link in this case) is clicked, the request is fired, and the text gets written to the database. Nice and straightforward.
Housekeeping
At some point or other, somebody's going to come along and put something in a note that they want to retract. Let's face it, nobody's perfect. They have the opportunity to change the content of the note and save it again, but what if they didn't actually want a note in the first place? I added a delete button for this purpose. Its actual function is a little deceptive. To start with, it hides the note (with CSS, display: none
). In order to complete the deletion, it then fires a request to the server, which removes the offending row from the database table. Next time the page is displayed, the note is no longer in the table, and it doesn't get displayed ever again.
The End
I hope I've described the process well enough. The code is fairly self-explanatory. It is arranged into a web user control (a button that creates notes), a web form (to hold the control), and a supplementary class file full of database routines. There is also a sql file which will create the required table and stored procedures. Edit the web.config file to your requirements (there are appConfig
settings at the bottom, change them), create the database stuff, and run the project. It should just work.
This is my first submission to CodeProject; let me know if you like it, hate it, or whatever.