Commit f476a761f710c3c201c94dff939fdd9ec351d30c
Committed by
Antonio Terceiro
1 parent
8bac0258
Exists in
master
and in
23 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 |