Commit f476a761f710c3c201c94dff939fdd9ec351d30c

Authored by Joenio Costa
Committed by Antonio Terceiro
1 parent 8bac0258

More user-friendly icon selector for block of links

(ActionItem1428)
app/helpers/box_organizer_helper.rb 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +module BoxOrganizerHelper
  2 +
  3 + def icon_selector(icon = 'no-ico')
  4 + render :partial => 'icon_selector', :locals => { :icon => icon }
  5 + end
  6 +
  7 +end
app/models/link_list_block.rb
@@ -73,10 +73,9 @@ class LinkListBlock < Block @@ -73,10 +73,9 @@ class LinkListBlock < Block
73 true 73 true
74 end 74 end
75 75
76 - def icons_options(selected = nil) 76 + def icons_options
77 ICONS.map do |i| 77 ICONS.map do |i|
78 - select = "selected='1'" if i[0] == selected  
79 - "<option class='icon-#{i[0]}' value='#{i[0]}' #{select}>#{gettext(i[1])}</option>" 78 + "<span class=\"icon-#{i[0]}\" onclick=\"changeIcon(this, '#{i[0]}')\"></span>"
80 end 79 end
81 end 80 end
82 81
app/views/box_organizer/_icon_selector.rhtml 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +<div class='icon' style='width:16px; height:16px;' onclick="hideOthersIconSelector(this); showIconSelector(this)">
  2 + <%= hidden_field_tag 'block[links][][icon]', icon %>
  3 + <span class='icon-<%= icon %>' style='display:block; width:16px; height:16px;'></span>
  4 + <div class="icon-selector" style='display:none;'>
  5 + <%= @block.icons_options %>
  6 + </div>
  7 +</div>
app/views/box_organizer/_link_list_block.rhtml
1 <strong><%= _('Links') %></strong> 1 <strong><%= _('Links') %></strong>
2 <div id='edit-link-list-block'> 2 <div id='edit-link-list-block'>
3 <table id='links' class='noborder'> 3 <table id='links' class='noborder'>
4 - <tr><th><%= _('Icon') %></th><th><%= _('Name') %></th><th><%= _('Address') %></th></tr> 4 + <tr><th></th><th><%= _('Name') %></th><th><%= _('Address') %></th></tr>
5 <% for link in @block.links do %> 5 <% for link in @block.links do %>
6 <tr> 6 <tr>
7 - <td><%= select_tag 'block[links][][icon]', @block.icons_options(link['icon']) %></td>  
8 - <td><%= text_field_tag 'block[links][][name]', link[:name], :maxlength => 20 %></td>  
9 - <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address] %></td> 7 + <td>
  8 + <%= icon_selector(link['icon']) %>
  9 + </td>
  10 + <td><%= text_field_tag 'block[links][][name]', link[:name], :class => 'link-name', :maxlength => 20 %></td>
  11 + <td class='cel-address'><%= text_field_tag 'block[links][][address]', link[:address], :class => 'link-address' %></td>
10 </tr> 12 </tr>
11 <% end %> 13 <% end %>
12 </table> 14 </table>
13 </div> 15 </div>
14 16
15 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page| 17 <%= link_to_function(_('New link'), nil, :class => 'button icon-add with-text') do |page|
16 - page.insert_html :bottom, 'links', content_tag('tr', content_tag('td', select_tag('block[links][][icon]', @block.icons_options)) + content_tag('td',text_field_tag('block[links][][name]', '', :maxlength => 20)) + content_tag('td',text_field_tag('block[links][][address]', nil, :class => 'cel-address'))) + 18 + page.insert_html :bottom, 'links', content_tag('tr',
  19 + content_tag('td', icon_selector('ok')) +
  20 + content_tag('td', text_field_tag('block[links][][name]', '', :maxlength => 20)) +
  21 + content_tag('td', text_field_tag('block[links][][address]', nil, :class => 'cel-address'))
  22 + ) +
