Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    New to the CF scene
    Join Date
    May 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts

    Help with JavaScript checklist app

    Hi - I'm relatively new to JavaScript programming. I've completed a tutorial on creating a basic checklist in JavaScript at:

    http://www.codecademy.com/courses/ht...#!/exercises/0

    The app I have created is at:
    http://dl.dropbox.com/u/39516415/htm...checklist.html

    I've been trying to tweak the checklist app a bit. So far I have achieved default text in the text field, which automatically deletes itself when the text field is focused. I want two more things:

    1. To be able to add an item to the checklist by pressing enter/return, removing the need for the button. Right now, when enter is pressed it just deletes the whole checklist (don't know why).

    2. For items already checked to stay checked when a new item is added. Right now, the CSS line-through remains but the checkbox goes back to unchecked when a new item is added.

    I've tried different and ambitious things to get around these two issues but nothing has worked. Some help please?

  • #2
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,883
    Thanks
    56
    Thanked 539 Times in 536 Posts
    Hi,

    it's a kind of an ugly way of doing this and if that is what your tutorial is teaching you I think you should look for something else.

    Javascript has methods for creating elements which aren't really a whole lot more to get your head around than creating a string and adding it as innerHTML.

    To use the enter key to fire a function you just have to listen to what key is being pressed. Here is another way of doing what you want to do, using the things I mentioned - feel free to ask questions:
    Code:
    <html>
    <head>
    <style>
    </style>
    </head>
    <body>
    <input type="text" id="txt" value="Add to checklist" />
    <div id="boxes"></div>
    <script type='text/javascript'>
    var count=0
    function makeBox(){
    var thediv=document.getElementById("boxes");
    var br = document.createElement("br");
    var box=document.createElement("input");
    box.type="checkbox"
    box.id="cb"+count;
    var label = document.createElement("label")
    label.htmlFor = "cb"+count;
    label.appendChild(document.createTextNode(document.getElementById("txt").value));
    document.getElementById("boxes").appendChild(box);
    document.getElementById("boxes").appendChild(label);
    document.getElementById("boxes").appendChild(br);
    document.getElementById("txt").value=""
    count++
    }
    
    if (window.addEventListener)
    addEvent = function(ob, type, fn ) {
    ob.addEventListener(type, fn, false );
    };
    else if (document.attachEvent)
    addEvent = function(ob, type, fn ) {
    var eProp = type + fn;
    ob['e'+eProp] = fn;
    ob[eProp] = function(){ob['e'+eProp]( window.event );};
    ob.attachEvent( 'on'+type, ob[eProp]);
    };
    
    function submitenter(e){
    var keycode;
    if (window.event){ keycode = window.event.keyCode;}
    else if (e){ keycode = e.which;}
    else {return true;}
    
    if (keycode == 13)
       {
       makeBox();
       return false;
       }
    else
       return true;
    }
    
    function set_focus(obj){
    if (obj.value=="Add to checklist"){
    	obj.value=""
    	}
    }
    
    addEvent(document.getElementById('txt'), 'keyup', function(event){submitenter(event)});
    addEvent(document.getElementById('txt'), 'focus', function(){set_focus(this)});
    </script>
    </body>
    </html>

  • Users who have thanked xelawho for this post:

    63charles (05-26-2012)

  • #3
    New to the CF scene
    Join Date
    May 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Well as I said, I'm relatively new so most of that code makes no sense to me. Are you sure there isn't a simpler way of doing it?

    But I guess it works, albeit without any CSS. Would you mind integrating my "checked-off" and "not-clicked" classes into your code so I can copy in my CSS? (as I would have no idea how to do it)

    If I could ask one question, what is the difference between having the script in the body rather than the head? I notice that your script doesn't run properly if in the head.

    Also, I've now encountered a third issue. I've been trying to have my greeting auto update itself based on the time of day. I tried using setTimeout(), but for some reason using innerHTML in the function causes it to not execute. Do you know why this is and is there a way to change the greeting text without innerHTML?

  • #4
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,883
    Thanks
    56
    Thanked 539 Times in 536 Posts
    the reason your greeting is not working is the same reason you encountered problems putting my code into the head - javascript cannot manipulate elements that don't exist yet. The browser reads the code from top to bottom, so if there is a command that gets run in the head to do something to the body it will fail because the browser doesn't know what's in the body yet.

    there are workarounds, but the other thing is related - the page will not start rendering the html (body) until it has finished reading the head, so putting javascript in the head slows down the rendering of the html elements of the page. If you put the call to your checkTime function at the bottom of the body, the function will only run once the "greeting" element exists, thereby avoiding that problem.

    sorry to bombard you with unfamiliar stuff. I thought you may be interested in seeing how to do it in a way that some people consider "proper".

    I was a little freaked out by the whole createElement thing at first, too, but now I think there is a simple elegance to it. Basically, createElement does the same thing as writing an html tag, so
    Code:
    var box=document.createElement("input");
    is (more or less) similar to writing:
    Code:
    <input/>
    in html

    you can then give that tag attributes using the dot notation, so doing
    Code:
    box.type="checkbox"
    is (more or less) similar to writing:
    Code:
    <input type="checkbox"/>
    and so on. The only other thing you have to do is then append that element to some existing part of the page, as a child element. In my case I hardcoded a "boxes" div then did it this way:
    Code:
    var thediv=document.getElementById("boxes");
    document.getElementById("boxes").appendChild(box);
    the addEvent is to add event listeners unobtrusively.

    the submitenter function listens for the keystrokes in the text input and if it is an "enter" (keycode 13), fires the makeBoxes function

    the set_focus function clears the text in the text input if it gains focus and the existing text is the default text

    I have added a crossedOut function, similar to the one that you had. This one finds the label for the box and puts a line through or not, depending on if the checkbox is checked or not. Here's how it looks now:

    Code:
    <html>
    <head>
    <style>
    .checked-off {text-decoration: line-through;}
    .not-clicked {color: #bbb;}
    </style>
    </head>
    <body>
    <input type="text" id="txt" value="Add to checklist" />
    <div id="boxes"></div>
    <script type='text/javascript'>
    var count=0
    function makeBox(){
    var thediv=document.getElementById("boxes");
    var br = document.createElement("br");
    var box=document.createElement("input");
    box.type="checkbox"
    box.id="cb"+count;
    var label = document.createElement("label")
    label.htmlFor = box.id;
    label.className = "not-clicked"
    label.appendChild(document.createTextNode(document.getElementById("txt").value));
    addEvent(box,*'click',function(){crossedOut(box,label)});
    document.getElementById("boxes").appendChild(box);
    document.getElementById("boxes").appendChild(label);
    document.getElementById("boxes").appendChild(br);
    document.getElementById("txt").value=""
    count++
    }
    
    if (window.addEventListener)
    addEvent = function(ob, type, fn ) {
    ob.addEventListener(type, fn, false );
    };
    else if (document.attachEvent)
    addEvent = function(ob, type, fn ) {
    var eProp = type + fn;
    ob['e'+eProp] = fn;
    ob[eProp] = function(){ob['e'+eProp]( window.event );};
    ob.attachEvent( 'on'+type, ob[eProp]);
    };
    
    function submitenter(e){
    var keycode;
    if (window.event){ keycode = window.event.keyCode;}
    else if (e){ keycode = e.which;}
    else {return true;}
    
    if (keycode == 13)
       {
       makeBox();
       return false;
       }
    else
       return true;
    }
    
    function set_focus(obj){
    if (obj.value=="Add to checklist"){
    	obj.value=""
    	}
    }
    
    function crossedOut(box,label) {
    label.className=box.checked?"checked-off":"not-clicked"
    				}
    							
    addEvent(document.getElementById('txt'),'keyup',function(event){submitenter(event)});
    addEvent(document.getElementById('txt'),'focus',function(){set_focus(this)});
    </script>
    </body>
    </html>
    Last edited by xelawho; 05-26-2012 at 04:23 PM.

  • #5
    New to the CF scene
    Join Date
    May 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Well thank you again but your code doesn't work. Also the not-clicked class is meant to refer to the default text in the text field (i.e. 'Add to checklist'), not a checkbox that hasn't been checked off.

    I do understand what you mean about script in the head vs the body though so thank you for that. EDIT: My greeting function now works in the body.
    Last edited by 63charles; 05-27-2012 at 12:15 AM.

  • #6
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,883
    Thanks
    56
    Thanked 539 Times in 536 Posts
    Quote Originally Posted by 63charles View Post
    Well thank you again but your code doesn't work.
    er... what doesn't work?

    EDIT: oh, I see now - stray asterix. Sorry 'bout that. You can change that line to:
    Code:
    addEvent(box,'click',function(){crossedOut(box,label)});
    you can change the css of your text input the same way you had it originally:
    Code:
    <input type="text" id="txt" value="Add to checklist" class="not-clicked"/>
    and change the line in the crossedOut function to
    Code:
    label.className=box.checked?"checked-off":""
    Last edited by xelawho; 05-27-2012 at 12:37 AM.

  • Users who have thanked xelawho for this post:

    63charles (05-27-2012)

  • #7
    New to the CF scene
    Join Date
    May 2012
    Posts
    4
    Thanks
    2
    Thanked 0 Times in 0 Posts
    Are you testing your code? I removed the asterisk and it still doesn't work. Default text does not delete when the text field is focused and pressing enter does not create the list item.

    EDIT: Sorry, my fault. I attempted to indent your code to make it easier to read and must have made an error. Works fine with the original version. Thank you!
    Last edited by 63charles; 05-27-2012 at 02:09 AM.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •