Friday, February 8, 2013
Warning to Airtel Nigeria Internet users
In my case, I got a notice that my plan would auto-renew in a few days, so I added 8000 naira credit to allow the auto-renewal. The next day, the plan ended because the gigabytes were exhausted. Airtel did not renew the plan despite the credit on my phone, they simply charged me the whole 8000 for "browsing without a plan," while never informing me that I was doing so.
Despite several useless phone calls to customer service (where they did not even know where my city Jos was), an hour in person with the local customer service, and an appeal to the manager, Airtel insisted that I was at fault, and they would not give a refund.
I know some other providers (MTN, I think) will drop the data connection until you explicitly say you want to continue without a plan, but Airtel conveniently "forgets" to let you know; you simply move with no notice from operating under your plan to exhausting your credit balance. While Airtel has provided good service, this fact would make me cautious about recommending it. I understand that Glo is also very good, but don't know how they handle this billing issue. Furthermore, Glo's Plans are cheaper with 7,500 naira for 8 GB as opposed to 8,000 naira for 5 GB with Airtel.
Thursday, June 7, 2012
Multiple Select Combo Form for Rails
= fields_for :record do |form|
= form.label :category_ids, “Categories”
%br
= form.select :category_ids,
Category.collect {|x| [x.name, x.id]}, {}, :multiple => true
I think the standard update action in the controller will handle this without any special action. To do the update manually, you could just say
@record.update_attributes(:category_ids=>params[:record][:category_ids])
See the Rails doc at http://bit.ly/LDDSma.
Wednesday, April 25, 2012
Add Check-in, Check-out to Dropbox
Dropbox is a great solution for online backup and, to some extent, for simple collaboration. One limitation, however, is that there is no way to know when a collaborator has opened a file for editing. If two people edit a file at the same time, Dropbox will save both edited files which will not have conflicting changes.
Notifybox is a third-party solution to this problem. It only works with Microsoft Office documents and on Windows, but it does seem workable and is free for use on a single folder.
When you open a file within a monitored folder, a dialog pops up:
If you choose “Check-out,” you can go ahead and edit the file. When you save and close it, Notifybox informs you that it is now checked-in.
If you choose “Cancel” instead, a dialog box tells you that you should close the file without saving it. This isn’t enforced, so it’s up to the user to pay attention to the prompts.
If you try to open a file that is already checked out by someone else, a different message tells you that you should close the file without saving since it is already in use. It appears that all the potential users must be using Notifybox … I don’t think that it can tell if someone has checked out a file unless that person is also using Notifybox.
It’s a simple solution that bridges a gap between Dropbox and more complex version control systems that are likely too intimidating for most casual users.
A full subscription costs $6 monthly and allows you to monitor multiple folders and subfolders, and to encrypt and compress files in your Dropbox folder. The free version lets you monitor a single folder.
Wednesday, March 28, 2012
Dead Paypal Security Key
88888888
(some gobbledygook strange characters)
batt 75
--E994--
Soft3328
I presume it means the battery was low, which wouldn’t be surprising. Well, should I just give it to my son to play with, or try to change the battery? I paid $5 for it but now they don’t even sell the key-chain model, and the credit-card model costs $30. Plus, I’m in Nigeria and it would take a good while to get a replacement.
I opened it up, which is fairly easy, and found a standard CR2032 lithium battery. I slid it out and slid in a new one. Uh oh, same error message! Well, let it sit for a while without the battery, I thought. So I took it out again, waited 5 minutes, then put the new one in. Now it just shows 88888888 no matter what! The button does nothing, the display does not turn off after a minute. Shorting some of the pads inside doesn’t do anything either. So now it’s no use even as a dumb toy.
It all makes sense, though. The key works by generating a 6 digit number every 30 seconds, and the number is verified by PayPal as belonging to your key. That means it’s tied to real clock time. If the battery is low and the unit thinks it may be unable to assure the accurate time, then it has to fail. Once that state has occurred, there should be no way to restore the correct state. Changing the battery doesn’t change the fact that the time has become suspect. Waiting 5 minutes before changing the battery probably put the key into a factory new state where it is waiting for programming.
Bottom line: If your security key fails, don’t bother trying to fix it. My own feeling is that it’s not worth $30 for the current credit-card-size key unless you have a weak password or are really careless with it, but then I might feel differently if I see a $3000 fraudulent charge on my account some day!
Saturday, November 13, 2010
Creating an Autocompleting Association Input in Rails3 + ActiveScaffold + JQuery UI
The Rails/ActiveScaffold project I’m working on has models for Member and Country. Each member belongs to a country—i.e. has a nationality. This is all done in the usual way using a key country_id in the member model to refer to the country:
class Member < ActiveRecord::Base
belongs_to :country
and
class Country < ActiveRecord::Base
has_many :members
The usual way of making an editing control in the member create and update forms is simply to add the line
config.columns[:country].form_ui = :select
to the members controller. This creates a dropdown select box populated with the labels and ids (values) of the countries table. If your list of options (countries in this case) is very large, however, it can be impractical to send the entire list for the user to select from. Hence the need for something like an Ajax-based autocompletion input. As the user enters characters, the newly forming string is sent back to the server, which returns a list of possible options that match the string to the current point. Type “Z” for the country and “Zimbabwe” and “Zambia” pop up.
I've spent several days trying to convert a select-box to an autocompleting-text-box in my Rails project. One thought was that perhaps I should have left well-enough alone rather than make the change. Even selecting a list of several hundred options for a select list does not add too much overhead: say 300 items of 20 characters each = 6 KB, hardly worth worrying about. Still, I’ve done it so will document what worked for me.
My second thought is actually a question: why isn’t it dirt-easy to do this in Rails and/or ActiveScaffold? Is it so rarely used? Or perhaps I simply missed the easy way even though I did quite a bit of searching. There is an auto_complete plugin but I couldn't get it to work with Rails 3 and ActiveScaffold--perhaps I could now that I understand more. I was greatly helped by Anup Narkhede's helpful example. In the end, though, I found a method that seems to me even easier than using the plugin!
How to Do It
Anyway, this is how I did it – I’m sure there are better ways. To start with an overview, the way I did this is:
- Adjust the member model so that we can set the
country_idindirectly just by sayingthis_member.country_name='France'. To do this define accessor method's to read and write the member's country name. The read method looks up thecountry_idand returns the name, while the write methodcountry_name=sets thecountry_idbased on the name.
- Replace the form's input for
country_idwith one forcountry_name.
- Create a lookup function to be called by JQuery. For example, if JQuery sends 'Z' the function will return {'Zambia','Zimbabwe'}.
- Add the JQuery autocomplete function to the
country_nameinput.
The Details
Start with these models:
class Member < ActiveRecord::Base
belongs_to :country
end
class Country < ActiveRecord::Base
validates_uniqueness_of :name
has_many :members
end
Step 1: add the accessor functions to the member model:
class Member < ActiveRecord::Base
belongs_to :country
def country_name
Country.find(country_id).name
end
def country_name= (name)
country = Country.find_by_name(name)
self.country_id = country.id if country
end
end
Step 2: Replace the form's input for country_id with one for country_name:
class MembersController < ApplicationController
active_scaffold :member do |config|
config.columns = [:name, :country_name]
end
end
Totally Optional Sidetrack: Before I hit on the technique of using the accessor methods in the model, I was overriding the MemberController
update and create methods, as Anup Narkhede had shown. If for some reason you use a variation of that technique, there is one gotcha to be aware of. You cannot simply look up the id and insert it as params[:record][:country] unless the :country column was included in the form, because it will be ignored. This is part of the security of Rails 3: the user can't pass back arbitrary fields, because only those present in the form are processed. So, when I was overriding the controller update and create methods, I had to include the original :country column as a hidden field in the form. I'm guessing that this is also the reason that Anup first saved the country id in an instance variable @country, then used it in a before_create_save method rather than just adding the new element to the parameter hash.Sidetrack: Note that you could compose any kind of string to use as the label rather than using "name." You would simply write the accessors for whatever you wanted. For example, you could use nationality rather than country name. Whatever is used, however, must be present and unique for each country so that the label-to-id lookup will return a single, valid country.
Step 3: Create a lookup function to be called by JQuery.
In app/controllers/autocomplete_controller.rb
class AutocompleteController < ApplicationController
def country
@countries = Country.where("name LIKE ?", "#{params[:term]}%").select("id, name")
@json_resp = []
@countries.each do |c|
@json_resp << c.name
end
respond_to do |format|
format.js { render :json => @json_resp }
end
end
I would have preferred to put this into the existing CountriesController, but for some reason when I did that the response was very slow (2+ seconds). In any case, it's important to get the routing right. I used
match 'autocomplete/:action'
Step 4. Set up JQuery
We need to add JQuery and JQuery UI to our project if they're not already present. Add to your default template (or elsewhere as long as it will be available)
<%= stylesheet_link_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/ui-lightness/jquery-ui.css' %>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js' %>
<%= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.js' %>
If you prefer, you can load the files to your own Rails
public/stylesheets and public/javascript folders and link to them there. Finally, add this short script to
public/javascripts/application.js:$(function() {
$( ".country_name-input" ).live("click", function(){
$(this).autocomplete({
source: "autocomplete/country.js"
});
});
});
The country_name-input (be careful of the underscore and hyphen) is the class of the input. You could use an ID or other means of specifying it depending on what ActiveScaffold or other framework is generating.
The
.live("click" piece is used to attach the JQuery UI autocomplete widget to country_name-input as soon as the input is clicked. We do this because, in ActiveScaffold or other Ajax-based views, the input may not exist in the DOM when the page loads, so some other event must be used to attach it. The demo and documentation for JQuery UI autocomplete are at http://jqueryui.com/demos/autocomplete/.Everything is in place and should work now, once you put a few countries into the countries table.
Please comment if you have any questions, corrections, or suggestions!
Tuesday, October 12, 2010
Change or Remove the Horizontal Line Above Footnotes in MS Word 2007
I look around and tried to find how to do this, but (a) the help documentation doesn’t seem to say, at least not in a place I thought to look and (b) most of the answers on the Web refer to the same set of instructions from years ago for Word 2003, even when they claim to be for 2007. The instructions are actually almost the same, except that Word 2007 no longer has a “normal” view, which is what you are supposed to start with in the instructions.
Anyway, here is how to do it in Word 2007
Saturday, April 3, 2010
Energy-efficient LCD Monitors
I’ve recently bought a Fit-PC and have an order in for the Fit-PC2 model. These are very small “desktop” computers that run on only a few (6-8) watts, but do all the usual things you need a computer to do. In contrast, typical laptops run at 30-60 watts.
I haven’t had a chance to try out the Fit-PC yet, because I need a monitor. Since I’ve been living out of a suitcase for the last 7 months, I’ve just been using a laptop. Now that I’m getting ready to return to Nigeria in two months, though, I’m looking for an energy-efficient monitor.
One review of energy-efficient monitors covers four models, but only one is in the size range I want for carrying overseas: the Lenovo Thinkvision L1940P. It runs at 18 watts, is rated 5 (of 5) stars by one reviewer on Amazon, and costs $222. However, Amazon also sells the 19-inch ViewSonic VX1932wm-LED,