17 javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight") 23 javascript_tag("$('edit-link-list-block').scrollTop = $('edit-link-list-block').scrollHeight")
18 end %> 24 end %>
config/cucumber.yml
1 -default: --tags ~@selenium,~@wip --exclude features/support/selenium.rb 1 +default: --tags ~@selenium,~@wip --exclude features/support/selenium.rb --exclude features/step_definitions/selenium_steps.rb
2 selenium: --tags @selenium,~@wip 2 selenium: --tags @selenium,~@wip
features/edit_block_of_links.feature 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +Feature: edit_block_of_links
  2 + As a profile owner
  3 + I want to edit a block of links
  4 +
  5 + Background:
  6 + Given I am on the homepage
  7 + And the following users
  8 + | login | name |
  9 + | eddievedder | Eddie Vedder |
  10 + And the following blocks
  11 + | owner | type |
  12 + | eddievedder | LinkListBlock |
  13 + And I am logged in as "eddievedder"
  14 +
  15 + @selenium
  16 + Scenario: show the icon selector
  17 + And I follow "Edit sideboxes"
  18 + Given I follow "Edit" within ".link-list-block"
  19 + And I follow "New link"
  20 + And the ".icon-selector" should not be visible
  21 + When I click ".icon"
  22 + Then the ".icon-selector" should be visible
features/step_definitions/selenium_steps.rb 0 → 100644
@@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
  1 +require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
  2 +
  3 +def string_to_element_locator(selector)
  4 + if selector.gsub!(/^\./, '')
  5 + "css=[class='#{selector}']"
  6 + else
  7 + raise "I can't find '#{selector}'!"
  8 + end
  9 +end
  10 +
  11 +Then /^the "([^\"]*)" should be visible$/ do |selector|
  12 + selenium.is_visible(string_to_element_locator(selector)).should be_true
  13 +end
  14 +
  15 +Then /^the "([^\"]*)" should not be visible$/ do |selector|
  16 + selenium.is_visible(string_to_element_locator(selector)).should be_false
  17 +end
  18 +
  19 +When /^I click "([^\"]*)"$/ do |selector|
  20 + selenium.click(string_to_element_locator(selector))
  21 +end
features/support/paths.rb
@@ -18,10 +18,11 @@ module NavigationHelpers @@ -18,10 +18,11 @@ module NavigationHelpers
18 article_id = Person[$2].articles.find_by_slug($1.to_slug).id 18 article_id = Person[$2].articles.find_by_slug($1.to_slug).id
19 "/myprofile/#{$2}/cms/edit/#{article_id}" 19 "/myprofile/#{$2}/cms/edit/#{article_id}"
20 20
21 - when /edit BlogArchivesBlock of (.+)/  
22 - owner = Profile[$1]  
23 - block = BlogArchivesBlock.find(:all).select{|i| i.owner == owner}.first  
24 - "/myprofile/#{$1}/profile_design/edit/#{block.id}" 21 + when /edit (.*Block) of (.+)/
  22 + owner = Profile[$2]
  23 + klass = $1.constantize
  24 + block = klass.find(:all).select{|i| i.owner == owner}.first
  25 + "/myprofile/#{$2}/profile_design/edit/#{block.id}"
25 26
26 when /^(.*)'s homepage$/ 27 when /^(.*)'s homepage$/
27 '/%s' % Profile.find_by_name($1).identifier 28 '/%s' % Profile.find_by_name($1).identifier
lib/tasks/cucumber.rake
@@ -23,6 +23,12 @@ begin @@ -23,6 +23,12 @@ begin
23 t.cucumber_opts = "--color --tags @wip:2 --wip --format #{ENV['CUCUMBER_FORMAT'] || 'progress'}" 23 t.cucumber_opts = "--color --tags @wip:2 --wip --format #{ENV['CUCUMBER_FORMAT'] || 'progress'}"
24 end 24 end
25 25
  26 + Cucumber::Rake::Task.new({:selenium => 'db:test:prepare'}, 'Run features with selenium') do |t|
  27 + t.binary = vendored_cucumber_binary
  28 + t.fork = true # You may get faster startup if you set this to false
  29 + t.cucumber_opts = "--color -p selenium --format #{ENV['CUCUMBER_FORMAT'] || 'pretty'}"
  30 + end
  31 +
