Monday, May 27, 2013

Alternate Way to Create Image Button in Sencha Touch

Hello,

Recently I was working on a sencha touch project where I need to use a nig round image in sencha touch button.  We all now that we can use images inside button using iconCls and iconMask property. That will put small icons inside your button along with button rounded corners and background colors. But in my case we don't need button background color or rounded border of button. We just need a round image with transparent background and user should be able to click on it. There are number of ways for doing it.

First we can use xtype : image and put image url to it. But sometimes tap event does not work over image. So this not an option. Other option is to use panel and put image as html inside and add tap evet to panel body. But that will be on complete panel body. So in case of round image if user tapped outside the image but inside a panel, tap event will be fired. So here is the third solution.

As we know that Ext.button extends the Ext.component so we can add html to component.  So we can add image as html as follow.

{
      xtype: 'button',

      html: '<img src="lib/images/myImage.png"/>'
}

After adding this image is added inside the button and but still have button background colors and rounded border. This you can remove by updating your sencha touch CSS. Find the following class in sencha touch CSS.

.x-button, .x-button.x-button-back:after, .x-button.x-button-forward:after, .x-toolbar .x-button, .x-toolbar .x-button.x-button-back:after, .x-toolbar .x-button.x-button-forward:after {
background-image: none;
background-color: #ccc;
background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f2f2f2), color-stop(3%, #d9d9d9), color-stop(100%,#bfbfbf));
background-image: -webkit-linear-gradient(top, #f2f2f2,#d9d9d9 3%,#bfbfbf);

background-image: -moz-linear-gradient(top, #f2f2f2,#d9d9d9 3%,#bfbfbf);

background-image: -o-linear-gradient(top, #f2f2f2,#d9d9d9 3%,#bfbfbf);

background-image: linear-gradient(top, #f2f2f2,#d9d9d9 3%,#bfbfbf);
}

and replace it with following class. This will remove all background of button but still you will have rounded borders.


.x-button,.x-toolbar .x-button.x-button-back:after,.x-toolbar .x-button.x-button-forward:after{background-image:none;}

Now to remove borders, find following class.

.x-button, .x-toolbar .x-button {
border: 1px solid #999;
border-top-color: #a6a6a6;
background-color: #ccc;
color: #000;
}

and replace it with 

.x-button, .x-toolbar .x-button {
color: #000;
}

That's it and your button will only have image. And still user can tap on and it and have a feeling like button. 

Pelase note that updated sencha touch css is applicable to all the buttons in your application so if you have more than one button which does not have image, please don't use this trick. In my case I was having only one button in application so that's why I am using this trick.

Hope this helps you.

Sunday, May 26, 2013

Capture CSS3 Animations Event in JavaScript

Hello,

This is my first blog on CSS 3 animations. Recently I was working on project where I created some CSS 3 animation. It was a sencha touch project, so we have some requirements like when animation ends we have to switch active item on view port. This we can only do in JavaScript and for that we have to capture CSS 3 animations events in JavaScript. So how to do it?

Basically we are going to add event handler. In case of web kit browser this is webkitAnimationEnd and webkitAnimationStart events. Please note that this event will only work if you have used -webkit-animation on the target. If you are using Transitions, there are some other events. I will cover that in next blogs. Check the code below. This shows exact syntax of adding animation start and end events.

Suppose you have html element with id box1 on which you are applying some CSS 3 animation.

document.getElementById("box1").addEventListener('webkitAnimationStart',function(event){

},false);

Above code will capture animation start event.

document.getElementById("box1").addEventListener('webkitAnimationEnd',function(event){

},false);

Above code will capture animation end event.

If you have infinite animation above functions be invoked every time when animation starts or ends. You also get event object as a parameter to callback function. It contains the target which invoked this event. You can get it using event.srcElement

Please note that above code will only work on web kit browsers.

Monday, May 13, 2013

Passing Query String With Index.html file in iOS Phonegap (Cordova)

Hello,

Imagine a scenario that you have Sencha Touch/ jQuery mobile application and you have used Phonegap (Cordova) to compile it to native iOS application.  Now your application expects some params like authentication token, or user id or anything it can be. You need to send this params along with your index.html file so that you can use it in app launch function. Have you ever faced this situation. If yes then here is the solution. Please remember this solution is specifically for iOS Cordova application.

First let's see how normally it works. When you create a Cordova based application in XCode, You have AppDelegate.h and AppDelegate.m file. Open AppDelegate.m file and find a function below.


- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

In this function find the following lines of code.

self.viewController.wwwFolderName = @"www";
self.viewController.startPage = @"index.html";

This specify that web assets folder is WWW and start page is index.html. If you have some other start page you can change the name here. Now if you try to pass query string as follow, it will not work.


self.viewController.startPage = @"index.html?query1=value1";

Because it treats it as page name and there is no such page. So how to resolve this.

First of all remove the start page name from code.

self.viewController.startPage = @"";

Now we will implement NSURL interface and add some custom functions in it to handle the query string. Add following code to your AppDelegate.m file above implementation of AppDelegate

@implementation NSURL (Additions)

- (NSURL *)URLByAppendingQueryString:(NSString *)queryString {
    if (![queryString length]) {
        return self;
    }
    
    NSString *URLString = [[NSString alloc] initWithFormat:@"%@%@%@", [self absoluteString],
                           [self query] ? @"&" : @"?", queryString];
    NSURL *theURL = [NSURL URLWithString:URLString];
    [URLString release];
    return theURL;
}

@end

This function accepts query string and add it to URL and create new URL. Now add following code at end of didFinishLaunchingWithOptions function.

NSString* newQueryString = @"query1=value1&query2=value2&query3=value3";
NSURL *newurl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"]];

newurl = [newurl URLByAppendingQueryString:newQueryString];
[self.viewController.webView loadRequest:[NSURLRequest requestWithURL:newurl]];


Above code will build custom URL with query string and load the URL in iOS webview.

Hope this helps you.