Monday, October 10, 2011

addEventListener vs attachEvent vs jquery bind

Unfortunately IE is not friendly to this idea (addEventListener) and decide to throw a javascript error.

After dig around, I found that we need to use AttachEvent insteead of AddEventListener to support IE.

Here are some of the reference
https://developer.mozilla.org/en/DOM/element.addEventListener
http://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx

as suggested solution, I did a fix in couple javascript code to fix this issue.

if (el.addEventListener){
el.addEventListener(‘click’, functionText, false);
} else if (el.attachEvent){
el.attachEvent(‘onclick’, functionText);
}

why not using Jquery Bind ?
and here is better solution if you use Event capture in addEventListener
Unfortunately, Event capturing is not supported by jQuery, as event capturing is not supported by IE, which jQuery supports.

if (el.addEventListener){
el.addEventListener(‘click’, functionText

Friday, August 05, 2011

TFS Unshelve to different branch

TFS Unshelve to different branch



For example (Trunk -> Branch)

Prerequisites :
Download and install the latest TFS Power toolshttp://visualstudiogallery.msdn.microsoft.com/c255a1e4-04ba-4f68-8f4e-cd473d6b971f

Steps :

1. Go to Console (cmd.exe)

2. Go to your target folder. otherwise you will get this error “unable to determine the workspace”

cd D:\Source\Branch1

3. execute tfpt.exe

tfpt unshelve ShelveName1 /migrate /source:$/Project/Trunk /target:$/Project/Branches/Branch1”



Here is the syntax : tfpt unshelve “MySampleShelveName” /migrate /source:”$/MyTeamProject/TheOrigionalBranch” /target:”TheDestinationBranch”

4. Confirm to unshelve

5. Merge

6. Check your pending changes (DONE)

——

Catches

If you get the error => “unable to determine the workspace”

NOTE: Take the latest from your source control and “cd” to a local path that is mapped to thetarget workspace. Also ensure that the current working directory is mapped, you can run “tf workspace” and see if the target folders are mapped.

Monday, July 25, 2011

implement ssl custom attribute in MVC

Example of how to implement your SSL Custom Attribute in MVC

· If it is login, then we must force it into secure otherwise we need to force to unsecure.

· Ideally in LoginController, we can use this attribute [CustomRequireHttps] which will force to use SSL

· For other controller, we can use this attribute [CustomRequireHttps(false)] which will force not to use SSL

· For other controller which always not required SSL we can create other attribute to force not to use SSL [CustomNotRequireHttps]

/// Represents an attribute that forces an unsecured HTTP request to be re-sent over HTTPS.
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public class CustomRequireHttpsAttribute : FilterAttribute, IAuthorizationFilter
{
private bool _ForceOnLoggedIn = false;

///
/// Constructor
///

///
public CustomRequireHttpsAttribute() : this(false);

///
/// Constructor
///

///
public CustomRequireHttpsAttribute(bool forceOnLoggedIn)
{
this._ForceOnLoggedIn = forceOnLoggedIn;
}



/// Handles unsecured HTTP requests that are sent to the action method.
/// An object that encapsulates information that is required in order to use the attribute.
/// The HTTP request contains an invalid transfer method override. All GET requests are considered invalid.
protected virtual void ForceSecure(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.Request.IsSecureConnection)
{
if (!string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
//throw error if the request is not get
throw new InvalidOperationException("MyRequireHttpsAttribute_MustUseSsl");
}

string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult(url);
}
}

/// Force unsecure page only deal with get method
/// An object that encapsulates information that is required in order to use the attribute.
/// The HTTP request contains an invalid transfer method override. All GET requests are considered invalid.
protected virtual void ForceUnsecure(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsSecureConnection)
{
//if it is secure page
if (string.Equals(filterContext.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
//only deal with get method
string url = "https://" + filterContext.HttpContext.Request.Url.Host + filterContext.HttpContext.Request.RawUrl;
filterContext.Result = new RedirectResult(url);
}
}
}



/// Determines whether a request is secured (HTTPS) and, if it is not, calls the method.
/// An object that encapsulates information that is required in order to use the attribute.
/// The parameter is null.
public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
throw new ArgumentNullException("filterContext");
}

if (_ForceOnLoggedIn == false)
{
this.ForceSecure(filterContext);
}
else
{
//check if Login
if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
{
//if login then need to force secure page
this.ForceSecure(filterContext);
}
else
{
//if not login then need to force to unsecure page
this.ForceUnsecure(filterContext);
}
}

}

Thursday, July 21, 2011

anti frogery for mvc and ajax

I just found very good solution to protect our sites from Anti Frogery for ASP.NET MVC and AJAX.

This solution can be easily applied to class controller and ajax.

Here is the article.

http://weblogs.asp.net/dixin/archive/2010/05/22/anti-forgery-request-recipes-for-asp-net-mvc-and-ajax.aspx

--

Wednesday, July 20, 2011

Javascript XSS Attack

Reminder for javascript XSS Attack

For example

var name = "<%= UserInput %>";

If there is a post which submit the username with
" ;alert(document.cookie);//

then this will trigger XSS Attack.

There is simple fix which I have added inside String Extension (available for Support R5)
var currentUsername = "<%= Encoder.JavascriptEncode(UserInput) %>";

Hopefully this post can be a reminder for all of us to protect our site.


Monday, July 11, 2011

Client validation in FF

Recently, I have to fix a bug where client validation doesn’t work in FF.

Finally, i notice that the problem exist in web.config which tells to force xhtmlConformance mode=”legacy”

1:
This will render the validation attribute

