Thursday, August 4, 2011

Jquery hide and show function cause weird behavior in flash movie

I encountered some weird problems for my flash control when I used Jquery function hide() and show() on it. I did some research and found other people had other weird problems too. For example, some saw their flash control reload and go back into the initial settings after show() function. I found a very good solution to my case, instead of using Jquery to hide and show, I simply hide the div where flash is in by setting its bottom to large negative number. Here is my codes:


function ShowInd() {
            $('#divInd').css("bottom", "0px")
}

 function HideInd() {
            $('#divInd').css("bottom", "-4000px")
}

For this to work correctly, I also set the "overflow" to "none".
Since I am on the hide/show element topic, I also want to clarify the difference between display: none and visibility: hidden for hiding an element.



visibility: hidden hides the element, but it still takes up space in the layout.
display: none removes the element completely from the document. It does not take up any space, even though the HTML for it is still in the source code.


Example from about.com: http://webdesign.about.com/od/examples/l/blfaqhidden.htm

Happy coding!

Friday, July 29, 2011

Just how stupid are IE users?

While I was very frustrated in fixing all the IE6 bugs for our website, this article came to me and bright up my day "Just how stupid are IE users"..http://news.cnet.com/8301-17852_3-20085679-71/just-how-stupid-are-ie-users/?fb_ref=fblike&fb_source=home_multiline.. very funny! I personally have no problems with IE or IE users and I don't think there's any correlation between a user's IQ and his/her browser. But IE 6 does give me a lot of headaches in application development and it's a pain in the butt to fix all its errors and bugs. So if you are still using IE6, please please upgrade it to IE 7 or higher. Or just use firefox or chrome or safari..

However, as an application developer, sometimes it's not my choice to make our website IE6 compatible. In this blog I will put down some of the IE 6 bugs that I encountered in my developer life. Hopefully you will find it useful and save you some efforts and time while you scratching your head for a IE6 bug.

1. When placing an absolute div within a relative positioned div, in IE6 and IE7 that div disappeared. The content within the div and the div just would not show. The fix is to wrap the absolute div with another empty <div> </div>.

2. Place an absolute div over a select tag in IE6. This happens a lot to pop up menu.. drop down menu.. popup tooltips. etc.. the fix is to add an empty iframe on top of the select tag and then put your popup div on top of the iframe. Here is some good articles:
http://esdi.excelsystems.com/wsexmp/divdrp.pgm?wsnum=00110
http://www.sitepoint.com/forums/css-53/div-menu-showing-under-select-element-ie6-iframe-solution-570683.html
http://weblogs.asp.net/bleroy/archive/2005/08/09/how-to-put-a-div-over-a-select-in-ie.aspx
someone even created a Jquery plugin for this fix.. Bravo to that.. here is the link to the plugin:
http://plugins.jquery.com/project/bgiframe

3. z-index fix.. I have  a list tag <ul><li>kk</li> </ul> and no matter how high the z-index is in the <li> tag, the content will not show as you expected on top of all other contents. This only happened to IE6/7.. the fix is to raise the z-index of the <ul> instead of <li>.. this way it will layer the content correctly.

4. zoom: 1 fix a lot of display errors in IE6/7. When I have some CSS that just won't work in IE, I see if adding a ZOOM property of 1 (one) will help. More about this issue:
http://www.positioniseverything.net/articles/haslayout.html
http://www.bennadel.com/blog/1354-The-Power-Of-ZOOM-Fixing-CSS-Issues-In-Internet-Explorer.htm

Will update this blog if I find and fix more bugs in the future~

Thursday, July 28, 2011

Javascript Tricks

Use anonymous function in setInterval, setTimeOut if we want to pass parameter to it..
for example,


function SlideShow($obj, opts) {    
        //Set the opacity of all images to 0
        $obj.find('li').css({ opacity: 0.0, marginLeft: opts.photoWidth});      

        //Get the first image and display it (set it to full opacity)                  
        $obj.find('li:first').css({ opacity: 1.0, marginLeft: 0 });                      
       
        //Call the gallery function to run the slideshow  
        //put a new variable COFtimer into the $obj object, this is because each slideshow should have its own timer
        $obj.COFtimer = setInterval(function(){gallery($obj, opts);}, opts.interval);

        //pause the slideshow on mouse over
        $obj.hover(
                function () {
                    clearInterval($obj.COFtimer);
                },
                function () {
                    $obj.COFtimer = setInterval(function(){gallery($obj, opts);}, opts.interval);
                }
            );
    }