26 desc 'Run all features' 32 desc 'Run all features'
27 task :all => [:ok, :wip] 33 task :all => [:ok, :wip]
28 end 34 end
public/javascripts/application.js
@@ -78,3 +78,24 @@ function disable_button(button) { @@ -78,3 +78,24 @@ function disable_button(button) {
78 button.disable(); 78 button.disable();
79 button.addClassName("disabled"); 79 button.addClassName("disabled");
80 } 80 }
  81 +
  82 +/* ICON SELECTOR - LinkListBlock */
  83 +
  84 +function showIconSelector(main_div) {
  85 + iconSelector = jQuery(main_div).children('.icon-selector')[0];
  86 + jQuery(iconSelector).toggle();
  87 +}
  88 +
  89 +function changeIcon(iconSelected, iconName) {
  90 + iconSelector = iconSelected.parentNode;
  91 + setTimeout('iconSelector.style.display = "none"', 100);
  92 + main_div = iconSelector.parentNode;
  93 + span = main_div.getElementsByTagName('span')[0];
  94 + span.className = iconSelected.className;
  95 + iconInput = main_div.getElementsByTagName('input')[0];
  96 + iconInput.value = iconName;
  97 +}
  98 +
  99 +function hideOthersIconSelector(current_div) {
  100 + jQuery('.icon-selector').not(jQuery(current_div).children('.icon-selector')).hide();
  101 +}
public/stylesheets/application.css
@@ -1513,7 +1513,6 @@ input.disabled { @@ -1513,7 +1513,6 @@ input.disabled {
1513 text-decoration: none; 1513 text-decoration: none;
1514 } 1514 }
1515 1515
1516 -  
1517 /* ==> blocks/link-list-block.css <<= */ 1516 /* ==> blocks/link-list-block.css <<= */
1518 1517
1519 #edit-link-list-block { 1518 #edit-link-list-block {
@@ -1527,7 +1526,7 @@ input.disabled { @@ -1527,7 +1526,7 @@ input.disabled {
1527 } 1526 }
1528 1527
1529 #edit-link-list-block table .cel-address { 1528 #edit-link-list-block table .cel-address {
1530 - width: 180px; 1529 + width: 220px;
1531 } 1530 }
1532 1531
1533 #edit-link-list-block table .cel-address input { 1532 #edit-link-list-block table .cel-address input {
@@ -1557,15 +1556,36 @@ input.disabled { @@ -1557,15 +1556,36 @@ input.disabled {
1557 padding-left: 23px; 1556 padding-left: 23px;
1558 } 1557 }
1559 1558
1560 -#edit-link-list-block select {  
1561 - width: 80px; 1559 +.icon-selector {
  1560 + background: #EEE;
  1561 + border: 1px solid #555;
  1562 + padding: 10px;
  1563 + width: 110px;
  1564 + height: 110px;
  1565 + position: absolute;
  1566 + z-index: 100;
  1567 +}
  1568 +.icon {
  1569 + border:1px solid #EEE;
  1570 +}
  1571 +.icon:hover {
  1572 + border: 1px solid black;
  1573 + cursor: pointer;
  1574 + background-color: #555;
1562 } 1575 }
1563 1576
1564 -#edit-link-list-block option {  
1565 - background-repeat: no-repeat;  
1566 - padding-left: 23px;  
1567 - margin: 2px;  
1568 - height: 16px; 1577 +.icon-selector span {
  1578 + height:16px;
  1579 + width:16px;
  1580 + border:1px solid #555;
  1581 + margin:2px;
  1582 + display: block;
  1583 + float: left;
  1584 +}
  1585 +
  1586 +.icon-selector span:hover {
  1587 + border: 1px solid black;
  1588 + background-color: #555;
1569 } 1589 }
1570 1590
1571 /* ==> blocks/profile-list-block.css <<= */ 1591 /* ==> blocks/profile-list-block.css <<= */
test/unit/link_list_block_test.rb
@@ -43,7 +43,7 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase @@ -43,7 +43,7 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
43 should 'display options for icons' do 43 should 'display options for icons' do
44 l = LinkListBlock.new 44 l = LinkListBlock.new
45 l.icons_options.each do |option| 45 l.icons_options.each do |option|
46 - assert_match(/<option class='icon-.+' value='.+' (selected='1')?>[^<>]+<\/option>/, option) 46 + assert_match(/<span class=\"icon-.+\" onclick=\"changeIcon\(this, '.+'\)\"><\/span>/, option)
47 end 47 end
48 end 48 end
49 49