添加course_group表单到数据库中,并建立对应于members和courses之间的关联,
对相应页面的修改 Signed-off-by: alan <547533434@qq.com>
This commit is contained in:
parent
3eddca8c6e
commit
63c9804da8
|
@ -201,13 +201,19 @@ class CoursesController < ApplicationController
|
||||||
@render_file = 'member_list'
|
@render_file = 'member_list'
|
||||||
@teachers= searchTeacherAndAssistant(@course)
|
@teachers= searchTeacherAndAssistant(@course)
|
||||||
@canShowCode = isCourseTeacher(User.current.id,@course) && params[:role] != '1'
|
@canShowCode = isCourseTeacher(User.current.id,@course) && params[:role] != '1'
|
||||||
|
@role = params[:role]
|
||||||
|
@course_group_id = params[:@course_group_id] unless params[:@course_group_id].nil?
|
||||||
case params[:role]
|
case params[:role]
|
||||||
when '1'
|
when '1'
|
||||||
@subPage_title = l :label_teacher_list
|
@subPage_title = l :label_teacher_list
|
||||||
@members = searchTeacherAndAssistant(@course)
|
@members = searchTeacherAndAssistant(@course)
|
||||||
when '2'
|
when '2'
|
||||||
@subPage_title = l :label_student_list
|
@subPage_title = l :label_student_list
|
||||||
@members = searchStudent(@course)
|
if @course_group_id
|
||||||
|
@members = search_student_in_group(@course, @course_group_id)
|
||||||
|
else
|
||||||
|
@members = searchStudent(@course)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
@subPage_title = ''
|
@subPage_title = ''
|
||||||
@members = @course.member_principals.includes(:roles, :principal).all.sort
|
@members = @course.member_principals.includes(:roles, :principal).all.sort
|
||||||
|
|
|
@ -170,7 +170,7 @@ module CoursesHelper
|
||||||
members
|
members
|
||||||
end
|
end
|
||||||
|
|
||||||
def searchStudent project
|
def search_student_in_group(project, course_group_id)
|
||||||
#searchPeopleByRoles(project, StudentRoles)
|
#searchPeopleByRoles(project, StudentRoles)
|
||||||
members = []
|
members = []
|
||||||
project.members.each do |m|
|
project.members.each do |m|
|
||||||
|
@ -178,6 +178,14 @@ module CoursesHelper
|
||||||
end
|
end
|
||||||
members
|
members
|
||||||
end
|
end
|
||||||
|
def searchStudent project
|
||||||
|
#searchPeopleByRoles(project, StudentRoles)
|
||||||
|
members = []
|
||||||
|
project.members.each do |m|
|
||||||
|
members << m if m && m.user && m.user.allowed_to?(:as_student,project)
|
||||||
|
end
|
||||||
|
members
|
||||||
|
end
|
||||||
# =====================================================================================
|
# =====================================================================================
|
||||||
|
|
||||||
#def searchCountByRoles project, roles_id
|
#def searchCountByRoles project, roles_id
|
||||||
|
|
|
@ -29,6 +29,8 @@ class Course < ActiveRecord::Base
|
||||||
has_many :news, :dependent => :destroy, :include => :author
|
has_many :news, :dependent => :destroy, :include => :author
|
||||||
has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy
|
has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy
|
||||||
|
|
||||||
|
has_many :course_groups, :dependent => :destroy
|
||||||
|
|
||||||
acts_as_taggable
|
acts_as_taggable
|
||||||
acts_as_nested_set :order => 'name', :dependent => :destroy
|
acts_as_nested_set :order => 'name', :dependent => :destroy
|
||||||
acts_as_attachable :view_permission => :view_files,
|
acts_as_attachable :view_permission => :view_files,
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
class CourseGroup < ActiveRecord::Base
|
||||||
|
# attr_accessible :title, :body
|
||||||
|
belongs_to :course
|
||||||
|
has_many :members
|
||||||
|
|
||||||
|
before_destroy :set_member_nil
|
||||||
|
|
||||||
|
attr_accessible :name
|
||||||
|
|
||||||
|
def set_member_nil
|
||||||
|
if self.members && self.members.count > 0
|
||||||
|
self.members.update_all("course_group_id = 0")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -24,6 +24,7 @@ class Member < ActiveRecord::Base
|
||||||
belongs_to :project
|
belongs_to :project
|
||||||
belongs_to :course
|
belongs_to :course
|
||||||
|
|
||||||
|
belongs_to :course_group
|
||||||
validates_presence_of :principal
|
validates_presence_of :principal
|
||||||
validates_uniqueness_of :user_id, :scope => [:project_id,:course_id]
|
validates_uniqueness_of :user_id, :scope => [:project_id,:course_id]
|
||||||
validate :validate_role
|
validate :validate_role
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
<div class="member_header">
|
<%= stylesheet_link_tag 'course_group', :media => 'all' %>
|
||||||
<p>
|
<div class="st_list">
|
||||||
<%= @subPage_title %>
|
<div class="st_search">
|
||||||
</p>
|
<span class="f_l"><%= @subPage_title %></span>
|
||||||
</div>
|
<% if @subPage_title == l(:label_student_list) %>
|
||||||
<div class="member_content">
|
<form class="f_l"><%= text_field_tag 'name', params[:name], name: "name", class: 'f_1'%></form>
|
||||||
<%= error_messages_for 'member' %>
|
<%= submit_tag l(:label_search), :class => 'f_2' %>
|
||||||
<%= render :partial => @render_file, :locals => {:members => @members} %>
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="member_content">
|
||||||
|
<%= error_messages_for 'member' %>
|
||||||
|
<%= render :partial => @render_file, :locals => {:members => @members} %>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
class CreateCourseGroups < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :course_groups do |t|
|
||||||
|
t.string :name
|
||||||
|
t.integer :course_id
|
||||||
|
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddColumnToMembers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :members, :course_group_id, :integer, default: 0
|
||||||
|
end
|
||||||
|
end
|
10
db/schema.rb
10
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20141120091234) do
|
ActiveRecord::Schema.define(:version => 20141126091750) do
|
||||||
|
|
||||||
create_table "activities", :force => true do |t|
|
create_table "activities", :force => true do |t|
|
||||||
t.integer "act_id", :null => false
|
t.integer "act_id", :null => false
|
||||||
|
@ -313,6 +313,13 @@ ActiveRecord::Schema.define(:version => 20141120091234) do
|
||||||
t.integer "container_id", :default => 0
|
t.integer "container_id", :default => 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "course_groups", :force => true do |t|
|
||||||
|
t.string "name"
|
||||||
|
t.integer "course_id"
|
||||||
|
t.datetime "created_at", :null => false
|
||||||
|
t.datetime "updated_at", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "course_infos", :force => true do |t|
|
create_table "course_infos", :force => true do |t|
|
||||||
t.integer "course_id"
|
t.integer "course_id"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
|
@ -651,6 +658,7 @@ ActiveRecord::Schema.define(:version => 20141120091234) do
|
||||||
t.datetime "created_on"
|
t.datetime "created_on"
|
||||||
t.boolean "mail_notification", :default => false, :null => false
|
t.boolean "mail_notification", :default => false, :null => false
|
||||||
t.integer "course_id", :default => -1
|
t.integer "course_id", :default => -1
|
||||||
|
t.integer "course_group_id", :default => 0
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "members", ["project_id"], :name => "index_members_on_project_id"
|
add_index "members", ["project_id"], :name => "index_members_on_project_id"
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
After Width: | Height: | Size: 958 B |
Binary file not shown.
After Width: | Height: | Size: 629 B |
Binary file not shown.
After Width: | Height: | Size: 217 B |
|
@ -1,696 +0,0 @@
|
||||||
//= require_directory ./rateable
|
|
||||||
/* Redmine - project management software
|
|
||||||
Copyright (C) 2006-2013 Jean-Philippe Lang */
|
|
||||||
|
|
||||||
function cleanArray (actual){
|
|
||||||
var newArray = new Array();
|
|
||||||
for (var i = 0; i< actual.length; i++){
|
|
||||||
if (actual[i]){
|
|
||||||
newArray.push(actual[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkAll(id, checked) {
|
|
||||||
if (checked) {
|
|
||||||
$('#'+id).find('input[type=checkbox]').attr('checked', true);
|
|
||||||
} else {
|
|
||||||
$('#'+id).find('input[type=checkbox]').removeAttr('checked');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleCheckboxesBySelector(selector) {
|
|
||||||
var all_checked = true;
|
|
||||||
$(selector).each(function(index) {
|
|
||||||
if (!$(this).is(':checked')) { all_checked = false; }
|
|
||||||
});
|
|
||||||
$(selector).attr('checked', !all_checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showAndScrollTo(id, focus) {
|
|
||||||
$('#'+id).show();
|
|
||||||
if (focus !== null) {
|
|
||||||
$('#'+focus).focus();
|
|
||||||
}
|
|
||||||
$('html, body').animate({scrollTop: $('#'+id).offset().top}, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleRowGroup(el) {
|
|
||||||
var tr = $(el).parents('tr').first();
|
|
||||||
var n = tr.next();
|
|
||||||
tr.toggleClass('open');
|
|
||||||
while (n.length && !n.hasClass('group')) {
|
|
||||||
n.toggle();
|
|
||||||
n = n.next('tr');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function collapseAllRowGroups(el) {
|
|
||||||
var tbody = $(el).parents('tbody').first();
|
|
||||||
tbody.children('tr').each(function(index) {
|
|
||||||
if ($(this).hasClass('group')) {
|
|
||||||
$(this).removeClass('open');
|
|
||||||
} else {
|
|
||||||
$(this).hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function expandAllRowGroups(el) {
|
|
||||||
var tbody = $(el).parents('tbody').first();
|
|
||||||
tbody.children('tr').each(function(index) {
|
|
||||||
if ($(this).hasClass('group')) {
|
|
||||||
$(this).addClass('open');
|
|
||||||
} else {
|
|
||||||
$(this).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAllRowGroups(el) {
|
|
||||||
var tr = $(el).parents('tr').first();
|
|
||||||
if (tr.hasClass('open')) {
|
|
||||||
collapseAllRowGroups(el);
|
|
||||||
} else {
|
|
||||||
expandAllRowGroups(el);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleFieldset(el) {
|
|
||||||
var fieldset = $(el).parents('fieldset').first();
|
|
||||||
fieldset.toggleClass('collapsed');
|
|
||||||
fieldset.children('div').toggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideFieldset(el) {
|
|
||||||
var fieldset = $(el).parents('fieldset').first();
|
|
||||||
fieldset.toggleClass('collapsed');
|
|
||||||
fieldset.children('div').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function initFilters(){
|
|
||||||
$('#add_filter_select').change(function(){
|
|
||||||
addFilter($(this).val(), '', []);
|
|
||||||
});
|
|
||||||
$('#filters-table td.field input[type=checkbox]').each(function(){
|
|
||||||
toggleFilter($(this).val());
|
|
||||||
});
|
|
||||||
$('#filters-table td.field input[type=checkbox]').live('click',function(){
|
|
||||||
toggleFilter($(this).val());
|
|
||||||
});
|
|
||||||
$('#filters-table .toggle-multiselect').live('click',function(){
|
|
||||||
toggleMultiSelect($(this).siblings('select'));
|
|
||||||
});
|
|
||||||
$('#filters-table input[type=text]').live('keypress', function(e){
|
|
||||||
if (e.keyCode == 13) submit_query_form("query_form");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFilter(field, operator, values) {
|
|
||||||
var fieldId = field.replace('.', '_');
|
|
||||||
var tr = $('#tr_'+fieldId);
|
|
||||||
if (tr.length > 0) {
|
|
||||||
tr.show();
|
|
||||||
} else {
|
|
||||||
buildFilterRow(field, operator, values);
|
|
||||||
}
|
|
||||||
$('#cb_'+fieldId).attr('checked', true);
|
|
||||||
toggleFilter(field);
|
|
||||||
$('#add_filter_select').val('').children('option').each(function(){
|
|
||||||
if ($(this).attr('value') == field) {
|
|
||||||
$(this).attr('disabled', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildFilterRow(field, operator, values) {
|
|
||||||
var fieldId = field.replace('.', '_');
|
|
||||||
var filterTable = $("#filters-table");
|
|
||||||
var filterOptions = availableFilters[field];
|
|
||||||
var operators = operatorByType[filterOptions['type']];
|
|
||||||
var filterValues = filterOptions['values'];
|
|
||||||
var i, select;
|
|
||||||
|
|
||||||
var tr = $('<tr class="filter">').attr('id', 'tr_'+fieldId).html(
|
|
||||||
'<td class="field"><input checked="checked" id="cb_'+fieldId+'" name="f[]" value="'+field+'" type="checkbox"><label for="cb_'+fieldId+'"> '+filterOptions['name']+'</label></td>' +
|
|
||||||
'<td class="operator"><select id="operators_'+fieldId+'" name="op['+field+']"></td>' +
|
|
||||||
'<td class="values"></td>'
|
|
||||||
);
|
|
||||||
filterTable.append(tr);
|
|
||||||
|
|
||||||
select = tr.find('td.operator select');
|
|
||||||
for (i=0;i<operators.length;i++){
|
|
||||||
var option = $('<option>').val(operators[i]).text(operatorLabels[operators[i]]);
|
|
||||||
if (operators[i] == operator) { option.attr('selected', true); }
|
|
||||||
select.append(option);
|
|
||||||
}
|
|
||||||
select.change(function(){ toggleOperator(field); });
|
|
||||||
|
|
||||||
switch (filterOptions['type']){
|
|
||||||
case "list":
|
|
||||||
case "list_optional":
|
|
||||||
case "list_status":
|
|
||||||
case "list_subprojects":
|
|
||||||
tr.find('td.values').append(
|
|
||||||
'<span style="display:none;"><select class="value" id="values_'+fieldId+'_1" name="v['+field+'][]"></select>' +
|
|
||||||
' <span class="toggle-multiselect"><a>复选/multi-select</a></span></span>'
|
|
||||||
);
|
|
||||||
select = tr.find('td.values select');
|
|
||||||
if (values.length > 1) { select.attr('multiple', true); }
|
|
||||||
for (i=0;i<filterValues.length;i++){
|
|
||||||
var filterValue = filterValues[i];
|
|
||||||
var option = $('<option>');
|
|
||||||
if ($.isArray(filterValue)) {
|
|
||||||
option.val(filterValue[1]).text(filterValue[0]);
|
|
||||||
if ($.inArray(filterValue[1], values) > -1) {option.attr('selected', true);}
|
|
||||||
} else {
|
|
||||||
option.val(filterValue).text(filterValue);
|
|
||||||
if ($.inArray(filterValue, values) > -1) {option.attr('selected', true);}
|
|
||||||
}
|
|
||||||
select.append(option);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "date":
|
|
||||||
case "date_past":
|
|
||||||
tr.find('td.values').append(
|
|
||||||
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="10" class="value date_value" /></span>' +
|
|
||||||
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="10" class="value date_value" /></span>' +
|
|
||||||
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="3" class="value" /> '+labelDayPlural+'</span>'
|
|
||||||
);
|
|
||||||
$('#values_'+fieldId+'_1').val(values[0]).datepicker(datepickerOptions);
|
|
||||||
$('#values_'+fieldId+'_2').val(values[1]).datepicker(datepickerOptions);
|
|
||||||
$('#values_'+fieldId).val(values[0]);
|
|
||||||
break;
|
|
||||||
case "string":
|
|
||||||
case "text":
|
|
||||||
tr.find('td.values').append(
|
|
||||||
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>'
|
|
||||||
);
|
|
||||||
$('#values_'+fieldId).val(values[0]);
|
|
||||||
break;
|
|
||||||
case "relation":
|
|
||||||
tr.find('td.values').append(
|
|
||||||
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="6" class="value" /></span>' +
|
|
||||||
'<span style="display:none;"><select class="value" name="v['+field+'][]" id="values_'+fieldId+'_1"></select></span>'
|
|
||||||
);
|
|
||||||
$('#values_'+fieldId).val(values[0]);
|
|
||||||
select = tr.find('td.values select');
|
|
||||||
for (i=0;i<allProjects.length;i++){
|
|
||||||
var filterValue = allProjects[i];
|
|
||||||
var option = $('<option>');
|
|
||||||
option.val(filterValue[1]).text(filterValue[0]);
|
|
||||||
if (values[0] == filterValue[1]) { option.attr('selected', true); }
|
|
||||||
select.append(option);
|
|
||||||
}
|
|
||||||
case "integer":
|
|
||||||
case "float":
|
|
||||||
tr.find('td.values').append(
|
|
||||||
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
|
|
||||||
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
|
|
||||||
);
|
|
||||||
$('#values_'+fieldId+'_1').val(values[0]);
|
|
||||||
$('#values_'+fieldId+'_2').val(values[1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleFilter(field) {
|
|
||||||
var fieldId = field.replace('.', '_');
|
|
||||||
if ($('#cb_' + fieldId).is(':checked')) {
|
|
||||||
$("#operators_" + fieldId).show().removeAttr('disabled');
|
|
||||||
toggleOperator(field);
|
|
||||||
} else {
|
|
||||||
$("#operators_" + fieldId).hide().attr('disabled', true);
|
|
||||||
enableValues(field, []);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function enableValues(field, indexes) {
|
|
||||||
var fieldId = field.replace('.', '_');
|
|
||||||
$('#tr_'+fieldId+' td.values .value').each(function(index) {
|
|
||||||
if ($.inArray(index, indexes) >= 0) {
|
|
||||||
$(this).removeAttr('disabled');
|
|
||||||
$(this).parents('span').first().show();
|
|
||||||
} else {
|
|
||||||
$(this).val('');
|
|
||||||
$(this).attr('disabled', true);
|
|
||||||
$(this).parents('span').first().hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($(this).hasClass('group')) {
|
|
||||||
$(this).addClass('open');
|
|
||||||
} else {
|
|
||||||
$(this).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleOperator(field) {
|
|
||||||
var fieldId = field.replace('.', '_');
|
|
||||||
var operator = $("#operators_" + fieldId);
|
|
||||||
switch (operator.val()) {
|
|
||||||
case "!*":
|
|
||||||
case "*":
|
|
||||||
case "t":
|
|
||||||
case "ld":
|
|
||||||
case "w":
|
|
||||||
case "lw":
|
|
||||||
case "l2w":
|
|
||||||
case "m":
|
|
||||||
case "lm":
|
|
||||||
case "y":
|
|
||||||
case "o":
|
|
||||||
case "c":
|
|
||||||
enableValues(field, []);
|
|
||||||
break;
|
|
||||||
case "><":
|
|
||||||
enableValues(field, [0,1]);
|
|
||||||
break;
|
|
||||||
case "<t+":
|
|
||||||
case ">t+":
|
|
||||||
case "><t+":
|
|
||||||
case "t+":
|
|
||||||
case ">t-":
|
|
||||||
case "<t-":
|
|
||||||
case "><t-":
|
|
||||||
case "t-":
|
|
||||||
enableValues(field, [2]);
|
|
||||||
break;
|
|
||||||
case "=p":
|
|
||||||
case "=!p":
|
|
||||||
case "!p":
|
|
||||||
enableValues(field, [1]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
enableValues(field, [0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleMultiSelect(el) {
|
|
||||||
if (el.attr('multiple')) {
|
|
||||||
el.removeAttr('multiple');
|
|
||||||
} else {
|
|
||||||
el.attr('multiple', true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function submit_query_form(id) {
|
|
||||||
selectAllOptions("selected_columns");
|
|
||||||
$('#'+id).submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function showTab(name) {
|
|
||||||
$('div#content .tab-content').hide();
|
|
||||||
$('div.tabs a').removeClass('selected');
|
|
||||||
$('#tab-content-' + name).show();
|
|
||||||
$('#tab-' + name).addClass('selected');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveTabRight(el) {
|
|
||||||
var lis = $(el).parents('div.tabs').first().find('ul').children();
|
|
||||||
var tabsWidth = 0;
|
|
||||||
var i = 0;
|
|
||||||
lis.each(function(){
|
|
||||||
if ($(this).is(':visible')) {
|
|
||||||
tabsWidth += $(this).width() + 6;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (tabsWidth < $(el).parents('div.tabs').first().width() - 60) { return; }
|
|
||||||
while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
|
|
||||||
lis.eq(i).hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function moveTabLeft(el) {
|
|
||||||
var lis = $(el).parents('div.tabs').first().find('ul').children();
|
|
||||||
var i = 0;
|
|
||||||
while (i<lis.length && !lis.eq(i).is(':visible')) { i++; }
|
|
||||||
if (i>0) {
|
|
||||||
lis.eq(i-1).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function displayTabsButtons() {
|
|
||||||
var lis;
|
|
||||||
var tabsWidth = 0;
|
|
||||||
var el;
|
|
||||||
$('div.tabs').each(function() {
|
|
||||||
el = $(this);
|
|
||||||
lis = el.find('ul').children();
|
|
||||||
lis.each(function(){
|
|
||||||
if ($(this).is(':visible')) {
|
|
||||||
tabsWidth += $(this).width() + 6;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if ((tabsWidth < el.width() - 60) && (lis.first().is(':visible'))) {
|
|
||||||
el.find('div.tabs-buttons').hide();
|
|
||||||
} else {
|
|
||||||
el.find('div.tabs-buttons').show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPredecessorFieldsVisibility() {
|
|
||||||
var relationType = $('#relation_relation_type');
|
|
||||||
if (relationType.val() == "precedes" || relationType.val() == "follows") {
|
|
||||||
$('#predecessor_fields').show();
|
|
||||||
} else {
|
|
||||||
$('#predecessor_fields').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showModal(id, width) {
|
|
||||||
var el = $('#'+id).first();
|
|
||||||
if (el.length === 0 || el.is(':visible')) {return;}
|
|
||||||
var title = el.find('h3.title').text();
|
|
||||||
el.dialog({
|
|
||||||
width: width,
|
|
||||||
modal: true,
|
|
||||||
resizable: false,
|
|
||||||
dialogClass: 'modal',
|
|
||||||
title: title
|
|
||||||
});
|
|
||||||
el.find("input[type=text], input[type=submit]").first().focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideModal(el) {
|
|
||||||
var modal;
|
|
||||||
if (el) {
|
|
||||||
modal = $(el).parents('.ui-dialog-content');
|
|
||||||
} else {
|
|
||||||
modal = $('#ajax-modal');
|
|
||||||
}
|
|
||||||
modal.dialog("close");
|
|
||||||
}
|
|
||||||
|
|
||||||
function submitPreview(url, form, target) {
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'post',
|
|
||||||
beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
|
|
||||||
data: $('#'+form).serialize(),
|
|
||||||
success: function(data){
|
|
||||||
$('#'+target).html(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function collapseScmEntry(id) {
|
|
||||||
$('.'+id).each(function() {
|
|
||||||
if ($(this).hasClass('open')) {
|
|
||||||
collapseScmEntry($(this).attr('id'));
|
|
||||||
}
|
|
||||||
$(this).hide();
|
|
||||||
});
|
|
||||||
$('#'+id).removeClass('open');
|
|
||||||
}
|
|
||||||
|
|
||||||
function expandScmEntry(id) {
|
|
||||||
$('.'+id).each(function() {
|
|
||||||
$(this).show();
|
|
||||||
if ($(this).hasClass('loaded') && !$(this).hasClass('collapsed')) {
|
|
||||||
expandScmEntry($(this).attr('id'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('#'+id).addClass('open');
|
|
||||||
}
|
|
||||||
|
|
||||||
function scmEntryClick(id, url) {
|
|
||||||
el = $('#'+id);
|
|
||||||
if (el.hasClass('open')) {
|
|
||||||
collapseScmEntry(id);
|
|
||||||
el.addClass('collapsed');
|
|
||||||
return false;
|
|
||||||
} else if (el.hasClass('loaded')) {
|
|
||||||
expandScmEntry(id);
|
|
||||||
el.removeClass('collapsed');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (el.hasClass('loading')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
el.addClass('loading');
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
success: function(data){
|
|
||||||
el.after(data);
|
|
||||||
el.addClass('open').addClass('loaded').removeClass('loading');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function randomKey(size) {
|
|
||||||
var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
|
|
||||||
var key = '';
|
|
||||||
for (i = 0; i < size; i++) {
|
|
||||||
key += chars[Math.floor(Math.random() * chars.length)];
|
|
||||||
}
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't use Rails' remote select because we need the form data
|
|
||||||
function updateIssueFrom(url) {
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'post',
|
|
||||||
data: $('#issue-form').serialize()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateBulkEditFrom(url) {
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'post',
|
|
||||||
data: $('#bulk_edit_form').serialize()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearMessage(id) {
|
|
||||||
$('#'+id).val("");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function observeAutocompleteField(fieldId, url, options) {
|
|
||||||
$(document).ready(function() {
|
|
||||||
$('#'+fieldId).autocomplete($.extend({
|
|
||||||
source: url,
|
|
||||||
select: function(e,ui){self.location="/issues/"+ui.item.value;},
|
|
||||||
minLength: 2,
|
|
||||||
search: function(){$('#'+fieldId).addClass('ajax-loading');},
|
|
||||||
response: function(){$('#'+fieldId).removeClass('ajax-loading');
|
|
||||||
}
|
|
||||||
}, options));
|
|
||||||
$('#'+fieldId).addClass('autocomplete');
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function observeSearchfield(fieldId, targetId, url) {
|
|
||||||
$('#'+fieldId).each(function() {
|
|
||||||
var $this = $(this);
|
|
||||||
$this.addClass('autocomplete');
|
|
||||||
$this.attr('data-value-was', $this.val());
|
|
||||||
var check = function() {
|
|
||||||
var val = $this.val();
|
|
||||||
if ($this.attr('data-value-was') != val){
|
|
||||||
$this.attr('data-value-was', val);
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'get',
|
|
||||||
data: {q: $this.val()},
|
|
||||||
success: function(data){ if(targetId) $('#'+targetId).html(data); },
|
|
||||||
beforeSend: function(){ $this.addClass('ajax-loading'); },
|
|
||||||
complete: function(){ $this.removeClass('ajax-loading'); }
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var reset = function() {
|
|
||||||
if (timer) {
|
|
||||||
clearInterval(timer);
|
|
||||||
timer = setInterval(check, 300);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var timer = setInterval(check, 300);
|
|
||||||
$this.bind('keyup click mousemove', reset);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function observeProjectModules() {
|
|
||||||
var f = function() {
|
|
||||||
/* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
|
|
||||||
if ($('#project_enabled_module_names_issue_tracking').attr('checked')) {
|
|
||||||
$('#project_trackers').show();
|
|
||||||
}else{
|
|
||||||
$('#project_trackers').hide();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$(window).load(f);
|
|
||||||
$('#project_enabled_module_names_issue_tracking').change(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
function initMyPageSortable(list, url) {
|
|
||||||
$('#list-'+list).sortable({
|
|
||||||
connectWith: '.block-receiver',
|
|
||||||
tolerance: 'pointer',
|
|
||||||
update: function(){
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
type: 'post',
|
|
||||||
data: {'blocks': $.map($('#list-'+list).children(), function(el){return $(el).attr('id');})}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$("#list-top, #list-left, #list-right").disableSelection();
|
|
||||||
}
|
|
||||||
|
|
||||||
var warnLeavingUnsavedMessage;
|
|
||||||
function warnLeavingUnsaved(message) {
|
|
||||||
warnLeavingUnsavedMessage = message;
|
|
||||||
|
|
||||||
$('form').submit(function(){
|
|
||||||
$('textarea').removeData('changed');
|
|
||||||
});
|
|
||||||
$('textarea').change(function(){
|
|
||||||
$(this).data('changed', 'changed');
|
|
||||||
});
|
|
||||||
window.onbeforeunload = function(){
|
|
||||||
var warn = false;
|
|
||||||
$('textarea').blur().each(function(){
|
|
||||||
if ($(this).data('changed')) {
|
|
||||||
warn = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (warn) {return warnLeavingUnsavedMessage;}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupAjaxIndicator() {
|
|
||||||
|
|
||||||
$('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) {
|
|
||||||
|
|
||||||
if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') {
|
|
||||||
$('#ajax-indicator').show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#ajax-indicator').bind('ajaxStop', function() {
|
|
||||||
$('#ajax-indicator').hide();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideOnLoad() {
|
|
||||||
$('.hol').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addFormObserversForDoubleSubmit() {
|
|
||||||
$('form[method=post]').each(function() {
|
|
||||||
if (!$(this).hasClass('multiple-submit')) {
|
|
||||||
$(this).submit(function(form_submission) {
|
|
||||||
if ($(form_submission.target).attr('data-submitted')) {
|
|
||||||
form_submission.preventDefault();
|
|
||||||
} else {
|
|
||||||
$(form_submission.target).attr('data-submitted', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function blockEventPropagation(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleAndSettingWordsVal(parent_widget, text_widget, value){
|
|
||||||
text_widget.val(value)
|
|
||||||
parent_widget.slideToggle(400)
|
|
||||||
}
|
|
||||||
function transpotUrl (scope) {
|
|
||||||
$(scope).each(function(){
|
|
||||||
var tmpContent = $(this).html();
|
|
||||||
tmpContent = tmpContent.replace(/(^|[^\"\'])(http|ftp|mms|rstp|news|https)(\:\/\/[^<\s\+,,]+)/gi,"$1<a href='$2$3' target='_blank'>$2$3<\/a>");
|
|
||||||
// tmpContent = tmpContent.replace(/(^|[^\/])(www\.[^<\s\+,,]+)/gi,"$1<a href='http:\/\/$2' style='color:blue' target='_blank'>$2</a>");
|
|
||||||
$(this).html(tmpContent);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(setupAjaxIndicator);
|
|
||||||
$(document).ready(hideOnLoad);
|
|
||||||
$(document).ready(addFormObserversForDoubleSubmit);
|
|
||||||
$(document).ready(function(){
|
|
||||||
$.ajaxSetup({
|
|
||||||
headers: {
|
|
||||||
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
function img_thumbnails() {
|
|
||||||
$('.thumbnails a').colorbox({rel:'nofollow'});
|
|
||||||
$('.attachments').find('a').each(function(index, element) {
|
|
||||||
var href_value = $(element).attr('href');
|
|
||||||
if (/\.(jpg|png|gif|bmp)$/.test(href_value)) {
|
|
||||||
$(element).colorbox({rel:'nofollow'});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$(document).ready(img_thumbnails);
|
|
||||||
|
|
||||||
function TimeClose(dateText, inst) {
|
|
||||||
if(inst.id=="issue_start_date"){
|
|
||||||
time=dateText;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var time=new Date();
|
|
||||||
function TimeBeforeShow(input){
|
|
||||||
if(input.id=="issue_due_date"){
|
|
||||||
//var minDate = $(input).datepicker('option', 'minDate');
|
|
||||||
var tempdata=$("#issue_start_date").attr("value");
|
|
||||||
|
|
||||||
$(input).datepicker('option', 'minDate',new Date(tempdata.replace(/-/g, "/")));
|
|
||||||
//$('.selector').datepicker('option', 'minDate', '12/25/2012');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function SetMinValue(){
|
|
||||||
/// var tempdata=$("#issue_start_date").attr("value");
|
|
||||||
//$('.selector').datepicker('option', 'minDate', '12/25/2012');
|
|
||||||
//alert(tempdata);
|
|
||||||
//$("#issue_due_date").datepicker({
|
|
||||||
// minDate: new Date(2014,08,23)
|
|
||||||
//var datepickerOptions=
|
|
||||||
//{dateFormat: 'yy-mm-dd',minDate: new Date(2014,08,23), showOn: 'button', buttonImageOnly: true, buttonImage: "path_to_image('/images/calendar.png')", showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};
|
|
||||||
//alert( $('.issue_due_date').length);
|
|
||||||
//$('.selector')[1].datepicker('option', 'minDate', new Date(2014, 0 - 8, 23));
|
|
||||||
//$("#issue_due_date").datepicker(datepickerOptions);
|
|
||||||
//$("##{issue_due_date}").datepicker(datepickerOptions);
|
|
||||||
//$("#issue_due_date").datepicker(
|
|
||||||
// {dateFormat: 'yy-mm-dd',minDate: new Date(2014,08,23), showOn: 'button', buttonImageOnly: true, buttonImage: "path_to_image('/images/calendar.png')", showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true}
|
|
||||||
//)
|
|
||||||
//});
|
|
||||||
}
|
|
||||||
function PrecentChange(obj){
|
|
||||||
var _v= obj;
|
|
||||||
if(_v==100)
|
|
||||||
{
|
|
||||||
//var select=$("select[id='issue_status_id']");
|
|
||||||
$("select[id='issue_status_id']").find("option[value='3']").attr("selected","selected");
|
|
||||||
}
|
|
||||||
else if(_v==0)
|
|
||||||
{
|
|
||||||
//alert(1);
|
|
||||||
$("select[id='issue_status_id']").find("option[value='1']").attr("selected","selected");
|
|
||||||
}
|
|
||||||
else if(_v!=100&&_v!=0)
|
|
||||||
{
|
|
||||||
// alert(2);
|
|
||||||
$("select[id='issue_status_id']").find("option[value='2']").attr("selected","selected");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
body{ font-size:12px; font-family:"微软雅黑","宋体"; line-height:1.9; background:#fff; font-style:normal;}
|
||||||
|
div,html,img,ul,li,p,body,h1,h2,h3,h4,p,a,table,tr,td,fieldset,input,span,textarea,form{ margin:0; padding:0;}
|
||||||
|
div,img,tr,td,textarea,form{ border:0;}
|
||||||
|
table,tr,td{border:0; cellspacing:0; cellpadding:0;}
|
||||||
|
ul,li{ list-style-type:none}
|
||||||
|
.cl{ clear:both; overflow:hidden; }
|
||||||
|
a{ text-decoration:none; }
|
||||||
|
a:hover{ }
|
||||||
|
/**** 常用***/
|
||||||
|
.f_l{ float:left;}
|
||||||
|
.f_r{ float:right;}
|
||||||
|
.b_lblue{ background:#64bdd9;}
|
||||||
|
.b_dblue{ background:#55a1b9; cursor:pointer;}
|
||||||
|
.f_b{ font-weight: bold;}
|
||||||
|
.c_blue{ color:#64bdd9;}
|
||||||
|
.c_grey{ color:#999999;}
|
||||||
|
.c_grey02{ color:#666666;}
|
||||||
|
.f_14{ font-size:14px;}
|
||||||
|
.c_dblue{ color:#3e6d8e;}
|
||||||
|
.c_red{ color:#ec0016;}
|
||||||
|
.w90{width:90px;}
|
||||||
|
.ml10{margin-left:10px;}
|
||||||
|
|
||||||
|
.container{ width:940px; margin:0 auto; font-size:12px;}
|
||||||
|
|
||||||
|
.st_list{ width:688px; padding-left:5px; height:800px;}
|
||||||
|
.st_search{ margin:10px 0;}
|
||||||
|
.st_search span{ font-size:14px; font-weight:bold; color:#606060; margin-right:35px;}
|
||||||
|
.st_search input{ border:1px solid #1c9ec7; background:#fff; height:20px; color:#c4c4c4; width:200px;}
|
||||||
|
.st_search input.f_2{ background:#1c9ec7; padding: 3px; margin-left: 3px; color:#fff;border:1px solid #1c9ec7; text-align:center; display:block; width:45px; height:28px; float:left; font-size:12px; }
|
||||||
|
.st_search a:hover{ background:#048fbb; text-decoration:none;}
|
||||||
|
|
||||||
|
.classbox{ border:1px solid #f8df8c; background:#fffce6; color:#0d90c3; padding:0 3px; float:left; margin-left:15px;}
|
||||||
|
.st_addclass{ margin-top:5px;}
|
||||||
|
.st_addclass ul li{ margin-bottom:10px;}
|
||||||
|
.st_addclass ul li,.st_addclass a,.st_addclass img{ float:left;}
|
||||||
|
.st_addclass img{ margin-top:3px;}
|
||||||
|
.st_addclass a{ color:#0d90c3;}
|
||||||
|
|
||||||
|
.st_box{ margin-top:10px; border-top:1px solid #CCC; padding-top:10px;}
|
||||||
|
.st_box ul li{ float:left;}
|
||||||
|
.st_box_top a{ font-weight:bold; color:#7a7a7a; float:left;}
|
||||||
|
.st_box_top a:hover{ color:#1c9ec7;}
|
||||||
|
a.st_up{ display: block; width:8px; float:left; height:13px; background:url(images/pic_up.png) 0 0 no-repeat; margin-top:5px; margin-left:3px;}
|
||||||
|
a.st_down{ display: block; width:8px; float:left; height:13px; background:url(images/pic_up.png) 0 -22px no-repeat; margin-top:5px; margin-left:3px;}
|
||||||
|
a.st_img { display:block;width:40px; height:40px; border:1px solid #CCC; padding:1px;}
|
||||||
|
a:hover.st_img { border:1px solid #1c9ec7; }
|
||||||
|
.st_boxlist{ border-bottom:1px dashed #CCC; height:53px; padding-top:10px; }
|
||||||
|
.st_boxlist a{ float:left;}
|
||||||
|
.st_boxlist ul{ float:left; width:200px; margin-left:10px;}
|
||||||
|
.st_boxlist ul li a{ color:#5d5d5d;}
|
||||||
|
.st_boxlist ul li a span{ color:#1c9ec7;}
|
||||||
|
.st_boxlist ul li a:hover span{ color:#ff8e15;}
|
||||||
|
.ml50{ margin-left:50px;}
|
||||||
|
.ml358{ margin-left:358px;}
|
||||||
|
.ml258{ margin-left:254px;}
|
||||||
|
.ml65{ margin-left:65px;}
|
||||||
|
a:hover.st_add{ color:#ff8e15;}
|
||||||
|
|
||||||
|
/****翻页***/
|
||||||
|
.wlist{ margin-top:15px; float:right;}
|
||||||
|
.wlist a{ float:left; border:1px solid #15bccf; padding:0 5px; margin-left:3px; color:#15bccf;}
|
||||||
|
.wlist a:hover{border:1px solid #15bccf; background-color:#15bccf; color:#fff;}
|
||||||
|
.wlist_select a { background-color:#64bdd9; color:#fff;}
|
||||||
|
|
||||||
|
.submit{height:21px;border:0; cursor:pointer; background:url(images/btn.png) no-repeat 0 0;width:42px; margin-top:2px; margin-left:3px; }
|
||||||
|
.isTxt{background:#fbfbfb url(images/inputBg.png) repeat-x left top;height:22px;line-height:22px;border:1px solid #c1c1c1;padding:0 5px;color:#666666;}
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html
|
||||||
|
|
||||||
|
# This model initially had no columns defined. If you add columns to the
|
||||||
|
# model remove the '{}' from the fixture names and add the columns immediately
|
||||||
|
# below each fixture, per the syntax in the comments below
|
||||||
|
#
|
||||||
|
one: {}
|
||||||
|
# column: value
|
||||||
|
#
|
||||||
|
two: {}
|
||||||
|
# column: value
|
|
@ -0,0 +1,7 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class CourseGroupTest < ActiveSupport::TestCase
|
||||||
|
# test "the truth" do
|
||||||
|
# assert true
|
||||||
|
# end
|
||||||
|
end
|
Loading…
Reference in New Issue