Saturday, January 9, 2016

Notes on learning React.js


I.  Learn HTML, CSS, Java script

If you've never used javascript, it is better to learn some basic about it as well as how html and css works.  Basically, these 3 are the basics for web development.  

The best place to learn or refresh memory about html, css, javascript is at w3schools.  It gives examples and allows you to get hands-on experience.  You can even practice SQL over there.

Here  is also a good tutorial on learning html basic page layout in 5 minutes.

II.  Run a Hello World React!  

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Hello React!</title>
    <script src="https://fb.me/react-0.14.6.js"></script>
    <script src="https://fb.me/react-dom-0.14.6.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
</head>
<body>
<section id="example"></section>
<script type="text/babel">
    ReactDOM.render(
    <h1>Hello, world!</h1>,
          document.getElementById('example')
    );
</script>
</body>
</html>

You can copy it to a file and name it myFirstReact.html and run it.  It displays "Hello, world!".  You will notice ReactDOM.reander().  The "Hello, world!" with h1 tags inside the script section is called JSX.  You don't have to use JSX with React, but it is good to use it and it is simple.  


III.  Download the Starter Kit

Get the development starter kit with a set of examples from React's GitHub site.
Then you can browse the examples and run them.

This is the very best way to learn.

Or learn React through React JSFiddle.

IV.  Install npm and react

It is recommended to use React with npm with bundler like browserify or webpack.  The following shows installing npm and react and build a bundle with browserify.

1.  Install npm

NPM comes with nodejs.  Here is the download page.


2.  Install Browserify

npm install -g browserify

If you encounter any issues, go to this link to check npm documentations.

The above command will install browserify to npm's default directory, which is normally the user local folder.
To find out where is this directory, use the following command.

npm config get prefix

3.  Install React

Go to npm's default directory through a command prompt.  Then use the following to install React, React DOM.

npm istall --save react react-dom babelify babel-preset-react

4.  Bundle with Browserify

Then create a main.js file to build bundle with browserify.  Put the following into the main.js to use react and react-dom npm packages.  Save the main.js in the npm default directory/node_modules.

// main.js var React = require('react'); var ReactDOM = require('react-dom'); ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('example') );

Then run the following with the command prompt.

browserify -t [ babelify --presets [ react ] ] main.js -o bundle.js

5.  Install babel for transform of JSX code to js.

npm install --global babel-cli

npm install babel-preset-react

Thursday, December 24, 2015

What's New - Java, Flex, HTML5, ReactJS

It has been quite a long time since my last post.  During all this time, I continued to work on Flex.  I developed a mobile app called Young Scholars for BlackBerry's Tablet Playbook.  I did that as a start because Playbook's launch was giving some motivations for developers.  Who developed an app for it and got published in their app world will be rewarded with a Playbook tablet.  Okay.  All the hard work cannot be justified for simply a free tablet.  But I was having a lot of fun.  My kids helped me to test the app aggressively as it is an app for kids.  I got very good reviews about it even though there are not that many playbook users overall.  However, I got busy with work and kids and didn't continue to push it out to Android and IOS.  It should just require some polishing work and repackaging.

Adobe's abandoning of Flex was quite a set back.  I since worked more on Java and primarily doing Java Development.  Recently my passion for websites and mobile apps revived.  I don't want to continue to use Flex any more.  That's why I am not going to spend time to make the Flex Young Scholars app out to Android and IOS.  I was being bad when I pushed that out to PlayBook.  I did it in a short time period about 2 months.  After that I didn't spend much time on it and ignored some users' email to ask for some tech support.  Since Flex's future is very dim and I don't want to do any maintenance work if I have to push out a Flex app.  But I am thinking to change the app into more popular languages, such as HTML5 with java script.  The app itself is very good idea.  I am not bragging but I was pretty addict to it.  It is a shame that I don't have the app on my phone and play with it more.

So here we go again.  Learning something new.  To be honest, I am really not a big fan of java script.  In a conference a while ago, I learned that java script actually had nothing to do with java.  The year when it came out, java was pretty popular.  So it was marketing strategy that the new scripting language for the web was named java script.  How misleading is that.

