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 | ... | ... |