1:
2: 3: controltovalidate="text1"
4: id="required1"
5: evaluationfunction="RequiredFieldValidatorEvaluateIsValid"
6: validationgroup="grp1"
7: initialvalue=""
8: style="color:Red;visibility:hidden;">required

Instead of this

1: 2: yle="color:Red;visibility:hidden;">required
3:
4:
The reason why it doesn’t work is EXPANDO.

When tracing in the debugger, you can see that the expando properties are
not recognized, though they do exist in the "attributes" collection.
Expando attributes are fine in Firefox, but cannot be accessed as if they
are a part of the DOM as IE allows. Any attribute that is not part of the
DOM is only accessible via obj.getAttribute('x') or obj.attributes['x'].value.

The ASP.NET 2.0 client script library needs to be updated to avoid the
DOM-like property access to expando attributes. Instead, use getAttribute().
Some links re expandos:
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/referen
ce/properties/expando.asp
http://www.xulplanet.com/ndeakin/archive/2004/9/12/
http://www.howtocreate.co.uk/tutorials/javascript/dombasics
Also, all HTML attributes are supposed to be caseless, so
and are identical. However IE 6 treats them as two
different attributes, so be sure that all references are in lowercase!


Wednesday, June 22, 2011

EJB 3.1 Cookbook

 

Recently I read new release book titled “EJB 3.1 Cookbook” by Richard M.Reese. http://www.packtpub.com/ejb-3-1-cookbook/book

If you wonder why I read this book instead of .NET book, Please find it on this post. =D

This book talks about building real world EJB solutions with a collection of simple but incredibly effective recipes and here a list of the overview of this book.

  • Build real world solutions and address many common tasks found in the development of EJB applications
  • Manage transactions and secure your EJB applications
  • Master EJB Web Services
  • Part of Packt's Cookbook series: Comprehensive step-by-step recipes illustrate the use of Java to incorporate EJB 3.1 technologies

Enterprise Java Beans enable rapid and simplified development of secure and portable applications based on Java technology.Creating and using EJBs can be challenging and rewarding. Among the challenges are learning the EJB technology itself, learning how to use the development environment you have chosen for EJB development, and the testing of the EJBs.

This EJB 3.1 Cookbook addresses all these challenges and covers new 3.1 features, along with explanations of useful retained features from earlier versions. It brings the reader quickly up to speed on how to use EJB 3.1 techniques through the use of step-by-step examples without the need to use multiple incompatible resources. The coverage is concise and to the point, and is organized to allow you to quickly find and learn those features of interest to you.

The book starts with coverage of EJB clients. The reader can choose the chapters and recipes which best address his or her specific needs. The newer EJB technologies presented include singleton beans which support application wide needs and interceptors to permit processing before and after a target method is invoked. Asynchronous invocation of methods and enhancements to the timer service are also covered.

The EJB 3.1 CookBook is a very straightforward and rewarding source of techniques supporting Java EE applications.

What you will learn from this book :

  • Create and use the different types of EJBs along with the use of the optional session bean business interface
  • Create a singleton session bean for application-wide use
  • Use declarative and programmatic techniques for security, timer services, and transaction processing
  • Use asynchronous session beans to complement message driven beans
  • Support aspect oriented features such as logging and data validation using interceptors
  • Use EJBs in support of message based applications
  • Master the use of deployment descriptors and improved packaging options
  • Use EJBs outside of the Java EE environment using the embeddable container

Approach

Each recipe comprises step-by-step instructions followed by an analysis of what was done in each task and other useful information. The book is designed so that you can read it chapter by chapter, or look at the list of recipes and refer to them in no particular order. It is packed with useful screenshots to make your learning even easier.

Who this book is written for

The book is aimed at Java EE and EJB developers and programmers. Readers should be familiar with the use of servlets in the construction of a web application. A working knowledge of XML is also desirable.

After I read this book I am really grateful to take .NET as my favourite framework. Because since in I was uni when I was first learned EJB, The version was not different. There is slightly changes and less improvement. However overall this book is really great. Easy to read and great coverage of knowledge.

Thursday, June 09, 2011

Html5 histoty API and CSS3 transitions

Check out new HTML5 History API allows us to manage the URL changes while CSS3 transitions handle the sliding. Permalinks are always maintained, your back button works as expected, and it's much faster than waiting for a full page load.

Basically we intercept your click, call pushState() to change the browser's URL, load in data with Ajax, then slide over to it.

$('#slider a').click(function() {
history.pushState({ path: this.path }, '', this.href)
$.get(this.href, function(data) {
$('#slider').slideTo(data)
})
return false
})
view rawslide.jsThis Gist brought to you by GitHub.
When you hit the back button, an onpopstate handler is fired after the URL changes, making it easy to send you "back".

$(window).bind('popstate', function() {
$('#slider').slideTo(location.pathname)
})
view rawunslide.jsThis Gist brought to you by GitHub.

Wednesday, June 08, 2011

TDD Practices

Just read couple good article which I think required for anyone who writing unit testing.

Here couple of screen shot from those article

Concept

Finding bugs (things that don’t work as you want them to) 
=> Manual testing (sometimes also automated integration tests)

Detecting regressions (things that used to work but have unexpectedly stopped working)
=> Automated integration tests (sometimes also manual testing, though time-consuming)

Designing software components robustly
=>Unit testing (within the TDD process)

 

Good unit tests vs bad ones

TDD helps you to deliver software components that individually behave according to your design. A suite of good unit tests is immensely valuable: it documents your design, and makes it easier to refactor and expand your code while retaining a clear overview of each component’s behaviour. However, a suite of bad unit tests is immensely painful: it doesn’t prove anything clearly, and can severely inhibit your ability to refactor or alter your code in any way.

Where do your tests sit on the following scale?

