January 25, 2016

How to Install Yii2 framework on Windows with XAMPP (as PHP development environment)

In this post, I will explain how to install Yii2 framework on Windows, with XAMPP as PHP development environment.
First you have to install XAMPP you can find here: XAMPP Installer
You can install Yii2 framework by two ways:
  • Install Using Composer
  • Install Manually

Install Using Composer

The recommended approach is to install Yii2 framework using composer, because it will automatically install and configures all the required plugins and packages. You can download composer from https://getcomposer.org/download/. Composer setup will ask for PHP installation path, in my XAMPP installation it is:
D:\xampp\php\php.exe

You can verify if composer is correctly installed, by executing the command composer in command prompt. If you get an error message, it means it is not added in the Environment Variables, so you have to add the composer.exe folder path in Environment Variables.

Next step is to install Composer assets plugin by executing the following command from command prompt:

composer global require "fxp/composer-asset-plugin:~1.1.1"

 
During installation of asset plugin, it will ask you for Github login credentials, because composer need to get API rate-limit to retrieve the dependent pacackges information from Github, you can find more information on this from Composer Documentation

Here we finished installing composer, and now we have to install Yii2. Move to a web-accessible folder, the folder where we usually place all web projects. In my XAMPP installation it is D:\xampp\htdocs
Now go to command prompt, move to the above mentioned web-accessible folder, and execute following command:
composer create-project --prefer-dist yiisoft/yii2-app-basic basic

 
It will install Yii2 framework to a folder named basic inside the htdocs folder, you can use your own project name in place of basic(last part in the above command). Then composer will download and configure all the required packages, and finally your Yii2 basic application is now ready. You can try access it by localhost path:
http://localhost/basic/web

Install Manually

Manuall Installation of Yii involves three steps:
  1. Download the archive file from yiiframework.com.
  2. Unpack the downloaded file to a Web-accessible folder, in our example it is D:\xampp\htdocs\basic
  3. Modify the config/web.php file by setting a secret key for the cookieValidationKey configuration item (this is done automatically if you are installing Yii using Composer):
        'cookieValidationKey' => 'enter your secret key here',
    

Thats it, you can access this new basic application by following url:
http://localhost/basic/web

You should see the following "Congratulations!" page in your browser.

If you did not see this page, please check if your PHP installation satisfies Yii's requirements. Just copy /requirements.php to /web/requirements.php and then access it via http://localhost/requirements.php. If you PHP development environment is properly configured, you should see the output similar to this:


You should configure your PHP installation so that it meets the minimum requirements of Yii. Most importantly, you should have PHP 5.4 or above.

References

http://www.yiiframework.com/doc-2.0/guide-start-installation.html



January 21, 2016

AngularJS Filter - How to limit filter on array of items to match with desired field.

AngularJS default filter enables us to filter items list according to a specified input text. By definition, It selects a subset of items from array and returns it as a new array.
For example we have the following list of users:
$scope.myList = [
{
  firstName: "Muhammad",
  lastName: "Idrees",
  description: "Idrees is working as Senior .Net Developer, connected with Ehsan and Faizan"
}, 
{
  firstName: "Ehsan",
  lastName: "Sajjad",
  description: "Ehsan is working as Senior .Net Developer, connected with Idrees"
},
{
  firstName: "Faizan",
  lastName: "Ahmed",
  description: "Faizan is technical consultant, connected with Idrees"
}
]
And here is our html markup, how we want to filter on this list:
 <body ng-app="demoApp" ng-controller="MyController" >
     <p >
        Search:
         <input type="text" ng-model="searchInput" / >
     </p >
     <p >
         <ul>
             <li ng-repeat="user in myList | filter: searchInput">
                 <h4 >{{user.firstName}} {{user.lastName}} </h4 >
                 <p >{{user.description}} </p >
             </li >
         </ul >
     </p >
 </body >
Now if we search for the name Ehsan by typing in the input field, it will display first two items, because both objects containing this search term (in firstname, lastname, or description).
But if I want to filter my list only for firstName, and do not want to match for lastName and description fields. This is how I can limit my filter to desired field.
 <ul>
   <li ng-repeat="user in myList | filter: { firstName : searchInput}" >
    <h4 >{{user.firstName}} {{user.lastName}} </h4 >
    <p >{{user.description}} </p >
   </li >
  </ul >
Now if we type any search term it will only look for that filter in the firstName field. If any record matches the term, it will be displayed.

January 14, 2016

WCF RIA Service - How to get the hosted server url from within wcf service.

While working on Microsoft LightSwitch Framework with Silverlight client, I encountered a problem, how to find the hosted URL/domain from within WCF RIA Service. Since I am working on local system with application hosted in IIS, and configured my application as virtual directory. So I want to know the address of application's virtual directory.
For example, consider this url:
http://localhost/MyWeb
Where localhost is my host name, and MyWeb is the application's virtual directory alias. There may be more nested pages inside, but we will ignore that, because we only want the url address of virtual directory.
Here is the solution:
We cannot access HttpContext class in silverlight/lightswitch client, so we have to call a proxy function hosted in WCF RIA Service, which will return the current hosted URL to client.
  • HttpContext.Current.Request.Url.Host will give you the host name.
  • HttpContext.Current.Request.ApplicationPath will give you the virtual directory name.
So concatenating these two url string parts will give us the path of virtual directory.
string virtualDirectoryHost = = HttpContext.Current.Request.Url.Host + HttpContext.Current.Request.ApplicationPath;
You might have to add namespace System.Web for HttpContext class or also might have to add reference to System.Web.dll.

January 12, 2016

AngularJS - Internationalization