But never mind, if that's the only choice.  Let's see how it works.  I learned from a developer friend that ReactJS seems pretty good.  Facebook is at the back of it so it should have something good.  It could be a better choice than Angular JS.

Friday, April 30, 2010

Becoming an iphone/ipad developer

Very recently, I happily jumped into the world of iphone/ipad app development and started writing codes in Objective C. That's why I changed the title of this blog. It has been such a pleasing experience. XCode works like a charm compared with FlexBuilder.

Monday, July 27, 2009

Resource Bundle - An Alternative Way to do localization in .Net

I posted another article on code project. Trying to copy and paste it over here was so much pain because the formatting of the source codes will totally mess up. So I will just post the link over here. I have been thinking about writing this article for a long time but hadn't found a good time earlier. Without that article, LocaleManger simply doesn't make sense to .Net developers because .Net resource files are not organized the way like Java or Flex. That article shows how localization can be done with a ResourceBundle class in .Net applications, with a walk through for both a WinForm application and a WPF application.


Friday, July 24, 2009

Using Microsoft Translate API in LocaleManager

Anyway, I needed to do some translation for an application I was working on. To make this task easier, I tried to plug in some codes to do machine translation with Google Translator. It turned out to be that Google doesn't like people to call their page from an application. After I got the translation from English to Chinese done, I continued to try to get Frech, German, Russian, Spanish, Japanese, and Korean, Arabic, etc. Then it stopped working.

I was getting 302 in service capture. Even when I went to browser to translate.google.com, I was redirected to some other page saying that Google suspect that there is some virus attack going on. It seems like Google only supports AJAX API for its translator, meaning that you can use it on webpages to let user to translate the page. But they don't want people to keep on request their page through an application. (That's interesting. I remeber when I was trying different load testing tools, I tried to use the tool to go to Google first to make a sample Load test.) I am not sure for how long Google block my IP. At least after the weekend, everything went back to normal.

Before I saw some news about Microsoft's Machine Translator and always wanted to try it. It turned out to be very simple to use. Here is a link to the Translate method on MSDN. An appID is required and here is the link to apply for an appID. I used the HTTP API in my application. For more details about other translator API, the Translator Hands on Lab is a good place to get information.

The Terms of Services for using the API are not very clear though. It seems like it is okay to use it in an application, however Microsoft reserves the right to start charging an app developer depending on the usage of their service. It is not clear like the Maps API's terms of services: Unlimited use. Use it in anyway you want.

But anyway, localManager now has the capabilities to do translation. It actually works pretty well. Human proof reading and editing is necessary of course with the machine translated text, but most of the translation is usable. At least it saves a lot of time and energy. From the Chinese translation I went through, I have to say that Microsoft Translator's overall quality is better than Google's. Microsoft's Translator can rearrage a phrase when needed pretty well. I was surprised with some translation they did for Chinese.

I want to take another look at the Terms and Services first and then I can push my new version of localeManager with translation capabilities.

Sunday, March 8, 2009

Locale Manager (4) - Dynamically Add Columns/Rows to a DataGrid

For other parts, please click the following links:
Part 1 - Introduction of Locale Manager
Part 2 - How to: Use Locale Manager
Part 3 - Example of Using DirectoryInfo and FolderBrowserDialog

III. Dynamically Add Columns to a DataGrid
If the datagrid you want to display always has the same number of columns and the headers remain the same, you can just configure the datagrid through property settings. However, sometimes the number of columns and headings depends on user's input, we need to dynamically add columns to the datagrid.

The following codes show how colomns are added to the Datagrid on Worksheet form based on which target locales user selects. Column index comes from enumeration of columns:
public enum Columns
{
No = 0, File, Name, Base
};

private void WorkSheetForm_Load(object sender, EventArgs e)
{
FileInfo[] files = Global.BaseDir.GetFiles("*"+ Global.Extension);
...
...
//determine number of columns for the datagrid
m_grid.ColumnCount = Global.Locales.Length + (int)Columns.Base + 1;
_numOfCols = m_grid.ColumnCount;

m_grid.Columns[(int)Columns.No].Name = "no.";
m_grid.Columns[(int)Columns.No].ValueType = typeof(int);

m_grid.Columns[(int)Columns.File].Name = "file";
m_grid.Columns[(int)Columns.Name].Name = "name";
m_grid.Columns[(int)Columns.Base].Name = Global.BaseDir.Name;

int i = (int)Columns.Base + 1;
foreach (string locale in Global.Locales)
m_grid.Columns[i++].Name = locale;
...
}

