Help save net neutrality! Learn more.
Close

javascript

Herb
2011-11-14
2013-06-03
  • Herb

    Herb - 2011-11-14

    Feeling a little dim here, but the + - icons (that should show/hide sidebar under Links, Menu, etc) do nothing.  Firefox "web console" says toggleBlock (the event handler for the img) is not defined.  A file that does contain a definition for toggleBlock, sb_javascript.js, seems to be referenced nowhere (the string does not appear in any file in the zip). 

    What am i missing?

     
  • nabber00

    nabber00 - 2011-11-15

    Right, that function doesn't work anymore.  It seems kind of pointless to me to do this without remembering across pages.  In other words, every time you select to hide a menu it comes right back on the next page load.  I've got it on the roadmap to remember the setting across page loads but haven't gotten to it yet.  Does that make sense or is the javascript only version still desired?

     
  • Herb

    Herb - 2011-11-15

    OK, makes sense.  Thanks.

     
  • Herb

    Herb - 2011-11-18

    For what it's worth, I made some changes to my local copy so the display state is remembered between "setup" and "index".  That is, if i hide "Links" and "Menu" on the Index page, and select Preferences, Links and Menu remain hidden on the Setup page.  Then if i expand "Menu", and click Submit, Links remains hidden and Menu remains expanded in the Index page.  (I stole a bit of javascript from the project site; it moves some settings to javascript variables.)

    Few changes were needed. I still need to extend them to the rest of the project (easy) and test (maybe not so easy because I'm unfamiliar wit h the project).

    In the process, I modified the javascript so there is only a single global, per Crockford's suggestion; everything else is a property of that global.

     
  • Herb

    Herb - 2011-11-18

    nabber00, in extending the +/- functionality to the categories page, I discovered a syntax error in the javascript behind the "Validate" button.  The concatenate-and-assign operator from php (.=) does not work in javascript :-), which much prefers +=.  This syntax error means the validate function does not (logically) exist (though Firefox, at least, doesn't much care, and the only consequence is that when you click the validate button, nothing happens.)

    There are a number of other changes that should probably be made to that script in order to avoid creating a lot of global variables.  I would suggest a "standard" for the project of running javascript through jslint to catch these things.  Because there are a lot of options that go along with jslint, the "standard" should include how those options should be set.

    What do you think?

     
  • nabber00

    nabber00 - 2011-11-19

    I'm glad you've got something working!  I'd be happy to include your code back into the project when you think it is ready.

    Sorry, what "Validate" button are you talking about?

    I'm not really a Javascript guy so I don't have any plans to make major changes or additions to the Javascript parts, unless its some kind of easy third party addon like for the editor.  In fact I have an open bug that is going to require removing some.  jslint certainly sounds like a good idea if Javascript development picks up though.

     
  • Herb

    Herb - 2011-11-19

    There are two buttons on the "Categories" page - "Validate" and "Submit".  Clicking Validate is supposed to run the category list through some javascript to be sure it is well-formed.   I don't recall, but the "submit" button may try to do the same thing before shipping out the form content.

     
  • nabber00

    nabber00 - 2011-11-19

    Ah OK, I haven't touched that code.  I can fix the javascript bug quick if the fix is really that simple.  I think the proper behavior is to do that check on the server side anyway when submit happens.

     
  • nabber00

    nabber00 - 2011-11-20

    I just checked in a fix for this.  Also the substring method wasn't being used correctly.

     
  • Herb

    Herb - 2011-11-27

    There are several ways to fix the problem.  One is to preserve a "state descriptor" string by putting it in window.name, the only javascript-accessible object that persists even as the URL displayed by the browser window changes.  The other is to send the descriptor back to the server (and there are several ways to implement this).  I used the first, replacing the get/set/find cookie functions with functions of the same name that put the "cookie" in window.name.

    There is another "issue" (too strong a word), and that is that the js creates an awful lot of global variables.  The trick to avoid this is to create a single global object, e.g., sb_javascript = {}; and then put functions in the object, e.g.,
    sb_javascript.getCookie = function(cookieName) {…}.  Otherwise, if you try to incorporate someone else's javascript package in the project, you're liable to run into collisions and mysterious bugs.  I did not do this with the js I wrote here because I wanted to minimize changes.  One thing at a time…

    If there is a way to upload code other than putting it in this box, let me know.  Here are the new cookie functions (which go in javascript.js):
    findCookie = function(cookieName) {
            var first, last
            first = window.name.indexOf(cookieName + "=");
            if (first < 0) return ;                                                                //name not found - internal error or initial state
            if (window.name.length < first+cookieName.length+1) return ;   //not long enough for ; - internal error
            last = (window.name.indexOf(";",first+cookieName.length+1))
            if (last < 0)  return;  
            return last < 0?  : ;
       }
      
       getCookie = function(cookieName) {
       // return comma-delimited string identified by cookieName.  Omit preceeding "=" and trailing ";".
            var loc = findCookie(cookieName);
            return (loc < 0 || loc < 0 ?"" :  window.name.substring(loc+cookieName.length + 1,loc));
        }
       
      setCookie = function(cookieName, cookieValue) {
      // replace substring identified by cookieName with cookieValue (or append NAME=VALUE;)
        if (cookieValue.indexOf("=")  >= 0) return 0;   //internal error; value must not contain "=" or ";"
        if (cookieValue.indexOf(";") >=0 ) return 0;
        var loc = findCookie(cookieName);
        // loc points to the first char of cookieName in window.name; loc points to the ;
        if (loc < 0 ) {
        //Name not found; append NAME=VALUE;
            window.name = window.name + cookieName + "=" + cookieValue + ";";
            return 1;
            }
         //Name found; replace existing value string in window.name:
         if (loc === 0) {
         // cookie is first item in window.name
            if (loc === window.name.length-1) {
                window.name = cookieName + "=" + cookieValue +  ";";   //cookie is first and only item in window.name.
                } else {
                // other stuff follows this cookie in window.name:
                window.name = cookieName + "=" + cookieValue +  ";" + window.name.substring(loc+1,window.name.length);
                }
            } else {
                if (loc === window.name.length-1) {
                //Other stuff preceeds this cookie, and this cookie is the last string in window.name:
                    window.name = window.name.substring(0,loc) + cookieName + "=" + cookieValue +  ";" ;
                    } else {
                    // this cookie is somewhere in the middle:
                    window.name = window.name.substring(0,loc) + cookieName + "=" + cookieValue + ";" + window.name.substring(loc +1,window.name.length);
                    }
               }  
         return 1;
            }

    Next I modified get_init_code (in sb_formatting.php) by adding a global $theme_vars at the top of the function, and then
    this, just before //Theme Style Sheet.  (Obviously, this defines  two new keys for the template, {CONTENT_WIDTH} and {MENU_WIDTH})
    //HJM
    $aList = array('content_width','menu_width');
            foreach ($aList as $key) {
                $tplKey = "{" . strtoupper($key) . "}";
                if (isset($theme_vars)){
                    $page_template->setTag($tplKey,$theme_vars);
                    } else {
                    $page_template->setTag($tplKey,0);
                    }
                }
            // end HJM

    Thirdly, restore some variables for javascript's use by adding this to index.tpl, just above {JAVASCRIPT}.  (I think the only one really needed is (img):
       <script type="text/javascript">
    //  Some of these settings (I'm not sure which, but one is 'img_path') are needed for show/hide code.
        blogSettings = ;
        blogSettings = '{BLOG_THEME}';
        blogSettings = 'themes/{BLOG_THEME}/images/';
        blogSettings = {CONTENT_WIDTH} ;
        blogSettings = {MENU_WIDTH} ;
        </script>
    <script src="scripts/sb_javascript.js" ></script>

    Finally, for test purposes, you can put this code in a "themes.php" copy, just after it creates the "maincontent" div:
    You can check the actual content of windows.name - that is, the 'cookies' - with this code (immediately after the maincontent div in themes.php):
    <button type="button" onClick="var txt=''; for(var i=0; i<window.name.length; i=i+50) {
                        txt = txt + window.name.substring(i,i+50) + '\n';}
                        alert('window.name.length is ' + window.name.length + '\nwindow.name is ' + txt);">
                                                         Window.name</button>this is in themes.php<br />

     

Log in to post a comment.