How to Initially Hide Element on First Page Load?

Discussion in 'Web Design and Development' started by Zedcars, Jun 9, 2017.

  1. Zedcars, Jun 9, 2017
    Last edited: Jun 9, 2017

    Zedcars macrumors 6502

    Zedcars

    Joined:
    Apr 5, 2010
    Location:
    Brighton, UK
    #1
    Hello,

    I'm trying to code the creation of 'sticky notes' on a webpage with a contextual menu right-click option. I nearly have it working, but there are a couple of things I cannot seem to figure out (I've been trying for a couple of weeks now!).

    I'm very new to web development (beginner level).

    I've combined some code for the sticky notes and context right-click menu. The problem I'm having is that when the page loads for the first time, a sticky note appears: I do not want that to happen. I would like it to initially load with no sticky notes visable, and only make them visable once they are added, or if they were previously added and automatically saved (which is already part of the code).

    So I used `display: none` to hide the css "note" element. However, if I do that then when I right-click to add a note it doesn't show up at all. So I understand I need to tell it to show if it's been created by my right-click menu option, but I've been struggling to understand how to do this.

    The second issue I have is that the sticky notes are created in random positions; whereas, I would like them to show up next to where I have right-clicked.

    Please could someone point me in the right direction. I apologise for my lack of basic knowledge.

    Here is what I have so far:

    HTML

    HTML:
    <!DOCTYPE html>
    <html>
    <head>
       <title>Custom Right Click Menu</title>
       <link rel="stylesheet" type="text/css" href="stickies.css" />
    
       <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
       <script type="text/javascript" src="stickies.js"></script>
    
    </head>
    <body>
    
    <!-- Menu div initially hidden -->
    <script>
    document.getElementById("newNoteButton").disabled = !db;
    </script>
    <div class="menu" id="newNoteButton" onclick="newNote()">
       <ul>
           <a href="#"><li>Add Note</li></a>
       </ul>
    </div>
    </body>
    </html>
    CSS

    Code:
    .menu{
        width: 100px;
        background: #000;
        color: #fff;
        position:absolute;
        z-index: 999999;
        display: none;
        box-shadow: 0 0 10px #713C3C;
    }
    .menu ul{
        list-style: none;
        padding: 0;
        margin:0;
    }
    .menu ul a{
        text-decoration: none;
    }
    .menu ul li{
        width: 88%;
        padding: 6%;
        background-color: #F04D44;
        color: #fff;
    }
    .menu ul li:hover{
        background-color: #F7BA4B;
        color: #444343;
    }
    
    body {
        font-family: 'Lucida Grande', 'Helvetica', sans-serif;
    }
    
    .note {
        background-color: rgb(255, 240, 70);
        height: 100px;
        padding: 10px;
        position: absolute;
        width: 200px;
        -webkit-box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.5);
    }
    
    .note:hover .closebutton {
        display: block;
    }
    
    .closebutton {
        display: none;
        background-image: url(deleteButton.png);
        height: 30px;
        position: absolute;
        left: -15px;
        top: -15px;
        width: 30px;
    }
    
    .closebutton:active {
        background-image: url(deleteButtonPressed.png);
    }
    
    .edit {
        outline: none;
    }
    
    .timestamp {
        position: absolute;
        left: 0px;
        right: 0px;
        bottom: 0px;
        font-size: 9px;
        background-color: #db0;
        color: white;
        border-top: 1px solid #a80;
        padding: 2px 4px;
        text-align: right;
    }
    Javascript

    Code:
    $(document).ready(function () {
            $("html").on("contextmenu",function(e){
                   //prevent default context menu for right click
                   e.preventDefault();
    
                   var menu = $(".menu");
    
                   //hide menu if already shown
                   menu.hide();
    
                   //get x and y values of the click event
                   var pageX = e.pageX;
                   var pageY = e.pageY;
    
                   //position menu div near mouse cliked area
                   menu.css({top: pageY , left: pageX});
    
                   var mwidth = menu.width();
                   var mheight = menu.height();
                   var screenWidth = $(window).width();
                   var screenHeight = $(window).height();
    
                   //if window is scrolled
                   var scrTop = $(window).scrollTop();
    
                   //if the menu is close to right edge of the window
                   if(pageX+mwidth > screenWidth){
                    menu.css({left:pageX-mwidth});
                   }
    
                   //if the menu is close to bottom edge of the window
                   if(pageY+mheight > screenHeight+scrTop){
                    menu.css({top:pageY-mheight});
                   }
    
                   //finally show the menu
                   menu.show();
            });
    
            $("html").on("click", function(){
                $(".menu").hide();
            });
        });
    
    
    var db = null;
    
    try {
        if (window.openDatabase) {
            db = openDatabase("NoteTest", "1.0", "HTML5 Database API example", 200000);
            if (!db)
                alert("Failed to open the database on disk.  This is probably because the version was bad or there is not enough space left in this domain's quota");
        } else
            alert("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");
    } catch(err) {
        db = null;
        alert("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");
    }
    
    var captured = null;
    var highestZ = 0;
    var highestId = 0;
    
    function Note()
    {
        var self = this;
    
        var note = document.createElement('div');
        note.className = 'note';
        note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
        note.addEventListener('click', function() { return self.onNoteClick() }, false);
        this.note = note;
    
        var close = document.createElement('div');
        close.className = 'closebutton';
        close.addEventListener('click', function(event) { return self.close(event) }, false);
        note.appendChild(close);
    
        var edit = document.createElement('div');
        edit.className = 'edit';
        edit.setAttribute('contenteditable', true);
        edit.addEventListener('keyup', function() { return self.onKeyUp() }, false);
        note.appendChild(edit);
        this.editField = edit;
    
        var ts = document.createElement('div');
        ts.className = 'timestamp';
        ts.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
        note.appendChild(ts);
        this.lastModified = ts;
    
        document.body.appendChild(note);
        return this;
    }
    
    Note.prototype = {
        get id()
        {
            if (!("_id" in this))
                this._id = 0;
            return this._id;
        },
    
        set id(x)
        {
            this._id = x;
        },
    
        get text()
        {
            return this.editField.innerHTML;
        },
    
        set text(x)
        {
            this.editField.innerHTML = x;
        },
    
        get timestamp()
        {
            if (!("_timestamp" in this))
                this._timestamp = 0;
            return this._timestamp;
        },
    
        set timestamp(x)
        {
            if (this._timestamp == x)
                return;
    
            this._timestamp = x;
            var date = new Date();
            date.setTime(parseFloat(x));
            this.lastModified.textContent = modifiedString(date);
        },
    
        get left()
        {
            return this.note.style.left;
        },
    
        set left(x)
        {
            this.note.style.left = x;
        },
    
        get top()
        {
            return this.note.style.top;
        },
    
        set top(x)
        {
            this.note.style.top = x;
        },
    
        get zIndex()
        {
            return this.note.style.zIndex;
        },
    
        set zIndex(x)
        {
            this.note.style.zIndex = x;
        },
    
        close: function(event)
        {
            this.cancelPendingSave();
    
            var note = this;
            db.transaction(function(tx)
            {
                tx.executeSql("DELETE FROM WebKitStickyNotes WHERE id = ?", [note.id]);
            });
    
            var duration = event.shiftKey ? 2 : .25;
            this.note.style.webkitTransition = '-webkit-transform ' + duration + 's ease-in, opacity ' + duration + 's ease-in';
            this.note.offsetTop; // Force style recalc
            this.note.style.webkitTransformOrigin = "0 0";
            this.note.style.webkitTransform = 'skew(30deg, 0deg) scale(0)';
            this.note.style.opacity = '0';
    
            var self = this;
            setTimeout(function() { document.body.removeChild(self.note) }, duration * 1000);
        },
    
        saveSoon: function()
        {
            this.cancelPendingSave();
            var self = this;
            this._saveTimer = setTimeout(function() { self.save() }, 200);
        },
    
        cancelPendingSave: function()
        {
            if (!("_saveTimer" in this))
                return;
            clearTimeout(this._saveTimer);
            delete this._saveTimer;
        },
    
        save: function()
        {
            this.cancelPendingSave();
    
            if ("dirty" in this) {
                this.timestamp = new Date().getTime();
                delete this.dirty;
            }
    
            var note = this;
            db.transaction(function (tx)
            {
                tx.executeSql("UPDATE WebKitStickyNotes SET note = ?, timestamp = ?, left = ?, top = ?, zindex = ? WHERE id = ?", [note.text, note.timestamp, note.left, note.top, note.zIndex, note.id]);
            });
        },
    
        saveAsNew: function()
        {
            this.timestamp = new Date().getTime();
    
            var note = this;
            db.transaction(function (tx)
            {
                tx.executeSql("INSERT INTO WebKitStickyNotes (id, note, timestamp, left, top, zindex) VALUES (?, ?, ?, ?, ?, ?)", [note.id, note.text, note.timestamp, note.left, note.top, note.zIndex]);
            });
        },
    
        onMouseDown: function(e)
        {
            captured = this;
            this.startX = e.clientX - this.note.offsetLeft;
            this.startY = e.clientY - this.note.offsetTop;
            this.zIndex = ++highestZ;
    
            var self = this;
            if (!("mouseMoveHandler" in this)) {
                this.mouseMoveHandler = function(e) { return self.onMouseMove(e) }
                this.mouseUpHandler = function(e) { return self.onMouseUp(e) }
            }
    
            document.addEventListener('mousemove', this.mouseMoveHandler, true);
            document.addEventListener('mouseup', this.mouseUpHandler, true);
    
            return false;
        },
    
        onMouseMove: function(e)
        {
            if (this != captured)
                return true;
    
            this.left = e.clientX - this.startX + 'px';
            this.top = e.clientY - this.startY + 'px';
            return false;
        },
    
        onMouseUp: function(e)
        {
            document.removeEventListener('mousemove', this.mouseMoveHandler, true);
            document.removeEventListener('mouseup', this.mouseUpHandler, true);
    
            this.save();
            return false;
        },
    
        onNoteClick: function(e)
        {
            this.editField.focus();
            getSelection().collapseToEnd();
        },
    
        onKeyUp: function()
        {
            this.dirty = true;
            this.saveSoon();
        },
    }
    
    function loaded()
    {
        db.transaction(function(tx) {
            tx.executeSql("SELECT COUNT(*) FROM WebkitStickyNotes", [], function(result) {
                loadNotes();
            }, function(tx, error) {
                tx.executeSql("CREATE TABLE WebKitStickyNotes (id REAL UNIQUE, note TEXT, timestamp REAL, left TEXT, top TEXT, zindex REAL)", [], function(result) {
                    loadNotes();
                });
            });
        });
    }
    
    function loadNotes()
    {
        db.transaction(function(tx) {
            tx.executeSql("SELECT id, note, timestamp, left, top, zindex FROM WebKitStickyNotes", [], function(tx, result) {
                for (var i = 0; i < result.rows.length; ++i) {
                    var row = result.rows.item(i);
                    var note = new Note();
                    note.id = row['id'];
                    note.text = row['note'];
                    note.timestamp = row['timestamp'];
                    note.left = row['left'];
                    note.top = row['top'];
                    note.zIndex = row['zindex'];
    
                    if (row['id'] > highestId)
                        highestId = row['id'];
                    if (row['zindex'] > highestZ)
                        highestZ = row['zindex'];
                }
    
                if (!result.rows.length)
                    newNote();
            }, function(tx, error) {
                alert('Failed to retrieve notes from database - ' + error.message);
                return;
            });
        });
    }
    
    function modifiedString(date)
    {
        return 'Last Modified: ' + date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
    }
    
    function newNote()
    {
        var note = new Note();
        note.id = ++highestId;
        note.timestamp = new Date().getTime();
        note.left = Math.round(Math.random() * 400) + 'px';
        note.top = Math.round(Math.random() * 500) + 'px';
        note.zIndex = ++highestZ;
        note.saveAsNew();
    }
    
    if (db != null)
        addEventListener('load', loaded, false);
    Link to download files:
    https://www.dropbox.com/s/e6ucgle1a7...-menu.zip?dl=0
     
  2. Zedcars thread starter macrumors 6502

    Zedcars

    Joined:
    Apr 5, 2010
    Location:
    Brighton, UK
    #2
    So I suppose a way to deal with this would be to only load the sticky note portion of the javascript once the right-click context menu has been selected/triggered.

    I can divide my js code into the sticky note and context-menu portions (which is what I had originally anyway):

    context-menu.js
    stickies.js

    Then remove the stickies.js from initially loading in the <head> of the html file.

    Then how would I go about running my 'stickies.js code once I've right-clicked and selected "Add Note"?
     
  3. 960design macrumors 68000

    Joined:
    Apr 17, 2012
    Location:
    Destin, FL
    #3
    This is a fairly common question. There are several ways to handle on load. The best in my opinion is to use CSS to initially visibility:hidden or display:none.
    • visibility:hidden; /*preserves the vertical and horizontal spacing of the hidden element*/
    • display:none; /*does NOT preserve the spacing, the element will expand when set to :block*/
    For your code check:
    Code:
    function loadNotes(){...}
    It looks like if the database returns no value then call newNote().
    Code:
    if (!result.rows.length)
                    newNote();
     
  4. Zedcars, Jun 10, 2017
    Last edited: Jun 10, 2017

    Zedcars thread starter macrumors 6502

    Zedcars

    Joined:
    Apr 5, 2010
    Location:
    Brighton, UK
    #4
    Oh thank you thank you thank you! :)

    I removed that section of code you highlighted and now it no longer loads the first sticky element.

    I'm so grateful. You've no idea how much time and effort I've put into trying to solve this seemingly simple problem.

    Now I just need to figure out how to place the creation of new notes near to the cursor (where I right-clicked) rather than randomly.
     
  5. 960design, Jun 10, 2017
    Last edited: Jun 11, 2017

    960design macrumors 68000

    Joined:
    Apr 17, 2012
    Location:
    Destin, FL
    #5
    You are quite welcome. For perspective, yesterday I spent three hours tracking down a misspelled variable in javascript: colomns should have been columns in a 4000 line js file. Bug hunting is all part of the fun.

    You will get it! I'll take a look at it again Monday, heading out on the boat this weekend.
     
  6. Zedcars thread starter macrumors 6502

    Zedcars

    Joined:
    Apr 5, 2010
    Location:
    Brighton, UK
    #6
    OK, so I've been struggling for a few days with this now. I've figured out that if I remove the following lines of code then the note position will no longer be random, but will be created in the top left corner:

    Code:
    note.left = Math.round(Math.random() * 400) + 'px';
    note.top = Math.round(Math.random() * 400) + 'px';
    I'd like it to be positioned where I've clicked the context menu "Add note".

    I've tried a few things, but nothing is working so far. I guess I need to call the mouse position on click and use that as the co-ordinates for the new note? :confused:
     
  7. 960design macrumors 68000

    Joined:
    Apr 17, 2012
    Location:
    Destin, FL
    #7
    Yes, that is what I would do. Create a couple of variables divide the new note height and width by 2 to find the center, then offset the x/y of the mouse click so that the center of the note appears right where the user clicks. I'd do some boundary checks as well to keep half the note from disappearing off the edges of the screen.
     
  8. Zedcars thread starter macrumors 6502

    Zedcars

    Joined:
    Apr 5, 2010
    Location:
    Brighton, UK
    #8
    Thank you for your help, although I think I've pretty much got to the limit of what I can do. It's just not happening lol
     

Share This Page