Sunday, May 2, 2010
Which javascript library to use? JQuery UI or Dojo?
How to render topology/hierarchical diagram view using javascript
The component comes with lots of good examples and nice documents. This code is a bit old but it easy to fix it and make updates for your need. This comes with CPOL. I had to make minor changes to make it work in IE, Firefox and Safari.
Monday, April 19, 2010
jQuery UI: Adding close option to dynamically added tabs
Have a div with id "sdcMeterTabs". Inside this div, have a ul with id "sdcMeterTabHeader"
In java script:
Call the following when a tree node is double clicked:
function addTab(id, nodeType, nName ){
var idPrefix = nodeType+"_";// nodetype_
var nodeId = idPrefix+id;
//Finds all with an attribute id equals idPrefix+ id
if($("a[id="+idPrefix+ id +"]").length > 0) {
// tab is already loaded so find the href of the tab and load
var addedTab = $("a[id^="+nodeId +"]");
var addedTabHref = $(addedTab).attr("href");
$("#sdcMeterTabs").tabs('select', addedTabHref);
} else {
// tab not loaded so add a new one
$("#sdcMeterTabs").tabs("option", "nodeId",nodeId); // adding nodeId in option
$("#sdcMeterTabs").tabs({ ajaxOptions: { cache: false } });//cache fase for IE
$("#sdcMeterTabs").tabs("add", "metering/grid/newtab.jsf", nName); // Use URL for your tab content
}
return false;
}
Call the following from $(document).ready(function ()
function initializeTabs(){
//tabs init with a custom tab template and an "add" callback filling in the content
var $tabs = $('#sdcMeterTabs').tabs({
ajaxOptions: {
error: function(xhr, status, index, anchor) {
$(anchor.hash).html("Couldn't load this tab.");
}
,spinner: 'Loading...'
,cache: false
}
,cache: false
,idPrefix:""
,event: 'mousedown'
,tabTemplate: '
'
,add: function(event, ui) {
//hack to set id on dom so that later, tabs can be manipulated. Specially, want to stop duplicate tab addition
var nodeId = $(this).tabs("option", "nodeId");
ui.tab.id= nodeId;
//select newely opened tab
$(this).tabs('select',ui.index);
return false;
}
,select: function(event, ui) {
$.get("dynamic/meteringBean/setMeterData.jsf?nodeTypeId="+ui.tab.id); //If you want to set some data
}
});
If you want to add Close, Close Other and Close All menu/actions:
function closeAllTabs(){
var tabElement = $('#sdcMeterTabs');
for (var i = tabElement.tabs('length') - 1; i >= 0; i--) {
tabElement.tabs('remove', i);
}
return false;
}
function closeCurrentTab(){
var tabElement = $('#sdcMeterTabs');
var selected =tabElement.tabs('option', 'selected'); // => 0
if(selected >= 0) {
tabElement.tabs('remove', selected);
}
return false;
}
function closeOtherTabs(){
var tabElement = $('#sdcMeterTabs');
var selected = tabElement.tabs('option', 'selected'); // => 0
if(selected >= 0) {
// remove tabs after the selected tab
for (var i = $('#sdcMeterTabs').tabs('length') - 1; i >= 0; i--) {
if(i != selected) {
tabElement.tabs('remove', i);
}
}
}
return false;
}
Sunday, November 9, 2008
Hpricot for XML parsing
Caution with String concat <<
>> a = "test"
=> "test"
>> a << 12
=> "test\f"
>>
dhtmlxGrid in a Rails App
In general, it is a nice component and comes with lots of sample code. Their support and knowledge is good. Their document list json as supported data type but json support is a subset of XML type. Even if you load the grind in JSON, when you serialize the grid, you get xml back and cell id is not sent back. In rails project, to generate xml, when you use xml builder, make sure, you don't indent. Grid dosn't load xml string with indentation.
Use Builder::XmlMarkup.new (no indent)
Don't use column name type
"type" is a reserved field name for single table inheritance (STI). Active Record allows inheritance by storing the name of the class in a column that by default is called “type”
Here are the magic field names in Rails:
http://wiki.rubyonrails.com/rails/pages/MagicFieldNames
HowtoGenerateJSON
require 'json/objects'
def to_json
result = Hash.new
rows = []
qg_rows = all_records
qg_rows.each_with_index do |row_data|
row = {}
data = []
row_data.each {|cells|
------
data << cell_data
}
row [:data] = data
rows << row
end
result[:rows] = rows
result.to_json
end
Saturday, October 11, 2008
escaping javascript
escape(string)method but it does not escapes the following chars:
* @ - _ + . /
Use encodeURIComponent(URIstring)instead. The encodeURIComponent method encodes all characters.Use the decodeURIComponent() function to decode URIs encoded with encodeURIComponent().
Friday, October 10, 2008
URI escaping
>> URI.escape('Test <>?/&;=:.')
=> "Test%20%3C%3E?/&;=:."
>> CGI.escape('Test <>?/&;=:.')
=> "Test+%3C%3E%3F%2F%26%3B%3D%3A."
CGI.escape is looking better but it does not escape dots which gives "RoutingError No route matches". Here is the solution working for me
>> test = URI.escape(CGI.escape('Test <>?/&;=:.'),'.')
=> "Test+%3C%3E%3F%2F%26%3B%3D%3A%2E"
>> CGI.unescape(test)
=> "Test <>?/&;=:."
Sunday, October 5, 2008
Formatting phone numbers, Fax numbers
In model
acts_as_number :revenue
acts_phone_number :phone
In view use attribute_ui
<%= company.revenue_ui %>
<%= company.phone_ui %>
---------------------------------------
Here is the code. Ideally model should not be using ActionView::Helpers::NumberHelper but for now this seems to be working fine for e.
class ActiveRecord::Base
include ActionView::Helpers::NumberHelper
include ERB::Util
def self.format_as_number(*args)
args.each do |arg|
define_method "#{arg.to_s}_ui=" do |number_string|
if number_string
# If a valid number, sanitize to digits only
if valid_number? number_string
number_string.gsub!(/[^0-9]/, "")
end
end
write_attribute(arg, number_string)
end
end
args.each do |arg|
define_method "#{arg.to_s}_ui" do
val = read_attribute(arg)
begin
number_with_delimiter val if val
rescue
val
end
end
end
define_method 'validate' do
args.each { |arg|
error_message = 'is invalid. It can contain only digits'
if !eval(arg.to_s).nil?
errors.add(arg, error_message) unless valid_number? eval(arg.to_s)
end
}
end
end
def self.format_as_phone_number(*args)
args.each do |arg|
define_method "#{arg.to_s}=" do |number_string|
if number_string
# If a valid phone number(can contain only 0-9/-()+xX),
# sanitize it to "digits only" only if 10 digits long
# If number has more that 10 digits, store it as is
if valid_phone? number_string
numbers = number_string.gsub(/[^0-9]/, "")
if numbers.size == 10
number_string = numbers
end
end
end
write_attribute(arg, number_string)
end
end
args.each do |arg|
define_method "#{arg.to_s}_ui" do
val = read_attribute(arg)
begin
if val
numbers = val.gsub(/[^0-9]/, "")
#Format 10 digits phone number only
if numbers.size == 10
return number_to_phone(numbers,:area_code => true)
end
end
val
rescue
val
end
end
end
define_method 'validate' do
args.each { |arg|
error_message = 'is invalid. It must contain at least 5 digits, only the following characters are allowed: 0-9/-()+x'
if !eval(arg.to_s).nil?
errors.add(arg, error_message) unless valid_phone? eval(arg.to_s)
end
}
end
end
# Valid phone number can contain only 0-9/-()+xX and whitespace.
def valid_phone?(number)
return true if( number.nil? || number.strip.size == 0)
n_digits = number.scan(/[0-9]/).size
valid_chars = (number =~ /^[xX.+\/\-() 0-9]+$/)
return n_digits >= 5 && valid_chars
end
# Valid number can contain only digits and ,.
def valid_number?(number)
return true if( number.nil? || number.strip.size == 0)
valid_chars = (number =~ /^[\,\ 0-9]+$/)
return valid_chars
end
end
Saturday, October 4, 2008
Protecting app from Cross Site Scripting
RoR provides methods for escaping metacharacters. To HTML escape data in RoR simply add an "h" inside your output tag.
It is hard to remember using this everywhere.
There are several plug-in available which you can install and forget about adding "h". I tried auto_escape plug-in. This modifies ActiveRecord and and automatically applies CGI.escapeHTML to all text column. The plug-in works by defining an after_find call_back from ActiveRecord. Whenever a record is found and loaded from DB, this escapes text columns. Plug-in worked great but it slowed down the APP.
xss_terminate plug-in makes stripping and sanitizing HTML automatic. Install the plug-in and forget about h() because you don't need to. This plug-in makes use of before_save hook and strips HTML tags. Generally there are more read operations than save, so performance wise this plug-in worked better for my case.
Tuesday, July 15, 2008
Textfield with auto complete
1) To install run script/plugin install auto_complete
2) In controller, add auto_complete_for :tag, :name where Tag is a model and name is a field, I wanted my auto complete on.
3) In view add <%= text_field_with_auto_complete :tag, :name %>. The method it implements will search through all the Tags in you records database and do a LIKE comparison on the name column, comparing the name to the contents of the tag[title] form field.
4) I had to reopen auto_plug to fix "Mysql::Error: #23000Column 'name' in where clause is ambiguous". In my case, for auto_complete_for method I was passing :joins condition.
I wanted to show tags for a given model. Both Tag and Model had same column name "name". To fix the problem, I created another plug_in name auto_complete_extended with single class init.rb. In init.rb I reopened auto_complete_for method (as follows):
class ActionController::Base
# Reopening auto_complete_for from auto_complete plug-in
### This is copy of auto_complete_for except for the part in condition where it qualifies column name with table name.
def self.auto_complete_for(object, method, options = {})
define_method("auto_complete_for_#{object}_#{method}") do
find_options = {
:conditions => [ "LOWER(#{object.to_s.pluralize}.#{method}) LIKE ?", '%' + params[object][method].downcase + '%' ],
:order => "#{method} ASC",
:limit => 10 }.merge!(options)
@items = object.to_s.camelize.constantize.find(:all, find_options)
render :inline => "<%= auto_complete_result @items, '#{method}' %>"
end
end
end
Thanks to for the following post. It helped me get started. http://codeintensity.blogspot.com/2008/02/auto-complete-text-fields-in-rails-2.html
Monday, June 23, 2008
File upload with attachment_fu
Content type can’t be blank
Content type is not included in the list
Size can’t be blank
Size is not included in the list
Filename can’t be blank
To get better validation message, either reopen attachment_fu.rb or do your own validation in your model. The following blog explains it nicely.
If you are using MySQL, you may want to increase max_allowed_packet size in “my.cnf”. The default size is apparently 1M. If you don't change this and upload a file larger than 1 M, you will get “ActiveRecord::StatementInvalid: Mysql::Error: #08S01Got a packet bigger than ‘max_allowed_packet’ bytes: INSERT INTO...
Sunday, June 22, 2008
WYSIWYG-editor on Rails
include ActionView::Helpers::SanitizeHelper
This was needed in Fckeditor: Version 0.4.3.
To write a plug-in to fckeditor, follow direction on http://docs.fckeditor.net/FCKeditor_2.x/Developers_Guide/Customization/Plug-ins. After reading documentation from this link, I used the following plugin as an example (note: fckeditor comes with this plug-in): /fckeditor/public/javascripts/fckeditor/editor/plugins/placeholder/
Graph/Charts
Sample:
#Redefining method pie(alpha, line_color, style, gradient = true, border_size = false)
# Original method had bug where it won't let you drop gradient
def pie(alpha, line_color, style, gradient = true, border_size = false)
@pie = "#{alpha},#{line_color},#{style}"
if !gradient
#@pie += ",#{!gradient}" # This is bug and won't drop gradient color
@pie += ",#{gradient}"
end
if border_size
@pie += "," if gradient === false
@pie += ",#{border_size}"
end
end
# Original Graph class is not exposing grid color setters.
def set_grid_color( color = '')
@x_grid_color = color
@y_axis_color = color
@x_axis_color = color
@x_grid_color = color
@y_grid_color = color
end
Ruby/Rails IDE
http://aptana.com/rails
http://tnlessone.wordpress.com/2007/02/28/ruby-rails-ide-comparison-idea-netbeans-radrails/