When the column "no." is added, I set its ValueType to int, otherwise it is going to be string by default. This matters when user clicks the header to do a sort. If the value type is string, the sorted result will be "1, 11, 2, 21, ..." instead of "1, 2, 3, ...".

m_grid.Columns[(int)Columns.No].Name = "no.";
m_grid.Columns[(int)Columns.No].ValueType = typeof(int);

IV. Dyanmically Add Rows to the Datagrid
The function AddRowToGrid() shows how to add a new row to the datagrid. The function AddToRow() shows how to fill out cells or access cell values in an existing row.

private void AddRowToGrid(string file, int i, string name, string value)
{
string[] row;
row = new string[_numOfCols];
row[(int)Columns.No] = i.ToString();
row[(int)Columns.File] = file;
row[(int)Columns.Name] = name.Trim();
row[(int)Columns.Base] = value.Trim();

m_grid.Rows.Add(row);
}

private void AddToRow(int i, int localeIndex, string value)
{
if (null!= value && i>=0)
m_grid.Rows[i].Cells[getColumnNo(localeIndex)].Value = value;
}

private int getColumnNo(int localeIndex)
{
return (int)Columns.Base + localeIndex + 1;
}

Locale Manager (3) - Example of Using DirectoryInfo, FolderBrowserDialog and Sharing Data between Different Forms

For part 1 and part 2, please click the following links:
Part 1 - Introduction of Locale Manager
Part 2 - How to: Use Locale Manager

I. Program Structure - using Model to store data

There are two forms in the code: MainForm and WorkSheetForm. MainForm is the one to ask the user to select the base locale directory by file browsing. Then, it displays all the sibling subdirectories of the base directory.
WorkSheetForm will show after the user selects one or more target locales and clicks the Load button. The program will dynamically add columns to the DataGrid depending on how many locales are selected.
This program uses the MVC (Model-View-Controller) pattern to pass data around the UI. Application data is stored in Global.cs, the Model. So, MainForm.cs passes data such as BaseDir, RootDir, and Locales to Global.cs, and WorkSheetForm.cs can go pick it up over there.
II. Using DirectoryInfo, FolderBrowserDialog

FolderBrowserDialog is used instead of a OpenFileDialog so that only folders are shown while user tries to find the base locale directory.

.Net's DirectoryInfo class is very handy and you can retrieve all different info about a directory or a file. The MainForm.cs uses this class to get the base directory and the root locale directory. The fillLocaleList() function finds all the sibling subdirectories and add them to the list box.
private void m_browse_Click(object sender, EventArgs e)
{
 m_baseDirBrowserDlg.SelectedPath = Environment.CurrentDirectory;
 if (m_baseDirBrowserDlg.ShowDialog(this) != DialogResult.OK)
     return;

 Global.BaseDir = new DirectoryInfo(m_baseDirBrowserDlg.SelectedPath);
 Global.RootDir = Global.BaseDir.Parent;

 m_baseLocale.Text = Global.BaseDir.Name;
 fillLocaleList();
}

private void fillLocaleList()
{
 m_allLocales.Items.Clear();
 m_selectedLocale.Items.Clear();

 DirectoryInfo[] subs = Global.RootDir.GetDirectories();

 foreach (DirectoryInfo sub in subs)
 {
     String dirName = sub.Name;
     //exclude base locale dir in the list
     if (dirName != Global.BaseDir.Name)
         m_allLocales.Items.Add(dirName);
 }

 if (m_allLocales.Items.Count > 0)
 {
     m_add.Enabled = true;
     m_addAll.Enabled = true;

     m_allLocales.SelectedIndex = 0;
 }
 else
     MessageBox.Show("No sibling folders were found for the base locale.");
}
The codes will enable buttons only when a user finishes the required steps first. This is very easy to do but will help the user a lot and make the application friendly.