SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Member
    Join Date
    Feb 2010
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question innerHTML resets forms; any alternatives?

    Hello,

    I'm eager for an answer to this issue, so I'm afraid I've skipped the Introductions forum. (I hope I haven't stepped on any toes by doing so!)

    My Program
    I'm working on a website that uses the Devanagari writing system (i.e. देवनागरी) extensively. Realizing that not everybody can read this font, I decided to write a transliterator for my site. When the value of a 'select' menu changes, all of the Devanagari is replaced with another writing system (I'll using "writing system" to avoid confusion with "script").

    The Implementation
    I select all of the text in the body of the document with document.body.innerHTML and iterate through it character by character.

    HTML Code:
    <html>
       <head>
          <title>Test</title>
          <script type="text/javascript" src="script.js">
          </script>
       </head>
       <body>
       
       <p>संस्कृत</p>
    
          <label>Dummy menu</label>
          <select>
             <option>Apples</option>
             <option>Broccoli</option>
             <option>Cereal</option>
          </select>   
          <label>Script:</label>
          <select onchange="Transliterate( this )">
             <option>Default</option>
             <option value="s1">Script 1</option>
             <option value="s2">Script 2</option>
          </select>
       </body>
    </html>
    Code:
    var backup = false;
    var OLD;
    
    var writingSystem1 = new Array(
       "अ", "आ", "इ", "ई", "उ", "ऊ",
       "ऋ", "ॠ", "ए", "ऐ", "ओ", "औ",
       "ा", "ि", "ी", "ु", "ू", "ृ", "ॄ",
       "े", "ै", "ो", "ौ", "ं", "ः", "्",
       "क", "ख", "ग", "घ", "ङ",
       "च", "छ", "ज", "झ", "ञ",
       "ट", "ठ", "ड", "ढ", "ण",
       "त", "थ", "द", "ध", "न",
       "प", "फ", "ब", "भ", "म",
       "य", "र", "ल", "व",
       "श", "ष", "स", "ह",
       "ॐ", "ऽ"
    );
    var writingSystem2 = new Array(
       "ಅ", "ಆ", "ಇ", "ಈ", "ಉ", "ಊ",
       "ಋ", "ೠ", "ಎ", "ಐ", "ಒ", "ಔ",
       "ಾ", "ಿ", "ೀ", "ು", "ೂ", "ೃ",   "ೄ",
       "ೆ", "ೈ", "ೊ", "ೌ", "ಂ", "ಃ", "್",
       "ಕ", "ಖ", "ಗ", "ಘ", "ಙ",
       "ಚ", "ಛ", "ಜ", "ಝ", "ಞ",
       "ಟ", "ಠ", "ಡ", "ಢ", "ಣ",
       "ತ", "ಥ", "ದ", "ಧ", "ನ",
       "ಪ", "ಫ", "ಬ", "ಭ", "ಮ",
       "ಯ", "ರ", "ಲ", "ವ",
       "ಶ", "ಷ", "ಸ", "ಹ",
       "ಓಂ", "ಽ"
    );
    
    var toScriptTwo = {};
    for (var i = 0; i < writingSystem1.length; i++) {
       toScriptTwo[writingSystem1[i]] = writingSystem2[i];
    }
    function setBackup() {
       backup = true;
       OLD = document.body.innerHTML;
    }
    function Swap(map) {
       if (!backup) setBackup();
       var newHTML = "";
       for (var i = 0, oldL; oldL = OLD[i]; i++) {
          if (map.hasOwnProperty(oldL)) {
             newHTML += map[oldL]; 
          } else {
             newHTML += oldL;
          }
       }
       return newHTML;
    }
    function Transliterate(elem) {
       var value = elem.options[elem.selectedIndex].value;
       if (value == "s1") {
          document.body.innerHTML = Swap(toScriptTwo);
       }
       else if (backup && value == "s2") {
             document.body.innerHTML = OLD;
       }
    }
    The Problem
    The writing system gets changed correctly; that's not the issue. The issue is that all of the forms on the page are reset to their default value.

    While looking for an answer, I came to understand that this is how innerHTML always works: all forms and fields are reset, since it does a "dumb replace" of these features and ignores their content. Many sites suggested that I use more standard DOM-related functions.

    But my problem with these functions is that they focus exclusively on elements and their hierarchy, whereas I just want to iterate through the text and transliterate. More explicitly: other users seemed to have problems with creating or inserting elements, but I want to do neither, so I don't know if a DOM-related approach is best.

    Moreover, I want this function to be fast. Right now, it can transliterate 200 lines of Devanagari in about half a second.

    My Question
    Is there a reasonable way to (1) transliterate quickly and (2) retain all form data?

    Thanks for reading!
    Last edited by transliterate; Feb 12, 2010 at 00:27. Reason: fixed a syntax error

  2. #2
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,280
    Mentioned
    51 Post(s)
    Tagged
    2 Thread(s)
    Hm, gosh, I'm trying to think of a page that changes languages and doesn't reset the forms... Do people change values and then decide to switch scripts? Or is it also resetting your language-selector form itself?

  3. #3
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,718
    Mentioned
    103 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by transliterate View Post
    My Question
    Is there a reasonable way to (1) transliterate quickly and (2) retain all form data?

    Thanks for reading!
    You can retain all of the form data by copying the elements property of each form.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  4. #4
    SitePoint Member
    Join Date
    Feb 2010
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    Hm, gosh, I'm trying to think of a page that changes languages and doesn't reset the forms... Do people change values and then decide to switch scripts? Or is it also resetting your language-selector form itself?
    The program would reset all forms, including the language select form. To fix that, I first put all of my page content in a separate div:

    HTML Code:
    <html>
       <head>
       <title>Test</title>
       </head>
       <body>
          <div id="content">
             <!-- content -->
          </div>
          <div id="footer">
             <select>
                <!-- the select menu-->
             </select>
          </div>
       </body>
    </html>
    and then modified my Javascript to use "document.getElementById('content')". The problem, then, was that any forms in the "content" div would be reset.

    Quote Originally Posted by pmw57 View Post
    You can retain all of the form data by copying the elements property of each form.
    Shucks, I was hoping I wouldn't have to do that. But if I want to keep the speed of innerHTML, it seems like I don't have much choice about it.

    Thanks for your replies, you guys! I think I'll add support for copying form data.

  5. #5
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,840
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Why not save the form content, run the innerHTML, then restore the form content
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  6. #6
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2008
    Posts
    5,757
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    gogo dom level 2
    Code:
    var treeWalker = document.createTreeWalker(
        document.firstChild,
        NodeFilter.SHOW_TEXT,
        { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } },
        false
    );
    
    
    
    while(treeWalker.nextNode()) {
        treeWalker.currentNode.nodeValue = translitToUpperCase(treeWalker.currentNode.nodeValue);
    }
    
    
    function translitToUpperCase(txt) {
        return txt.toUpperCase();
    }
    Seems to work, I just pasted this into the browser address bar on a few web pages
    Code:
    javascript:(function(){var treeWalker=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,{acceptNode:function(node){return NodeFilter.FILTER_ACCEPT;}},false);while(treeWalker.nextNode()){treeWalker.currentNode.nodeValue=translitToUpperCase(treeWalker.currentNode.nodeValue);}function translitToUpperCase(txt){return txt.toUpperCase();}})()


Tags for this Thread

Bookmarks

Posting Permissions

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