This is a function from one of my own Jquery plugins which I recently implemented for slideshow of pictures. In the future I will write another blog about this plugin.
In the highlighted code,  $obj and opts are two parameter passed to gallery function.
Also note that in this case, I utilized javascript enclosure feature to pass these two parameters to function gallery().
Another javascript feature I utilized and really loved is I dynamically added a new variable "COFtimer" into $obj. This way each slideshow object ($obj) will have its own timer object and won't interfere each other's timer.

Thursday, July 21, 2011

DIY Map & IE error after refresh

Recently I have been working on our department public website and need an interactive US state map for different social indicators in 50 states. I found a great and free mapping control called DIY map online. Here is the website: http://www.backspace.com/
It's written in flash and really lightweight. It can be controlled by javascript functions on the HTML page.


I tested the following US albers map on IE but found a little bug:
http://backspace.com/mapapp/us_albers/index.html
The map loaded correctly for the first time, but when I refreshed (F5) the page, the map is gone. I tested it on IE6 and IE7 and found the same bug. But the same page worked fine and had no problems in firefox and chrome.

I also found that this page has no refresh problem in IE:
http://backspace.com/mapapp/us/with_javascript/sample_with_javascript.html

I noticed that the one that has error used swfobject for the us_albers map and I believed
this caused the problem in IE. Here is the original code:


<script type="text/javascript" src="swfobject.js"></script> 
    <script type="text/javascript"> 
        //swfobject.registerObject("DIYMap", "10.0.0");
        var flashvars = {
          data_file: "senate.xml",
          use_js: "on"
        };
        var params = {
          allowscriptaccess: "always"
        };
        swfobject.embedSWF("us_albers.swf", "map", "600", "400", "9.0.0", "expressInstall.swf", flashvars, params);
</script> 


<div id="map"> 
   <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p> 
</div> 



So I changed the swfObject calling function to "Static publishing" as described from this page: http://learnswfobject.com/the-basics/
It seemed that "Static publishing" fixed the problem. 




<div id="mapDiv">
            <object id="map"
             classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
             width="580px"
             height="410px">
            <param name="movie" value="<%=GetFlashLink() %>" />

          <!--[if !IE]>-->
          <object type="application/x-shockwave-flash"
                  data="<%=GetFlashLink() %>" 
                  width="580px" 
                  height="410px">
          <!--<![endif]-->

            <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>

          <!--[if !IE]>-->
          </object>
          <!--<![endif]--> 
        </object>
        </div>
<script type=text/javascript>
        function RegisterFlash() {
            swfobject.registerObject("map", "9");
        }
        //this is to fix the IE7 asp.net error
        window.map = window.document['map'];

        RegisterFlash();    

</script>