image

Unit tests created through the TDD process naturally sit at the extreme left of this scale. They contain a lot of knowledge about the behaviour of a single unit of code. If that unit’s behaviour changes, so must its unit tests, and vice-versa. But they don’t contain any knowledge or assumptions about other parts of your codebase, so changes to other parts of your codebase don’t make them start failing (and if yours do, that shows they aren’t true unit tests). Therefore they’re cheap to maintain, and as a development technique, TDD scales up to any size of project.

At the other end of the scale, integration tests contain no knowledge about how your codebase is broken down into units, but instead make statements about how the whole system behaves towards an external user. They’re reasonably cheap to maintain (because no matter how you restructure the internal workings of your system, it needn’t affect an external observer) and they prove a great deal about what features are actually working today.

Anywhere in between, it’s unclear what assumptions you’re making and what you’re trying to prove. Refactoring might break these tests, or it might not, regardless of whether the end-user experience still works. Changing the external services you use (such as upgrading your database) might break these tests, or it might not, regardless of whether the end-user experience still works. Any small change to the internal workings of a single unit might force you to fix hundreds of seemingly unrelated hybrid tests, so they tend to consume a huge amount of maintenance time – sometimes in the region of 10 times longer than you spend maintaining the actual application code. And it’s frustrating because you know that adding more preconditions to make these hybrid tests go green doesn’t truly prove anything.

 

Tips for writing great unit tests

Enough vague discussion – time for some practical advice. Here’s some guidance for writing unit tests that sit snugly at Sweet Spot A on the preceding scale, and are virtuous in other ways too.

  • Make each test orthogonal (i.e., independent) to all the others
    Any given behaviour should be specified in one and only one test. Otherwise if you later change that behaviour, you’ll have to change multiple tests. The corollaries of this rule include:
    • Don’t make unnecessary assertions
      Which specific behaviour are you testing? It’s counterproductive to Assert() anything that’s also asserted by another test: it just increases the frequency of pointless failures without improving unit test coverage one bit. This also applies to unnecessary Verify() calls – if it isn’t the core behaviour under test, then stop making observations about it! Sometimes, TDD folks express this by saying “have only one logical assertion per test”.
      Remember, unit tests are a design specification of how a certain behaviour should work, not a list of observations of everything the code happens to do.
    • Test only one code unit at a time
      Your architecture must support testing units (i.e., classes or very small groups of classes) independently, not all chained together. Otherwise, you have lots of overlap between tests, so changes to one unit can cascade outwards and cause failures everywhere.
      If you can’t do this, then your architecture is limiting your work’s quality – consider using Inversion of Control.
    • Mock out all external services and state
      Otherwise, behaviour in those external services overlaps multiple tests, and state data means that different unit tests can influence each other’s outcome.
      You’ve definitely taken a wrong turn if you have to run your tests in a specific order, or if they only work when your database or network connection is active.
      (By the way, sometimes your architecture might mean your code touches static variables during unit tests. Avoid this if you can, but if you can’t, at least make sure each test resets the relevant statics to a known state before it runs.)
    • Avoid unnecessary preconditions
      Avoid having common setup code that runs at the beginning of lots of unrelated tests. Otherwise, it’s unclear what assumptions each test relies on, and indicates that you’re not testing just a single unit.
      An exception: Sometimes I find it useful to have a common setup method shared by a very small number of unit tests (a handful at the most) but only if all those tests require all of those preconditions. This is related to the context-specification unit testing pattern, but still risks getting unmaintainable if you try to reuse the same setup code for a wide range of tests.

    (By the way, I wouldn’t count pushing multiple data points through the same test (e.g., using NUnit’s [TestCase] API) as violating this orthogonality rule. The test runner may display multiple failures if something changes, but it’s still only one test method to maintain, so that’s fine.)

  • Don’t unit-test configuration settings
    By definition, your configuration settings aren’t part of any unit of code (that’s why you extracted the setting out of your unit’s code). Even if you could write a unit test that inspects your configuration, it merely forces you to specify the same configuration in an additional redundant location. Congratulations: it proves that you can copy and paste!

    Personally I regard the use of things like filters in ASP.NET MVC as being configuration. Filters like [Authorize] or [RequiresSsl] are configuration options baked into the code. By all means write an integration test for the externally-observable behaviour, but it’s meaningless to try unit testing for the filter attribute’s presence in your source code – it just proves that you can copy and paste again. That doesn’t help you to design anything, and it won’t ever detect any defects.

  • Name your unit tests clearly and consistently
    If you’re testing how ProductController’s Purchase action behaves when stock is zero, then maybe have a test fixture class called PurchasingTests with a unit test called ProductPurchaseAction_IfStockIsZero_RendersOutOfStockView(). This name describes the subject (ProductController’s Purchase action), the scenario (stock is zero), and the result (renders “out of stock” view). I don’t know whether there’s an existing name for this naming pattern, though I know others follow it. How about S/S/R

    Avoid non-descriptive unit tests names such as Purchase() or OutOfStock(). Maintenance is hard if you don’t know what you’re trying to maintain.

Wednesday, May 25, 2011

IE9 [Tidy Error] in Umbraco

In the mean time to solve this problem is to force the compatibility mode in IE9 inside the umbraco folder

This how you can do this

Header name : X-UA-Compatible
Value : IE=8

image

Tuesday, May 24, 2011

Google Chrome Autofill for password

Recently I found an error in my web apps when I ran it to Google Chrome.

After debugging , It seems Google Chrome do prefill after the page load and trigger the javascript.

So be careful to have this javascript which purposely trigger login button on change on password text box.


