Saturday, February 1, 2014

Displaying a Bootstrap Modal in Rails with an AJAX call

I am in the process of building a simple Learning Management Solution. I wanted to display a Bootstrap modal pop-up on click of the Add Capsules button. The idea was that on click of this button, an AJAX call should be made to the server, with the current Learning Path ID, so that it can query the DB, and find the potential capsules to be returned for the learning path. I would return an HTML snippet as response, which I wanted to insert into the body of the modal.

See screenshot below of how it looks:

Bootstrap Modal Pop up on click of Add Capsules button (with Ajax response body)












Check out this commit on Github to see the work that was needed: Bootstrap Modal Commit. The comment on the Github explains the details. It was actually quite easy once you know how.

I believe instead of sending an HTML snippet from the backend, a better practice is to send JSON data, and then construct the HTML at the browser via javascript. I guess, I could do that too, but this was really simple to do. I might modify it to return JSON some time in the recent future.

Reference:

Friday, January 10, 2014

Using Capybara and RSpec assertions in Page Objects

On my Rails project, I am using RSpec and Capybara to write functional tests.  I did not want to specify any HTML elements in my Capybara feature files, since that makes the feature files brittle to HTML / CSS changes. It also violates the DRY principle and basic code hygiene.

So, I decided to refactor out my HTML centric Capybara code into separate Page Objects. If you are unfamiliar with Page Objects, then read the following:



The Page Object pattern for encapsulating HTML centric DSL is a common pattern followed while writing UI level functional tests in ThoughtWorks.

The problem I was facing when I refactored my code into Page objects was that I was unable to use the RSpec 'expect' syntax in Page Objects. Turns out all I had to do in my page objects was:

include RSpec::Matchers

Here is the full code from my project on Github.
https://github.com/gsluthra/dakshina/tree/master/spec/features

The appropriate feature files and page objects in a GIST:
https://gist.github.com/gsluthra/8356015

Saturday, September 21, 2013

Transferring all contacts from BlackBerry to Android Galaxy Phone

Yesterday, I was attempting to switch over from my Blackberry, to a Samsung Galaxy S, and spent quite some time figuring out.

There are many links on the internet. Finally here is what I did:

1. Bluetooth Option: I tried pairing my galaxy with blackberry in bluetooth. The pairing was successful. Then in bluetooth menu of Blackberry itself, when you select a bluetooth device, you will find an option saying "Transfer Contacts". I did that, and BB said -- 400 Contacts Transferred, but the Galaxy only added the FIRST contact! So basically, this method did not work for me :(

2. Using BlackBerry Desktop Software (for Mac):

  • I chose to "Sync Contacts" with Computer. There it gave me a warning, that this is the first time you are syncing contacts what should it do. I chose "MERGE", since I didn't anyways have any contacts on my Mac. 
  • After this, when I typed "Address Book" in my SpotLight, I saw all my Contacts had been successfully imported into my Local Address Book of Mac.
  • In Address Book preferences, if you select "Local On My Mac", there was an option for syncing Address book with Google Account. I gave it credentials of a new Gmail account I have created solely for Contact syncing with my android. Once I did that, all my contacts were sent to GMAIL. Then I unchecked the Gmail sync option from AddressBook since I didn't want any more sync to happen. 
  • I registered that particular GMAIL account in my Android (in Settings -> Account), and chose to sync only the CONTACTS. 




That's it. The contacts are now in my phone.. and they will stay 2 way synch with my Android-only GMAIL account, which is kinda neat.

Bye Bye Blackberry. I will miss the tiny red blinking light of my Blackberry.

Friday, June 21, 2013

Tata Photon & Reliance USB Dongle Connection Settings

TATA PHOTON

In India, if you want to manually enter your TATA Photon connection settings (on a Mac or Linux or Windows), here is what you need to do:

Telephone Number: #777
Account Name: 9XXXXXXXXX@photon.ttsl.in (prefix your tata photon phone number which usually starts with a 9)
Password: internet


RELIANCE NON-3G DONGLE

In India, if you want to manually enter your Reliance USB dongle connection settings (on a Mac or Linux or Windows), here is what you need to do:

Telephone Number: #777
Account Name: 9XXXXXXXXX (your reliance phone number which usually starts with a 9)
Password: Same as your reliance phone number which you entered above as account name

This should do the trick, since this is what worked for me on my Mac.

Monday, December 31, 2012

Debugging code in IntelliJ for OpenMRS Jetty

Yesterday, while working on OpenMRS I needed to debug some Java code. I could not easily find steps for debugging OpenMRS with IntelliJ on Google, so I decided to write down my findings.

I used IntelliJ's Remote JVM option to connect to OpenMRS Jetty server.

Step1: Configure Jetty to open a remote debugging port:

One needs to set the following in MAVEN_OPTS so that Jetty opens a remote debugging port for IntelliJ to connect to:



I updated the MAVEN_OPTS in my home directory's .zshrc file (since i use ZSH shell on Mac). You may need to set the MAVEN_OPTS variable appropriately for your environment (Windows/Linux/etc) so that it is correctly set, before starting Jetty on command line.

The value "51696" that I have mentioned above is the port where I want the debugger to run. The memory options have been set because Jetty gives an OutOfMemoryException with OpenMRS if the memory is insufficient (and by default, it seems to be insufficient - so you are better off setting the memory values too).

Now, start Jetty normally using "mvn jetty:run". You will notice the following line being printed by Jetty to indicate that debug port has been opened.

Listening for transport dt_socket at address: 51696

Step2: Configure IntelliJ to connect to the remote debugging port of Jetty:

In IntelliJ, go to "Run" menu, and select "Edit Configurations". Select the "Defaults" option on the left menu, and click on the "+" on the Right side, to create a new configuration. In that Select "Remote" option, and enter options as "localhost" and port as "51696" (same as the port number in step 1 above). Put "Name" as anything you like. I have set it as "OpenMRS Jetty".

OpenMRS Jetty Remote Debugger in IntelliJ IDE


That's it! Now you can debug using this "OpenMRS Jetty" configuration. On clicking "Debug" you should see the debugger connected to Jetty, and breakpoints will start working.

Note: If you want to perform Debugging on Eclipse, then basic process would be the same. Step1: No change. Step2: In Eclipse choose Remote JVM Debugging option (similar to IntelliJ).

There are other ways of debugging OpenMRS too, especially if you run Jetty from inside the IDE. But, for me, this method was simpler.


Sunday, December 16, 2012

Vagrant -- An interesting approach to setup development environments FAST!



If you have never heard of Vagrant, or are interested in understanding what is Vagrant, then this blog should be useful to you.

The Need for Vagrant

Recently, I was involved in organizing the GraceHopper Hackathon in Bangalore where we expected about 50+ women developers to come and contribute to Humanitarian software projects like OpenMRS, RapidFTR, and others. Since all participants would mostly be new to the projects, and we had a single day to get them going, and contribute -- we wanted to ensure that people spend as less a time on setup of their dev environment as possible.

I got introduced to Vagrant, because at the GraceHopper Hackathon, one of the projects - RapidFTR, provides people with the ability to setup their environment using a Vagrant box -- and that's when I realized -- this is interesting!

Setting up a development environment for many projects now-a-days isn't a matter of simply running a script or downloading a piece of software. On most projects, the average setup time to get all up and running is usually a day, and sometimes more. Most often, time is spent on setting environment variables, handling software version conflicts, or general configuration. Not to mention, that once you are done, doing this for the next project would be even more challenging.

Vagrant: The Solution

Vagrant provides an elegant solution to this whole mess.

In simple terms, Vagrant allows you to provides a "box" which has everything pre-installed and setup for you -- and all you do is "start" the box on your machine and you are set. This box is essentially a Virtual Box VM, which is running in invisible mode (background mode) on your machine, and has the whole development environment for your software setup inside it. But, instead of coding inside the Vagrant VM, you code on your laptop -- and do your builds, compilations and server startups, etc inside the Vagrant VM.

Vagrant essentially shares a folder on the "box" which is also available on your laptop, and this is the folder that contains the code of your project. Any modifications to that folder by your laptop (host), or the box (guest), will be reflected to each other.

Basically this means that your laptop owns the code, so you use your favorite powerful IDE and laptop environment to modify code, and you use the vagrant environment to "run" the code.

The advantages you get when using a Vagrant box are:

  1. You don't install stuff on your machine, and mess your machine up with all the weird libraries and settings. All you have on your machine is the "code". Rest is inside the VM.
  2. You have exactly the same development environment as everyone else in your team.
  3. The development environment is created once (Vagrant box), and used everywhere on all Operating Systems. This is because the Box is essentially a VM, which is running on top of Virtual Box. And Virtual Box VMs can be run on any host operating system.


Is it different from using a VM?

Some people ask the question -- why Vagrant Box? Why don't I just setup a Virtual Box VM and everyone can work on that VM. That is also the same -- isn't it?

Well the answer is -- "Almost".

If you create a VM, and then ask people to work on that VM on their machines -- you are in for trouble most of the time! In most cases a VM on your machine is slow. It is especially painful when you have to do things like editing, coding, etc. Plus that also means you have to learn the shortcuts of the VM to make you productive on that VM.

When using a Vagrant box, you aren't working in the VM. You are working on your own laptop, and only connecting to the VM in "ssh" (command-line) mode. In effect, you are actually just firing a few commands to VM -- like build, start server, etc and the rest of the work is being done on your own machine. For you, the Vagrant box is just like a "server" to which you connect and tell what to do.


A Vagrant VM is usually viewed as a light-weight command-line only VM which usually runs a Linux OS (Lucid32 by default, but you can use Ubuntu or anything else).


Vagrant also allows you to configure port forwarding, so that when you type a URL in your browser like http://localhost:3000, you get connected to your server application running inside vagrant -- just as-if the server was running directly on your laptop.

Steps to setup a Vagrant Box on your machine:

When you have a Vagrant Box based Development environment setup (like RapidFTR did), here is all you do to get yourself setup:


  1. Install Virtual Box for your laptop. If you have a Mac, then you install Virtual Box for Mac (and so on). This will act as the environment inside which Vagrant box will run.
  2. Install Vagrant for your laptop. Once you install vagrant, you will see that on command line "vagrant" command will become available.
  3. You download the code into a folder on your machine (say from Github or your network code repository).
  4. You "add" a vagrant box to you laptop using the "vagrant box add" command. This command will need the path to your vagrant box VM. Alternatively, the box can be downloaded and added automatically from the internet as part of the vagrant up command (in next step).
  5. You then do a "vagrant up" to start your box. This vagrant "up" command is done from your code directory, and the code directory will contain a "Vagrant" configuration file with configuration details on the Vagrant box to run. If the box isn't found on your local machine, vagrant will attempt to download the box from the URL provided in the vagrant configuration file. (This means you didn't use the box add command to add the box locally - as was mentioned in the previous step).
  6. Once the vagrant box is up and running, then you ssh into the Vagrant box using the "vagrant ssh" command (or putty on windows) -- to build/start/stop your project application.


That's it. Now you are free to modify code on your local machine, and see it working via the vagrant box VM environment.

Chef your Vagrant

Vagrant also allows you to run chef scripts as part of your vagrant up command. The chef scripts will perform the installation and setup of software inside your Vagrant box. This way -- the power of infrastructure automation and provisioning provided by chef, can be combined with the power of a decoupled development environment provided by Vagrant.

Monday, August 20, 2012

Pretty Fractal Trees using HTML-5 Canvas & Random Numbers

Last week I sat down to see how I can generate a fractal tree on a web page. It turned out to be a very interesting exercise using HTML5 Canvas and simple Math trigonometric functions. Using random numbers for changing the length of the tree branch, and the angle of branch split -- I was quite successful in generating very realistic looking trees!

Each time you render the HTML, the trees look quite different. I can see how Game creators can create interesting looking forests for "heroes" to travel in using such techniques.

HTML 5 Canvas with a Fractal Tree





















Here is the code (also posted on github):