Another solution would be appending a javascript timestamp to the embed string. This way IE6 and 7 think the data file is a new one and will try to reload every time. Here is a sample codes from this link (http://blogs.popart.com/2007/11/flash-externalinterface-in-asp-net-applications/)



 var localplayer= ‘player.swf?guid=’ + Math.random()*99999999;
 var so = new SWFObject(localplaer, “player”, …);


Happy programming~

Flash object inside ASP.NET form error in IE 7

Several months ago I posted a blog about how to access a flash object by javascript. I found a very interesting error when I put a flash object inside a form in asp.net and called this flash by javascript. The error from IE would be "object not found or not defined" and it just didn't allow me to control the flash by javascript.
I found that this error only occurs in IE 7 with flash player version 9. The same page works perfectly fine in other browsers including firefox and chrome. I also found that this error would not occur if we test it in flash player version 10 with IE 7 and IE 6.
After spending almost a whole day to debug this error, I found that if I put the flash object outside of the <form> </form> tag in asp.net, the error is gone. Here is my flash embed tag:


  <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0"
 id="usmap" width=580 height=410> 
              <param name=movie value="flash.swf"> 
              <param name=quality value=high> 
              <param name=play value=false> 
              <param name=bgcolor value=#FFFFFF> 
              <embed play=false swliveconnect="true" name="usmap" src="flash.swf" quality=high bgcolor=#FFFFFF  
 width=580 height=410 type="application/x-shockwave-flash"  
 pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"> </embed > 
</object > 


My javascript for calling the flash object:
<script type="text/javascript">

function getFlashMovieObject(movieName) {
          if (window.document[movieName]) {
              return window.document[movieName];
          }
          if (navigator.appName.indexOf("Microsoft Internet") == -1) {
              if (document.embeds && document.embeds[movieName])
                  return document.embeds[movieName];
          }
          else // if (navigator.appName.indexOf("Microsoft Internet")!=-1)
          {
              return document.getElementById(movieName);              
          }
      }



 function somefunction() {
          var flashObj = getFlashMovieObject("usmap");
          if (flashObj) {
              flashObj.someFunctionFromFlash();
          }
      }

</script>


As I said, the only solution I found is to put this flash embed object outside of the asp.net form tag. However, this is an ugly solution and not very realistic as ASP.NET page put all the controls inside form tag. After some hard work of googling, I finally found the reason:



The problem really comes down to the fact that every ASP.NET page is wrapped in a <form> tag and there is a bug in Internet Explorer that hides the containing flash object (the player) in the DOM. To solve this problem, you can simple elevate the player object to a window level element, as shown in Figure 3 below.
window.player = document.getElementById(‘player’);

Ref: http://blogs.popart.com/2007/11/flash-externalinterface-in-asp-net-applications/

This is a really great and simple solution. All I need to do is to add this line into my javascript:
window.usmap = document.getElementById('usmap');
or
window.usmap = window.document['usmap'];


Hope you find this one useful too.


Happy programming!

Thursday, March 17, 2011

ASP.NET validate values input with comma

When user input integer or float values, sometimes they will include comma in the value. For example, instead of inputting "123456", they might input "123,456". However, the Asp.net comparevalidator will not recognize comma and will give user an error message. To fix it, I use a Regulare Expression validator. Here is the regular expression:


"(-)*[0-9]+(,[0-9]+)*(.[0-9]+)*"

And the ASP.NET tags:
<asp:TextBox runat="server" ID="txtValue"></asp:TextBox>

<asp:RegularExpressionValidator runat="server" ID="RegularExpressionValidator1" ErrorMessage="Value has to be number." Display="Dynamic" ForeColor="Red" ControlToValidate="txtValue" ValidationExpression="(-)*[0-9]+(,[0-9]+)*(.[0-9]+)*"></asp:RegularExpressionValidator>

Here is the compare validator which will only work with int/float values without comma
<asp:CompareValidator runat="server" ID="cvValue" ErrorMessage="Value has to be number." Display="Dynamic" ForeColor="Red" ControlToValidate="txtValue" Operator="DataTypeCheck" Type="Double"></asp:CompareValidator>


Happy programming~

SQL Server: format values with comma

I need to format values in SQL server with comma separated. For example, value "123456" should be "123,456" and "12345.1234" should be "123,45.1234". Unfortunately, I couldn't find any build in function in SQL server to achieve this. I was thinking to write my own function to format this kind of value, then I found out that SQL server can format "money" type value this way.

DECLARE @v MONEY
SELECT @v = 1322323.6666

SELECT CONVERT(VARCHAR,@v,0)  --1322323.67    
Rounded but no formatting

SELECT CONVERT(VARCHAR,@v,1)    --1,322,323.67    
Formatted with commas

SELECT CONVERT(VARCHAR,@v,2)    --1322323.6666 
No formatting


The only issue is this function will automatically format the decimal points also. For example, the above one should be " 1,322,323.6666" instead of "1,322,323.67" in my requirement. 
So I decided to write my own function to format the values by taking advantage of the convert function for money. My basic algorithm is 
1) divide value into "integer" part and "decimal" part
2) Converting the "integer" part to money type first and then format it by using "convert(varchar, @v, 2)" function
3) Combine the formatted "integer" part with the original "decimal" part.


Here is the source code of my function:


create FUNCTION [dbo].[FormatValueWithComma]
(
    -- Add the parameters for the function here
    @v nvarchar(30)
)
RETURNS nvarchar(30)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @Result nvarchar(30)

    -- Add the T-SQL statements to compute the return value here
   
   
    declare @dotIndex as int
    set @dotIndex = charindex('.', @v)   
    declare @number as varchar(30) -- the integer part before decimal point

    if @dotIndex = 0
    begin
      
-- convert to money and then convert to varchar
       set @number = convert(varchar, cast(@v as money), 1)      
        set @Result = substring(@number, 0, len(@number)-2)
    End
    else
    begin
        set @number = convert(varchar, cast(substring(@v, 0, @dotIndex) as money), 1)
        set @Result = substring(@number, 0, len(@number)-2)+  substring(@v, @dotIndex, len(@v))
    end


    -- Return the result of the function
    RETURN @Result

END



Happy programming~