Script doesn't work in Safari

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • elektrophyte

    Script doesn't work in Safari

    I've got a short script that works fine in I.E. and Firefox, but not in
    Safari. It is supposed to print a constantly-updating counter on the
    webpage. Any ideas how to get it to work in Safari? The script uses the
    Date object, especially Date.getTime(). Could that have something to do
    with the problem?

    Thanks,

    E


    // This <form> is put into the same HTML page as the script...
    <form name="counter" style="margin: 0; padding: 0;">
    <input type="text" name="amount" value="0" size="40" readonly="true"
    style="margin:0 ;padding:0;bord er:none;font-size:24px;color :#cc0000;">
    </form>

    // Here is the script...
    <script type="text/javascript">

    // The formatNumber function comes from Danny Goodman's JavaScript
    Cookbook.
    [ ... some code left out here for brevity ... ]

    var startingDate = new Date(2005, 0, 1);
    var startingDebt = 1000000000;
    function updateCounter() {
    var nowDate = new Date();
    var debtTimeInSecon ds = (nowDate.getTim e() -
    startingDate.ge tTime())/1000;
    var newValue = startingDebt + (debtTimeInSeco nds * 3.47);
    document.counte r.amount.value = "$" + formatNumber(ne wValue, 2);
    }
    updateCounter() ;
    intervalID = setInterval("up dateCounter()", 1000);
    </script>

  • RobG

    #2
    Re: Script doesn't work in Safari

    elektrophyte wrote:[color=blue]
    > I've got a short script that works fine in I.E. and Firefox, but not in
    > Safari. It is supposed to print a constantly-updating counter on the
    > webpage. Any ideas how to get it to work in Safari? The script uses the
    > Date object, especially Date.getTime(). Could that have something to do
    > with the problem?
    >
    > Thanks,
    >
    > E
    >
    >
    > // This <form> is put into the same HTML page as the script...
    > <form name="counter" style="margin: 0; padding: 0;">
    > <input type="text" name="amount" value="0" size="40" readonly="true"
    > style="margin:0 ;padding:0;bord er:none;font-size:24px;color :#cc0000;">
    > </form>
    >
    > // Here is the script...
    > <script type="text/javascript">
    >
    > // The formatNumber function comes from Danny Goodman's JavaScript
    > Cookbook.
    > [ ... some code left out here for brevity ... ]
    >
    > var startingDate = new Date(2005, 0, 1);
    > var startingDebt = 1000000000;
    > function updateCounter() {
    > var nowDate = new Date();
    > var debtTimeInSecon ds = (nowDate.getTim e() -
    > startingDate.ge tTime())/1000;[/color]

    Manually wrap posted code at about 70 characters, allowing
    auto-wrapping can cause problems and with space indents not tabs.

    You also don't need the 'getTime()' method:

    var debtTimeInSecon ds = (nowDate - startingDate)/1000;

    [color=blue]
    > var newValue = startingDebt + (debtTimeInSeco nds * 3.47);
    > document.counte r.amount.value = "$" + formatNumber(ne wValue, 2);
    > }
    > updateCounter() ;
    > intervalID = setInterval("up dateCounter()", 1000);
    > </script>
    >[/color]

    It works fine in Safari 1.0.3 as far as I can tell if you remove the
    'formatNumber() ' function. Post it for a fix.


    --
    RobG

    Comment

    • RobG

      #3
      Re: Script doesn't work in Safari

      RobG wrote:[color=blue]
      > elektrophyte wrote:
      >[/color]
      [...][color=blue]
      >
      > It works fine in Safari 1.0.3 as far as I can tell if you remove the
      > 'formatNumber() ' function. Post it for a fix.[/color]

      A little more playing shows that the debit in cents seems to exceed the
      size of integer that Safari can handle. I'll guess that the Danny
      Goodman's function converts the amount to cents and uses Math.floor (or
      round maybe) to truncate the decimal cents.

      Here's a version of the script that uses a modified version of Dr J R
      Stockton's 'TryCash()' function (which originally was based on cents
      but I've modified it to use decimal currency). Lightly tested (Firefox
      & Safari on OS X):


      <script type="text/javascript">

      var startingDate = new Date(2005,0,1);
      var startingDebt = 1000000000;

      function updateCounter() {
      var nowDate = new Date();
      var debtTimeInSecon ds = (nowDate - startingDate)/1000;
      var newValue = startingDebt + (debtTimeInSeco nds * 3.47);
      document.counte r.amount.value = TryCash(newValu e + ' $ , .');
      }
      updateCounter() ;
      intervalID = setInterval("up dateCounter()", 1000);

      function toCash(p, c, t, d) {
      var s = (0 > p)? "-" : "";
      p = p.split('.');
      var m = String(Math.abs (p[0]));
      var j, k = "", f;
      c = c || "";
      t = t || "";
      d = d || ".";
      while (m.length < 3) {
      m = "0"+m;
      }
      f = (p[1])? twoDigits(p[1]) : '00';
      j = m.length;
      while (j > 3) {
      k = t+m.substring(j-3, j)+k;
      j -= 3;
      }
      k = m.substring(0, j)+k;
      return s+c+k+d+f;
      }

      function TryCash(S) {
      var T = S.split(/\s+/);
      return toCash(T[0], T[1], T[2], T[3]);
      }

      function twoDigits(x){
      return (x.length < 2)? x+'0' : x.substring(0,2 );
      }

      </script>





      --
      RobG

      Comment

      • Dr John Stockton

        #4
        Re: Script doesn't work in Safari

        JRS: In article <428e9d89$0$956 $5a62ac22@per-qv1-newsreader-
        01.iinet.net.au >, dated Sat, 21 May 2005 12:31:32, seen in
        news:comp.lang. javascript, RobG <rgqld@iinet.ne t.auau> posted :[color=blue]
        >RobG wrote:[color=green]
        >> elektrophyte wrote:
        >>[/color]
        >[...][color=green]
        >>
        >> It works fine in Safari 1.0.3 as far as I can tell if you remove the
        >> 'formatNumber() ' function. Post it for a fix.[/color]
        >
        > A little more playing shows that the debit in cents seems to exceed the
        > size of integer that Safari can handle.
        > ...[/color]

        Which is?

        Does Safari actually have a distinct integer type?

        Is it just that Math.floor .ceil .round use Int32 internally (so that
        they may have the mechanism for returning larger numbers, but never
        generate them)?

        AFAIR, according to spec, the only things that should be limited to
        Int32 are the seven operators ~ & | ^ << >> >>> and their assignment
        forms.

        ~~X appears to truncate X towards zero and do a signed modulo
        2^32 on it. There must be a use for that.

        --
        © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
        <URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
        <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
        <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

        Comment

        • elektrophyte

          #5
          Re: Script doesn't work in Safari

          Thank you very much for the replies. As suggested I removed the
          getTime() and formatNumber() calls and now it works in Safari. Now I
          just need to debug formatNumber(). I got it from Danny Goodman's
          JavaScript Cookbook (Oreilly). Maybe I'll just try to write my own
          function to format the number. In case anyone is curious, I'll add
          Goodman's code below.

          // The formatNumber function comes from Danny Goodman's
          // JavaScript Cookbook.
          function formatNumber (num, decplaces) {
          // convert in case it arrives as a string value
          num = parseFloat(num) ;
          // make sure it passes conversion
          if (!isNaN(num)) {
          // multiply value by 10 to the decplaces power;
          // round the result to the nearest integer;
          // convert the result to a string
          var str = "" + Math.round (eval(num) *
          Math.pow(10,dec places));
          // exponent means value is too big or small
          // for this routine
          if (str.indexOf("e ") != -1) {
          return "Out of Range";
          }
          // if needed for small values, pad zeros
          // to the left of the number
          while (str.length <= decplaces) {
          str = "0" + str;
          }
          // calculate decimal point position
          var decpoint = str.length - decplaces;
          // assemble final result from: (a) the string
          // up to the position of
          // the decimal point; (b) the decimal point;
          // and (c) the balance
          // of the string. Return finished product.
          return str.substring(0 ,decpoint) + "." +
          str.substring(d ecpoint,str.len gth);
          } else {
          return "NaN";
          }
          }

          Comment

          • RobG

            #6
            Re: Script doesn't work in Safari

            elektrophyte wrote:[color=blue]
            > Thank you very much for the replies. As suggested I removed the
            > getTime() and formatNumber() calls and now it works in Safari. Now I
            > just need to debug formatNumber(). I got it from Danny Goodman's
            > JavaScript Cookbook (Oreilly). Maybe I'll just try to write my own
            > function to format the number. In case anyone is curious, I'll add
            > Goodman's code below.
            >[/color]

            Here's another that can handle any precision and adds commas. Remove
            validation and comments and it's only marginally longer that DG's.


            function formatDecimal(n , d) {
            // Is n digit(s) with optional point or optional point and digit(s)
            if ( !/^(\d+)[\.|(\.\d+)]*$/.test(n) ) {
            return "Number part should be format 0 or 0.0";
            }

            // Is d an int?
            if ( !/^(\d+)[\.|(\.0+)]*$/.test(d) ) {
            return "Number of decimal places must be an integer";
            }

            // nd is number of digits before zero
            var nd = (n + '').split('.')[0].length;

            // len is total number of digits required
            var len = +d + nd;

            // n is array of digits with decimal place removed
            n = n.replace(/\./,'').split('');

            // If there is a digit after required length, do rounding,
            var i=len, r='';

            // If last+1 digit is bigger than 4
            if ( n[i] && n[i] > 4 ){
            // While preceding number is 9 and not first
            while ( 9 == n[--i] && i > 0 ) {
            // Make it zero
            n[i] = 0;
            }
            // Add one to wherever we got to
            n[i] -= -1;
            }

            // Build up integer part
            i = 0;
            while ( i < nd ) {
            // No commas version;
            // r += '' + n[i++];

            // Commas version
            r += (( (nd-i)%3 )? '' : (0 == i)? '':',') + n[i++];
            }

            // Add decimal part
            if ( d > 0 ) {
            r += '.';
            while ( i < len ) {
            r += n[i++] || '0';
            }
            }
            return r;
            }


            --
            Rob

            Comment

            • RobG

              #7
              Re: Script doesn't work in Safari

              RobG wrote:
              [...][color=blue]
              > Here's another that can handle any precision and adds commas. Remove
              > validation and comments and it's only marginally longer that DG's.[/color]

              I should post sooner, I'd find the bugs quicker...
              [color=blue]
              >
              >
              > function formatDecimal(n , d) {
              > // Is n digit(s) with optional point or optional point and digit(s)
              > if ( !/^(\d+)[\.|(\.\d+)]*$/.test(n) ) {
              > return "Number part should be format 0 or 0.0";
              > }
              >
              > // Is d an int?
              > if ( !/^(\d+)[\.|(\.0+)]*$/.test(d) ) {
              > return "Number of decimal places must be an integer";
              > }
              >
              > // nd is number of digits before zero
              > var nd = (n + '').split('.')[0].length;
              >
              > // len is total number of digits required
              > var len = +d + nd;
              >
              > // n is array of digits with decimal place removed
              > n = n.replace(/\./,'').split('');
              >
              > // If there is a digit after required length, do rounding,
              > var i=len, r='';
              >
              > // If last+1 digit is bigger than 4
              > if ( n[i] && n[i] > 4 ){
              > // While preceding number is 9 and not first
              > while ( 9 == n[--i] && i > 0 ) {
              > // Make it zero
              > n[i] = 0;
              > }
              > // Add one to wherever we got to
              > n[i] -= -1;
              > }[/color]

              If the number is 999.9, result is 1000.0 not 1,000.0. Here's the fix:

              // Add one to wherever we got to
              n[i] -= -1;

              // Make sure it's not '10'
              if ( 10 == n[i] )
              n[i] = 0;
              n.splice(i,0,'1 ');
              }

              If the 'comma' output is not required, the fix isn't needed.

              [...]

              --
              Rob

              Comment

              • RobG

                #8
                Re: Script doesn't work in Safari

                RobG wrote:[color=blue]
                > RobG wrote:
                > [...]
                >[/color]
                [...][color=blue]
                >
                > // Make sure it's not '10'
                > if ( 10 == n[i] )
                > n[i] = 0;
                > n.splice(i,0,'1 ');
                > }
                >[/color]

                Brain-dead day:

                // Make sure it's not '10'
                if ( 10 == n[i] ) {
                n[i] = 0;
                n.splice(i,0,'1 ');
                nd++;
                }




                --
                Rob

                Comment

                • Dr John Stockton

                  #9
                  Re: Script doesn't work in Safari

                  JRS: In article <1116871406.595 639.45680@o13g2 000cwo.googlegr oups.com>,
                  dated Mon, 23 May 2005 11:03:26, seen in news:comp.lang. javascript,
                  elektrophyte <elektrophyte@y ahoo.com> posted :[color=blue]
                  >Thank you very much for the replies. As suggested I removed the
                  >getTime() and formatNumber() calls and now it works in Safari. Now I
                  >just need to debug formatNumber(). I got it from Danny Goodman's
                  >JavaScript Cookbook (Oreilly). Maybe I'll just try to write my own
                  >function to format the number.[/color]

                  That would be unwise, unless you need the practice; many have done so
                  and got it wrong. Instead, read the newsgroup FAQ.
                  [color=blue]
                  > In case anyone is curious, I'll add
                  >Goodman's code below.
                  >
                  >// The formatNumber function comes from Danny Goodman's
                  >// JavaScript Cookbook.
                  >function formatNumber (num, decplaces) {
                  > // convert in case it arrives as a string value
                  > num = parseFloat(num) ;
                  > // make sure it passes conversion
                  > if (!isNaN(num)) {
                  > // multiply value by 10 to the decplaces power;
                  > // round the result to the nearest integer;
                  > // convert the result to a string
                  > var str = "" + Math.round (eval(num) *[/color]
                  ^^^^

                  Pointless. Function parseFloat always returns a Number, even though it
                  may be NaN or an Infinity.

                  When replying, please quote, attribute & ignore Lahn :

                  Keith Thompson wrote in comp.lang.c, message ID
                  <lnwtuhfy7d.fsf @nuthaus.mib.or g> :-
                  If you want to post a followup via groups.google.c om, don't use
                  the "Reply" link at the bottom of the article. Click on "show
                  options" at the top of the article, then click on the "Reply" at
                  the bottom of the article headers.

                  --
                  © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
                  <URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
                  <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
                  <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

                  Comment

                  • Dr John Stockton

                    #10
                    Re: Script doesn't work in Safari

                    JRS: In article <08yke.1605$Zn. 80936@news.optu s.net.au>, dated Tue, 24
                    May 2005 04:33:00, seen in news:comp.lang. javascript, RobG
                    <rgqld@iinet.ne t.auau> posted :[color=blue]
                    >
                    > Here's another that can handle any precision and adds commas. Remove
                    > validation and comments and it's only marginally longer that DG's.
                    >
                    >
                    >function formatDecimal(n , d) {[/color]


                    Float arithmetic has rounding errors; therefore, a Number that ideally
                    would be zero may be slightly negative. Your routine fails with those,
                    as with genuine negatives.

                    Also, it fails with input '5e5', though it works with '550000'

                    It looks rather slow, though I've not checked.

                    I don't see why one should want a routine that treats its parameter as a
                    string; but it does work with numbers that more-numeric methods would
                    find too big.

                    --
                    © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
                    <URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
                    <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
                    <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

                    Comment

                    • RobG

                      #11
                      Re: Script doesn't work in Safari

                      Dr John Stockton wrote:[color=blue]
                      > JRS: In article <08yke.1605$Zn. 80936@news.optu s.net.au>, dated Tue, 24
                      > May 2005 04:33:00, seen in news:comp.lang. javascript, RobG
                      > <rgqld@iinet.ne t.auau> posted :
                      >[color=green]
                      >> Here's another that can handle any precision and adds commas. Remove
                      >> validation and comments and it's only marginally longer that DG's.
                      >>
                      >>
                      >>function formatDecimal(n , d) {[/color]
                      >
                      >
                      >
                      > Float arithmetic has rounding errors; therefore, a Number that ideally
                      > would be zero may be slightly negative. Your routine fails with those,
                      > as with genuine negatives.[/color]

                      Yes, but the negative part could be easily fixed.
                      [color=blue]
                      >
                      > Also, it fails with input '5e5', though it works with '550000'
                      >[/color]

                      Yes.
                      [color=blue]
                      > It looks rather slow, though I've not checked.[/color]

                      Takes about 6 times longer than toFixed(), 3 times longer than simple
                      string truncation methods.
                      [color=blue]
                      >
                      > I don't see why one should want a routine that treats its parameter as a
                      > string; but it does work with numbers that more-numeric methods would
                      > find too big.
                      >[/color]

                      'cos it's more fun than using toFixed() :-)

                      toFixed() is *the* fastest method and, in the OP's case, if it's not
                      supported, then simply truncating the decimal cents is likely perfectly
                      adequate (unless decimal cents are important in what looks like US
                      military spending or national debt).



                      --
                      Rob

                      Comment

                      • Dr John Stockton

                        #12
                        Re: Script doesn't work in Safari

                        JRS: In article <RMSke.1644$Zn. 81925@news.optu s.net.au>, dated Wed, 25
                        May 2005 04:01:53, seen in news:comp.lang. javascript, RobG
                        <rgqld@iinet.ne t.auau> posted :[color=blue]
                        >
                        > toFixed() is *the* fastest method and, in the OP's case, if it's not
                        > supported, then simply truncating the decimal cents is likely perfectly
                        > adequate (unless decimal cents are important in what looks like US
                        > military spending or national debt).[/color]

                        AIUI, when actually doing accounts, the arithmetic must be exact, and in
                        compliance with applicable rounding rules.

                        Here, BT has recently announced that, from 2005-06-17, billed VAT will
                        be rounded up, rather than down, to the nearest penny. In either case,
                        small rounding errors such as can be expected when using non-integers
                        can flip the result from one state to another, when the nominal
                        calculation gives an exact result.

                        Wasting a few billion is another matter, of course; only to be expected.

                        --
                        © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 IE 4 ©
                        <URL:http://www.jibbering.c om/faq/> JL/RC: FAQ of news:comp.lang. javascript
                        <URL:http://www.merlyn.demo n.co.uk/js-index.htm> jscr maths, dates, sources.
                        <URL:http://www.merlyn.demo n.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.

                        Comment

                        • Thomas 'PointedEars' Lahn

                          #13
                          Re: Script doesn't work in Safari

                          elektrophyte wrote:
                          [color=blue]
                          > [...]
                          > // The formatNumber function comes from Danny Goodman's
                          > // JavaScript Cookbook.
                          > function formatNumber (num, decplaces) {
                          > // convert in case it arrives as a string value
                          > num = parseFloat(num) ;
                          > // make sure it passes conversion
                          > if (!isNaN(num)) {[/color]
                          ^^^^^^^^^^^[color=blue]
                          > // multiply value by 10 to the decplaces power;
                          > // round the result to the nearest integer;
                          > // convert the result to a string
                          > var str = "" + Math.round (eval(num) *[/color]
                          ^^^^^^^^^[color=blue]
                          > Math.pow(10,dec places));[/color]

                          OK, at least from now on Goodman can no longer be considered a viable
                          source for JS information either. Sometimes I hate it when I'm right.


                          PointedEars

                          Comment

                          • Richard Cornford

                            #14
                            Re: Script doesn't work in Safari

                            Thomas 'PointedEars' Lahn wrote:[color=blue]
                            > elektrophyte wrote:[color=green]
                            >> // The formatNumber function comes from Danny Goodman's[/color][/color]
                            <snip>[color=blue][color=green]
                            >> var str = "" + Math.round (eval(num) *[/color]
                            > ^^^^^^^^^[color=green]
                            >> Math.pow(10,dec places));[/color]
                            >
                            > OK, at least from now on Goodman can no longer be considered
                            > a viable source for JS information either.[/color]

                            No change then. Danny Goodman has promoted the most extraordinary -
                            eval - abuses over the years, and much else that is positively
                            discouraged by the competent.

                            Richard.


                            Comment

                            Working...