Commit f476a761f710c3c201c94dff939fdd9ec351d30c
Committed by
Antonio Terceiro
1 parent
8bac0258
Exists in
master
and in
29 other branches
More user-friendly icon selector for block of links
(ActionItem1428)
Showing
12 changed files
with
133 additions
and
23 deletions
Show diff stats
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 |
@@ -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
@@ -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 |
@@ -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 < ActiveSupport::TestCase | @@ -43,7 +43,7 @@ class LinkListBlockTest < 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 |