var setupTriggerButton = function ()
{
//for login trigger
//DON'T DO ONCHANGE - only use keypress, because browser (Chrome) can automatically fill and cause postback
/*
$(".txtTriggerButton").live("change", function (e)
{
var rel = $(this).attr("rel");
if (rel && rel != "")
{
$(rel).click();
}
});
*/
//trigger login
$(".txtTriggerButton").live("keypress", function (e)
{
var rel = $(this).attr("rel");
if (rel && rel != "")
{
//$.log('run from DISABLE DEFAULT BUtton');
return runFunctionOnEnter(e,
function ()
{
$(rel).click();
}
);
}
});
}



Tuesday, April 19, 2011

ClientIDMode = “Predictable” broke my dropdown list auto partial postback

In my previous post, I try to upgrade my recent .NET web apps to use recent .NET for capabilities by doing this

<pages controlRenderingCompatibilityVersion="4.0">






But unfortunately, I find couple of my control inside UPDATE PANEL – does not do Partial Postback anymore. (It is doing FULL postback now)

This only happen to a control outside button which I have set as autoPostback = true.





After looking around and test which part that I need to put it back, I found clientIDMode.

I need to set clientIDMode=“AutoID” because the default value is “Predictable”.





<pages controlRenderingCompatibilityVersion="4.0" clientIDMode="Predictable">






The weird things is I try to compare the id and html which generated by both “predictable and “AutoID”. And the result is the SAME but the different is one of them can do partial postback and one of them not.





<!-- Generated when I set "clientIDMode='Predictable'" -->
<select class="ddlPostback" id="ContentPlaceHolderDefault_MainContainerPlaceHolder_ucProductDetail_rptVariationChoiceGroup_ddlChoiceGroup_0" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup\',\'\')', 0)" name="ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup">
<option value="">Please select</option>
<option value="2" selected="selected">Green</option>
<option value="3">Yellow</option>
<option value="4">Blue</option>
<option value="5">Brown</option>
</select>


<!-- Generated when I set "clientIDMode='AutoID'" -->
<select class="ddlPostback" id="ContentPlaceHolderDefault_MainContainerPlaceHolder_ucProductDetail_rptVariationChoiceGroup_ddlChoiceGroup_0" onchange="javascript:setTimeout('__doPostBack(\'ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup\',\'\')', 0)" name="ctl00$ctl00$ctl00$ContentPlaceHolderDefault$MainContainerPlaceHolder$ucProductDetail$rptVariationChoiceGroup$ctl00$ddlChoiceGroup">
<option value="">Please select</option>
<option value="2" selected="selected">Green</option>
<option value="3">Yellow</option>
<option value="4">Blue</option>
<option value="5">Brown</option>
</select>



Friday, April 15, 2011

Grab asp.net 4.0 benefits

When you upgrade asp.net 2.0/3.5 project using Visual studio.
VS will automatically add a configuration which prevent you from breaking the results of the projects.

Here is couple example of the configuration which preserve the behaviour of .net 2.0/3.5

<pages controlRenderingCompatibilityVersion="3.5" enableEventValidation="false" clientIDMode="AutoID">





ControlRenderingCompatibilityVersion Setting in the Web.config File



ASP.NET controls have been modified in the .NET Framework version 4 in order to let you specify more precisely how they render markup. In previous versions of the .NET Framework, some controls emitted markup that you had no way to disable. By default, ASP.NET 4 this type of markup is no longer generated.



If you use Visual Studio 2010 to upgrade your application from ASP.NET 2.0 or ASP.NET 3.5, the tool automatically adds a setting to the Web.config file that preserves legacy rendering. However, if you upgrade an application by changing the application pool in IIS to target the .NET Framework 4, ASP.NET uses the new rendering mode by default.



 



ClientIDMode Changes



The ClientIDMode setting in ASP.NET 4 lets you specify how ASP.NET generates the id attribute for HTML elements. In previous versions of ASP.NET, the default behavior was equivalent to the AutoID setting of ClientIDMode. However, the default setting is now Predictable.



If you use Visual Studio 2010 to upgrade your application from ASP.NET 2.0 or ASP.NET 3.5, the tool automatically adds a setting to the Web.config file that preserves the behavior of earlier versions of the .NET Framework. However, if you upgrade an application by changing the application pool in IIS to target the .NET Framework 4, ASP.NET uses the new mode by default.




<httpRuntime requestValidationMode="2.0"/>        





ASP.NET Request Validation



The request validation feature in ASP.NET provides a certain level of default protection against cross-site scripting (XSS) attacks. In previous versions of ASP.NET, request validation was enabled by default. However, it applied only to ASP.NET pages (.aspx files and their class files) and only when those pages were executing.



In ASP.NET 4, by default, request validation is enabled for all requests, because it is enabled before the BeginRequest phase of an HTTP request. As a result, request validation applies to requests for all ASP.NET resources, not just .aspx page requests. This includes requests such as Web service calls and custom HTTP handlers. Request validation is also active when custom HTTP modules are reading the contents of an HTTP request.



As a result, request validation errors might now occur for requests that previously did not trigger errors.



==================================



To get asp.net 4.0 benefits including smaller viewstate, you need to clean that configuration or change that into this.


<pages controlRenderingCompatibilityVersion="4.0">



Tuesday, April 12, 2011

Reference By Value for integer doesn’t work in entity framework / LINQ query

 

Just find an interesting bugs, where I thought reference by value (int) can be used in entity framework or linq query.

Here is the code



lst = new List<IQueryable<tblProduct>>();
int choiceID = 30;
lst.Add(from t in originalQuery
where t.tblProductChoiceTag.Any(c => c.ChoiceID == choiceID)
select t);
choiceID = 31;
lst.Add(from t in originalQuery
where t.tblProductChoiceTag.Any(c => c.ChoiceID == choiceID)
select t);