To add internationalization to our demo app we can use a third-party module called angular-translate, you can download from https://github.com/angular-translate/bower-angular-translate/releases. I will add two text labels with language translations, English-Language, Arabic-Language and Urdu-Language.

A sample output of this demo will be like this:

With Arabic-Translator:

With Urdu-Translator:

With English-Translator:

First, we need to load the script in html page, so that AngularJS can find the module. Add following script tag in html page's head tag:

<script src="assets/libs/angular-translate.min.js"></script>

Next we have to add a dependency on the module pascalprecht.translate defined in angular-translate. So, we go to our main app module and add pascalprecht.translate module in the dependencies list. It now looks like this:
var demoApp = angular.module('demoApp', ['pascalprecht.translate']);
Now, we need to add $translateProvider dependency in the config function of our main module demoApp. Then we add translations for the languages we required in our application. In this demo I am using English-Language, Arabic-Language and Urdu-Language. The following code shows how it's done:
demoApp.config(['$translateProvider', function ($translateProvider) {

    $translateProvider.translations('ar', {
        TITLE: 'تدويل تجريبي',
        DESCRIPTION: 'يمكننا استخدام وحدة خارجية، angular-translate ، إضافة إلى تدويل التطبيق التجريبي لدينا.',
    });

    $translateProvider.translations('ur', {
        TITLE: 'بین الاقوامیت سازی ڈیمو',
        DESCRIPTION: 'ہم ڈیمو اپلی کیشن کے لئے عالمگیریت شامل کرنے کے لئے، angular-translate ، ایک تیسری پارٹی کے ماڈیول کا استعمال کر سکتے ہیں.'
    });

    $translateProvider.translations('en', {
        TITLE: 'Internationalization Demo',
        DESCRIPTION: 'We can use a third-party module, angular-translate, to add internationalization to our demo app.'
    });

    $translateProvider.preferredLanguage('en');
}]);

We use translateProvider.translations to add the translations against a key. Here we added translations for English, Arabic and Urdu languages. If you want to support more languages you can keep adding more translations in the same way. Finally, we set the preferred language to English by calling function$translateProvider.preferredLanguage('en').

Next, we'll add options in html page to let user switch between available languages, so we add a toggle button to html page using bootstrap. The following markup do this work:

<div class="btn-group btn-toggle">
 <button class="btn btn-xs btn-default"
  ng-class="{ar:'active'}[languagePreference.currentLanguage]"
  ng-click="languagePreference.switchLanguage('ar')">
  Arabic</button>

 <button class="btn btn-xs btn-default"
  ng-class="{de:'active'}[languagePreference.currentLanguage]"
  ng-click="languagePreference.switchLanguage('ur')">
  Urdu</button>

 <button class="btn btn-xs btn-default"
  ng-class="{en:'active'}[languagePreference.currentLanguage]"
  ng-click="languagePreference.switchLanguage('en')">
  English
 </button>
</div>
The next thing we need to do is add a function languagePreference.switchLanguage() to $rootScope, which we called in the above markup for toggle button's click event. This accepts a language key and sets the specified language a variable named languagePreference.currentLanguage, used in the above markup in ng-class attribute to setup view for the selected language by applying active class. For that we need to modify the run block in our demoApp module as follows:

demoApp.run(['$rootScope', '$translate', function ($rootScope, $translate) {
    
    $rootScope.languagePreference = { currentLanguage: 'en' };
    $rootScope.languagePreference.switchLanguage = function (key) {

        $translate.use(key);
        $rootScope.languagePreference.currentLanguage = key;
    }

}]);

The function $translate.use(key) takes a key and loads the translations written against it, that we defined in the config function.

Now comes the final thing, to use this translator in UI. We need to replace the static hardcoded strings with a call to translate filter.

For example, regular text will go like this:

<h3>{{'TITLE'}}</h3>
<p>{{'DESCRIPTION'}}</p>
After adding translate filter, the final html will become like this:
<h3>{{'TITLE' | translate}}</h3>
<p>{{'DESCRIPTION' | translate}}</p>
Thats it. We have setup a simple html page with two strings, i.e. TITLE and DESCRIPTION, that will be displayed in three different languages. Similary you can add more language translations in the config function if you need. Also the same way you can add more html text with translate filter where required.

January 4, 2016

AngularJS - Custom Filters

AngularJS Filters helps to filter/format data to be displayed to the users. Mostly filers are used in data binding expressions in HTML templates, but you can also use inside controllers, services and directives. AngularJS provides many useful built-in filters, here is a list of some important options:

  • uppercase - used to transform text to upper-case
  • currency - transform a number in currency format
  • number - an expression is formatted as number
  • date - formats a date to string

Following is an example, how we apply filter to an expression:

{{name | uppercase }}

Where name is a model variable in $scope object and uppercase is the name of the filter. A filter is separated from expression by a vertical pipe character (|).

Lets start creating our custom filter. To register a filter we use the function filter() from angular module. First argument is the name of the filter, and second argument is a the factory function used to define the filter's functionality. Filters can accept arguments, so you also use filters in more customized way by adding arguments based on your requirements.

The following snippet creates a filter to replace spaces with some other character (passed in argument).

demoApp.filter('replaceSpaces',function(){
    return function (input, replaceWith) {

        return input.replace(/ /g, replaceWith);
    }
});

And this is how we use this filter in html templates:

{{'Spaces should be removed from this text.' | replaceSpaces : '-'}}

Here we applied filter replaceSpaces with argument '-', separated by ":". So this filter will replace all the occurrences of white spaces with dash sign (-) (or any other character you passed in the argument).