www.webdeveloper.com
Results 1 to 15 of 15

Thread: [RESOLVED] School help Editable text !

  1. #1
    Join Date
    Oct 2012
    Posts
    18

    resolved [RESOLVED] School help Editable text !

    My assignment is to make all p class="fan" editable, with a save button and a cancel button. I am only allowed to use Javascript.

    I have read all the schoolbooks and searched the internet for hours. I made a few attemps but they... well they failed hard. Could someone just point me in the right direction pls ....

  2. #2
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    750
    Eh, this code is a little messier than I would have liked but it gets the job done on a basic level.
    Code:
    <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', _SetEdits, false);
    
    function _SetEdits() {
      for($i = 0 ; $i < document.getElementsByClassName('fan').length ; $i++) {
        document.getElementsByClassName('fan')[$i].addEventListener('click', function(){_EditMe(this)}, false);
      }
    }
    
    var $fanObj;
    var $oldTxt = "";
    var $activeEdit = false;
    function _EditMe($obj) {
      if($activeEdit == false) {
        $activeEdit = true;
        _CancelEdit();
        $fanObj = $obj;
        $oldTxt = $obj.innerHTML;
        $obj.innerHTML = '<input id="editFan" type="text" value="' + $oldTxt + '" /><br /><input type="button" 
    
    value="Save" onclick="_SaveEdit()" /><input type="button" value="Cancel" onclick="_CancelEdit()" />';
      }
    }
    function _SaveEdit() {
      $fanObj.innerHTML = document.getElementById('editFan').value;
      $oldTxt = "";
      setTimeout(function(){$activeEdit = false;}, 100);
    }
    function _CancelEdit() {
      if($oldTxt != "") {
        $fanObj.innerHTML = $oldTxt;
        $oldTxt = "";
        setTimeout(function(){$activeEdit = false;}, 100);
      }
    }
    </script>
    It will find all elements with the class name "fan" and set them so that when you click on them you can edit the contents and then either save or cancel. To be fair I guess I didn't make it exclusive to <p> elements with the class name "fan" so if that's necessary one additional check would need to be in place. I should also point out that '.getElementsByClassName()' is only supported in IE versions 9 and higher which means if this needs to work in IE8 or below that area of the code would need to be rescripted to grab all <p> elements and then filter them out by class name through a loop.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  3. #3
    Join Date
    Oct 2012
    Posts
    18
    Thx for the answer mate. Correct me if im wrong, this is Jquery right ? I havent started that course yet :P

  4. #4
    Join Date
    Oct 2012
    Posts
    18
    This is what i have come up with. Renamed class to "editable". Problem now is that i have only made it possible to create the Save button, and once i saved i cant edit the text again and i cant to find how to resize the editscreen.

    HTML Code:
    window.onload = function  () {
    	
    	var p_array = document.getElementsByTagName("p"); 						
    	
    	for (var counter=0; counter<p_array.length; counter++){					
    		if (p_array[counter].getAttribute("class") == "editable"){				
    			p_array[counter].onclick = fixa;			
    		} 
    	} 
    
    
    	
    var editing  = false;
    
    if (document.getElementById && document.createElement) {
    	var butt = document.createElement('BUTTON');
    	var buttext = document.createTextNode('Save!');
    	butt.appendChild(buttext);
    	butt.onclick = saveEdit;
    }
    
    
    function fixa(e) {
    	if (editing) return;
    	if (!document.getElementById || !document.createElement) return;
    	var obj = e.target;
    	while (obj.nodeType != 1) {
    		obj = obj.parentNode;
    	}
    	if (obj.tagName == 'textarea' || obj.tagName == 'A') return;
    	while (obj.nodeName != 'P' && obj.nodeName != 'HTML') {
    		obj = obj.parentNode;
    	}
    	if (obj.nodeName == 'HTML') return;
    	var x = obj.innerHTML;
    	var y = document.createElement('textarea');
    	var z = obj.parentNode;
    	var o = document.getElementsByTagName('textarea');
    	z.insertBefore(y,obj);
    	z.insertBefore(butt,obj);
    	z.removeChild(obj);
    	y.value = x;
    	y.focus();
    	editing = true;
    }
    
    function saveEdit() {
    	var area = document.getElementsByTagName('textarea')[0];
    	var y = document.createElement('P');
    	var z = area.parentNode;
    	y.innerHTML = area.value;
    	z.insertBefore(y,area);
    	z.removeChild(area);
    	z.removeChild(document.getElementsByTagName('button')[0]);
    	editing = false;
    }
    
    
    
    
    	} 
    
    	
    
    
    
    
    

  5. #5
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    750
    Firstly, my original code was just regular javascript, no jquery used. Secondly, there are two things you need to add to your code to correct your issue with only being able to edit once.

    When you recreate the <p> element to fill it will the edited text, you don't set the class of this new element to 'editable'. So you'd need to add a line to your saveEdit() function:
    Code:
    y.className = "editable";
    The second thing would be that you need to set the onclick event for this element so that it will change to the edit controls when clicked. To be fair, you wouldn't actually need to set the class with the code above if you just directly set the onclick event. The class itself really only applies during the loading of the page when your script scans for <p> elements with the class 'editable', but after that the class wouldn't be needed.
    Code:
    y.onclick = fixa;
    As far as a cancel button goes, you would probably want to store the original innerHTML in a global variable so you can recall this later in a cancelEdit() function. It would work similar to your saveEdit() function, however you would be using your global variable to set the innerHTML instead of the textarea's value.

    Lastly, I'm not sure what you mean in regard to not being able to resize the edit screen. The textarea itself is resizable by the user and you can also set the style.width or style.height in your script if you want to have it initially be a set size. Which also reminds me that if you are going to use a textarea for the editing of those <p> elements, you should probably include a .replace() line in your code to deal with line breaks. HTML code is added to the page as well so perhaps you may want to encode the string to avoid any issues with that.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  6. #6
    Join Date
    Oct 2012
    Posts
    18
    Thank you sensei, I shall do my best

    I tried the code u gave me before, but there was a erroer at line 19 i couldnt figure out
    Last edited by Vraith11; 11-16-2012 at 02:22 PM.

  7. #7
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    750
    My original code might error if you just copy and paste directly. As annoying as it is, sometimes copying and pasting longer lines of code tends to get broken up, thus you have a line of code that has extra breaks in it, giving you incomplete lines of code. I'll edit that really quickly to fix the issue I saw with that and just make sure you check any time you copy and paste code that there are no unnecessary breaks in the middle of any lines of code.

    [EDIT]
    Nevermind, it turns out I can't edit the post after a certain amount of time. Well here's a repaste of the code with that line break issue fixed.
    Code:
    <script type="text/javascript">
    document.addEventListener('DOMContentLoaded', _SetEdits, false);
    
    function _SetEdits() {
      for($i = 0 ; $i < document.getElementsByClassName('fan').length ; $i++) {
        document.getElementsByClassName('fan')[$i].addEventListener('click', function(){_EditMe(this)}, false);
      }
    }
    
    var $fanObj;
    var $oldTxt = "";
    var $activeEdit = false;
    function _EditMe($obj) {
      if($activeEdit == false) {
        $activeEdit = true;
        _CancelEdit();
        $fanObj = $obj;
        $oldTxt = $obj.innerHTML;
        $obj.innerHTML = '<input id="editFan" type="text" value="' + $oldTxt + '" /><br /><input type="button" value="Save" onclick="_SaveEdit()" /><input type="button" value="Cancel" onclick="_CancelEdit()" />';
      }
    }
    function _SaveEdit() {
      $fanObj.innerHTML = document.getElementById('editFan').value;
      $oldTxt = "";
      setTimeout(function(){$activeEdit = false;}, 100);
    }
    function _CancelEdit() {
      if($oldTxt != "") {
        $fanObj.innerHTML = $oldTxt;
        $oldTxt = "";
        setTimeout(function(){$activeEdit = false;}, 100);
      }
    }
    </script>
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  8. #8
    Join Date
    Oct 2012
    Posts
    18
    Anyway to make this to a "textarea" box ? Yeah i know, im a noob when it comes to Javascript. Learned more from you then my teacher thou

    HTML Code:
    document.addEventListener('DOMContentLoaded', SetEdit, false);
    
    function SetEdit() {
      for(i = 0 ; i < document.getElementsByClassName('editable').length ; i++) {
        document.getElementsByClassName('editable')[i].addEventListener('click', function(){EditMe(this)}, false);
    	
      }
    }
    
    
    var editableObj;
    var oldTxt = "";
    var activeEdit = false;
    function EditMe(obj) {
      if(activeEdit == false) {
        activeEdit = true;
        CancelEdit();
        editableObj = obj;
        oldTxt = obj.innerHTML;
        obj.innerHTML = '<input id="editEditable" style="width:750px;" type="text" value="' + oldTxt + '" /><br /><input type="button" value="Save" onclick="SaveEdit()" /><input type="button" value="Cancel" onclick="CancelEdit()" />';
      }
    }
    function SaveEdit() {
      editableObj.innerHTML = document.getElementById('editEditable').value;
      oldTxt = "";
      setTimeout(function(){activeEdit = false;}, 100);
    }
    function CancelEdit() {
      if(oldTxt != "") {
        editableObj.innerHTML = oldTxt;
        oldTxt = "";
        setTimeout(function(){activeEdit = false;}, 100);
      }
    }
    
    

  9. #9
    Join Date
    May 2004
    Location
    Manhattan NY
    Posts
    6,028
    When you say "a save button" do you mean just for that page load, or subsequent page loads as well? Because if it's the latter, it requires either local storage or a cookie, if only JavaScript is to be used.

  10. #10
    Join Date
    May 2004
    Location
    Manhattan NY
    Posts
    6,028
    If this is a beginner course, the code above might draw suspicion that you didn't do it yourself. Here's a very simplistic working example I just whipped up


    <!DOCTYPE html>


    <head>


    <script>
    window.onload = function() {
    document.getElementsByTagName("button")[0].onclick = function() {
    document.getElementsByTagName("div")[0].style.display = "none";
    document.getElementsByTagName("textarea")[0].style.display = "block";
    }



    document.getElementsByTagName("button")[1].onclick = function() {
    document.getElementsByTagName("div")[0].innerHTML = document.getElementsByTagName("textarea")[0].value;
    document.getElementsByTagName("textarea")[0].style.display = "none";
    document.getElementsByTagName("div")[0].style.display = "block";
    }
    }
    </script>


    <style>
    textarea { display: none; width: 500px; height: 300px; }

    div { width: 500px; height: 300px; }

    </style>


    </head>

    <body>
    <div>
    default text...


    </div>
    <textarea></textarea>

    <button>Edit</button><button>Save</button>
    </body>
    </html>
    Last edited by JPnyc; 11-17-2012 at 08:54 AM.

  11. #11
    Join Date
    Oct 2012
    Posts
    18
    its not a beginner course, even thou i started JC 2 weeks ago . I had no problem figuring out canvas and other jc related stuff, i just cant get the hang on DOM tree functions.

    Thx for the reply friend, but I am not allowed to change the html or css. Just pure JC

  12. #12
    Join Date
    May 2004
    Location
    Manhattan NY
    Posts
    6,028
    Did you post the HTML somewhere, because I didn't see it. Also, what browsers must it work in? I assume the p's have to be editable one at a time, yes, and onclick of some element?

  13. #13
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    750
    Quote Originally Posted by Vraith11 View Post
    Anyway to make this to a "textarea" box ? Yeah i know, im a noob when it comes to Javascript. Learned more from you then my teacher thou
    Well, to simply change the text box to a textarea you would just substitute the <input> tag in the _EditMe() function. But as I mentioned before if you are using a textarea for the editing then you will need to consider line breaks using the .replace() method in javascript.
    Code:
    document.addEventListener('DOMContentLoaded', _SetEdits, false);
    
    function _SetEdits() {
      for($i = 0 ; $i < document.getElementsByClassName('editable').length ; $i++) {
        document.getElementsByClassName('editable')[$i].addEventListener('click', function(){_EditMe(this)}, false);
      }
    }
    
    var $fanObj;
    var $oldTxt = "";
    var $activeEdit = false;
    function _EditMe($obj) {
      if($activeEdit == false) {
        $activeEdit = true;
        _CancelEdit();
        $fanObj = $obj;
        $oldTxt = $obj.innerHTML.replace(/<br>/g, "\n");
        $obj.innerHTML = '<textarea id="editFan" type="text" style="width: 300px; height: 80px;">' + $oldTxt + '</textarea><br /><input type="button" value="Save" onclick="_SaveEdit()" /><input type="button" value="Cancel" onclick="_CancelEdit()" />';
      }
    }
    function _SaveEdit() {
      $fanObj.innerHTML = document.getElementById('editFan').value.replace(/\n/g, "<br />");
      $oldTxt = "";
      setTimeout(function(){$activeEdit = false;}, 100);
    }
    function _CancelEdit() {
      if($oldTxt != "") {
        $fanObj.innerHTML = $oldTxt;
        $oldTxt = "";
        setTimeout(function(){$activeEdit = false;}, 100);
      }
    }
    I suppose I should also explain the code so that you actually know what it does and why it works, rather than just having an answer.

    The first thing in the script is an event listener being added to the page that waits for the page to load all of its content. When this event is triggered then the _SetEdits() function finds all elements with your 'editable' class and binds a function to their onclick event called _EditMe().

    The final 3 functions work on a pretty simple logic. _EditMe() runs a simple check to see if $activeEdit is true or false (I'll explain why later). Then it will set $activeEdit and run _CancelEdit() to make sure any other edits do not interfere (just a precaution for special cases that could occur). Next it sets a global variables to hold the <p> object you are editing and its text. The last step replaces the <p> elements content with a simple edit interface, containing a text area and 2 buttons to save or cancel.
    _SaveEdit() will simple take the textareas content, replace any line breaks with the proper HTML and put it inside of your <p> element (using our global variables). It will then reset our global content variable and $activeEdit (to allow another element to be edited).
    _CancelEdit() first checks to make sure our global content variable $oldTxt has a value and if so, it will place this content back in to our <p> element, resetting it to its previous value and removing our edit interface. It also then resets the global content variable and $activeEdit to allow editing of another element.

    The reason for $activeEdit due to the fact that our <p> element has an onclick event set and so when you click either the save or cancel button, it will also trigger the onclick event of their parent element, the <p> element. So to prevent an endless loop of _EditMe() being triggered, the $activeEdit variable prevents this from happening until the script says its okay. setTimeout() waits 100 milliseconds before allowing another edit; the time could be changed but it's simply just allowing the onclick event of the <p> element to fire, see that $activeEdit is not allowed before changing $activeEdit.
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

  14. #14
    Join Date
    Oct 2012
    Posts
    18
    First of all i wanna say that thank you. I have read 2 books ( some chapters many times ) , the diffrence between you and those books is I understand what you are telling, althou I will read what you have written probably 30 times so it really sticks in my head. If ure webcarierr wont work out, you will make a hell of a teacher. Thank you so much.

    p.s. why the dollar sign everywhere? Works great without it . Thank you again
    Last edited by Vraith11; 11-17-2012 at 03:16 PM.

  15. #15
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    750
    Every coder has their own methods and preferences in how they format their code. For instance, the whole "tabs vs spaces" thing is a common thing different coders have opinions on.

    For me, I like to try and declare my variables with dollar signs in front, mainly beacuse it helps me transition between javascript and PHP more easily. I also like to declare functions with an underscore "_" so that I don't ever get a function name confused with anything else.

    These things aren't needed, and really it all comes down to what you like best. In the end your code must be readable and understandable by you of all people (though it's nice to be able to make sure others can understand it as well).
    "Given billions of tries, could a spilled bottle of ink ever fall into the words of Shakespeare?"

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

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



Recent Articles