IQueryable<tblProduct> q = null;

bool first = true;
foreach (var tquery in lst)
{
if (first)
{
q = tquery;
first = false;
}
else
{ //the next one combine it
q = q.Union(tquery);
}

}











When it executed, linq query will use the last choiceID (31) and override (30).

This really weird, because I thought It is saved to use the same (int) variable because it will pass by value.




Here is another example


var q = (from t in DBHelper.Instance.tblProductVariation
where t.ProductID == pid
&& t.tblChoice.Count == choices.Count
select t);

foreach (var c in choices)
{
q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == c.ChoiceID)
select t);
}
a
return q.FirstOrDefault();




See on this query which the value will be iterating from the choice object



q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == c.ChoiceID)
select t);




this code will pass the same value of choiceID.


To fix this you need to change it into local variable.


var cid = c.ChoiceID;

q = (from t in q
where t.tblChoice.Any(ch=>ch.ChoiceID == cid)
select t);







Anyone can explain this ?

Friday, April 08, 2011

Firefox Update panel after 2 mins idle time

Recently, I fight with firefox bug which aborting my partial postback from update panel after 2 mins idle time.

Here was my step to investigate this problem

  • check other browsers (IE, IE6, Chrome) – and the result, only firefox does this weird behaviour
  • create simple update panel and tested on FF. – unfortunately this work perfectly
    and then I wonder why my actual code does not work.
  • Apply more content on Update Panel – It is not work again (oh my be it’s I need to make my content on update panel smaller)
  • After trying to make my update panel content smaller, it still not work.
  • Then I use my previous simple update panel to test if it is content outside update panel is matter. – (Yes, it is the content outside update panel is matter)
  • Confuse how I solve this, we still need to use update panel for particular reason because of the due date, etc. so we can’t change anything (we have to keep the update panel but has to work in FF)

After looking around the solutions, luckily I found on the other section of my project work perfectly after 2 mins idle in FF.

I try to investigate why that section work but not this. Finally I figure out that the different is that part is calling ajax call on other page before call partial postback.

Then here is my simple solutions to fix this.

  • Register Begin Request
    Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(microsoftAJAX_BeginRequest);
  • check the browser if it is mozilla and the time difference is 2 mins then request to other server page (ASPX page) first synchonously before continue the process.

    Here is the code, hopefully it will help your problem as well.
    //check availability for partial postback for FF fixed. FF will abort the partial postback call after 2 mins unless it call ajax to other page first
    var checkConnectionForPartialPostback = function ()
    {
    $.ajax({
    url: "/usercontrols/testconnection.aspx",
    async: false
    });
    };

    //check availability for partial postback for FF fixed. FF will abort the partial postback call after 2 mins unless it call ajax to other page first
    var checkAvailabilityForPartialPostback = function ()
    {
    //firefox fix for time diff
    if ($.browser.mozilla && GetTimeDiff(new Date(), lastLoadTime).getMinutes() >= 2)
    {
    //refresh this page
    checkConnectionForPartialPostback();
    }
    else
    {
    lastLoadTime = new Date();
    }
    };







Wednesday, April 06, 2011

IE9–Fastest Browser ?

Some people said that IE9 aim to be the fastest browser in the world.

Is that true ? Check this out and compare it with other browser

http://ie.microsoft.com/testdrive/Performance/KungFu/Default.html

Basic Geolocation example

Here is some basic geolocation example and display it to google maps.

<!DOCTYPE html>
<html>

<head>
<script src="js/jquery-1.4.2.min.js"></script>
<script src="js/yqlgeo.js"></script>
<script>
jQuery(window).ready(function(){
jQuery("#btnInit").click(initiate_geolocation);
})

function initiate_geolocation() {
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_errors);
}
else
{
yqlgeo.get('visitor', normalize_yql_response);
}
}

function handle_errors(error)
{
switch(error.code)
{
case error.PERMISSION_DENIED: alert("user did not share geolocation data");
break;

case error.POSITION_UNAVAILABLE: alert("could not detect current position");
break;

case error.TIMEOUT: alert("retrieving position timedout");
break;

default: alert("unknown error");
break;
}
}

function normalize_yql_response(response)
{
if (response.error)
{
var error = { code : 0 };
handle_error(error);
return;
}

var position = {
coords :
{
latitude: response.place.centroid.latitude,
longitude: response.place.centroid.longitude
},
address :
{
city: response.place.locality2.content,
region: response.place.admin1.content,
country: response.place.country.content
}
};

handle_geolocation_query(position);
}

function handle_geolocation_query(position){
alert('Lat: ' + position.coords.latitude + ' ' +
'Lon: ' + position.coords.latitude);
}
</script>

</head>
<body>
<div>
<button id="btnInit" >Find my location</button>
</div>

</body>
</html>function handle_geolocation_query(position)
{
var image_url = "http://maps.google.com/maps/api/staticmap?sensor=false&center=" + position.coords.latitude + "," +
position.coords.longitude + "&zoom=14&size=300x400&markers=color:blue|label:S|" +
position.coords.latitude + ',' + position.coords.longitude;

jQuery("#map").remove();
jQuery(document.body).append(
jQuery(document.createElement("img")).attr("src", image_url).attr('id','map')
);
}



JQuery Intellisense in VS 2010

 

If you want  jquery intellisense in your visual studio like this the you can get the vsdoc file generator which hosted by damo

http://damianedwards.com/vsdoc/

image

Tuesday, March 29, 2011

Refresh Javascript

Here are my favourite links to refresh or introduce Javascript to new comers.

