Commit 894e8962bae842f50f754f91e813a9f36d988fb2
1 parent
bd4954d3
Exists in
master
and in
29 other branches
New way to categorize contents
Showing
11 changed files
with
134 additions
and
98 deletions
Show diff stats
app/controllers/box_organizer_controller.rb
| ... | ... | @@ -99,6 +99,17 @@ class BoxOrganizerController < ApplicationController |
| 99 | 99 | end |
| 100 | 100 | end |
| 101 | 101 | |
| 102 | + def update_categories | |
| 103 | + @object = params[:id] ? boxes_holder.blocks.find(params[:id]) : nil | |
| 104 | + if params[:category_id] | |
| 105 | + @current_category = Category.find(params[:category_id]) | |
| 106 | + @categories = @current_category.children | |
| 107 | + else | |
| 108 | + @categories = environment.top_level_categories | |
| 109 | + end | |
| 110 | + render :partial => 'shared/select_categories', :locals => {:object_name => 'block', :multiple => true}, :layout => false | |
| 111 | + end | |
| 112 | + | |
| 102 | 113 | protected :boxes_editor? |
| 103 | 114 | |
| 104 | 115 | end | ... | ... |
app/controllers/my_profile/cms_controller.rb
| ... | ... | @@ -208,7 +208,7 @@ class CmsController < MyProfileController |
| 208 | 208 | @current_category = Category.find(params[:category_id]) |
| 209 | 209 | @categories = @current_category.children |
| 210 | 210 | else |
| 211 | - @categories = environment.top_level_categories.select{|i| !i.children.empty?} | |
| 211 | + @categories = environment.top_level_categories | |
| 212 | 212 | end |
| 213 | 213 | render :partial => 'shared/select_categories', :locals => {:object_name => 'article', :multiple => true}, :layout => false |
| 214 | 214 | end | ... | ... |
app/controllers/my_profile/profile_editor_controller.rb
| ... | ... | @@ -59,7 +59,7 @@ class ProfileEditorController < MyProfileController |
| 59 | 59 | @current_category = Category.find(params[:category_id]) |
| 60 | 60 | @categories = @current_category.children |
| 61 | 61 | else |
| 62 | - @categories = environment.top_level_categories.select{|i| !i.children.empty?} | |
| 62 | + @categories = environment.top_level_categories | |
| 63 | 63 | end |
| 64 | 64 | render :partial => 'shared/select_categories', :locals => {:object_name => 'profile_data', :multiple => true}, :layout => false |
| 65 | 65 | end | ... | ... |
app/helpers/application_helper.rb
| ... | ... | @@ -619,49 +619,18 @@ module ApplicationHelper |
| 619 | 619 | end |
| 620 | 620 | |
| 621 | 621 | attr_reader :environment |
| 622 | + | |
| 622 | 623 | def select_categories(object_name, title=nil, title_size=4) |
| 623 | 624 | return nil if environment.enabled?(:disable_categories) |
| 624 | 625 | if title.nil? |
| 625 | 626 | title = _('Categories') |
| 626 | 627 | end |
| 627 | 628 | |
| 628 | - object = instance_variable_get("@#{object_name}") | |
| 629 | - | |
| 630 | - result = content_tag 'h'+title_size.to_s(), title | |
| 631 | - result << javascript_tag( 'function open_close_cat( link ) { | |
| 632 | - var div = link.parentNode.getElementsByTagName("div")[0]; | |
| 633 | - var end = function(){ | |
| 634 | - if ( div.style.display == "none" ) { | |
| 635 | - this.link.className="button icon-button icon-down" | |
| 636 | - } else { | |
| 637 | - this.link.className="button icon-button icon-up-red" | |
| 638 | - } | |
| 639 | - } | |
| 640 | - Effect.toggle( div, "slide", { link:link, div:div, afterFinish:end } ) | |
| 641 | - }') | |
| 642 | - environment.top_level_categories.select{|i| !i.children.empty?}.each do |toplevel| | |
| 643 | - next unless object.accept_category?(toplevel) | |
| 644 | - # FIXME | |
| 645 | - ([toplevel] + toplevel.children_for_menu).each do |cat| | |
| 646 | - if cat.top_level? | |
| 647 | - result << '<div class="categorie_box">'.html_safe | |
| 648 | - result << icon_button( :down, _('open'), '#', :onclick => 'open_close_cat(this); return false' ) | |
| 649 | - result << content_tag('h5', toplevel.name) | |
| 650 | - result << '<div style="display:none"><ul class="categories">'.html_safe | |
| 651 | - else | |
| 652 | - checkbox_id = "#{object_name}_#{cat.full_name.downcase.gsub(/\s+|\//, '_')}" | |
| 653 | - result << content_tag('li', labelled_check_box( | |
| 654 | - cat.full_name_without_leading(1, " → "), | |
| 655 | - "#{object_name}[category_ids][]", cat.id, | |
| 656 | - object.category_ids.include?(cat.id), :id => checkbox_id, | |
| 657 | - :onchange => 'this.parentNode.className=(this.checked?"cat_checked":"")' ), | |
| 658 | - :class => ( object.category_ids.include?(cat.id) ? 'cat_checked' : '' ) ) + "\n" | |
| 659 | - end | |
| 660 | - end | |
| 661 | - result << '</ul></div></div>'.html_safe | |
| 662 | - end | |
| 629 | + @object = instance_variable_get("@#{object_name}") | |
| 630 | + @categories = environment.top_level_categories | |
| 663 | 631 | |
| 664 | - content_tag('div', result) | |
| 632 | + @current_categories = environment.top_level_categories.select{|i| !i.children.empty?} | |
| 633 | + render :partial => 'shared/select_categories_top', :locals => {:object_name => object_name, :title => title, :title_size => title_size, :multiple => true, :categories_selected => @object.categories }, :layout => false | |
| 665 | 634 | end |
| 666 | 635 | |
| 667 | 636 | def theme_option(opt = nil) | ... | ... |
app/helpers/categories_helper.rb
| ... | ... | @@ -48,4 +48,9 @@ module CategoriesHelper |
| 48 | 48 | labelled_form_field(_('Type of category'), select_tag('type', options_for_select(TYPES, value))) |
| 49 | 49 | end |
| 50 | 50 | |
| 51 | + #FIXME make this test | |
| 52 | + def selected_category_link(cat) | |
| 53 | + link_to_function(cat.full_name, nil, :id => "remove-selected-category-#{cat.id}-button", :class => 'select-subcategory-link') {|page| page["selected-category-#{cat.id}"].remove} | |
| 54 | + end | |
| 55 | + | |
| 51 | 56 | end | ... | ... |
app/views/shared/_select_categories.rhtml
| 1 | -<div id="category-ajax-selector"> | |
| 1 | +<% extend CategoriesHelper %> | |
| 2 | + | |
| 3 | +<% categories_for_selection = @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)} %> | |
| 4 | + | |
| 2 | 5 | <% if !@current_category.nil? %> |
| 3 | - <h3 class="box-title"><%= _('Current category:') %></h3> | |
| 6 | + <div class="category-helper-label"><%= _('Selected:') %></div> | |
| 4 | 7 | <%= hidden_field_tag "#{object_name}[#{object_name}_category_id]", @current_category.id unless multiple %> |
| 8 | + <%= hidden_field_tag "#{object_name}[category_ids][]", @current_category.id if multiple %> | |
| 9 | + <%= button_to_remote_without_text(:back, _('Back'), | |
| 10 | + { :update => "select-categories", | |
| 11 | + :url => { :action => 'update_categories', :id => @object }, | |
| 12 | + :loaded => visual_effect(:highlight, "select-categories") | |
| 13 | + }, | |
| 14 | + :id => 'cancel-category-button') %> | |
| 5 | 15 | <% |
| 6 | 16 | categories = [@current_category] |
| 7 | 17 | categories.push(@current_category) while @current_category = @current_category.parent |
| ... | ... | @@ -13,34 +23,28 @@ |
| 13 | 23 | :loaded => visual_effect(:highlight, "select-categories"), |
| 14 | 24 | :class => 'select-current-category-link')}.join(' → ') |
| 15 | 25 | %> |
| 16 | - <strong> | |
| 17 | - <%= button_to_function_without_text(:save, _('Save'), nil, :id => 'save-category-button') do |page| | |
| 18 | - page.insert_html :bottom, 'selected-categories', content_tag('li', categories.first.full_name + | |
| 26 | + <%= button_to_function_without_text(:add, _('Add'), nil, :id => 'save-category-button') do |page| | |
| 27 | + page.insert_html :bottom, 'selected-categories', content_tag('span', | |
| 19 | 28 | hidden_field_tag("#{object_name}[category_ids][]", categories.first.id) + |
| 20 | - button_to_function_without_text(:cancel, _('Remove'), nil, :id => "remove-selected-category-#{categories.first.id}-button") {|page| page["selected-category-#{categories.first.id}"].remove}, :id => "selected-category-#{categories.first.id}") | |
| 29 | + selected_category_link(categories.first), :id => "selected-category-#{categories.first.id}") | |
| 21 | 30 | end if multiple %> |
| 22 | - <%= button_to_remote_without_text(:cancel, _('Cancel'), | |
| 23 | - { :update => "select-categories", | |
| 24 | - :url => { :action => 'update_categories', :id => @object }, | |
| 25 | - :loaded => visual_effect(:highlight, "select-categories") | |
| 26 | - }, | |
| 27 | - :id => 'cancel-category-button') %> | |
| 28 | - </strong> | |
| 31 | + <% unless categories_for_selection.empty? %> | |
| 32 | + <hr> | |
| 33 | + <div class="category-helper-label"><%= _('Click to select a subcategory') %></div> | |
| 34 | + <% end %> | |
| 29 | 35 | <% else %> |
| 30 | - <h3 class="box-title"><%= _('Select a category:') %></h3> | |
| 36 | + <div class="category-helper-label"><%= _('Click to select a category') %></div> | |
| 31 | 37 | <% end %> |
| 32 | 38 | |
| 33 | -<% if !@categories.empty? %> | |
| 34 | - <h3><%= _('Categories:') %></h3> | |
| 35 | - <% @categories.select{|i| !@object.respond_to?(:accept_category?) || @object.accept_category?(i)}.each do |category| %> | |
| 36 | - <%= link_to_remote category.name, | |
| 37 | - { :update => "select-categories", | |
| 38 | - :url => { :action => "update_categories", :category_id => category.id, :id => @object}, | |
| 39 | - :loaded => visual_effect(:highlight, "select-categories") | |
| 40 | - }, | |
| 41 | - :class => 'select-subcategory-link', | |
| 42 | - :id => "select-category-#{category.id}-link" | |
| 43 | - %> | |
| 44 | - <% end %> | |
| 39 | +<div class="toplevel-categories"> | |
| 40 | +<% categories_for_selection.each do |category| %> | |
| 41 | + <%= link_to_remote category.name, | |
| 42 | + { :update => "select-categories", | |
| 43 | + :url => { :action => "update_categories", :category_id => category.id, :id => @object}, | |
| 44 | + :loaded => visual_effect(:highlight, "select-categories") | |
| 45 | + }, | |
| 46 | + :class => 'select-subcategory-link', | |
| 47 | + :id => "select-category-#{category.id}-link" | |
| 48 | + %> | |
| 45 | 49 | <% end %> |
| 46 | 50 | </div> | ... | ... |
| ... | ... | @@ -0,0 +1,28 @@ |
| 1 | +<% categories_selected ||= nil %> | |
| 2 | +<% title ||= nil %> | |
| 3 | + | |
| 4 | +<% extend CategoriesHelper %> | |
| 5 | + | |
| 6 | +<%= content_tag "h#{title_size}", title, :class => "box-title" %> | |
| 7 | + | |
| 8 | +<%= hidden_field_tag "#{object_name}[category_ids][]", nil %> | |
| 9 | + | |
| 10 | +<div id="category-ajax-selector"> | |
| 11 | +<div id="select-categories"> | |
| 12 | + <%= render :partial => 'shared/select_categories', :locals => {:object_name => object_name, :multiple => true, :categories_selected => categories_selected }, :layout => false %> | |
| 13 | +</div> | |
| 14 | + | |
| 15 | +<% unless categories_selected.nil? %> | |
| 16 | +<hr> | |
| 17 | +<div id="selected-categories"> | |
| 18 | + <span class="label"><%= _('Selected categories:') %></span> | |
| 19 | + <% categories_selected.each do |cat| %> | |
| 20 | + <span id="selected-category-<%= cat.id %>"> | |
| 21 | + <%= hidden_field_tag("#{object_name}[category_ids][]", cat.id) %> | |
| 22 | + <%= selected_category_link(cat) %> | |
| 23 | + </span> | |
| 24 | + <% end %> | |
| 25 | +</div> | |
| 26 | +<div style="clear: both;"></div> | |
| 27 | +<% end %> | |
| 28 | +</div> | ... | ... |
public/stylesheets/application.css
| ... | ... | @@ -346,21 +346,25 @@ div.pending-tasks { |
| 346 | 346 | margin-bottom: 1px; |
| 347 | 347 | } |
| 348 | 348 | /* * * category ajax selector * * */ |
| 349 | - | |
| 349 | +#category-ajax-selector .category-helper-label { | |
| 350 | + font-size: 8pt; color: rgb(158, 158, 158); | |
| 351 | + padding: 5px 0px; | |
| 352 | +} | |
| 350 | 353 | #category-ajax-selector { |
| 351 | 354 | border: 1px solid #AAA; |
| 352 | - background: #EEE; | |
| 353 | - padding: 15px 0px 15px 20px; | |
| 354 | - margin: 30px 0px 0px 0px; | |
| 355 | + padding: 3px 10px 10px 10px; | |
| 356 | + margin: 0px 0px 0px 0px; | |
| 355 | 357 | position: relative; |
| 356 | - font-size: 18px; | |
| 358 | + font-size: 10px; | |
| 357 | 359 | } |
| 358 | 360 | #category-ajax-selector a { |
| 359 | - font-size: 14px; | |
| 361 | + font-size: 12px; | |
| 360 | 362 | } |
| 361 | -#category-ajax-selector h3 { | |
| 362 | - margin: 10px 0px; | |
| 363 | - font-size: 14px; | |
| 363 | +#selected-categories span { | |
| 364 | + float: left; | |
| 365 | +} | |
| 366 | +#selected-categories .label { | |
| 367 | + font-weight: bold; | |
| 364 | 368 | } |
| 365 | 369 | #category-ajax-selector .box-title { |
| 366 | 370 | position: absolute; |
| ... | ... | @@ -376,25 +380,28 @@ div.pending-tasks { |
| 376 | 380 | .msie6 #category-ajax-selector .box-title { |
| 377 | 381 | top: -29px; |
| 378 | 382 | } |
| 379 | -#category-ajax-selector .select-subcategory-link { | |
| 383 | +#category-ajax-selector .select-subcategory-link, | |
| 384 | +.select-subcategory-link { | |
| 380 | 385 | border: 1px solid #BBB; |
| 381 | 386 | padding: 1px 3px; |
| 382 | 387 | margin: 0px 1px; |
| 383 | 388 | text-decoration: none; |
| 384 | 389 | white-space: nowrap; |
| 385 | 390 | font-size: 11px; |
| 391 | + line-height: 18px; | |
| 386 | 392 | } |
| 387 | -#category-ajax-selector .select-subcategory-link:hover { | |
| 393 | +#category-ajax-selector .select-subcategory-link:hover, | |
| 394 | +.select-subcategory-link:hover { | |
| 388 | 395 | background-color: black; |
| 389 | 396 | } |
| 390 | 397 | #category-ajax-selector .button { |
| 391 | - display: block; | |
| 392 | - position: absolute; | |
| 393 | 398 | top: 4px; |
| 394 | 399 | right: 2px; |
| 395 | 400 | } |
| 396 | -#category-ajax-selector .icon-save { | |
| 401 | +#category-ajax-selector .icon-add { | |
| 397 | 402 | right: 25px; |
| 403 | + display: block; | |
| 404 | + position: absolute; | |
| 398 | 405 | } |
| 399 | 406 | #profile-header, #profile-footer { |
| 400 | 407 | clear: both; | ... | ... |
test/functional/cms_controller_test.rb
| ... | ... | @@ -451,24 +451,23 @@ class CmsControllerTest < ActionController::TestCase |
| 451 | 451 | assert_tag :tag => 'h3', :content => /max size #{UploadedFile.max_size.to_humanreadable}/ |
| 452 | 452 | end |
| 453 | 453 | |
| 454 | - should 'display link for selecting categories' do | |
| 455 | - # FIXME | |
| 456 | - assert true | |
| 457 | - #env = Environment.default | |
| 458 | - #top = env.categories.build(:display_in_menu => true, :name => 'Top-Level category'); top.save! | |
| 459 | - #c1 = env.categories.build(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id); c1.save! | |
| 460 | - #c2 = env.categories.build(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id); c2.save! | |
| 461 | - #c3 = env.categories.build(:display_in_menu => true, :name => "Test Category 3", :parent_id => top.id); c3.save! | |
| 462 | - | |
| 463 | - #article = Article.new(:name => 'test') | |
| 464 | - #article.profile = profile | |
| 465 | - #article.save! | |
| 466 | - | |
| 467 | - #get :edit, :profile => profile.identifier, :id => article.id | |
| 468 | - | |
| 469 | - #[c1,c2,c3].each do |item| | |
| 470 | - # assert_tag :tag => 'a', :attributes => { :id => "select-category-#{item.id}-link" } | |
| 471 | - #end | |
| 454 | + should 'display link for selecting top categories' do | |
| 455 | + env = Environment.default | |
| 456 | + top = env.categories.build(:display_in_menu => true, :name => 'Top-Level category'); top.save! | |
| 457 | + top2 = env.categories.build(:display_in_menu => true, :name => 'Top-Level category 2'); top2.save! | |
| 458 | + c1 = env.categories.build(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id); c1.save! | |
| 459 | + c2 = env.categories.build(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id); c2.save! | |
| 460 | + c3 = env.categories.build(:display_in_menu => true, :name => "Test Category 3", :parent_id => top.id); c3.save! | |
| 461 | + | |
| 462 | + article = Article.new(:name => 'test') | |
| 463 | + article.profile = profile | |
| 464 | + article.save! | |
| 465 | + | |
| 466 | + get :edit, :profile => profile.identifier, :id => article.id | |
| 467 | + | |
| 468 | + [top, top2].each do |item| | |
| 469 | + assert_tag :tag => 'a', :attributes => { :id => "select-category-#{item.id}-link" } | |
| 470 | + end | |
| 472 | 471 | end |
| 473 | 472 | |
| 474 | 473 | should 'be able to associate articles with categories' do | ... | ... |
test/functional/environment_design_controller_test.rb
| ... | ... | @@ -366,4 +366,16 @@ class EnvironmentDesignControllerTest < ActionController::TestCase |
| 366 | 366 | assert @controller.instance_variable_get('@side_block_types').include?(CustomBlock8) |
| 367 | 367 | end |
| 368 | 368 | |
| 369 | + should 'update categories' do | |
| 370 | + env = Environment.default | |
| 371 | + login_as(create_admin_user(env)) | |
| 372 | + top = env.categories.create!(:display_in_menu => true, :name => 'Top-Level category') | |
| 373 | + c1 = env.categories.create!(:display_in_menu => true, :name => "Test category 1", :parent_id => top.id) | |
| 374 | + c2 = env.categories.create!(:display_in_menu => true, :name => "Test category 2", :parent_id => top.id) | |
| 375 | + get :update_categories, :category_id => top.id | |
| 376 | + assert_template 'shared/_select_categories' | |
| 377 | + assert_equal top, assigns(:current_category) | |
| 378 | + assert_equal [c1, c2], assigns(:categories) | |
| 379 | + end | |
| 380 | + | |
| 369 | 381 | end | ... | ... |
test/functional/profile_editor_controller_test.rb
| ... | ... | @@ -73,7 +73,8 @@ class ProfileEditorControllerTest < ActionController::TestCase |
| 73 | 73 | get :edit, :profile => profile.identifier |
| 74 | 74 | assert_response :success |
| 75 | 75 | assert_template 'edit' |
| 76 | - assert_tag :tag => 'input', :attributes => {:name => 'profile_data[category_ids][]', :value => cat2.id} | |
| 76 | + assert_tag :tag => 'input', :attributes => {:name => 'profile_data[category_ids][]'} | |
| 77 | + assert_tag :tag => 'a', :attributes => { :class => 'select-subcategory-link', :id => "select-category-#{cat1.id}-link" } | |
| 77 | 78 | end |
| 78 | 79 | |
| 79 | 80 | should 'save categorization of profile' do |
| ... | ... | @@ -236,7 +237,7 @@ class ProfileEditorControllerTest < ActionController::TestCase |
| 236 | 237 | cat2 = Environment.default.categories.create!(:display_in_menu => true, :name => 'sub category', :parent => cat1) |
| 237 | 238 | person = create_user('testuser').person |
| 238 | 239 | get :edit, :profile => 'testuser' |
| 239 | - assert_tag :tag => 'input', :attributes => { :type => 'checkbox', :name => 'profile_data[category_ids][]', :value => cat2.id} | |
| 240 | + assert_tag :tag => 'a', :attributes => { :class => 'select-subcategory-link', :id => "select-category-#{cat1.id}-link" } | |
| 240 | 241 | end |
| 241 | 242 | |
| 242 | 243 | should 'render edit template' do | ... | ... |