http://www.jslint.com/lint.html

http://vimeo.com/18511621

http://developer.yahoo.com/yui/theater/ by Douglas Crockford

 

Javascript is a wild language which need to be tamed.
Here are some js pattern which I think best pattern to tackle down the scoping and closure issue which called (Module Pattern)

http://stackoverflow.com/questions/3722820/examples-of-practical-javascript-object-oriented-design-patterns

Recently I build a framework called SiteUI which follows this pattern and give you protection and flexibility.

SiteUI.BaseUI = function (options)
{
//default options
var defaultsOpt = {
//set it to false otherwise, when you disable from the ajax, it when postback it will enable all your control
//but if you have other reason you can do so.
disableAllButtonOnSubmit: false,
ajaxProcessMessage: "Processing..."
};

var options = $.extend(defaultsOpt, options);


//optional value - to disable all button on submit or not
var disableAllButtonOnSubmit = options.disableAllButtonOnSubmit;
var setDisableAllButtonOnSubmit = function (value)
{
disableAllButtonOnSubmit = value;
}

var ajaxProcessMessage = options.ajaxProcessMessage;
var setAjaxProcessMessage = function (value)
{
ajaxProcessMessage = value;
}

//Shopping Cart Control
var shoppingCartControl = null;

var ddlPostbackSelector = '.ddlPostback';
var txtPostbackSelector = '.txtPostback';
var btnPostbackSelector = '.btnPostback';
var chkPostbackSelector = '.chkPostback';

var loadingSelector = '.postbackLoading';
var loaderHtml = "<img src='/images/ajax-loader.gif' class='postbackLoading' style='width:15px;height:15px;position:absolute; z-index:9999;' />";



var isHideLoadingBeforePostbackTemporary = false;
//this to indication a form validator after call back - (CommonFormValidator.js option)
var formValidator_CallBack = function (source, isValid)
{
//alert('formValidator_CallBack : ' + isValid);
if (!isValid)
{
//not valid - hide loading temporary - because this will be called first before click happen
isHideLoadingBeforePostbackTemporary = true;
}
};

//Show loading
var showLoadingBeforePostback = function (source, addLoadingToParent)
{
//alert('showLoadingBeforePostback isHideLoadingBeforePostbackTemporary: ' + isHideLoadingBeforePostbackTemporary);
if (!isHideLoadingBeforePostbackTemporary)
{
//add loader html after
if (addLoadingToParent)
{
$(source).parent().after(loaderHtml);
showPageLoader(); //show page loader
}
else
{
$(source).after(loaderHtml);
showPageLoader(); //show page loader
}
}
else
{
//set it to false again
isHideLoadingBeforePostbackTemporary = false;
}
};

//Clear Loading Function
var clearLoading = function ()
{
$(loadingSelector).remove();
hidePageLoader();
};

//show Page loader - this using jquery.loader this will disable all the button automatically
var showPageLoader = function ()
{
$.loader({
className: "loaderBox",
content: ''
});

};

//hide page loader
var hidePageLoader = function ()
{
$.loader('close');
};

//Show Hide Loading On Content
var showHideLoadingOnContent = function (contentSelector, isShow)
{
if (isShow)
{
$(contentSelector).before(loaderHtml); //add loader after it fades

//show loading
showPageLoader(); //show page loader to hide
$(contentSelector).animate({ opacity: 0 }, 150);
//$(contentSelector).effect('fade',null,500);

}
else
{
//hide loading - remove all loading selector
$(loadingSelector).remove(); //remove loader first
hidePageLoader(); // hide page loader
//just in case if in the beginning it hides this
$(contentSelector).animate({ opacity: 1 }, 150);
//$(contentSelector).effect('fade',null,500);
}
};

//redirect content
var redirectContent = function (url, contentSelector)
{
if (contentSelector)
{ //only if they pass content selector we can redirect with show and hide loading
showHideLoadingOnContent(contentSelector, true);
}

window.location = url;
};

//update content
var updateContent = function (responseText, contentSelector, updateContent_Callback)
{

$(contentSelector).html(responseText);


if (updateContent_Callback)
updateContent_Callback(responseText);

//hide loading on content
showHideLoadingOnContent(contentSelector, false);
};

//Used to track last Request Ajax URL
var lastRequestAjaxUrl = "";
//load content
var loadContent = function (ajaxUrl, relatedData, contentSelector, updateContent_Callback)
{
showHideLoadingOnContent(contentSelector, true);

lastRequestAjaxUrl = ajaxUrl;
$.ajax({
type: "POST",
url: ajaxUrl,
data: relatedData,
complete: function (data, stat)
{
//only process last request ajax url
if (this.url == lastRequestAjaxUrl)
{
//$.log("Update this " + this.url + " VS " + lastRequestAjaxUrl);
if (stat == "success")
{
var isError = true;
updateContent(data.responseText, contentSelector, updateContent_Callback);
}
else
{
updateContent("<p>Error Loading Data : " + stat + ' : ' + data.responseText + "</p>", contentSelector, updateContent_Callback);
}
}
else
{
//$.log("Dispose this ajax " + this.url + " VS " + lastRequestAjaxUrl);
}
}
});
};


// *************** MICROSOFT AJAX INIT - HANDLE ALL AJAX CALL*******************
var initMicrosoftAjaxRequest = function ()
{
/// <reference name="MicrosoftAjax.js"/>
if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined')
{
Sys.Application.add_init(microsoftAJAX_App_Init);
}
};

var microsoftAJAX_App_Init = function ()
{
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(microsoftAJAX_BeginRequest);
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(microsoftAJAX_EndRequest);
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(microsoftAJAX_pageLoaded);
};

var postbackTriggerElement;
var microsoftAJAX_BeginRequest = function (sender, args)
{
if (disableAllButtonOnSubmit)
{
//disable all button
disableAllSubmitButtons(true);
}
postbackTriggerElement = args.get_postBackElement()
var ctrl = $(postbackTriggerElement);

//remove all validation error
removeAllValidationError();

if (ctrl.is("input:checkbox") || ctrl.is("input:radio"))
{
ctrl.hide(); //hide this check box
if (!ctrl.hasClass("noLoaderOnPostback"))
{
showLoadingBeforePostback(ctrl, true); //show loading on this control
}
}
else if (ctrl.is("input:submit"))
{ //you can change it to other
if (ctrl.hasClass("waitLabelOnPostback"))
{
if (ajaxProcessMessage != "")
{
ctrl.val(ajaxProcessMessage);
}
}

if (ctrl.hasClass("disableOnPostback"))
{
ctrl.attr('disabled', true); //disable but later on postback it will enable or disable based on the behaviour
}


if (!ctrl.hasClass("noLoaderOnPostback"))
{
showLoadingBeforePostback(ctrl);
}
}
else
{ //other items show loading
//show loading on this control
if (!ctrl.hasClass("noLoaderOnPostback"))
{
showLoadingBeforePostback(ctrl);
}
}
};

var microsoftAJAX_pageLoaded = function (sender, args)
{
if (!postbackTriggerElement)
{
return;
}

//get updated panels and referesh
var updatedPanels = args.get_panelsUpdated();
for (i = 0; i < updatedPanels.length; i++)
{
//apply filter textbox
setFilterTextbox(updatedPanels[i].id);
//set rating
setRating(updatedPanels[i].id);
//set date picker
setDatePicker(updatedPanels[i].id);
//set text area counter
setTextAreaCounter(updatedPanels[i].id);

//Call Microsoft AJAX_EndRequest_AdditionalFunciton() if available
if (typeof (microsoftAJAX_PageLoaded_AdditionalFunction) == 'function')
{
microsoftAJAX_PageLoaded_AdditionalFunction(updatedPanels[i].id);
}
}
};


//end request
var microsoftAJAX_EndRequest = function (sender, args)
{
if (args.get_error() != undefined)
{
var errorMessage = args.get_error().message;
args.set_errorHandled(true);
alert("Error in ajax call : " + errorMessage);
clearLoading(); //clear loading
return;
}


if (disableAllButtonOnSubmit)
{
//enable all button
disableAllSubmitButtons(false);
}




//Call Microsoft AJAX_EndRequest_AdditionalFunciton() if available
if (typeof (microsoftAJAX_EndRequest_AdditionalFunction) == 'function')
{
microsoftAJAX_EndRequest_AdditionalFunction();
}


//empty the postback element
postbackTriggerElement = null;

hidePageLoader(); //hide page loader
};


//this can be override by calling set ajax page loaded
var microsoftAJAX_PageLoaded_AdditionalFunction = function (updatedPanelId)
{
//baseUI. microsoft AJAX Page Loaded Additional funxtion
//you can write default function here
};

//this can be override by calling set ajax end request
var microsoftAJAX_EndRequest_AdditionalFunction = function ()
{
//baseUI. microsoft AJAX End Request Additional funxtion
//you can write default function here
};

//override ajax end request
var overrideMicrosoftAJAX_EndRequest_AdditionalFunction = function (func)
{
microsoftAJAX_EndRequest_AdditionalFunction = func;
};

//override ajax page loaded
var overrideMicrosoftAJAX_PageLoaded_AdditionalFunction = function (func)
{
microsoftAJAX_PageLoaded_AdditionalFunction = func;
};
//-----------------------------------------------



//use for postback
var setupPostbackControlEvents = function ()
{
//show loading before postback
$(ddlPostbackSelector).live("change", function (e)
{
//e.preventDefault();//cannot prevent default, it won't go to onclick
showLoadingBeforePostback(this);
});

//filter search keyword
$(txtPostbackSelector).live("change", function (e)
{
//e.preventDefault();//cannot prevent default, it won't go to onclick
showLoadingBeforePostback(this);
});

$(btnPostbackSelector).live("click", function (e)
{
//e.preventDefault(); //cannot prevent default, it won't go to onclick
showLoadingBeforePostback(this);

if ($(this).hasClass("clearValidation"))
{
//check if it has class clear validation
removeAllValidationError();
}

});


$(chkPostbackSelector + " input").live("change", function (e)
{
//e.preventDefault(); //cannot prevent default, it won't go to onclick
showLoadingBeforePostback(this, true);
removeAllValidationError(); //it will clear validation - usually this will change the view
});
};


//setup Dropdown Item
var setupDropdownItem = function ()
{

//find drop down item trigger
$('.dropdownItemTrigger').each(function ()
{
// Make the drop down cart appear/disappear.
var boxSelector = $(this).attr('rel');

// Set natural height and other properties of hidable object.
$(boxSelector).data('naturalHeight', $(boxSelector).height());
$(boxSelector).addClass('hidden');
$(boxSelector).css(
{
display: 'none',
bottom: 'auto'
});

// Create back reference.
$(boxSelector).data('trigger', $(this));
});

$('.dropdownItemTrigger').live("click", function (e)
{
e.preventDefault();

var $trigger = $(this);

// Don't do anything if the drop down item is already animating.
if ($trigger.hasClass('disabled')) return false;

// Find direction.
var direction = $trigger.hasClass('maximise') ? 1 : -1;

// Find effect type.
var classes = $trigger.attr('class'); //.match(/effect-/);
var effect = $trigger.attr('class').match(/\beffect-[a-z]{1,}/);
//alert(effect);

// Make the drop down cart appear/disappear.
var boxSelector = $trigger.attr('rel');



if (boxSelector == shoppingCartControl.shoppingCartControlSelector)
{
shoppingCartControl.checkToReload();
}

$(boxSelector).trigger('dropdowntoggle', [direction, effect]);
});

$('.dropdownItem').live('dropdowntoggle', function (e, direction, fxtype)
{
var $dropdownItem = $(this);
var $trigger = $dropdownItem.data('trigger');


// Ensure direction.
if (isNaN(direction)) direction = $dropdownItem.hasClass('shown') ? -1 : 1;

// Disable trigger.
$trigger.addClass('disabled');

// Set states. / cursor
$trigger.toggleClass('maximise', direction == -1);
$trigger.toggleClass('minimise', direction == 1);

$dropdownItem.toggleClass('hidden', direction == -1);
$dropdownItem.toggleClass('shown', direction == 1);

// Effect
//var currPosition = $dropdownItem.css('top').replace(/([a-z]+)/, '') * 1
var currPosition; // = direction == 1 ? $dropdownItem.height() * -1 : 0;
var displacement; // = $dropdownItem.height(); //$dropdownItem.data('naturalHeight');
var newPosition; // = currPosition + displacement * direction;

//alert(fxtype);
// Toggle drop down item + Effect
if (fxtype == 'effect-slide')
{
// Calculate new values.
currPosition = direction == 1 ? ($dropdownItem.height() * -1) : 0 - 50;
displacement = $dropdownItem.height(); //$dropdownItem.data('naturalHeight');
newPosition = currPosition + displacement * direction;

// Execute
$dropdownItem.css(
{
display: 'block',
top: currPosition
}).animate(
{
top: newPosition
}, 400, function ()
{
$trigger.toggleClass('active', direction == 1);

$trigger.removeClass('disabled');
});
}
else
{
// if (fxtype=='effect-fade') {
// Calculate new values.
var currOpacity = direction == 1 ? 0 : 1;
var newOpacity = direction == 1 ? 1 : 0;


//Execute
$dropdownItem.css(
{
display: 'block',
top: 0,
opacity: currOpacity
}).animate(
{
opacity: newOpacity
}, 400, function ()
{
$trigger.toggleClass('active', direction == 1);
if (direction == -1)
{
//hide the display
$dropdownItem.css({display: 'none'});
}
$trigger.removeClass('disabled');
});
}

});
};

/*this doesn't work for shopping cart in IE 6*/
var setupDropdownItemUsingJqueryUI = function ()
{
//Bind Drop down item - just require this button
$('.dropdownItemTriggerBlind').live("click", function (e)
{
e.preventDefault();

var $trigger = $(this);
// Make the drop down cart appear/disappear.
var boxSelector = $trigger.attr('rel');

//check if it is shopping cart control
if (boxSelector == shoppingCartControl.shoppingCartControlSelector)
{
shoppingCartControl.checkToReload();
}


//using jquery.ui toggle( effect, [options], [speed], [callback] )
$(boxSelector).toggle('blind', null, 300);

});

}


/*Setup Events - This will be call unsynchronously*/
var setupEvents = function ()
{ //setup postback control events
setupPostbackControlEvents();
//setup drop down
setupDropdownItem();



//for login trigger
$(".txtTriggerLogin").live("change", function (e)
{
$(".btnLogin").click();
});

$(".txtTriggerLogin").live("keypress", function (e)
{
//$.log('run from DISABLE DEFAULT BUtton');
return runFunctionOnEnter(e,
function ()
{
$(".btnLogin").click();
}
);
});


// Removes SEO text in navItems
$(".clearText").html("");
$(".clearText").removeClass("clearText");

// Clears input fields on Focus
// Title must match the value to clear.
$(".clearField").live("blur", function ()
{
if ($(this).val() == "")
{
$(this).val($(this).attr("title"));
};
});

$(".clearField").live("focus", function ()
{

if ($(this).val() == $(this).attr("title"))
{
$(this).val("");
};
});


//bind shopping cart
//cart = new SiteUI.ShoppingCart();
//cart.updateCartHover();
};

/*Constructor*/
var bindDefaultBehaviour = function ()
{
//init ajax request behaviour
initMicrosoftAjaxRequest();
//disable default button
disableDefaultButton();

//set droppy menu
$('#dropdownNavigation').droppy();

shoppingCartControl = new SiteUI.ShoppingCartControl();

//run this async
setTimeout(function ()
{
setupEvents();


//apply filter textbox
setFilterTextbox();

setRating();
setDatePicker();
setTextAreaCounter();

}, 0);
};

var init = function ()
{

}

//return public method
return {
bindDefaultBehaviour: bindDefaultBehaviour,
formValidator_CallBack: formValidator_CallBack,
redirectContent: redirectContent,
setupPostbackControlEvents: setupPostbackControlEvents,

loadContent: loadContent,
updateContent: updateContent,

clearLoading: clearLoading,
showLoadingBeforePostback: showLoadingBeforePostback,
showHideLoadingOnContent: showHideLoadingOnContent,

showPageLoader: showPageLoader,
hidePageLoader: hidePageLoader,

setAjaxProcessMessage: setAjaxProcessMessage,
setDisableAllButtonOnSubmit: setDisableAllButtonOnSubmit,
overrideMicrosoftAJAX_EndRequest_AdditionalFunction: overrideMicrosoftAJAX_EndRequest_AdditionalFunction,
overrideMicrosoftAJAX_PageLoaded_AdditionalFunction: overrideMicrosoftAJAX_PageLoaded_AdditionalFunction
};
}