new gradebook2 features
changes: * a little i18n work * show only a certain section * show attendance * include ungraded assigments in score * don't wait for first xhr to fire second * cool drop down menu thing Change-Id: Ie93fd06e20aec399710e32441f8d35c686fbbaf2 Reviewed-on: https://gerrit.instructure.com/4868 Tested-by: Hudson <hudson@instructure.com> Reviewed-by: Brian Whitmer <brian@instructure.com>
This commit is contained in:
parent
9c8dbf57ad
commit
8209a36844
|
@ -4,21 +4,21 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
this.Gradebook = class Gradebook
|
||||
minimumAssignmentColumWidth = 10
|
||||
|
||||
assignmentsToHide = $.store.userGet('hidden_columns_' + $("#current_context_code").text()).split(',')
|
||||
|
||||
constructor: (@options) ->
|
||||
@chunk_start = 0
|
||||
@students = {}
|
||||
@rows = []
|
||||
@filterFn = (student) -> true
|
||||
@sortFn = (student) -> student.display_name
|
||||
@init()
|
||||
@includeUngradedAssignments = false
|
||||
|
||||
init: () ->
|
||||
if @options.assignment_groups
|
||||
return @gotAssignmentGroups(@options.assignment_groups)
|
||||
$.ajaxJSON( @options.assignment_groups_url, "GET", {}, @gotAssignmentGroups )
|
||||
@assignmentsToHide = ($.store.userGet("hidden_columns_#{@options.context_code}") || '').split(',')
|
||||
@sectionToShow = Number($.store.userGet("grading_show_only_section#{@options.context_id}")) || undefined
|
||||
@show_attendance = $.store.userGet("show_attendance_#{@options.context_code}") == 'true'
|
||||
@include_ungraded_assignments = $.store.userGet("include_ungraded_assignments_#{@options.context_code}") == 'true'
|
||||
$.when(
|
||||
$.ajaxJSON( @options.assignment_groups_url, "GET", {}, @gotAssignmentGroups),
|
||||
$.ajaxJSON( @options.sections_and_students_url, "GET", @sectionToShow && {sections: [@sectionToShow]})
|
||||
).then (assignmentGroupsArgs, studentsArgs) =>
|
||||
@gotStudents.apply(this, studentsArgs)
|
||||
@initHeader()
|
||||
|
||||
gotAssignmentGroups: (assignment_groups) =>
|
||||
@assignment_groups = {}
|
||||
|
@ -30,9 +30,6 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
$.htmlEscapeValues(assignment)
|
||||
assignment.due_at = $.parseFromISO(assignment.due_at) if assignment.due_at
|
||||
@assignments[assignment.id] = assignment
|
||||
if @options.sections
|
||||
return @gotStudents(@options.sections)
|
||||
$.ajaxJSON( @options.sections_and_students_url, "GET", {}, @gotStudents )
|
||||
|
||||
gotStudents: (sections) =>
|
||||
@sections = {}
|
||||
|
@ -52,27 +49,32 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
for id, assignment of @assignments
|
||||
student["assignment_#{id}"] ||= { assignment_id: id, user_id: student.id }
|
||||
@rows.push(student)
|
||||
|
||||
@sections_enabled = sections.length > 1
|
||||
|
||||
for id, student of @students
|
||||
student.display_name = "<div class='student-name'>#{student.name}</div>"
|
||||
student.display_name += "<div class='student-section'>#{student.section.name}</div>" if @sections_enabled
|
||||
|
||||
@initGrid()
|
||||
@buildRows()
|
||||
@getSubmissionsChunk()
|
||||
@getSubmissionsChunks()
|
||||
|
||||
rowFilter: (student) =>
|
||||
!@sectionToShow || (student.section.id == @sectionToShow)
|
||||
# filter, sort, and build the dataset for slickgrid to read from, then force
|
||||
# a full redraw
|
||||
buildRows: () ->
|
||||
@rows.length = 0
|
||||
sortables = {}
|
||||
|
||||
for id, column of @gradeGrid.getColumns() when ''+column.object?.submission_types is "attendance"
|
||||
column.unselectable = !@show_attendance
|
||||
column.cssClass = if @show_attendance then '' else 'completely-hidden'
|
||||
@$grid.find("[id*='#{column.id}']").showIf(@show_attendance)
|
||||
|
||||
for id, student of @students
|
||||
student.row = -1
|
||||
if @filterFn(student)
|
||||
if @rowFilter(student)
|
||||
@rows.push(student)
|
||||
@calculateStudentGrade(student)
|
||||
sortables[student.id] = @sortFn(student)
|
||||
|
||||
@rows.sort (a, b) ->
|
||||
|
@ -85,17 +87,16 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
@multiGrid.updateRowCount()
|
||||
@multiGrid.render()
|
||||
|
||||
getSubmissionsChunk: (student_id) ->
|
||||
if @options.submissions
|
||||
return this.gotSubmissionsChunk(@options.submissions)
|
||||
students = @rows[@chunk_start...(@chunk_start+@options.chunk_size)]
|
||||
params = {
|
||||
student_ids: (student.id for student in students)
|
||||
assignment_ids: (id for id, assignment of @assignments)
|
||||
response_fields: ['user_id', 'url', 'score', 'grade', 'submission_type', 'submitted_at', 'assignment_id', 'grade_matches_current_submission']
|
||||
}
|
||||
if students.length > 0
|
||||
getSubmissionsChunks: () ->
|
||||
loop
|
||||
students = @rows[@chunk_start...(@chunk_start+@options.chunk_size)]
|
||||
break unless students.length
|
||||
params =
|
||||
student_ids: (student.id for student in students)
|
||||
assignment_ids: (id for id, assignment of @assignments)
|
||||
response_fields: ['user_id', 'url', 'score', 'grade', 'submission_type', 'submitted_at', 'assignment_id', 'grade_matches_current_submission']
|
||||
$.ajaxJSON(@options.submissions_url, "GET", params, @gotSubmissionsChunk)
|
||||
@chunk_start += @options.chunk_size
|
||||
|
||||
gotSubmissionsChunk: (student_submissions) =>
|
||||
for data in student_submissions
|
||||
|
@ -109,8 +110,7 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
@multiGrid.removeRow(student.row)
|
||||
@calculateStudentGrade(student)
|
||||
@multiGrid.render()
|
||||
@chunk_start += @options.chunk_size
|
||||
@getSubmissionsChunk()
|
||||
|
||||
|
||||
cellFormatter: (row, col, submission) =>
|
||||
if !@rows[row].loaded
|
||||
|
@ -149,8 +149,8 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
if student.loaded
|
||||
result = INST.GradeCalculator.calculate(student.submissionsAsArray, @assignment_groups, 'percent')
|
||||
for group in result.group_sums
|
||||
student["assignment_group_#{group.group.id}"] = group[if @includeUngradedAssignments then 'final' else 'current']
|
||||
student["total_grade"] = result[if @includeUngradedAssignments then 'final' else 'current']
|
||||
student["assignment_group_#{group.group.id}"] = group[if @include_ungraded_assignments then 'final' else 'current']
|
||||
student["total_grade"] = result[if @include_ungraded_assignments then 'final' else 'current']
|
||||
|
||||
highlightColumn: (columnIndexOrEvent) =>
|
||||
if isNaN(columnIndexOrEvent)
|
||||
|
@ -201,8 +201,8 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
columnDef.name = ''
|
||||
@$grid.find(".c#{colIndex}").add($columnHeader).addClass('minimized')
|
||||
$columnHeader.data('minimized', true)
|
||||
assignmentsToHide.push(columnDef.id)
|
||||
$.store.userSet('hidden_columns_' + $("#current_context_code").text(), $.uniq(assignmentsToHide).join(','))
|
||||
@assignmentsToHide.push(columnDef.id)
|
||||
$.store.userSet("hidden_columns_#{@options.context_code}", $.uniq(@assignmentsToHide).join(','))
|
||||
|
||||
unminimizeColumn: ($columnHeader) =>
|
||||
colIndex = $columnHeader.index()
|
||||
|
@ -212,8 +212,8 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
columnDef.name = columnDef.unminimizedName
|
||||
@$grid.find(".c#{colIndex}").add($columnHeader).removeClass('minimized')
|
||||
$columnHeader.removeData('minimized')
|
||||
assignmentsToHide = $.grep assignmentsToHide, (el) -> el != columnDef.id
|
||||
$.store.userSet('hidden_columns_' + $("#current_context_code").text(), $.uniq(assignmentsToHide).join(','))
|
||||
assignmentsToHide = $.grep @assignmentsToHide, (el) -> el != columnDef.id
|
||||
$.store.userSet("hidden_columns_#{@options.context_code}", $.uniq(@assignmentsToHide).join(','))
|
||||
|
||||
hoverMinimizedCell: (event) =>
|
||||
$hoveredCell = $(event.currentTarget)
|
||||
|
@ -230,7 +230,7 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
else if submission.score?
|
||||
htmlLines.push submission.score
|
||||
# add lines for dropped, late, resubmitted
|
||||
Array::push.apply htmlLines, $.map(SubmissionCell.classesBasedOnSubmission(submission, assignment), (c)-> $("#submission_tooltip_#{c}").text())
|
||||
Array::push.apply htmlLines, $.map(SubmissionCell.classesBasedOnSubmission(submission, assignment), (c)=> GRADEBOOK_TRANSLATIONS["#submission_tooltip_#{c}"])
|
||||
else if assignment.points_possible?
|
||||
htmlLines.push I18n.t('points_out_of', "out of %{points_possible}", points_possible: assignment.points_possible)
|
||||
|
||||
|
@ -281,6 +281,7 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
@minimizeColumn($columnHeader) unless isMinimized
|
||||
else if isMinimized
|
||||
@unminimizeColumn($columnHeader)
|
||||
|
||||
$(document).trigger('gridready')
|
||||
|
||||
# # debugging stuff, remove
|
||||
|
@ -313,32 +314,76 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
# console.log(event, documentation, arguments)
|
||||
# set up row sorting options
|
||||
|
||||
initHeader: () =>
|
||||
if @sections_enabled
|
||||
$courseSectionTemplate = jQUI19('#course_section_template').removeAttr('id').detach()
|
||||
$sectionToShowMenu = jQUI19('#section_to_show').next()
|
||||
allSectionsText = $('#section_being_shown').text()
|
||||
$('#section_being_shown').text(@sections[@sectionToShow].name) if @sectionToShow
|
||||
for i, section of @sections
|
||||
$courseSectionTemplate.clone().appendTo($sectionToShowMenu)
|
||||
.find('label')
|
||||
.attr('for', "section_option_#{section.id}")
|
||||
.text(section.name)
|
||||
.end()
|
||||
.find('input')
|
||||
.attr(id: "section_option_#{section.id}", value: section.id)
|
||||
.prop('checked', section.id == @sectionToShow)
|
||||
jQUI19('#section_to_show').show().kyleMenu
|
||||
buttonOpts: {icons: {primary: "ui-icon-sections", secondary: "ui-icon-droparrow"}}
|
||||
$sectionToShowMenu.bind 'menuselect', (event, ui) =>
|
||||
@sectionToShow = Number($sectionToShowMenu.find('input[name="section_to_show_radio"]:checked').val()) || undefined
|
||||
$.store[ if @sectionToShow then 'userSet' else 'userRemove']("grading_show_only_section#{@options.context_id}", @sectionToShow)
|
||||
$('#section_being_shown').text(if @sectionToShow then @sections[@sectionToShow].name else allSectionsText)
|
||||
@buildRows()
|
||||
|
||||
$settingsMenu = jQUI19('#gradebook_settings').next()
|
||||
$.each ['show_attendance', 'include_ungraded_assignments'], (i, setting) =>
|
||||
$settingsMenu.find("##{setting}").prop('checked', @[setting]).change (event) =>
|
||||
@[setting] = $(event.target).is(':checked')
|
||||
$.store.userSet "#{setting}_#{@options.context_code}", (''+@[setting])
|
||||
@buildRows()
|
||||
|
||||
jQUI19('#gradebook_settings').show().kyleMenu
|
||||
buttonOpts: {icons: {primary: "ui-icon-cog", secondary: "ui-icon-droparrow"}}
|
||||
|
||||
$settingsMenu.find('.gradebook_upload_link').click (event) ->
|
||||
event.preventDefault()
|
||||
dialogData =
|
||||
bgiframe: true
|
||||
autoOpen: false
|
||||
modal: true
|
||||
width: 410
|
||||
resizable: false
|
||||
buttons: {}
|
||||
dialogData['buttons'][I18n.t('buttons.upload_data', 'Upload Data')] = -> $(this).submit()
|
||||
$("#upload_modal").dialog(dialogData).dialog('open')
|
||||
|
||||
initGrid: () ->
|
||||
#this is used to figure out how wide to make each column
|
||||
$widthTester = $('<span style="padding:10px" />').appendTo('#content')
|
||||
testWidth = (text, minWidth) ->
|
||||
Math.max($widthTester.text(text).outerWidth(), minWidth)
|
||||
testWidth = (text, minWidth) -> Math.max($widthTester.text(text).outerWidth(), minWidth)
|
||||
|
||||
@columns = [{
|
||||
id: 'student',
|
||||
name: 'Student Name',
|
||||
field: 'display_name',
|
||||
width: 150,
|
||||
cssClass: "meta-cell",
|
||||
resizable: false,
|
||||
id: 'student'
|
||||
name: I18n.t 'student_name', 'Student Name'
|
||||
field: 'display_name'
|
||||
width: 150
|
||||
cssClass: "meta-cell"
|
||||
resizable: false
|
||||
sortable: true
|
||||
},
|
||||
{
|
||||
id: 'secondary_identifier',
|
||||
name: 'secondary ID',
|
||||
id: 'secondary_identifier'
|
||||
name: I18n.t 'secondary_id', 'Secondary ID'
|
||||
field: 'secondary_identifier'
|
||||
width: 100,
|
||||
cssClass: "meta-cell secondary_identifier_cell",
|
||||
resizable: false,
|
||||
width: 100
|
||||
cssClass: "meta-cell secondary_identifier_cell"
|
||||
resizable: false
|
||||
sortable: true
|
||||
}]
|
||||
|
||||
for id, assignment of @assignments when assignment.submission_types isnt "not_graded"
|
||||
for id, assignment of @assignments
|
||||
html = "<div class='assignment-name'>#{assignment.name}</div>"
|
||||
html += "<div class='assignment-points-possible'>#{I18n.t 'points_out_of', "out of %{points_possible}", points_possible: assignment.points_possible}</div>" if assignment.points_possible?
|
||||
outOfFormatter = assignment &&
|
||||
|
@ -362,7 +407,10 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
sortable: true
|
||||
toolTip: true
|
||||
|
||||
if $.inArray(fieldName, assignmentsToHide) != -1
|
||||
if ''+assignment.submission_types is "not_graded"
|
||||
columnDef.cssClass = 'ungraded'
|
||||
columnDef.unselectable = true
|
||||
else if ($.inArray(fieldName, @assignmentsToHide) != -1)
|
||||
columnDef.width = 10
|
||||
do (fieldName) =>
|
||||
$(document)
|
||||
|
@ -444,7 +492,7 @@ I18n.scoped 'gradebook2', (I18n) ->
|
|||
else if a[propertyToSortBy] > b[propertyToSortBy] then 1
|
||||
else 0
|
||||
if sortAsc then res else 0 - res
|
||||
|
||||
|
||||
@multiGrid.parent_grid.onKeyDown = () =>
|
||||
# TODO: start editing automatically when a number or letter is typed
|
||||
false
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
(($) ->
|
||||
$.fn.kyleMenu = (options) ->
|
||||
this.each ->
|
||||
opts = $.extend(true, {}, $.fn.kyleMenu.defaults, options)
|
||||
$menu = $(this).button(opts.buttonOpts).next()
|
||||
.menu(opts.menuOpts)
|
||||
.popup(opts.popupOpts)
|
||||
.addClass("ui-kyle-menu")
|
||||
$menu.bind "menuselect", -> $(this).removeClass "ui-state-open"
|
||||
|
||||
$.fn.kyleMenu.defaults =
|
||||
popupOpts:
|
||||
position: { my: 'center top', at: 'center bottom', offset: '0 10px' },
|
||||
open: (event) ->
|
||||
# handle sticking the carat right below where you clicked on the button
|
||||
$(this).find(".ui-menu-carat").remove()
|
||||
$trigger = jQUI19(this).popup("option", "trigger")
|
||||
triggerWidth = $trigger.width()
|
||||
differenceInWidth = $(this).width() - triggerWidth
|
||||
caratOffset = Math.min(
|
||||
Math.max(20, event.offsetX),
|
||||
triggerWidth - 20
|
||||
) + differenceInWidth/2
|
||||
$('<span class="ui-menu-carat"><span /></span>').css('left', caratOffset).prependTo(this)
|
||||
|
||||
# this, along with the webkit animation makes it bounce into place.
|
||||
$(this).css('-webkit-transform-origin-x', caratOffset + 'px').addClass('ui-state-open')
|
||||
close: ->
|
||||
$(this).removeClass "ui-state-open"
|
||||
buttonOpts:
|
||||
icons: {primary: "ui-icon-home", secondary: "ui-icon-droparrow"}
|
||||
)(this.jQuery)
|
|
@ -1,7 +1,5 @@
|
|||
this.SubmissionCell = class SubmissionCell
|
||||
|
||||
tooltipTexts = {}
|
||||
|
||||
constructor: (@opts) ->
|
||||
@init()
|
||||
|
||||
|
@ -61,9 +59,7 @@ this.SubmissionCell = class SubmissionCell
|
|||
opts.submission ||= @opts.item[@opts.column.field]
|
||||
opts.assignment ||= @opts.column.object
|
||||
specialClasses = SubmissionCell.classesBasedOnSubmission(opts.submission, opts.assignment)
|
||||
tooltipText = $.map(specialClasses, (c)->
|
||||
tooltipTexts[c] ?= $("#submission_tooltip_#{c}").text()
|
||||
).join(', ')
|
||||
tooltipText = $.map(specialClasses, (c)-> GRADEBOOK_TRANSLATIONS["submission_tooltip_#{c}"]).join ', '
|
||||
|
||||
"""
|
||||
#{ if tooltipText then '<div class="gradebook-tooltip">'+ tooltipText + '</div>' else ''}
|
||||
|
@ -78,6 +74,7 @@ this.SubmissionCell = class SubmissionCell
|
|||
classes.push('resubmitted') if submission.grade_matches_current_submission == false
|
||||
classes.push('late') if assignment.due_at && submission.submitted_at && (submission.submitted_at.timestamp > assignment.due_at.timestamp)
|
||||
classes.push('dropped') if submission.drop
|
||||
classes.push('ungraded') if ''+assignment.submission_types is "not_graded"
|
||||
classes
|
||||
|
||||
class SubmissionCell.out_of extends SubmissionCell
|
||||
|
|
|
@ -122,6 +122,10 @@ $cell_height: 33px
|
|||
.slick-cell.editable
|
||||
border-color: #2fa1ff
|
||||
|
||||
.slick-cell.ungraded
|
||||
background-image: url("/images/4_percent_opacity.png")
|
||||
background-repeat: repeat
|
||||
|
||||
.gradebook-tooltip
|
||||
display: none
|
||||
background-color: #444
|
||||
|
@ -153,7 +157,8 @@ $cell_height: 33px
|
|||
top: -5px
|
||||
.slick-cell.hover &, .gradebook-cell.focus &, .slick-cell.selected &
|
||||
display: block
|
||||
|
||||
.slick-cell.completely-hidden
|
||||
display: none
|
||||
|
||||
|
||||
.gradebook-cell
|
||||
|
@ -161,7 +166,6 @@ $cell_height: 33px
|
|||
height: $cell_height - 8px
|
||||
position: relative
|
||||
text-align: center
|
||||
|
||||
border: 1px solid transparent
|
||||
border-right: 1px dotted silver
|
||||
border-bottom-color: silver
|
||||
|
@ -294,3 +298,9 @@ $gradebook_checkbox_width: 16px
|
|||
.minimized .slick-column-name
|
||||
display: none
|
||||
|
||||
// STUFF FOR HEADER
|
||||
#gradebook-toolbar
|
||||
background: url('/images/gradebook-header-bg.png') repeat-x
|
||||
height: 28px
|
||||
padding: 8px 20px
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
@import "environment.sass";
|
||||
|
||||
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */
|
||||
|
||||
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
||||
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
||||
.ui-button-icons-only { width: 3.4em; }
|
||||
button.ui-button-icons-only { width: 3.7em; }
|
||||
|
||||
/*button text element */
|
||||
.ui-button .ui-button-text { display: block; line-height: 1.4; }
|
||||
|
||||
.ui-button-text-only .ui-button-text { padding: .4em 1em; }
|
||||
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }
|
||||
.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }
|
||||
.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; }
|
||||
.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button { padding: .4em 1em; }
|
||||
|
||||
/*button icon element(s) */
|
||||
.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }
|
||||
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
||||
.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }
|
||||
.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
|
||||
/*button sets*/
|
||||
.ui-buttonset { margin-right: 7px; }
|
||||
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
||||
|
||||
/* workarounds */
|
||||
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
||||
|
||||
|
||||
/* Instructure Changes */
|
||||
$button-text-color: #525252;
|
||||
.ui-button {
|
||||
@include vertical-gradiant(#f3f3f3, #cecece);
|
||||
@include border-radius(10px);
|
||||
@include box-shadow(rgba(0,0,0,0.5), 0px, 1px, 2px, 0);
|
||||
border: 1px solid #bdbdbd;
|
||||
&.ui-state-hover {
|
||||
@include vertical-gradiant(#ffffff, #dfdfdf);
|
||||
transition: all 0.25s ease-in-out;
|
||||
-webkit-transition: all 0.9s ease-in-out;
|
||||
-moz-transition: all 0.9s ease-in-out;
|
||||
}
|
||||
&.ui-state-active { @include vertical-gradiant(#a8a8a8, #c6c6c6) }
|
||||
|
||||
.ui-button-text {
|
||||
font-size: 12px;
|
||||
color: $button-text-color;
|
||||
text-shadow: #fff 0 1px 1px;
|
||||
}
|
||||
|
||||
$triangle-edge-size: 5px;
|
||||
.ui-icon-droparrow {
|
||||
background-image: none;
|
||||
border: solid transparent;
|
||||
border-width: $triangle-edge-size $triangle-edge-size 0 $triangle-edge-size;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top-color: $button-text-color;
|
||||
margin: -2px 2px 0px;
|
||||
}
|
||||
.ui-icon-droparrow:before {
|
||||
border-color: $button-text-color transparent;
|
||||
border-style: solid;
|
||||
border-width: $triangle-edge-size+1px $triangle-edge-size+1px 0 $triangle-edge-size+1px;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
content: "asfsadf";
|
||||
width: 300px;
|
||||
height: 400px;
|
||||
background-color: red;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
@import "environment.sass";
|
||||
|
||||
/*
|
||||
* jQuery UI Menu @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Menu#theming
|
||||
*/
|
||||
.ui-menu { list-style:none; padding: 0; margin: 0; display:block; outline: none; }
|
||||
.ui-menu .ui-menu { margin-top: -3px; position: absolute; }
|
||||
.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; }
|
||||
.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 6px .4em; line-height: 1.5; zoom: 1; }
|
||||
.ui-menu .ui-menu-item a.ui-state-focus,
|
||||
.ui-menu .ui-menu-item a.ui-state-active { margin: -1px; }
|
||||
|
||||
.ui-menu li.ui-state-disabled { padding: 0.7em 0.4em 0.5em; margin: .4em 0 .2em; line-height: 1.5; }
|
||||
|
||||
/* icon support */
|
||||
.ui-menu-icons { position: relative; }
|
||||
.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; }
|
||||
|
||||
/* left-aligned */
|
||||
.ui-menu .ui-icon { position: absolute; top: .6em; left: .4em; }
|
||||
|
||||
/* right-aligned */
|
||||
.ui-menu .ui-menu-icon { position: static; float: right; }
|
||||
|
||||
|
||||
.ui-menu .ui-menu-input-group {
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.ui-menu-item span.ui-menu-input-group { padding-left: 2em; }
|
||||
|
||||
.ui-menu-item label { cursor: pointer; }
|
||||
|
||||
.ui-menu .ui-corner-all {
|
||||
@include border-radius(0);
|
||||
}
|
||||
|
||||
$kyle-menu-bg-color: #e6e7e9;
|
||||
$kyle-menu-border-color: #b0afaf;
|
||||
$kyle-menu-carat-size: 10px;
|
||||
$kyle-menu-border-radius: 10px;
|
||||
|
||||
|
||||
.ui-kyle-menu {
|
||||
margin-top: $kyle-menu-carat-size;
|
||||
background-color: $kyle-menu-bg-color;
|
||||
border: 1px solid $kyle-menu-border-color;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #525252;
|
||||
position: absolute; // take it out of the "flow" so that it pops on top and doesnt push things down
|
||||
z-index: 9999;
|
||||
@include border-radius($kyle-menu-border-radius);
|
||||
@include box-shadow(rgba(0,0,0,0.4), 0px, 2px, 4px, -1px);
|
||||
|
||||
opacity: 0;
|
||||
&.ui-state-open{
|
||||
opacity:1;
|
||||
-webkit-animation-duration:.5s;
|
||||
-webkit-animation-name:kylemenu-bounce;
|
||||
/* webkit-transform-origin-x will be set in js and will match the carat position */
|
||||
-webkit-transform-origin-y: 0;
|
||||
}
|
||||
|
||||
// the .ui-menu-carat is the outer border of the carat to make it match the border of the popup
|
||||
// and the span inside it is the same
|
||||
.ui-menu-carat, .ui-menu-carat span {
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
content: "";
|
||||
|
||||
border-color: $kyle-menu-border-color transparent;
|
||||
border-width: 0px $kyle-menu-carat-size+1px $kyle-menu-carat-size+1px;
|
||||
top: -$kyle-menu-carat-size - 1px;
|
||||
margin-left: -$kyle-menu-carat-size - 1px;
|
||||
}
|
||||
.ui-menu-carat span {
|
||||
border-color: $kyle-menu-bg-color transparent;
|
||||
border-width: 0px $kyle-menu-carat-size $kyle-menu-carat-size;
|
||||
top: 1px;
|
||||
margin-left: -$kyle-menu-carat-size;
|
||||
}
|
||||
a { color: #525252}
|
||||
.ui-menu-item {
|
||||
hr {
|
||||
margin: 0 2px;
|
||||
height: 0;
|
||||
border: 0;
|
||||
border-top: 1px solid #d4d5d7;
|
||||
border-bottom: 1px solid #f2f2f3;
|
||||
}
|
||||
}
|
||||
// have to use first-of-type instead of :first-child because the carat that gets inserted becomes
|
||||
// :first-child but the carat is not an <li>, so this gets the first <li> which is what we want.
|
||||
// doesn't work in ie8- but that's ok because neither does the border radius we are trying to fix.
|
||||
li:first-of-type a { @include border-top-radius($kyle-menu-border-radius) }
|
||||
li:last-child a { @include border-bottom-radius($kyle-menu-border-radius) }
|
||||
.ui-state-focus {
|
||||
@include vertical-gradiant(#0abdff, #008fd6);
|
||||
border-top: 1px solid #d5f1fe;
|
||||
border-bottom: 1px solid #1e7eca;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
text-shadow: rgba(0,0,0,0.5) 1px 0 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes kylemenu-bounce {
|
||||
from { opacity:0.0; -webkit-transform:scale(0,0); }
|
||||
25% { opacity:0.3; -webkit-transform: scale(.1,.1); }
|
||||
30% { opacity:0.4; -webkit-transform: scale(.3,.3); }
|
||||
35% { opacity:0.5; -webkit-transform: scale(.6,.6); }
|
||||
40% { opacity:0.6; -webkit-transform: scale(.7,.7); }
|
||||
45% { opacity:0.7; -webkit-transform: scale(1,1); }
|
||||
50% { opacity:0.8; -webkit-transform: scale(1.2,1.2); }
|
||||
55% { opacity:0.9; -webkit-transform: scale(1.1,1.1); }
|
||||
60% { opacity:1.0; -webkit-transform: scale(1,1); }
|
||||
to { opacity:1.0; -webkit-transform: scale(1,1); }
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<% jammit_js :jquery_ui_menu %>
|
||||
<% js_block do %>
|
||||
<script>
|
||||
$(function() {
|
||||
jQUI19('#section_to_show')
|
||||
.kyleMenu()
|
||||
.next().bind('menuselect', function(event, ui){
|
||||
$("<div/>").text("Selected: " + ui.item.text()).appendTo("#log");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
||||
<button id="section_to_show">Showing all sections</button>
|
||||
<ul style="width: 200px;">
|
||||
<li>Choose a section to show</li>
|
||||
<li><a href="#"><label for="radio4">All Sections</label><input type="radio" id="radio4" name="radioTest2" checked="checked" /></a></li>
|
||||
<li><a href="#"><label for="radio5">Red Section</label><input type="radio" id="radio5" name="radioTest2" /></a></li>
|
||||
<li><a href="#"><label for="radio6">Blue Section</label><input type="radio" id="radio6" name="radioTest2" /></a></li>
|
||||
</ul>
|
||||
|
||||
<div class="ui-widget" style="clear: left; margin-top:2em; font-family:Arial">
|
||||
Log:
|
||||
<div id="log" style="height: 400px; width: 300px; overflow: auto;" class="ui-widget-content"></div>
|
||||
</div>
|
|
@ -2,7 +2,7 @@
|
|||
content_for :page_title, "Gradebook - #{@context.name}"
|
||||
@body_classes << "gradebook2"
|
||||
@show_left_side = false
|
||||
jammit_js :slickgrid, :gradebook2
|
||||
jammit_js :jquery_ui_menu, :slickgrid, :gradebook2
|
||||
jammit_css :slickgrid, :gradebook2
|
||||
options = {
|
||||
:chunk_size => 35,
|
||||
|
@ -10,41 +10,43 @@
|
|||
:sections_and_students_url => api_v1_course_sections_url(@context, :include => [:students]),
|
||||
:submissions_url => api_v1_course_student_submissions_url(@context, :grouped => '1'),
|
||||
:change_grade_url => api_v1_course_assignment_submission_url(@context, ":assignment", ":submission"),
|
||||
#:assignment_groups => @context.assignment_groups.all(:include => :assignments),
|
||||
#:sections => @context.course_sections.all(:include => :users),
|
||||
#:submissions => @context.submissions.all(),
|
||||
:context_id => @context.id,
|
||||
:context_code => @context.asset_string
|
||||
}
|
||||
%>
|
||||
<div id="gradebook-toolbar">
|
||||
|
||||
<button style="display:none;" id="section_to_show">Showing: <span id="section_being_shown">All Sections</span></button>
|
||||
<ul style="display: none; width: 200px;">
|
||||
<li>Choose a section to show</li>
|
||||
<li><a href="#"><label for="radio4">All Sections</label><input type="radio" name="section_to_show_radio" checked /></a></li>
|
||||
<li id="course_section_template"><a href="#"><label class="section_name" for="radio4">All Sections</label><input type="radio" name="section_to_show_radio" /></a></li>
|
||||
</ul>
|
||||
<button id="gradebook_settings"> </button>
|
||||
<ul style="display: none; width: 210px;">
|
||||
<li><a href="<%= context_url(@context, :context_gradebook_url) %>/history"><%= I18n.t('view_grading_history', 'View Grading History') %></a></li>
|
||||
<li><a href="<%= context_url(@context, :context_gradebook_url) %>.csv"><%= I18n.t('download_scores', 'Download Scores (.csv)') %></a></li>
|
||||
<li><a class="gradebook_upload_link" href="#"><%= I18n.t('upload_scores', 'Upload Scores (from .csv)') %></a></li>
|
||||
<!-- <li><a href="#"><%= I18n.t('set_group_weights', 'Set Group Weights') %></a></li> -->
|
||||
<li><a href="#"><label><%= I18n.t('show_attendance_columns', 'Show Attendance Columns') %> <input type="checkbox" id="show_attendance" /></label></a></li>
|
||||
<li><a href="#"><label><%= I18n.t('include_ungraded', 'Include Ungraded Assignments') %><input type="checkbox" id="include_ungraded_assignments" /></label></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="gradebook-grid-wrapper">
|
||||
<div id="gradebook_students_grid"></div>
|
||||
<div id="gradebook_grid"></div>
|
||||
</div>
|
||||
|
||||
<!-- gradebook images -->
|
||||
<div style="display:none;">
|
||||
<span id="submission_tooltip_dropped"><%= t 'dropped_for_grading', 'Dropped for grading purposes' %></span>
|
||||
<span id="submission_tooltip_late"><%= t 'submitted_late', 'Submitted late' %></span>
|
||||
<span id="submission_tooltip_resubmitted"><%= t 'resubmitted', 'Resubmitted since last graded' %></span>
|
||||
<%= image_tag "pass.png", :id => "submission_entry_pass_image", :alt => "Pass", :title => "Pass", :class => "graded_icon" %>
|
||||
<%= image_tag "pass.png", :id => "submission_entry_complete_image", :alt => "Complete", :title => "Complete", :class => "graded_icon" %>
|
||||
<%= image_tag "fail.png", :id => "submission_entry_fail_image", :alt => "Fail", :title => "Fail", :class => "graded_icon" %>
|
||||
<%= image_tag "fail.png", :id => "submission_entry_incomplete_image", :alt => "Incomplete", :title => "Incomplete", :class => "graded_icon" %>
|
||||
</div>
|
||||
|
||||
<div id="gradebook_dialogs" style="display:none;">
|
||||
<div id="sort_rows_dialog" title="Sort Gradebook Rows">
|
||||
<button type="button" class="button sort_gradebook sort_rows" data-sort_by="display_name" title="By Student Name" style="width: 300px;">By Student Name</button>
|
||||
<button type="button" class="button sort_gradebook sort_rows" data-sort_by="section" title="By Section Name" style="width: 300px;">By Section Name</button>
|
||||
<button type="button" class="button sort_gradebook sort_rows by_grade" data-sort_by="grade_desc" title="By Total (Highest First)" style="width: 300px;">By Total (Highest First)</button>
|
||||
<button type="button" class="button sort_gradebook sort_rows by_grade" data-sort_by="grade_asc" title="By Total (Lowest First)" style="width: 300px;">By Total (Lowest First)</button>
|
||||
</div>
|
||||
<%= render :partial => 'gradebook_uploads/form' %>
|
||||
</div>
|
||||
|
||||
<% js_block do %>
|
||||
<script>
|
||||
GRADEBOOK_TRANSLATIONS = <%= {
|
||||
:submission_tooltip_dropped => t('dropped_for_grading', 'Dropped for grading purposes'),
|
||||
:submission_tooltip_late => t('submitted_late', 'Submitted late'),
|
||||
:submission_tooltip_resubmitted => t('resubmitted', 'Resubmitted since last graded'),
|
||||
:submission_tooltip_ungraded => t('ungraded', 'Not factored into grading')
|
||||
}.to_json.html_safe %>;
|
||||
new Gradebook(<%= options.to_json.html_safe %>);
|
||||
</script>
|
||||
<% end %>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<% form_for(@gradebook_upload, :url => context_url(@context, :context_gradebook_uploads_url), :html => {:multipart => true, :id => "upload_modal", :title => t('titles.upload_form', "Choose a CSV file to upload")}) do |f| %>
|
||||
<% form_for(@gradebook_upload || @context.build_gradebook_upload, :url => context_url(@context, :context_gradebook_uploads_url), :html => {:multipart => true, :id => "upload_modal", :title => t('titles.upload_form', "Choose a CSV file to upload")}) do |f| %>
|
||||
<%= f.error_messages %>
|
||||
<%= f.label :uploaded_data, t('labels.upload', "Choose a CSV file to upload") %>
|
||||
<%= f.file_field :uploaded_data %>
|
||||
|
|
|
@ -124,6 +124,17 @@ javascripts:
|
|||
- public/javascripts/user_lists.js
|
||||
datagrid:
|
||||
- public/javascripts/datagrid.js
|
||||
jquery_ui_menu:
|
||||
- public/javascripts/jquery-1.6.2.js
|
||||
- public/javascripts/jquery.ui.core-1.9.js
|
||||
- public/javascripts/jquery.ui.position-1.9.js
|
||||
- public/javascripts/jquery.ui.widget-1.9.js
|
||||
- public/javascripts/jquery.ui.menu-1.9.js
|
||||
- public/javascripts/jquery.ui.button-1.9.js
|
||||
- public/javascripts/jquery.ui.popup-1.9.js
|
||||
- public/javascripts/jquery.ui.menu.inputmenu.js
|
||||
- public/javascripts/compiled/jquery.kylemenu.js
|
||||
- public/javascripts/jquery.ui.menu-1.9_unsetup.js
|
||||
gradebook2:
|
||||
- public/javascripts/compiled/multi_grid.js
|
||||
- public/javascripts/compiled/grade_calculator.js
|
||||
|
@ -217,6 +228,8 @@ stylesheets:
|
|||
- public/stylesheets/compiled/g_reset.css
|
||||
- public/stylesheets/compiled/g_base.css
|
||||
- public/stylesheets/static/jquery-ui-theme.css
|
||||
- public/stylesheets/compiled/jquery-ui-button.css
|
||||
- public/stylesheets/compiled/jquery-ui-menu.css
|
||||
- public/stylesheets/static/jquery.autocomplete.css
|
||||
- public/stylesheets/compiled/g_instructure.css
|
||||
- public/stylesheets/compiled/g_util_misc.css
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 515 B |
Binary file not shown.
After Width: | Height: | Size: 612 B |
Binary file not shown.
After Width: | Height: | Size: 369 B |
Binary file not shown.
After Width: | Height: | Size: 192 B |
|
@ -3,11 +3,11 @@
|
|||
I18n.scoped('gradebook2', function(I18n) {
|
||||
var Gradebook;
|
||||
return this.Gradebook = Gradebook = (function() {
|
||||
var assignmentsToHide, minimumAssignmentColumWidth;
|
||||
var minimumAssignmentColumWidth;
|
||||
minimumAssignmentColumWidth = 10;
|
||||
assignmentsToHide = $.store.userGet('hidden_columns_' + $("#current_context_code").text()).split(',');
|
||||
function Gradebook(options) {
|
||||
this.options = options;
|
||||
this.initHeader = __bind(this.initHeader, this);
|
||||
this.hoverMinimizedCell = __bind(this.hoverMinimizedCell, this);
|
||||
this.unminimizeColumn = __bind(this.unminimizeColumn, this);
|
||||
this.minimizeColumn = __bind(this.minimizeColumn, this);
|
||||
|
@ -20,48 +20,51 @@
|
|||
this.staticCellFormatter = __bind(this.staticCellFormatter, this);
|
||||
this.cellFormatter = __bind(this.cellFormatter, this);
|
||||
this.gotSubmissionsChunk = __bind(this.gotSubmissionsChunk, this);
|
||||
this.rowFilter = __bind(this.rowFilter, this);
|
||||
this.gotStudents = __bind(this.gotStudents, this);
|
||||
this.gotAssignmentGroups = __bind(this.gotAssignmentGroups, this);
|
||||
this.chunk_start = 0;
|
||||
this.students = {};
|
||||
this.rows = [];
|
||||
this.filterFn = function(student) {
|
||||
return true;
|
||||
};
|
||||
this.sortFn = function(student) {
|
||||
return student.display_name;
|
||||
};
|
||||
this.init();
|
||||
this.includeUngradedAssignments = false;
|
||||
this.assignmentsToHide = ($.store.userGet("hidden_columns_" + this.options.context_code) || '').split(',');
|
||||
this.sectionToShow = Number($.store.userGet("grading_show_only_section" + this.options.context_id)) || void 0;
|
||||
this.show_attendance = $.store.userGet("show_attendance_" + this.options.context_code) === 'true';
|
||||
this.include_ungraded_assignments = $.store.userGet("include_ungraded_assignments_" + this.options.context_code) === 'true';
|
||||
$.when($.ajaxJSON(this.options.assignment_groups_url, "GET", {}, this.gotAssignmentGroups), $.ajaxJSON(this.options.sections_and_students_url, "GET", this.sectionToShow && {
|
||||
sections: [this.sectionToShow]
|
||||
})).then(__bind(function(assignmentGroupsArgs, studentsArgs) {
|
||||
this.gotStudents.apply(this, studentsArgs);
|
||||
return this.initHeader();
|
||||
}, this));
|
||||
}
|
||||
Gradebook.prototype.init = function() {
|
||||
if (this.options.assignment_groups) {
|
||||
return this.gotAssignmentGroups(this.options.assignment_groups);
|
||||
}
|
||||
return $.ajaxJSON(this.options.assignment_groups_url, "GET", {}, this.gotAssignmentGroups);
|
||||
};
|
||||
Gradebook.prototype.gotAssignmentGroups = function(assignment_groups) {
|
||||
var assignment, group, _i, _j, _len, _len2, _ref;
|
||||
var assignment, group, _i, _len, _results;
|
||||
this.assignment_groups = {};
|
||||
this.assignments = {};
|
||||
_results = [];
|
||||
for (_i = 0, _len = assignment_groups.length; _i < _len; _i++) {
|
||||
group = assignment_groups[_i];
|
||||
$.htmlEscapeValues(group);
|
||||
this.assignment_groups[group.id] = group;
|
||||
_ref = group.assignments;
|
||||
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
||||
assignment = _ref[_j];
|
||||
$.htmlEscapeValues(assignment);
|
||||
if (assignment.due_at) {
|
||||
assignment.due_at = $.parseFromISO(assignment.due_at);
|
||||
_results.push((function() {
|
||||
var _j, _len2, _ref, _results2;
|
||||
_ref = group.assignments;
|
||||
_results2 = [];
|
||||
for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
|
||||
assignment = _ref[_j];
|
||||
$.htmlEscapeValues(assignment);
|
||||
if (assignment.due_at) {
|
||||
assignment.due_at = $.parseFromISO(assignment.due_at);
|
||||
}
|
||||
_results2.push(this.assignments[assignment.id] = assignment);
|
||||
}
|
||||
this.assignments[assignment.id] = assignment;
|
||||
}
|
||||
return _results2;
|
||||
}).call(this));
|
||||
}
|
||||
if (this.options.sections) {
|
||||
return this.gotStudents(this.options.sections);
|
||||
}
|
||||
return $.ajaxJSON(this.options.sections_and_students_url, "GET", {}, this.gotStudents);
|
||||
return _results;
|
||||
};
|
||||
Gradebook.prototype.gotStudents = function(sections) {
|
||||
var assignment, id, section, student, _i, _j, _len, _len2, _name, _ref, _ref2, _ref3;
|
||||
|
@ -102,18 +105,31 @@
|
|||
}
|
||||
this.initGrid();
|
||||
this.buildRows();
|
||||
return this.getSubmissionsChunk();
|
||||
return this.getSubmissionsChunks();
|
||||
};
|
||||
Gradebook.prototype.rowFilter = function(student) {
|
||||
return !this.sectionToShow || (student.section.id === this.sectionToShow);
|
||||
};
|
||||
Gradebook.prototype.buildRows = function() {
|
||||
var i, id, sortables, student, _len, _ref, _ref2;
|
||||
var column, i, id, sortables, student, _len, _ref, _ref2, _ref3, _ref4;
|
||||
this.rows.length = 0;
|
||||
sortables = {};
|
||||
_ref = this.students;
|
||||
_ref = this.gradeGrid.getColumns();
|
||||
for (id in _ref) {
|
||||
student = _ref[id];
|
||||
column = _ref[id];
|
||||
if ('' + ((_ref2 = column.object) != null ? _ref2.submission_types : void 0) === "attendance") {
|
||||
column.unselectable = !this.show_attendance;
|
||||
column.cssClass = this.show_attendance ? '' : 'completely-hidden';
|
||||
this.$grid.find("[id*='" + column.id + "']").showIf(this.show_attendance);
|
||||
}
|
||||
}
|
||||
_ref3 = this.students;
|
||||
for (id in _ref3) {
|
||||
student = _ref3[id];
|
||||
student.row = -1;
|
||||
if (this.filterFn(student)) {
|
||||
if (this.rowFilter(student)) {
|
||||
this.rows.push(student);
|
||||
this.calculateStudentGrade(student);
|
||||
sortables[student.id] = this.sortFn(student);
|
||||
}
|
||||
}
|
||||
|
@ -126,46 +142,49 @@
|
|||
return 0;
|
||||
}
|
||||
});
|
||||
_ref2 = this.rows;
|
||||
for (i = 0, _len = _ref2.length; i < _len; i++) {
|
||||
student = _ref2[i];
|
||||
_ref4 = this.rows;
|
||||
for (i = 0, _len = _ref4.length; i < _len; i++) {
|
||||
student = _ref4[i];
|
||||
student.row = i;
|
||||
}
|
||||
this.multiGrid.removeAllRows();
|
||||
this.multiGrid.updateRowCount();
|
||||
return this.multiGrid.render();
|
||||
};
|
||||
Gradebook.prototype.getSubmissionsChunk = function(student_id) {
|
||||
var assignment, id, params, student, students;
|
||||
if (this.options.submissions) {
|
||||
return this.gotSubmissionsChunk(this.options.submissions);
|
||||
}
|
||||
students = this.rows.slice(this.chunk_start, this.chunk_start + this.options.chunk_size);
|
||||
params = {
|
||||
student_ids: (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = students.length; _i < _len; _i++) {
|
||||
student = students[_i];
|
||||
_results.push(student.id);
|
||||
}
|
||||
return _results;
|
||||
})(),
|
||||
assignment_ids: (function() {
|
||||
var _ref, _results;
|
||||
_ref = this.assignments;
|
||||
_results = [];
|
||||
for (id in _ref) {
|
||||
assignment = _ref[id];
|
||||
_results.push(id);
|
||||
}
|
||||
return _results;
|
||||
}).call(this),
|
||||
response_fields: ['user_id', 'url', 'score', 'grade', 'submission_type', 'submitted_at', 'assignment_id', 'grade_matches_current_submission']
|
||||
};
|
||||
if (students.length > 0) {
|
||||
return $.ajaxJSON(this.options.submissions_url, "GET", params, this.gotSubmissionsChunk);
|
||||
Gradebook.prototype.getSubmissionsChunks = function() {
|
||||
var assignment, id, params, student, students, _results;
|
||||
_results = [];
|
||||
while (true) {
|
||||
students = this.rows.slice(this.chunk_start, this.chunk_start + this.options.chunk_size);
|
||||
if (!students.length) {
|
||||
break;
|
||||
}
|
||||
params = {
|
||||
student_ids: (function() {
|
||||
var _i, _len, _results2;
|
||||
_results2 = [];
|
||||
for (_i = 0, _len = students.length; _i < _len; _i++) {
|
||||
student = students[_i];
|
||||
_results2.push(student.id);
|
||||
}
|
||||
return _results2;
|
||||
})(),
|
||||
assignment_ids: (function() {
|
||||
var _ref, _results2;
|
||||
_ref = this.assignments;
|
||||
_results2 = [];
|
||||
for (id in _ref) {
|
||||
assignment = _ref[id];
|
||||
_results2.push(id);
|
||||
}
|
||||
return _results2;
|
||||
}).call(this),
|
||||
response_fields: ['user_id', 'url', 'score', 'grade', 'submission_type', 'submitted_at', 'assignment_id', 'grade_matches_current_submission']
|
||||
};
|
||||
$.ajaxJSON(this.options.submissions_url, "GET", params, this.gotSubmissionsChunk);
|
||||
_results.push(this.chunk_start += this.options.chunk_size);
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
Gradebook.prototype.gotSubmissionsChunk = function(student_submissions) {
|
||||
var data, student, submission, _i, _j, _len, _len2, _ref;
|
||||
|
@ -186,9 +205,7 @@
|
|||
this.multiGrid.removeRow(student.row);
|
||||
this.calculateStudentGrade(student);
|
||||
}
|
||||
this.multiGrid.render();
|
||||
this.chunk_start += this.options.chunk_size;
|
||||
return this.getSubmissionsChunk();
|
||||
return this.multiGrid.render();
|
||||
};
|
||||
Gradebook.prototype.cellFormatter = function(row, col, submission) {
|
||||
var assignment;
|
||||
|
@ -238,9 +255,9 @@
|
|||
_ref = result.group_sums;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
group = _ref[_i];
|
||||
student["assignment_group_" + group.group.id] = group[this.includeUngradedAssignments ? 'final' : 'current'];
|
||||
student["assignment_group_" + group.group.id] = group[this.include_ungraded_assignments ? 'final' : 'current'];
|
||||
}
|
||||
return student["total_grade"] = result[this.includeUngradedAssignments ? 'final' : 'current'];
|
||||
return student["total_grade"] = result[this.include_ungraded_assignments ? 'final' : 'current'];
|
||||
}
|
||||
};
|
||||
Gradebook.prototype.highlightColumn = function(columnIndexOrEvent) {
|
||||
|
@ -293,11 +310,11 @@
|
|||
columnDef.name = '';
|
||||
this.$grid.find(".c" + colIndex).add($columnHeader).addClass('minimized');
|
||||
$columnHeader.data('minimized', true);
|
||||
assignmentsToHide.push(columnDef.id);
|
||||
return $.store.userSet('hidden_columns_' + $("#current_context_code").text(), $.uniq(assignmentsToHide).join(','));
|
||||
this.assignmentsToHide.push(columnDef.id);
|
||||
return $.store.userSet("hidden_columns_" + this.options.context_code, $.uniq(this.assignmentsToHide).join(','));
|
||||
};
|
||||
Gradebook.prototype.unminimizeColumn = function($columnHeader) {
|
||||
var colIndex, columnDef;
|
||||
var assignmentsToHide, colIndex, columnDef;
|
||||
colIndex = $columnHeader.index();
|
||||
columnDef = this.gradeGrid.getColumns()[colIndex];
|
||||
columnDef.cssClass = (columnDef.cssClass || '').replace(' minimized', '');
|
||||
|
@ -305,10 +322,10 @@
|
|||
columnDef.name = columnDef.unminimizedName;
|
||||
this.$grid.find(".c" + colIndex).add($columnHeader).removeClass('minimized');
|
||||
$columnHeader.removeData('minimized');
|
||||
assignmentsToHide = $.grep(assignmentsToHide, function(el) {
|
||||
assignmentsToHide = $.grep(this.assignmentsToHide, function(el) {
|
||||
return el !== columnDef.id;
|
||||
});
|
||||
return $.store.userSet('hidden_columns_' + $("#current_context_code").text(), $.uniq(assignmentsToHide).join(','));
|
||||
return $.store.userSet("hidden_columns_" + this.options.context_code, $.uniq(this.assignmentsToHide).join(','));
|
||||
};
|
||||
Gradebook.prototype.hoverMinimizedCell = function(event) {
|
||||
var $hoveredCell, assignment, columnDef, htmlLines, offset, submission, _ref;
|
||||
|
@ -324,9 +341,9 @@
|
|||
} else if (submission.score != null) {
|
||||
htmlLines.push(submission.score);
|
||||
}
|
||||
Array.prototype.push.apply(htmlLines, $.map(SubmissionCell.classesBasedOnSubmission(submission, assignment), function(c) {
|
||||
return $("#submission_tooltip_" + c).text();
|
||||
}));
|
||||
Array.prototype.push.apply(htmlLines, $.map(SubmissionCell.classesBasedOnSubmission(submission, assignment), __bind(function(c) {
|
||||
return GRADEBOOK_TRANSLATIONS["#submission_tooltip_" + c];
|
||||
}, this)));
|
||||
} else if (assignment.points_possible != null) {
|
||||
htmlLines.push(I18n.t('points_out_of', "out of %{points_possible}", {
|
||||
points_possible: assignment.points_possible
|
||||
|
@ -396,6 +413,71 @@
|
|||
}, this));
|
||||
return $(document).trigger('gridready');
|
||||
};
|
||||
Gradebook.prototype.initHeader = function() {
|
||||
var $courseSectionTemplate, $sectionToShowMenu, $settingsMenu, allSectionsText, i, section, _ref;
|
||||
if (this.sections_enabled) {
|
||||
$courseSectionTemplate = jQUI19('#course_section_template').removeAttr('id').detach();
|
||||
$sectionToShowMenu = jQUI19('#section_to_show').next();
|
||||
allSectionsText = $('#section_being_shown').text();
|
||||
if (this.sectionToShow) {
|
||||
$('#section_being_shown').text(this.sections[this.sectionToShow].name);
|
||||
}
|
||||
_ref = this.sections;
|
||||
for (i in _ref) {
|
||||
section = _ref[i];
|
||||
$courseSectionTemplate.clone().appendTo($sectionToShowMenu).find('label').attr('for', "section_option_" + section.id).text(section.name).end().find('input').attr({
|
||||
id: "section_option_" + section.id,
|
||||
value: section.id
|
||||
}).prop('checked', section.id === this.sectionToShow);
|
||||
}
|
||||
jQUI19('#section_to_show').show().kyleMenu({
|
||||
buttonOpts: {
|
||||
icons: {
|
||||
primary: "ui-icon-sections",
|
||||
secondary: "ui-icon-droparrow"
|
||||
}
|
||||
}
|
||||
});
|
||||
$sectionToShowMenu.bind('menuselect', __bind(function(event, ui) {
|
||||
this.sectionToShow = Number($sectionToShowMenu.find('input[name="section_to_show_radio"]:checked').val()) || void 0;
|
||||
$.store[this.sectionToShow ? 'userSet' : 'userRemove']("grading_show_only_section" + this.options.context_id, this.sectionToShow);
|
||||
$('#section_being_shown').text(this.sectionToShow ? this.sections[this.sectionToShow].name : allSectionsText);
|
||||
return this.buildRows();
|
||||
}, this));
|
||||
}
|
||||
$settingsMenu = jQUI19('#gradebook_settings').next();
|
||||
$.each(['show_attendance', 'include_ungraded_assignments'], __bind(function(i, setting) {
|
||||
return $settingsMenu.find("#" + setting).prop('checked', this[setting]).change(__bind(function(event) {
|
||||
this[setting] = $(event.target).is(':checked');
|
||||
$.store.userSet("" + setting + "_" + this.options.context_code, '' + this[setting]);
|
||||
return this.buildRows();
|
||||
}, this));
|
||||
}, this));
|
||||
jQUI19('#gradebook_settings').show().kyleMenu({
|
||||
buttonOpts: {
|
||||
icons: {
|
||||
primary: "ui-icon-cog",
|
||||
secondary: "ui-icon-droparrow"
|
||||
}
|
||||
}
|
||||
});
|
||||
return $settingsMenu.find('.gradebook_upload_link').click(function(event) {
|
||||
var dialogData;
|
||||
event.preventDefault();
|
||||
dialogData = {
|
||||
bgiframe: true,
|
||||
autoOpen: false,
|
||||
modal: true,
|
||||
width: 410,
|
||||
resizable: false,
|
||||
buttons: {}
|
||||
};
|
||||
dialogData['buttons'][I18n.t('buttons.upload_data', 'Upload Data')] = function() {
|
||||
return $(this).submit();
|
||||
};
|
||||
return $("#upload_modal").dialog(dialogData).dialog('open');
|
||||
});
|
||||
};
|
||||
Gradebook.prototype.initGrid = function() {
|
||||
var $widthTester, assignment, columnDef, fieldName, grids, group, html, id, minWidth, options, outOfFormatter, sortRowsBy, testWidth, _ref, _ref2;
|
||||
$widthTester = $('<span style="padding:10px" />').appendTo('#content');
|
||||
|
@ -405,7 +487,7 @@
|
|||
this.columns = [
|
||||
{
|
||||
id: 'student',
|
||||
name: 'Student Name',
|
||||
name: I18n.t('student_name', 'Student Name'),
|
||||
field: 'display_name',
|
||||
width: 150,
|
||||
cssClass: "meta-cell",
|
||||
|
@ -413,7 +495,7 @@
|
|||
sortable: true
|
||||
}, {
|
||||
id: 'secondary_identifier',
|
||||
name: 'secondary ID',
|
||||
name: I18n.t('secondary_id', 'Secondary ID'),
|
||||
field: 'secondary_identifier',
|
||||
width: 100,
|
||||
cssClass: "meta-cell secondary_identifier_cell",
|
||||
|
@ -424,41 +506,42 @@
|
|||
_ref = this.assignments;
|
||||
for (id in _ref) {
|
||||
assignment = _ref[id];
|
||||
if (assignment.submission_types !== "not_graded") {
|
||||
html = "<div class='assignment-name'>" + assignment.name + "</div>";
|
||||
if (assignment.points_possible != null) {
|
||||
html += "<div class='assignment-points-possible'>" + (I18n.t('points_out_of', "out of %{points_possible}", {
|
||||
points_possible: assignment.points_possible
|
||||
})) + "</div>";
|
||||
}
|
||||
outOfFormatter = assignment && assignment.grading_type === 'points' && (assignment.points_possible != null) && SubmissionCell.out_of;
|
||||
minWidth = outOfFormatter ? 70 : 50;
|
||||
fieldName = "assignment_" + id;
|
||||
columnDef = {
|
||||
id: fieldName,
|
||||
field: fieldName,
|
||||
name: html,
|
||||
object: assignment,
|
||||
formatter: this.cellFormatter,
|
||||
editor: outOfFormatter || SubmissionCell[assignment.grading_type] || SubmissionCell,
|
||||
minWidth: minimumAssignmentColumWidth,
|
||||
maxWidth: 200,
|
||||
width: testWidth(assignment.name, minWidth),
|
||||
sortable: true,
|
||||
toolTip: true
|
||||
};
|
||||
if ($.inArray(fieldName, assignmentsToHide) !== -1) {
|
||||
columnDef.width = 10;
|
||||
__bind(function(fieldName) {
|
||||
return $(document).bind('gridready', __bind(function() {
|
||||
return this.minimizeColumn(this.$grid.find("[id*='" + fieldName + "']"));
|
||||
}, this)).unbind('gridready.render').bind('gridready.render', __bind(function() {
|
||||
return this.gradeGrid.invalidate();
|
||||
}, this));
|
||||
}, this)(fieldName);
|
||||
}
|
||||
this.columns.push(columnDef);
|
||||
html = "<div class='assignment-name'>" + assignment.name + "</div>";
|
||||
if (assignment.points_possible != null) {
|
||||
html += "<div class='assignment-points-possible'>" + (I18n.t('points_out_of', "out of %{points_possible}", {
|
||||
points_possible: assignment.points_possible
|
||||
})) + "</div>";
|
||||
}
|
||||
outOfFormatter = assignment && assignment.grading_type === 'points' && (assignment.points_possible != null) && SubmissionCell.out_of;
|
||||
minWidth = outOfFormatter ? 70 : 50;
|
||||
fieldName = "assignment_" + id;
|
||||
columnDef = {
|
||||
id: fieldName,
|
||||
field: fieldName,
|
||||
name: html,
|
||||
object: assignment,
|
||||
formatter: this.cellFormatter,
|
||||
editor: outOfFormatter || SubmissionCell[assignment.grading_type] || SubmissionCell,
|
||||
minWidth: minimumAssignmentColumWidth,
|
||||
maxWidth: 200,
|
||||
width: testWidth(assignment.name, minWidth),
|
||||
sortable: true,
|
||||
toolTip: true
|
||||
};
|
||||
if ('' + assignment.submission_types === "not_graded") {
|
||||
columnDef.cssClass = 'ungraded';
|
||||
columnDef.unselectable = true;
|
||||
} else if ($.inArray(fieldName, this.assignmentsToHide) !== -1) {
|
||||
columnDef.width = 10;
|
||||
__bind(function(fieldName) {
|
||||
return $(document).bind('gridready', __bind(function() {
|
||||
return this.minimizeColumn(this.$grid.find("[id*='" + fieldName + "']"));
|
||||
}, this)).unbind('gridready.render').bind('gridready.render', __bind(function() {
|
||||
return this.gradeGrid.invalidate();
|
||||
}, this));
|
||||
}, this)(fieldName);
|
||||
}
|
||||
this.columns.push(columnDef);
|
||||
}
|
||||
_ref2 = this.assignment_groups;
|
||||
for (id in _ref2) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
(function() {
|
||||
(function($) {
|
||||
$.fn.kyleMenu = function(options) {
|
||||
return this.each(function() {
|
||||
var $menu, opts;
|
||||
opts = $.extend(true, {}, $.fn.kyleMenu.defaults, options);
|
||||
$menu = $(this).button(opts.buttonOpts).next().menu(opts.menuOpts).popup(opts.popupOpts).addClass("ui-kyle-menu");
|
||||
return $menu.bind("menuselect", function() {
|
||||
return $(this).removeClass("ui-state-open");
|
||||
});
|
||||
});
|
||||
};
|
||||
return $.fn.kyleMenu.defaults = {
|
||||
popupOpts: {
|
||||
position: {
|
||||
my: 'center top',
|
||||
at: 'center bottom',
|
||||
offset: '0 10px'
|
||||
},
|
||||
open: function(event) {
|
||||
var $trigger, caratOffset, differenceInWidth, triggerWidth;
|
||||
$(this).find(".ui-menu-carat").remove();
|
||||
$trigger = jQUI19(this).popup("option", "trigger");
|
||||
triggerWidth = $trigger.width();
|
||||
differenceInWidth = $(this).width() - triggerWidth;
|
||||
caratOffset = Math.min(Math.max(20, event.offsetX), triggerWidth - 20) + differenceInWidth / 2;
|
||||
$('<span class="ui-menu-carat"><span /></span>').css('left', caratOffset).prependTo(this);
|
||||
return $(this).css('-webkit-transform-origin-x', caratOffset + 'px').addClass('ui-state-open');
|
||||
},
|
||||
close: function() {
|
||||
return $(this).removeClass("ui-state-open");
|
||||
}
|
||||
},
|
||||
buttonOpts: {
|
||||
icons: {
|
||||
primary: "ui-icon-home",
|
||||
secondary: "ui-icon-droparrow"
|
||||
}
|
||||
}
|
||||
};
|
||||
})(this.jQuery);
|
||||
}).call(this);
|
|
@ -9,8 +9,6 @@
|
|||
return child;
|
||||
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||
this.SubmissionCell = SubmissionCell = (function() {
|
||||
var tooltipTexts;
|
||||
tooltipTexts = {};
|
||||
function SubmissionCell(opts) {
|
||||
this.opts = opts;
|
||||
this.init();
|
||||
|
@ -86,8 +84,7 @@
|
|||
opts.assignment || (opts.assignment = this.opts.column.object);
|
||||
specialClasses = SubmissionCell.classesBasedOnSubmission(opts.submission, opts.assignment);
|
||||
tooltipText = $.map(specialClasses, function(c) {
|
||||
var _ref;
|
||||
return (_ref = tooltipTexts[c]) != null ? _ref : tooltipTexts[c] = $("#submission_tooltip_" + c).text();
|
||||
return GRADEBOOK_TRANSLATIONS["submission_tooltip_" + c];
|
||||
}).join(', ');
|
||||
return "" + (tooltipText ? '<div class="gradebook-tooltip">' + tooltipText + '</div>' : '') + "\n<div class=\"gradebook-cell " + (opts.editable ? 'gradebook-cell-editable focus' : '') + " " + opts.classes + " " + (specialClasses.join(' ')) + "\">\n <a href=\"#\" class=\"gradebook-cell-comment\"><span class=\"gradebook-cell-comment-label\">submission comments</span></a>\n " + innerContents + "\n</div>";
|
||||
};
|
||||
|
@ -109,6 +106,9 @@
|
|||
if (submission.drop) {
|
||||
classes.push('dropped');
|
||||
}
|
||||
if ('' + assignment.submission_types === "not_graded") {
|
||||
classes.push('ungraded');
|
||||
}
|
||||
return classes;
|
||||
};
|
||||
return SubmissionCell;
|
||||
|
|
|
@ -2118,6 +2118,7 @@
|
|||
}
|
||||
var xhr = $.ajax(params);
|
||||
$.ajaxJSON.storeRequest(xhr, url, submit_type, data);
|
||||
return xhr;
|
||||
};
|
||||
$.ajaxJSON.unhandledXHRs = [];
|
||||
$.ajaxJSON.ignoredXHRs = [];
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* jQuery UI Button @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Button
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
var lastActive, startXPos, startYPos, clickDragged,
|
||||
baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
|
||||
stateClasses = "ui-state-hover ui-state-active ",
|
||||
typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
|
||||
formResetHandler = function() {
|
||||
var buttons = $( this ).find( ":ui-button" );
|
||||
setTimeout(function() {
|
||||
buttons.button( "refresh" );
|
||||
}, 1 );
|
||||
},
|
||||
radioGroup = function( radio ) {
|
||||
var name = radio.name,
|
||||
form = radio.form,
|
||||
radios = $( [] );
|
||||
if ( name ) {
|
||||
if ( form ) {
|
||||
radios = $( form ).find( "[name='" + name + "']" );
|
||||
} else {
|
||||
radios = $( "[name='" + name + "']", radio.ownerDocument )
|
||||
.filter(function() {
|
||||
return !this.form;
|
||||
});
|
||||
}
|
||||
}
|
||||
return radios;
|
||||
};
|
||||
|
||||
$.widget( "ui.button", {
|
||||
version: "@VERSION",
|
||||
defaultElement: "<button>",
|
||||
options: {
|
||||
disabled: null,
|
||||
text: true,
|
||||
label: null,
|
||||
icons: {
|
||||
primary: null,
|
||||
secondary: null
|
||||
}
|
||||
},
|
||||
_create: function() {
|
||||
this.element.closest( "form" )
|
||||
.unbind( "reset.button" )
|
||||
.bind( "reset.button", formResetHandler );
|
||||
|
||||
if ( typeof this.options.disabled !== "boolean" ) {
|
||||
this.options.disabled = this.element.prop( "disabled" );
|
||||
}
|
||||
|
||||
this._determineButtonType();
|
||||
this.hasTitle = !!this.buttonElement.attr( "title" );
|
||||
|
||||
var self = this,
|
||||
options = this.options,
|
||||
toggleButton = this.type === "checkbox" || this.type === "radio",
|
||||
hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ),
|
||||
focusClass = "ui-state-focus";
|
||||
|
||||
if ( options.label === null ) {
|
||||
options.label = this.buttonElement.html();
|
||||
}
|
||||
|
||||
if ( this.element.is( ":disabled" ) ) {
|
||||
options.disabled = true;
|
||||
}
|
||||
|
||||
this.buttonElement
|
||||
.addClass( baseClasses )
|
||||
.attr( "role", "button" )
|
||||
.bind( "mouseenter.button", function() {
|
||||
if ( options.disabled ) {
|
||||
return;
|
||||
}
|
||||
$( this ).addClass( "ui-state-hover" );
|
||||
if ( this === lastActive ) {
|
||||
$( this ).addClass( "ui-state-active" );
|
||||
}
|
||||
})
|
||||
.bind( "mouseleave.button", function() {
|
||||
if ( options.disabled ) {
|
||||
return;
|
||||
}
|
||||
$( this ).removeClass( hoverClass );
|
||||
})
|
||||
.bind( "click.button", function( event ) {
|
||||
if ( options.disabled ) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
});
|
||||
|
||||
this.element
|
||||
.bind( "focus.button", function() {
|
||||
// no need to check disabled, focus won't be triggered anyway
|
||||
self.buttonElement.addClass( focusClass );
|
||||
})
|
||||
.bind( "blur.button", function() {
|
||||
self.buttonElement.removeClass( focusClass );
|
||||
});
|
||||
|
||||
if ( toggleButton ) {
|
||||
this.element.bind( "change.button", function() {
|
||||
if ( clickDragged ) {
|
||||
return;
|
||||
}
|
||||
self.refresh();
|
||||
});
|
||||
// if mouse moves between mousedown and mouseup (drag) set clickDragged flag
|
||||
// prevents issue where button state changes but checkbox/radio checked state
|
||||
// does not in Firefox (see ticket #6970)
|
||||
this.buttonElement
|
||||
.bind( "mousedown.button", function( event ) {
|
||||
if ( options.disabled ) {
|
||||
return;
|
||||
}
|
||||
clickDragged = false;
|
||||
startXPos = event.pageX;
|
||||
startYPos = event.pageY;
|
||||
})
|
||||
.bind( "mouseup.button", function( event ) {
|
||||
if ( options.disabled ) {
|
||||
return;
|
||||
}
|
||||
if ( startXPos !== event.pageX || startYPos !== event.pageY ) {
|
||||
clickDragged = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ( this.type === "checkbox" ) {
|
||||
this.buttonElement.bind( "click.button", function() {
|
||||
if ( options.disabled || clickDragged ) {
|
||||
return false;
|
||||
}
|
||||
$( this ).toggleClass( "ui-state-active" );
|
||||
self.buttonElement.attr( "aria-pressed", self.element[0].checked );
|
||||
});
|
||||
} else if ( this.type === "radio" ) {
|
||||
this.buttonElement.bind( "click.button", function() {
|
||||
if ( options.disabled || clickDragged ) {
|
||||
return false;
|
||||
}
|
||||
$( this ).addClass( "ui-state-active" );
|
||||
self.buttonElement.attr( "aria-pressed", "true" );
|
||||
|
||||
var radio = self.element[ 0 ];
|
||||
radioGroup( radio )
|
||||
.not( radio )
|
||||
.map(function() {
|
||||
return $( this ).button( "widget" )[ 0 ];
|
||||
})
|
||||
.removeClass( "ui-state-active" )
|
||||
.attr( "aria-pressed", "false" );
|
||||
});
|
||||
} else {
|
||||
this.buttonElement
|
||||
.bind( "mousedown.button", function() {
|
||||
if ( options.disabled ) {
|
||||
return false;
|
||||
}
|
||||
$( this ).addClass( "ui-state-active" );
|
||||
lastActive = this;
|
||||
$( document ).one( "mouseup", function() {
|
||||
lastActive = null;
|
||||
});
|
||||
})
|
||||
.bind( "mouseup.button", function() {
|
||||
if ( options.disabled ) {
|
||||
return false;
|
||||
}
|
||||
$( this ).removeClass( "ui-state-active" );
|
||||
})
|
||||
.bind( "keydown.button", function(event) {
|
||||
if ( options.disabled ) {
|
||||
return false;
|
||||
}
|
||||
if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) {
|
||||
$( this ).addClass( "ui-state-active" );
|
||||
}
|
||||
})
|
||||
.bind( "keyup.button", function() {
|
||||
$( this ).removeClass( "ui-state-active" );
|
||||
});
|
||||
|
||||
if ( this.buttonElement.is("a") ) {
|
||||
this.buttonElement.keyup(function(event) {
|
||||
if ( event.keyCode === $.ui.keyCode.SPACE ) {
|
||||
// TODO pass through original event correctly (just as 2nd argument doesn't work)
|
||||
$( this ).click();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: pull out $.Widget's handling for the disabled option into
|
||||
// $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
|
||||
// be overridden by individual plugins
|
||||
this._setOption( "disabled", options.disabled );
|
||||
this._resetButton();
|
||||
},
|
||||
|
||||
_determineButtonType: function() {
|
||||
|
||||
if ( this.element.is(":checkbox") ) {
|
||||
this.type = "checkbox";
|
||||
} else if ( this.element.is(":radio") ) {
|
||||
this.type = "radio";
|
||||
} else if ( this.element.is("input") ) {
|
||||
this.type = "input";
|
||||
} else {
|
||||
this.type = "button";
|
||||
}
|
||||
|
||||
if ( this.type === "checkbox" || this.type === "radio" ) {
|
||||
// we don't search against the document in case the element
|
||||
// is disconnected from the DOM
|
||||
var ancestor = this.element.parents().last(),
|
||||
labelSelector = "label[for=" + this.element.attr("id") + "]";
|
||||
this.buttonElement = ancestor.find( labelSelector );
|
||||
if ( !this.buttonElement.length ) {
|
||||
ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
|
||||
this.buttonElement = ancestor.filter( labelSelector );
|
||||
if ( !this.buttonElement.length ) {
|
||||
this.buttonElement = ancestor.find( labelSelector );
|
||||
}
|
||||
}
|
||||
this.element.addClass( "ui-helper-hidden-accessible" );
|
||||
|
||||
var checked = this.element.is( ":checked" );
|
||||
if ( checked ) {
|
||||
this.buttonElement.addClass( "ui-state-active" );
|
||||
}
|
||||
this.buttonElement.prop( "aria-pressed", checked );
|
||||
} else {
|
||||
this.buttonElement = this.element;
|
||||
}
|
||||
},
|
||||
|
||||
widget: function() {
|
||||
return this.buttonElement;
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
this.element
|
||||
.removeClass( "ui-helper-hidden-accessible" );
|
||||
this.buttonElement
|
||||
.removeClass( baseClasses + " " + stateClasses + " " + typeClasses )
|
||||
.removeAttr( "role" )
|
||||
.removeAttr( "aria-pressed" )
|
||||
.html( this.buttonElement.find(".ui-button-text").html() );
|
||||
|
||||
if ( !this.hasTitle ) {
|
||||
this.buttonElement.removeAttr( "title" );
|
||||
}
|
||||
},
|
||||
|
||||
_setOption: function( key, value ) {
|
||||
this._super( "_setOption", key, value );
|
||||
if ( key === "disabled" ) {
|
||||
if ( value ) {
|
||||
this.element.prop( "disabled", true );
|
||||
} else {
|
||||
this.element.prop( "disabled", false );
|
||||
}
|
||||
return;
|
||||
}
|
||||
this._resetButton();
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
var isDisabled = this.element.is( ":disabled" );
|
||||
if ( isDisabled !== this.options.disabled ) {
|
||||
this._setOption( "disabled", isDisabled );
|
||||
}
|
||||
if ( this.type === "radio" ) {
|
||||
radioGroup( this.element[0] ).each(function() {
|
||||
if ( $( this ).is( ":checked" ) ) {
|
||||
$( this ).button( "widget" )
|
||||
.addClass( "ui-state-active" )
|
||||
.attr( "aria-pressed", "true" );
|
||||
} else {
|
||||
$( this ).button( "widget" )
|
||||
.removeClass( "ui-state-active" )
|
||||
.attr( "aria-pressed", "false" );
|
||||
}
|
||||
});
|
||||
} else if ( this.type === "checkbox" ) {
|
||||
if ( this.element.is( ":checked" ) ) {
|
||||
this.buttonElement
|
||||
.addClass( "ui-state-active" )
|
||||
.attr( "aria-pressed", "true" );
|
||||
} else {
|
||||
this.buttonElement
|
||||
.removeClass( "ui-state-active" )
|
||||
.attr( "aria-pressed", "false" );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_resetButton: function() {
|
||||
if ( this.type === "input" ) {
|
||||
if ( this.options.label ) {
|
||||
this.element.val( this.options.label );
|
||||
}
|
||||
return;
|
||||
}
|
||||
var buttonElement = this.buttonElement.removeClass( typeClasses ),
|
||||
buttonText = $( "<span></span>" )
|
||||
.addClass( "ui-button-text" )
|
||||
.html( this.options.label )
|
||||
.appendTo( buttonElement.empty() )
|
||||
.text(),
|
||||
icons = this.options.icons,
|
||||
multipleIcons = icons.primary && icons.secondary,
|
||||
buttonClasses = [];
|
||||
|
||||
if ( icons.primary || icons.secondary ) {
|
||||
if ( this.options.text ) {
|
||||
buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
|
||||
}
|
||||
|
||||
if ( icons.primary ) {
|
||||
buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
|
||||
}
|
||||
|
||||
if ( icons.secondary ) {
|
||||
buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
|
||||
}
|
||||
|
||||
if ( !this.options.text ) {
|
||||
buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
|
||||
|
||||
if ( !this.hasTitle ) {
|
||||
buttonElement.attr( "title", buttonText );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buttonClasses.push( "ui-button-text-only" );
|
||||
}
|
||||
buttonElement.addClass( buttonClasses.join( " " ) );
|
||||
}
|
||||
});
|
||||
|
||||
$.ui.button.version = "@VERSION";
|
||||
|
||||
$.widget( "ui.buttonset", {
|
||||
options: {
|
||||
items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)"
|
||||
},
|
||||
|
||||
_create: function() {
|
||||
this.element.addClass( "ui-buttonset" );
|
||||
},
|
||||
|
||||
_init: function() {
|
||||
this.refresh();
|
||||
},
|
||||
|
||||
_setOption: function( key, value ) {
|
||||
if ( key === "disabled" ) {
|
||||
this.buttons.button( "option", key, value );
|
||||
}
|
||||
|
||||
this._super( "_setOption", key, value );
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
var ltr = this.element.css( "direction" ) === "ltr";
|
||||
|
||||
this.buttons = this.element.find( this.options.items )
|
||||
.filter( ":ui-button" )
|
||||
.button( "refresh" )
|
||||
.end()
|
||||
.not( ":ui-button" )
|
||||
.button()
|
||||
.end()
|
||||
.map(function() {
|
||||
return $( this ).button( "widget" )[ 0 ];
|
||||
})
|
||||
.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
|
||||
.filter( ":first" )
|
||||
.addClass( ltr ? "ui-corner-left" : "ui-corner-right" )
|
||||
.end()
|
||||
.filter( ":last" )
|
||||
.addClass( ltr ? "ui-corner-right" : "ui-corner-left" )
|
||||
.end()
|
||||
.end();
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
this.element.removeClass( "ui-buttonset" );
|
||||
this.buttons
|
||||
.map(function() {
|
||||
return $( this ).button( "widget" )[ 0 ];
|
||||
})
|
||||
.removeClass( "ui-corner-left ui-corner-right" )
|
||||
.end()
|
||||
.button( "destroy" );
|
||||
}
|
||||
});
|
||||
|
||||
}( jQuery ) );
|
|
@ -0,0 +1,307 @@
|
|||
/*!
|
||||
* jQuery UI @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
// prevent duplicate loading
|
||||
// this is only a problem because we proxy existing functions
|
||||
// and we don't want to double proxy them
|
||||
$.ui = $.ui || {};
|
||||
if ( $.ui.version ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.extend( $.ui, {
|
||||
version: "@VERSION",
|
||||
|
||||
keyCode: {
|
||||
ALT: 18,
|
||||
BACKSPACE: 8,
|
||||
CAPS_LOCK: 20,
|
||||
COMMA: 188,
|
||||
COMMAND: 91,
|
||||
COMMAND_LEFT: 91, // COMMAND
|
||||
COMMAND_RIGHT: 93,
|
||||
CONTROL: 17,
|
||||
DELETE: 46,
|
||||
DOWN: 40,
|
||||
END: 35,
|
||||
ENTER: 13,
|
||||
ESCAPE: 27,
|
||||
HOME: 36,
|
||||
INSERT: 45,
|
||||
LEFT: 37,
|
||||
MENU: 93, // COMMAND_RIGHT
|
||||
NUMPAD_ADD: 107,
|
||||
NUMPAD_DECIMAL: 110,
|
||||
NUMPAD_DIVIDE: 111,
|
||||
NUMPAD_ENTER: 108,
|
||||
NUMPAD_MULTIPLY: 106,
|
||||
NUMPAD_SUBTRACT: 109,
|
||||
PAGE_DOWN: 34,
|
||||
PAGE_UP: 33,
|
||||
PERIOD: 190,
|
||||
RIGHT: 39,
|
||||
SHIFT: 16,
|
||||
SPACE: 32,
|
||||
TAB: 9,
|
||||
UP: 38,
|
||||
WINDOWS: 91 // COMMAND
|
||||
}
|
||||
});
|
||||
|
||||
// plugins
|
||||
$.fn.extend({
|
||||
_focus: $.fn.focus,
|
||||
focus: function( delay, fn ) {
|
||||
return typeof delay === "number" ?
|
||||
this.each(function() {
|
||||
var elem = this;
|
||||
setTimeout(function() {
|
||||
$( elem ).focus();
|
||||
if ( fn ) {
|
||||
fn.call( elem );
|
||||
}
|
||||
}, delay );
|
||||
}) :
|
||||
this._focus.apply( this, arguments );
|
||||
},
|
||||
|
||||
scrollParent: function() {
|
||||
var scrollParent;
|
||||
if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
|
||||
scrollParent = this.parents().filter(function() {
|
||||
return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
|
||||
}).eq(0);
|
||||
} else {
|
||||
scrollParent = this.parents().filter(function() {
|
||||
return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
|
||||
}).eq(0);
|
||||
}
|
||||
|
||||
return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
|
||||
},
|
||||
|
||||
zIndex: function( zIndex ) {
|
||||
if ( zIndex !== undefined ) {
|
||||
return this.css( "zIndex", zIndex );
|
||||
}
|
||||
|
||||
if ( this.length ) {
|
||||
var elem = $( this[ 0 ] ), position, value;
|
||||
while ( elem.length && elem[ 0 ] !== document ) {
|
||||
// Ignore z-index if position is set to a value where z-index is ignored by the browser
|
||||
// This makes behavior of this function consistent across browsers
|
||||
// WebKit always returns auto if the element is positioned
|
||||
position = elem.css( "position" );
|
||||
if ( position === "absolute" || position === "relative" || position === "fixed" ) {
|
||||
// IE returns 0 when zIndex is not specified
|
||||
// other browsers return a string
|
||||
// we ignore the case of nested elements with an explicit value of 0
|
||||
// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
|
||||
value = parseInt( elem.css( "zIndex" ), 10 );
|
||||
if ( !isNaN( value ) && value !== 0 ) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
elem = elem.parent();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
},
|
||||
|
||||
disableSelection: function() {
|
||||
return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
|
||||
".ui-disableSelection", function( event ) {
|
||||
event.preventDefault();
|
||||
});
|
||||
},
|
||||
|
||||
enableSelection: function() {
|
||||
return this.unbind( ".ui-disableSelection" );
|
||||
}
|
||||
});
|
||||
|
||||
$.each( [ "Width", "Height" ], function( i, name ) {
|
||||
var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
|
||||
type = name.toLowerCase(),
|
||||
orig = {
|
||||
innerWidth: $.fn.innerWidth,
|
||||
innerHeight: $.fn.innerHeight,
|
||||
outerWidth: $.fn.outerWidth,
|
||||
outerHeight: $.fn.outerHeight
|
||||
};
|
||||
|
||||
function reduce( elem, size, border, margin ) {
|
||||
$.each( side, function() {
|
||||
size -= parseFloat( $.curCSS( elem, "padding" + this, true ) ) || 0;
|
||||
if ( border ) {
|
||||
size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true ) ) || 0;
|
||||
}
|
||||
if ( margin ) {
|
||||
size -= parseFloat( $.curCSS( elem, "margin" + this, true ) ) || 0;
|
||||
}
|
||||
});
|
||||
return size;
|
||||
}
|
||||
|
||||
$.fn[ "inner" + name ] = function( size ) {
|
||||
if ( size === undefined ) {
|
||||
return orig[ "inner" + name ].call( this );
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
$( this ).css( type, reduce( this, size ) + "px" );
|
||||
});
|
||||
};
|
||||
|
||||
$.fn[ "outer" + name] = function( size, margin ) {
|
||||
if ( typeof size !== "number" ) {
|
||||
return orig[ "outer" + name ].call( this, size );
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
$( this).css( type, reduce( this, size, true, margin ) + "px" );
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
// selectors
|
||||
function focusable( element, isTabIndexNotNaN ) {
|
||||
var nodeName = element.nodeName.toLowerCase();
|
||||
if ( "area" === nodeName ) {
|
||||
var map = element.parentNode,
|
||||
mapName = map.name,
|
||||
img;
|
||||
if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
|
||||
return false;
|
||||
}
|
||||
img = $( "img[usemap=#" + mapName + "]" )[0];
|
||||
return !!img && visible( img );
|
||||
}
|
||||
return ( /input|select|textarea|button|object/.test( nodeName )
|
||||
? !element.disabled
|
||||
: "a" == nodeName
|
||||
? element.href || isTabIndexNotNaN
|
||||
: isTabIndexNotNaN)
|
||||
// the element and all of its ancestors must be visible
|
||||
&& visible( element );
|
||||
}
|
||||
|
||||
function visible( element ) {
|
||||
return !$( element ).parents().andSelf().filter(function() {
|
||||
return $.curCSS( this, "visibility" ) === "hidden" ||
|
||||
$.expr.filters.hidden( this );
|
||||
}).length;
|
||||
}
|
||||
|
||||
$.extend( $.expr[ ":" ], {
|
||||
data: function( elem, i, match ) {
|
||||
return !!$.data( elem, match[ 3 ] );
|
||||
},
|
||||
|
||||
focusable: function( element ) {
|
||||
return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
|
||||
},
|
||||
|
||||
tabbable: function( element ) {
|
||||
var tabIndex = $.attr( element, "tabindex" ),
|
||||
isTabIndexNaN = isNaN( tabIndex );
|
||||
return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
|
||||
}
|
||||
});
|
||||
|
||||
// support
|
||||
$(function() {
|
||||
var body = document.body,
|
||||
div = body.appendChild( div = document.createElement( "div" ) );
|
||||
|
||||
$.extend( div.style, {
|
||||
minHeight: "100px",
|
||||
height: "auto",
|
||||
padding: 0,
|
||||
borderWidth: 0
|
||||
});
|
||||
|
||||
$.support.minHeight = div.offsetHeight === 100;
|
||||
$.support.selectstart = "onselectstart" in div;
|
||||
|
||||
// set display to none to avoid a layout bug in IE
|
||||
// http://dev.jquery.com/ticket/4014
|
||||
body.removeChild( div ).style.display = "none";
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// deprecated
|
||||
$.extend( $.ui, {
|
||||
// $.ui.plugin is deprecated. Use the proxy pattern instead.
|
||||
plugin: {
|
||||
add: function( module, option, set ) {
|
||||
var proto = $.ui[ module ].prototype;
|
||||
for ( var i in set ) {
|
||||
proto.plugins[ i ] = proto.plugins[ i ] || [];
|
||||
proto.plugins[ i ].push( [ option, set[ i ] ] );
|
||||
}
|
||||
},
|
||||
call: function( instance, name, args ) {
|
||||
var set = instance.plugins[ name ];
|
||||
if ( !set || !instance.element[ 0 ].parentNode ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( var i = 0; i < set.length; i++ ) {
|
||||
if ( instance.options[ set[ i ][ 0 ] ] ) {
|
||||
set[ i ][ 1 ].apply( instance.element, args );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
contains: $.contains,
|
||||
|
||||
// only used by resizable
|
||||
hasScroll: function( el, a ) {
|
||||
|
||||
//If overflow is hidden, the element might have extra content, but the user wants to hide it
|
||||
if ( $( el ).css( "overflow" ) === "hidden") {
|
||||
return false;
|
||||
}
|
||||
|
||||
var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
|
||||
has = false;
|
||||
|
||||
if ( el[ scroll ] > 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: determine which cases actually cause this to happen
|
||||
// if the element doesn't have the scroll set, see if it's possible to
|
||||
// set the scroll
|
||||
el[ scroll ] = 1;
|
||||
has = ( el[ scroll ] > 0 );
|
||||
el[ scroll ] = 0;
|
||||
return has;
|
||||
},
|
||||
|
||||
// these are odd functions, fix the API or move into individual plugins
|
||||
isOverAxis: function( x, reference, size ) {
|
||||
//Determines when x coordinate is over "b" element axis
|
||||
return ( x > reference ) && ( x < ( reference + size ) );
|
||||
},
|
||||
isOver: function( y, x, top, left, height, width ) {
|
||||
//Determines when x, y coordinates is over "b" element
|
||||
return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width );
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
|
@ -0,0 +1,514 @@
|
|||
/*
|
||||
* jQuery UI Menu @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Menu
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
var idIncrement = 0;
|
||||
|
||||
$.widget( "ui.menu", {
|
||||
version: "@VERSION",
|
||||
defaultElement: "<ul>",
|
||||
delay: 150,
|
||||
options: {
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "right top"
|
||||
}
|
||||
},
|
||||
_create: function() {
|
||||
var self = this;
|
||||
this.activeMenu = this.element;
|
||||
this.menuId = this.element.attr( "id" ) || "ui-menu-" + idIncrement++;
|
||||
if ( this.element.find( ".ui-icon" ).length ) {
|
||||
this.element.addClass( "ui-menu-icons" );
|
||||
}
|
||||
this.element
|
||||
.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
|
||||
.attr({
|
||||
id: this.menuId,
|
||||
role: "menu"
|
||||
})
|
||||
.bind( "click.menu", function( event ) {
|
||||
var item = $( event.target ).closest( ".ui-menu-item:has(a)" );
|
||||
if ( self.options.disabled ) {
|
||||
return false;
|
||||
}
|
||||
if ( !item.length ) {
|
||||
return;
|
||||
}
|
||||
// it's possible to click an item without hovering it (#7085)
|
||||
if ( !self.active || ( self.active[ 0 ] !== item[ 0 ] ) ) {
|
||||
self.focus( event, item );
|
||||
}
|
||||
self.select( event );
|
||||
})
|
||||
.bind( "mouseover.menu", function( event ) {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
var target = $( event.target ).closest( ".ui-menu-item" );
|
||||
if ( target.length ) {
|
||||
//Remove ui-state-active class from siblings of the newly focused menu item to avoid a jump caused by adjacent elements both having a class with a border
|
||||
target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
|
||||
self.focus( event, target );
|
||||
}
|
||||
})
|
||||
.bind( "mouseout.menu", function( event ) {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
var target = $( event.target ).closest( ".ui-menu-item" );
|
||||
if ( target.length ) {
|
||||
self.blur( event );
|
||||
}
|
||||
})
|
||||
.bind( "focus.menu", function( event ) {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
self.focus( event, $( event.target ).children( ".ui-menu-item:first" ) );
|
||||
})
|
||||
.bind( "blur.menu", function( event ) {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
self.collapseAll( event );
|
||||
});
|
||||
this.refresh();
|
||||
|
||||
this.element.attr( "tabIndex", 0 ).bind( "keydown.menu", function( event ) {
|
||||
if ( self.options.disabled ) {
|
||||
return;
|
||||
}
|
||||
switch ( event.keyCode ) {
|
||||
case $.ui.keyCode.PAGE_UP:
|
||||
self.previousPage( event );
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
break;
|
||||
case $.ui.keyCode.PAGE_DOWN:
|
||||
self.nextPage( event );
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
break;
|
||||
case $.ui.keyCode.HOME:
|
||||
self._move( "first", "first", event );
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
break;
|
||||
case $.ui.keyCode.END:
|
||||
self._move( "last", "last", event );
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
break;
|
||||
case $.ui.keyCode.UP:
|
||||
self.previous( event );
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
break;
|
||||
case $.ui.keyCode.DOWN:
|
||||
self.next( event );
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
break;
|
||||
case $.ui.keyCode.LEFT:
|
||||
if (self.collapse( event )) {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
case $.ui.keyCode.RIGHT:
|
||||
if (self.expand( event )) {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
case $.ui.keyCode.ENTER:
|
||||
if ( self.active.children( "a[aria-haspopup='true']" ).length ) {
|
||||
if ( self.expand( event ) ) {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.select( event );
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
case $.ui.keyCode.ESCAPE:
|
||||
if ( self.collapse( event ) ) {
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
default:
|
||||
event.stopPropagation();
|
||||
clearTimeout( self.filterTimer );
|
||||
var match,
|
||||
prev = self.previousFilter || "",
|
||||
character = String.fromCharCode( event.keyCode ),
|
||||
skip = false;
|
||||
|
||||
if (character == prev) {
|
||||
skip = true;
|
||||
} else {
|
||||
character = prev + character;
|
||||
}
|
||||
function escape( value ) {
|
||||
return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" );
|
||||
}
|
||||
match = self.activeMenu.children( ".ui-menu-item" ).filter( function() {
|
||||
return new RegExp("^" + escape(character), "i")
|
||||
.test( $( this ).children( "a" ).text() );
|
||||
});
|
||||
match = skip && match.index(self.active.next()) != -1 ? self.active.nextAll(".ui-menu-item") : match;
|
||||
if ( !match.length ) {
|
||||
character = String.fromCharCode(event.keyCode);
|
||||
match = self.activeMenu.children(".ui-menu-item").filter( function() {
|
||||
return new RegExp("^" + escape(character), "i")
|
||||
.test( $( this ).children( "a" ).text() );
|
||||
});
|
||||
}
|
||||
if ( match.length ) {
|
||||
self.focus( event, match );
|
||||
if (match.length > 1) {
|
||||
self.previousFilter = character;
|
||||
self.filterTimer = setTimeout( function() {
|
||||
delete self.previousFilter;
|
||||
}, 1000 );
|
||||
} else {
|
||||
delete self.previousFilter;
|
||||
}
|
||||
} else {
|
||||
delete self.previousFilter;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this._bind( document, {
|
||||
click: function( event ) {
|
||||
if ( !$( event.target ).closest( ".ui-menu" ).length ) {
|
||||
this.collapseAll( event );
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
//destroy (sub)menus
|
||||
this.element
|
||||
.removeAttr( "aria-activedescendant" )
|
||||
.find( "ul" )
|
||||
.andSelf()
|
||||
.removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
|
||||
.removeAttr( "role" )
|
||||
.removeAttr( "tabIndex" )
|
||||
.removeAttr( "aria-labelledby" )
|
||||
.removeAttr( "aria-expanded" )
|
||||
.removeAttr( "aria-hidden" )
|
||||
.show();
|
||||
|
||||
//destroy menu items
|
||||
this.element.find( ".ui-menu-item" )
|
||||
.unbind( ".menu" )
|
||||
.removeClass( "ui-menu-item" )
|
||||
.removeAttr( "role" )
|
||||
.children( "a" )
|
||||
.removeClass( "ui-corner-all ui-state-hover" )
|
||||
.removeAttr( "tabIndex" )
|
||||
.removeAttr( "role" )
|
||||
.removeAttr( "aria-haspopup" )
|
||||
.removeAttr( "id" )
|
||||
.children( ".ui-icon" )
|
||||
.remove();
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
var self = this,
|
||||
|
||||
// initialize nested menus
|
||||
submenus = this.element.find( "ul:not(.ui-menu)" )
|
||||
.addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
|
||||
.attr( "role", "menu" )
|
||||
.hide()
|
||||
.attr( "aria-hidden", "true" )
|
||||
.attr( "aria-expanded", "false" ),
|
||||
|
||||
// don't refresh list items that are already adapted
|
||||
items = submenus.add( this.element ).children( "li:not(.ui-menu-item):has(a)" )
|
||||
.addClass( "ui-menu-item" )
|
||||
.attr( "role", "presentation" );
|
||||
|
||||
items.children( "a" )
|
||||
.addClass( "ui-corner-all" )
|
||||
.attr( "tabIndex", -1 )
|
||||
.attr( "role", "menuitem" )
|
||||
.attr( "id", function( i ) {
|
||||
return self.element.attr( "id" ) + "-" + i;
|
||||
});
|
||||
|
||||
submenus.each( function() {
|
||||
var menu = $( this ),
|
||||
item = menu.prev( "a" );
|
||||
|
||||
item.attr( "aria-haspopup", "true" )
|
||||
.prepend( '<span class="ui-menu-icon ui-icon ui-icon-carat-1-e"></span>' );
|
||||
menu.attr( "aria-labelledby", item.attr( "id" ) );
|
||||
});
|
||||
},
|
||||
|
||||
focus: function( event, item ) {
|
||||
var nested,
|
||||
self = this;
|
||||
|
||||
this.blur( event );
|
||||
|
||||
if ( this._hasScroll() ) {
|
||||
var borderTop = parseFloat( $.curCSS( this.activeMenu[0], "borderTopWidth", true ) ) || 0,
|
||||
paddingTop = parseFloat( $.curCSS( this.activeMenu[0], "paddingTop", true ) ) || 0,
|
||||
offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop,
|
||||
scroll = this.activeMenu.scrollTop(),
|
||||
elementHeight = this.activeMenu.height(),
|
||||
itemHeight = item.height();
|
||||
|
||||
if ( offset < 0 ) {
|
||||
this.activeMenu.scrollTop( scroll + offset );
|
||||
} else if ( offset + itemHeight > elementHeight ) {
|
||||
this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
|
||||
}
|
||||
}
|
||||
|
||||
this.active = item.first()
|
||||
.children( "a" )
|
||||
.addClass( "ui-state-focus" )
|
||||
.end();
|
||||
self.element.attr( "aria-activedescendant", self.active.children("a").attr("id") );
|
||||
|
||||
// highlight active parent menu item, if any
|
||||
this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active");
|
||||
|
||||
self.timer = setTimeout( function() {
|
||||
self._close();
|
||||
}, self.delay );
|
||||
|
||||
nested = $( ">ul", item );
|
||||
if ( nested.length && ( /^mouse/.test( event.type ) ) ) {
|
||||
self._startOpening(nested);
|
||||
}
|
||||
this.activeMenu = item.parent();
|
||||
|
||||
this._trigger( "focus", event, { item: item } );
|
||||
},
|
||||
|
||||
blur: function( event ) {
|
||||
if ( !this.active ) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout( this.timer );
|
||||
|
||||
this.active.children( "a" ).removeClass( "ui-state-focus" );
|
||||
this.active = null;
|
||||
|
||||
this._trigger( "blur", event, { item: this.active } );
|
||||
},
|
||||
|
||||
_startOpening: function( submenu ) {
|
||||
clearTimeout( this.timer );
|
||||
|
||||
// Don't open if already open fixes a Firefox bug that caused a .5 pixel
|
||||
// shift in the submenu position when mousing over the carat icon
|
||||
if ( submenu.attr( "aria-hidden" ) !== "true" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
self.timer = setTimeout( function() {
|
||||
self._close();
|
||||
self._open( submenu );
|
||||
}, self.delay );
|
||||
},
|
||||
|
||||
_open: function( submenu ) {
|
||||
clearTimeout( this.timer );
|
||||
this.element
|
||||
.find( ".ui-menu" )
|
||||
.not( submenu.parents() )
|
||||
.hide()
|
||||
.attr( "aria-hidden", "true" );
|
||||
|
||||
var position = $.extend({}, {
|
||||
of: this.active
|
||||
}, $.type(this.options.position) == "function"
|
||||
? this.options.position(this.active)
|
||||
: this.options.position
|
||||
);
|
||||
|
||||
submenu.show()
|
||||
.removeAttr( "aria-hidden" )
|
||||
.attr( "aria-expanded", "true" )
|
||||
.position( position );
|
||||
},
|
||||
|
||||
collapseAll: function( event ) {
|
||||
this.element
|
||||
.find( "ul" )
|
||||
.hide()
|
||||
.attr( "aria-hidden", "true" )
|
||||
.attr( "aria-expanded", "false" )
|
||||
.end()
|
||||
.find( "a.ui-state-active" )
|
||||
.removeClass( "ui-state-active" );
|
||||
|
||||
this.blur( event );
|
||||
this.activeMenu = this.element;
|
||||
},
|
||||
|
||||
_close: function() {
|
||||
this.active.parent()
|
||||
.find( "ul" )
|
||||
.hide()
|
||||
.attr( "aria-hidden", "true" )
|
||||
.attr( "aria-expanded", "false" )
|
||||
.end()
|
||||
.find( "a.ui-state-active" )
|
||||
.removeClass( "ui-state-active" );
|
||||
},
|
||||
|
||||
collapse: function( event ) {
|
||||
var newItem = this.active && this.active.parents("li:not(.ui-menubar-item)").first();
|
||||
if ( newItem && newItem.length ) {
|
||||
this.active.parent()
|
||||
.attr("aria-hidden", "true")
|
||||
.attr("aria-expanded", "false")
|
||||
.hide();
|
||||
this.focus( event, newItem );
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
expand: function( event ) {
|
||||
var self = this,
|
||||
newItem = this.active && this.active.children("ul").children("li").first();
|
||||
|
||||
if ( newItem && newItem.length ) {
|
||||
this._open( newItem.parent() );
|
||||
|
||||
//timeout so Firefox will not hide activedescendant change in expanding submenu from AT
|
||||
setTimeout( function() {
|
||||
self.focus( event, newItem );
|
||||
}, 20 );
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
next: function(event) {
|
||||
this._move( "next", "first", event );
|
||||
},
|
||||
|
||||
previous: function(event) {
|
||||
this._move( "prev", "last", event );
|
||||
},
|
||||
|
||||
first: function() {
|
||||
return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
|
||||
},
|
||||
|
||||
last: function() {
|
||||
return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
|
||||
},
|
||||
|
||||
_move: function( direction, filter, event ) {
|
||||
if ( !this.active ) {
|
||||
this.focus( event, this.activeMenu.children( ".ui-menu-item" )[ filter ]() );
|
||||
return;
|
||||
}
|
||||
|
||||
var next;
|
||||
if ( direction === "first" || direction === "last" ) {
|
||||
next = this.active[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" ).eq( -1 );
|
||||
} else {
|
||||
next = this.active[ direction + "All" ]( ".ui-menu-item" ).eq( 0 );
|
||||
}
|
||||
|
||||
if ( next.length ) {
|
||||
this.focus( event, next );
|
||||
} else {
|
||||
this.focus( event, this.activeMenu.children( ".ui-menu-item" )[ filter ]() );
|
||||
}
|
||||
},
|
||||
|
||||
nextPage: function( event ) {
|
||||
if ( this._hasScroll() ) {
|
||||
if ( !this.active ) {
|
||||
this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
|
||||
return;
|
||||
}
|
||||
if ( this.last() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var base = this.active.offset().top,
|
||||
height = this.element.height(),
|
||||
result;
|
||||
this.active.nextAll( ".ui-menu-item" ).each( function() {
|
||||
result = $( this );
|
||||
return $( this ).offset().top - base - height < 0;
|
||||
});
|
||||
|
||||
this.focus( event, result );
|
||||
} else {
|
||||
this.focus( event, this.activeMenu.children( ".ui-menu-item" )
|
||||
[ !this.active ? "first" : "last" ]() );
|
||||
}
|
||||
},
|
||||
|
||||
previousPage: function( event ) {
|
||||
if ( this._hasScroll() ) {
|
||||
if ( !this.active ) {
|
||||
this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
|
||||
return;
|
||||
}
|
||||
if ( this.first() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var base = this.active.offset().top,
|
||||
height = this.element.height(),
|
||||
result;
|
||||
this.active.prevAll( ".ui-menu-item" ).each( function() {
|
||||
result = $( this );
|
||||
return $(this).offset().top - base + height > 0;
|
||||
});
|
||||
|
||||
this.focus( event, result );
|
||||
} else {
|
||||
this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
|
||||
}
|
||||
},
|
||||
|
||||
_hasScroll: function() {
|
||||
return this.element.height() < this.element.prop( "scrollHeight" );
|
||||
},
|
||||
|
||||
select: function( event ) {
|
||||
// save active reference before collapseAll triggers blur
|
||||
var ui = {
|
||||
item: this.active
|
||||
};
|
||||
this.collapseAll( event );
|
||||
this._trigger( "select", event, ui );
|
||||
}
|
||||
});
|
||||
|
||||
}( jQuery ));
|
|
@ -0,0 +1 @@
|
|||
jQUI19 = jQuery.noConflict(true);
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* jQuery UI Input Menu Extension
|
||||
*
|
||||
* Copyright 2010, Kris Borchers
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* http://github.com/kborchers/jquery-ui-extensions
|
||||
*/
|
||||
(function( $ ) {
|
||||
|
||||
var proto = $.ui.menu.prototype,
|
||||
originalRefresh = proto.refresh;
|
||||
|
||||
$.extend( proto, {
|
||||
refresh: function() {
|
||||
originalRefresh.call( this );
|
||||
var that = this;
|
||||
var items = this.element.find( "li.ui-menu-item" );
|
||||
var inputGroupLabeled = false;
|
||||
|
||||
this.element.bind( "click.menu", function( event ) {
|
||||
if( !new RegExp(/^a$/i).test(event.target.tagName) ) event.preventDefault();
|
||||
});
|
||||
|
||||
var inputIDCount = 0;
|
||||
this.element.find( "input[type='checkbox'], input[type='radio']" ).each( function() {
|
||||
var labelElement = $( this ).closest( "label" );
|
||||
if( labelElement.length ) {
|
||||
$( this ).insertBefore( labelElement );
|
||||
|
||||
if( !$( this ).attr( "id" ) ) {
|
||||
$( this ).attr( "id", "ui-input-" + inputIDCount++ );
|
||||
}
|
||||
|
||||
labelElement.attr( "for", $( this ).attr( "id" ) );
|
||||
}
|
||||
});
|
||||
|
||||
items.children( "a" ).each( function( index, item ) {
|
||||
var current = $( item ), parent = current.parent();
|
||||
|
||||
if( current.children().is( "input[type='checkbox'], input[type='radio']" ) ) {
|
||||
current.closest( "ul" ).addClass( "ui-menu-icons" );
|
||||
|
||||
if( current.children( "input[type='checkbox']" ).is( ":checked" ) ) {
|
||||
current.prepend( '<span class="ui-icon ui-icon-check"></span>' );
|
||||
parent.attr({
|
||||
role: "menuitemcheckbox",
|
||||
"aria-checked": "true"
|
||||
});
|
||||
} else if( current.children( "input[type='radio']" ).is( ":checked" ) ) {
|
||||
current.prepend( '<span class="ui-icon ui-icon-radio-on"></span>' );
|
||||
parent.attr({
|
||||
role: "menuitemradio",
|
||||
"aria-checked": "true"
|
||||
});
|
||||
} else if( current.children( "input[type='radio']" ).length ) {
|
||||
current.prepend( '<span class="ui-icon ui-icon-radio-off"></span>' );
|
||||
parent.attr({
|
||||
role: "menuitemradio",
|
||||
"aria-checked": "false"
|
||||
});
|
||||
} else {
|
||||
parent.attr({
|
||||
role: "menuitemcheckbox",
|
||||
"aria-checked": "false"
|
||||
});
|
||||
}
|
||||
|
||||
if( current.children().is( "input[type='radio']" ) ) {
|
||||
parent.attr( "radio-group", current.children( "input[type='radio']" ).attr( "name" ) );
|
||||
}
|
||||
|
||||
if( parent.prev().length && !parent.prev().children( "a" ).length ) {
|
||||
parent.prev()
|
||||
.addClass( "ui-state-disabled" )
|
||||
.html( "<span class='ui-menu-input-group'>" + parent.prev().text() + "</span>" )
|
||||
.bind( "click.menu", false )
|
||||
.after( '<li class="ui-menu-item"><hr /></li>' );
|
||||
inputGroupLabeled = true;
|
||||
}
|
||||
else if( parent.prev().length && !parent.prev().children( "a" ).children().is( "input[type='checkbox'], input[type='radio']" ) ) {
|
||||
parent.before( "<li><hr /></li>" );
|
||||
}
|
||||
|
||||
if( inputGroupLabeled && parent.next().length && !parent.next().children( "a" ).children().is( "input[type='checkbox'], input[type='radio']" ) ) {
|
||||
parent.after( "<li><hr /></li>" );
|
||||
inputGroupLabeled = false;
|
||||
}
|
||||
else if( parent.next().length && !parent.next().children( "a" ).children().is( "input[type='checkbox'], input[type='radio']" ) ) {
|
||||
parent.after( "<li><hr /></li>" );
|
||||
}
|
||||
|
||||
current.children( "input[type='checkbox'], input[type='radio']" ).hide();
|
||||
}
|
||||
});
|
||||
|
||||
items.bind( "keydown.menu", function( event ) {
|
||||
if( event.keyCode === $.ui.keyCode.SPACE ) {
|
||||
if ( that.active.children( "a" ).children().is( "input[type='checkbox'], input[type='radio']" ) ) {
|
||||
that.select( event );
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
select: function( event ) {
|
||||
// save active reference before closeAll triggers blur
|
||||
var ui = {
|
||||
item: this.active
|
||||
};
|
||||
|
||||
if( this.active.children( "a" ).children().is( "input[type='checkbox']" ) ) {
|
||||
if( this.active.attr( "aria-checked" ) === "false" ) {
|
||||
this.active.children( "a" ).prepend( '<span class="ui-icon ui-icon-check"></span>' );
|
||||
this.active.attr( "aria-checked", "true" );
|
||||
this.active.children( "a" ).children( "input[type='checkbox']" ).prop( "checked", "checked" ).trigger('change');
|
||||
} else if( this.active.attr( "aria-checked") === "true" ) {
|
||||
this.active.children( "a" ).children( "span.ui-icon-check" ).remove();
|
||||
this.active.attr( "aria-checked", "false" );
|
||||
this.active.children( "a" ).children( "input[type='checkbox']" ).removeAttr( "checked" ).trigger('change');
|
||||
}
|
||||
}
|
||||
|
||||
if( this.active.children( "a" ).children().is( "input[type='radio']" ) ) {
|
||||
if( this.active.attr( "aria-checked" ) === "false" ) {
|
||||
this.active.children( "a" ).children( "span.ui-icon-radio-off" ).toggleClass( "ui-icon-radio-on ui-icon-radio-off" );
|
||||
this.active.attr( "aria-checked", "true" );
|
||||
this.active.children( "a" ).children( "input[type='radio']" ).prop( "checked", "checked" ).trigger('change');
|
||||
this.active.siblings( "[radio-group=" + $( this.active ).attr( "radio-group" ) + "]" ).each( function() {
|
||||
$( this ).attr( "aria-checked", "false" );
|
||||
$( this ).children( "a" ).children( "span.ui-icon-radio-on" ).toggleClass( "ui-icon-radio-on ui-icon-radio-off" );
|
||||
$( this ).children( "a" ).children( "input[type='radio']" ).removeAttr( "checked" );
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if( !this.active.children( "a" ).children().is( "input[type='checkbox'], input[type='radio']" ) ) this.collapseAll();
|
||||
this._trigger( "select", event, ui );
|
||||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* jQuery UI Popup @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Popup
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.core.js
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.position.js
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
var idIncrement = 0;
|
||||
|
||||
$.widget( "ui.popup", {
|
||||
version: "@VERSION",
|
||||
options: {
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "left bottom"
|
||||
}
|
||||
},
|
||||
_create: function() {
|
||||
if ( !this.options.trigger ) {
|
||||
this.options.trigger = this.element.prev();
|
||||
}
|
||||
|
||||
if ( !this.element.attr( "id" ) ) {
|
||||
this.element.attr( "id", "ui-popup-" + idIncrement++ );
|
||||
this.generatedId = true;
|
||||
}
|
||||
|
||||
if ( !this.element.attr( "role" ) ) {
|
||||
// TODO alternatives to tooltip are dialog and menu, all three aren't generic popups
|
||||
this.element.attr( "role", "dialog" );
|
||||
this.generatedRole = true;
|
||||
}
|
||||
|
||||
this.options.trigger
|
||||
.attr( "aria-haspopup", "true" )
|
||||
.attr( "aria-owns", this.element.attr( "id" ) );
|
||||
|
||||
this.element
|
||||
.addClass( "ui-popup" )
|
||||
this.close();
|
||||
|
||||
this._bind(this.options.trigger, {
|
||||
keydown: function( event ) {
|
||||
// prevent space-to-open to scroll the page, only happens for anchor ui.button
|
||||
if ( this.options.trigger.is( "a:ui-button" ) && event.keyCode == $.ui.keyCode.SPACE ) {
|
||||
event.preventDefault();
|
||||
}
|
||||
// TODO handle SPACE to open popup? only when not handled by ui.button
|
||||
if ( event.keyCode == $.ui.keyCode.SPACE && this.options.trigger.is( "a:not(:ui-button)" ) ) {
|
||||
this.options.trigger.trigger( "click", event );
|
||||
}
|
||||
// translate keydown to click
|
||||
// opens popup and let's tooltip hide itself
|
||||
if ( event.keyCode == $.ui.keyCode.DOWN ) {
|
||||
// prevent scrolling
|
||||
event.preventDefault();
|
||||
this.options.trigger.trigger( "click", event );
|
||||
}
|
||||
},
|
||||
click: function( event ) {
|
||||
event.preventDefault();
|
||||
if (this.isOpen) {
|
||||
// let it propagate to close
|
||||
return;
|
||||
}
|
||||
var that = this;
|
||||
clearTimeout( this.closeTimer );
|
||||
setTimeout(function() {
|
||||
that.open( event );
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
|
||||
if ( !this.element.is( ":ui-menu" ) ) {
|
||||
//default use case, wrap tab order in popup
|
||||
this._bind({ keydown : function( event ) {
|
||||
if ( event.keyCode !== $.ui.keyCode.TAB ) {
|
||||
return;
|
||||
}
|
||||
var tabbables = $( ":tabbable", this.element ),
|
||||
first = tabbables.first(),
|
||||
last = tabbables.last();
|
||||
if ( event.target === last[ 0 ] && !event.shiftKey ) {
|
||||
first.focus( 1 );
|
||||
event.preventDefault();
|
||||
} else if ( event.target === first[ 0 ] && event.shiftKey ) {
|
||||
last.focus( 1 );
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this._bind({
|
||||
focusout: function( event ) {
|
||||
var that = this;
|
||||
// use a timer to allow click to clear it and letting that
|
||||
// handle the closing instead of opening again
|
||||
that.closeTimer = setTimeout( function() {
|
||||
that.close( event );
|
||||
}, 100);
|
||||
},
|
||||
focusin: function( event ) {
|
||||
clearTimeout( this.closeTimer );
|
||||
}
|
||||
});
|
||||
|
||||
this._bind({
|
||||
// TODO only triggered on element if it can receive focus
|
||||
// bind to document instead?
|
||||
// either element itself or a child should be focusable
|
||||
keyup: function( event ) {
|
||||
if ( event.keyCode == $.ui.keyCode.ESCAPE && this.element.is( ":visible" ) ) {
|
||||
this.close( event );
|
||||
// TODO move this to close()? would allow menu.select to call popup.close, and get focus back to trigger
|
||||
this.options.trigger.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this._bind(document, {
|
||||
click: function( event ) {
|
||||
if ( this.isOpen && !$(event.target).closest(".ui-popup").length ) {
|
||||
this.close( event );
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
_destroy: function() {
|
||||
this.element
|
||||
.show()
|
||||
.removeClass( "ui-popup" )
|
||||
.removeAttr( "aria-hidden" )
|
||||
.removeAttr( "aria-expanded" )
|
||||
.unbind( "keypress.ui-popup");
|
||||
|
||||
this.options.trigger
|
||||
.removeAttr( "aria-haspopup" )
|
||||
.removeAttr( "aria-owns" );
|
||||
|
||||
if ( this.generatedId ) {
|
||||
this.element.removeAttr( "id" );
|
||||
}
|
||||
if ( this.generatedRole ) {
|
||||
this.element.removeAttr( "role" );
|
||||
}
|
||||
},
|
||||
|
||||
open: function( event ) {
|
||||
var position = $.extend( {}, {
|
||||
of: this.options.trigger
|
||||
}, this.options.position );
|
||||
|
||||
this.element
|
||||
.show()
|
||||
.attr( "aria-hidden", "false" )
|
||||
.attr( "aria-expanded", "true" )
|
||||
.position( position );
|
||||
|
||||
if (this.element.is( ":ui-menu" )) { //popup is a menu
|
||||
this.element.menu( "focus", event, this.element.children( "li" ).first() );
|
||||
this.element.focus();
|
||||
} else {
|
||||
// set focus to the first tabbable element in the popup container
|
||||
// if there are no tabbable elements, set focus on the popup itself
|
||||
var tabbables = this.element.find( ":tabbable" );
|
||||
this.removeTabIndex = false;
|
||||
if ( !tabbables.length ) {
|
||||
if ( !this.element.is(":tabbable") ) {
|
||||
this.element.attr("tabindex", "0");
|
||||
this.removeTabIndex = true;
|
||||
}
|
||||
tabbables = tabbables.add( this.element[ 0 ] );
|
||||
}
|
||||
tabbables.first().focus( 1 );
|
||||
}
|
||||
|
||||
// take trigger out of tab order to allow shift-tab to skip trigger
|
||||
this.options.trigger.attr( "tabindex", -1 );
|
||||
this.isOpen = true;
|
||||
this._trigger( "open", event );
|
||||
},
|
||||
|
||||
close: function( event ) {
|
||||
this.element
|
||||
.hide()
|
||||
.attr( "aria-hidden", "true" )
|
||||
.attr( "aria-expanded", "false" );
|
||||
|
||||
this.options.trigger.attr( "tabindex" , 0 );
|
||||
if ( this.removeTabIndex ) {
|
||||
this.element.removeAttr( "tabindex" );
|
||||
}
|
||||
this.isOpen = false;
|
||||
this._trigger( "close", event );
|
||||
}
|
||||
});
|
||||
|
||||
}(jQuery));
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* jQuery UI Position @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Position
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
$.ui = $.ui || {};
|
||||
|
||||
var rhorizontal = /left|center|right/,
|
||||
rvertical = /top|center|bottom/,
|
||||
roffset = /[+-]\d+%?/,
|
||||
rposition = /^\w+/,
|
||||
rpercent = /%$/,
|
||||
center = "center",
|
||||
_position = $.fn.position;
|
||||
|
||||
$.position = {
|
||||
scrollbarWidth: function() {
|
||||
var w1, w2,
|
||||
div = $( "<div style='display:block;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
|
||||
innerDiv = div.children()[0];
|
||||
|
||||
$( "body" ).append( div );
|
||||
w1 = innerDiv.offsetWidth;
|
||||
div.css( "overflow", "scroll" );
|
||||
|
||||
w2 = innerDiv.offsetWidth;
|
||||
|
||||
if ( w1 === w2 ) {
|
||||
w2 = div[0].clientWidth;
|
||||
}
|
||||
|
||||
div.remove();
|
||||
|
||||
return w1 - w2;
|
||||
},
|
||||
getScrollInfo: function( within ) {
|
||||
var that = within[0],
|
||||
scrollHeight = within.height() < that.scrollHeight,
|
||||
scrollWidth = within.width() < that.scrollWidth,
|
||||
scrollbarWidth = $.position.scrollbarWidth();
|
||||
|
||||
return {
|
||||
height: scrollHeight ? scrollbarWidth : 0,
|
||||
width : scrollWidth ? scrollbarWidth : 0
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.position = function( options ) {
|
||||
if ( !options || !options.of ) {
|
||||
return _position.apply( this, arguments );
|
||||
}
|
||||
|
||||
// make a copy, we don't want to modify arguments
|
||||
options = $.extend( {}, options );
|
||||
|
||||
var target = $( options.of ),
|
||||
within = $( options.within || window ),
|
||||
targetElem = target[0],
|
||||
collision = ( options.collision || "flip" ).split( " " ),
|
||||
offsets = {},
|
||||
atOffset,
|
||||
targetWidth,
|
||||
targetHeight,
|
||||
basePosition;
|
||||
|
||||
if ( targetElem.nodeType === 9 ) {
|
||||
targetWidth = target.width();
|
||||
targetHeight = target.height();
|
||||
basePosition = { top: 0, left: 0 };
|
||||
} else if ( $.isWindow( targetElem ) ) {
|
||||
targetWidth = target.width();
|
||||
targetHeight = target.height();
|
||||
basePosition = { top: target.scrollTop(), left: target.scrollLeft() };
|
||||
} else if ( targetElem.preventDefault ) {
|
||||
// force left top to allow flipping
|
||||
options.at = "left top";
|
||||
targetWidth = targetHeight = 0;
|
||||
basePosition = { top: options.of.pageY, left: options.of.pageX };
|
||||
} else {
|
||||
targetWidth = target.outerWidth();
|
||||
targetHeight = target.outerHeight();
|
||||
basePosition = target.offset();
|
||||
}
|
||||
|
||||
// force my and at to have valid horizontal and vertical positions
|
||||
// if a value is missing or invalid, it will be converted to center
|
||||
$.each( [ "my", "at" ], function() {
|
||||
var pos = ( options[ this ] || "" ).split( " " ),
|
||||
horizontalOffset,
|
||||
verticalOffset;
|
||||
|
||||
if ( pos.length === 1) {
|
||||
pos = rhorizontal.test( pos[ 0 ] ) ?
|
||||
pos.concat( [ center ] ) :
|
||||
rvertical.test( pos[ 0 ] ) ?
|
||||
[ center ].concat( pos ) :
|
||||
[ center, center ];
|
||||
}
|
||||
pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : center;
|
||||
pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : center;
|
||||
|
||||
// calculate offsets
|
||||
horizontalOffset = roffset.exec( pos[ 0 ] );
|
||||
verticalOffset = roffset.exec( pos[ 1 ] );
|
||||
offsets[ this ] = [
|
||||
horizontalOffset ? horizontalOffset[ 0 ] : 0,
|
||||
verticalOffset ? verticalOffset[ 0 ] : 0
|
||||
];
|
||||
|
||||
// reduce to just the positions without the offsets
|
||||
options[ this ] = [
|
||||
rposition.exec( pos[ 0 ] )[ 0 ],
|
||||
rposition.exec( pos[ 1 ] )[ 0 ]
|
||||
];
|
||||
});
|
||||
|
||||
// normalize collision option
|
||||
if ( collision.length === 1 ) {
|
||||
collision[ 1 ] = collision[ 0 ];
|
||||
}
|
||||
|
||||
if ( options.at[ 0 ] === "right" ) {
|
||||
basePosition.left += targetWidth;
|
||||
} else if ( options.at[ 0 ] === center ) {
|
||||
basePosition.left += targetWidth / 2;
|
||||
}
|
||||
|
||||
if ( options.at[ 1 ] === "bottom" ) {
|
||||
basePosition.top += targetHeight;
|
||||
} else if ( options.at[ 1 ] === center ) {
|
||||
basePosition.top += targetHeight / 2;
|
||||
}
|
||||
|
||||
atOffset = [
|
||||
parseInt( offsets.at[ 0 ], 10 ) *
|
||||
( rpercent.test( offsets.at[ 0 ] ) ? targetWidth / 100 : 1 ),
|
||||
parseInt( offsets.at[ 1 ], 10 ) *
|
||||
( rpercent.test( offsets.at[ 1 ] ) ? targetHeight / 100 : 1 )
|
||||
];
|
||||
basePosition.left += atOffset[ 0 ];
|
||||
basePosition.top += atOffset[ 1 ];
|
||||
|
||||
return this.each(function() {
|
||||
var elem = $( this ),
|
||||
elemWidth = elem.outerWidth(),
|
||||
elemHeight = elem.outerHeight(),
|
||||
marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0,
|
||||
marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0,
|
||||
scrollInfo = $.position.getScrollInfo( within ),
|
||||
collisionWidth = elemWidth + marginLeft +
|
||||
( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ) + scrollInfo.width,
|
||||
collisionHeight = elemHeight + marginTop +
|
||||
( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ) + scrollInfo.height,
|
||||
position = $.extend( {}, basePosition ),
|
||||
myOffset = [
|
||||
parseInt( offsets.my[ 0 ], 10 ) *
|
||||
( rpercent.test( offsets.my[ 0 ] ) ? elem.outerWidth() / 100 : 1 ),
|
||||
parseInt( offsets.my[ 1 ], 10 ) *
|
||||
( rpercent.test( offsets.my[ 1 ] ) ? elem.outerHeight() / 100 : 1 )
|
||||
],
|
||||
collisionPosition;
|
||||
|
||||
if ( options.my[ 0 ] === "right" ) {
|
||||
position.left -= elemWidth;
|
||||
} else if ( options.my[ 0 ] === center ) {
|
||||
position.left -= elemWidth / 2;
|
||||
}
|
||||
|
||||
if ( options.my[ 1 ] === "bottom" ) {
|
||||
position.top -= elemHeight;
|
||||
} else if ( options.my[ 1 ] === center ) {
|
||||
position.top -= elemHeight / 2;
|
||||
}
|
||||
|
||||
position.left += myOffset[ 0 ];
|
||||
position.top += myOffset[ 1 ];
|
||||
|
||||
// prevent fractions (see #5280)
|
||||
position.left = Math.round( position.left );
|
||||
position.top = Math.round( position.top );
|
||||
|
||||
collisionPosition = {
|
||||
left: position.left - marginLeft,
|
||||
top: position.top - marginTop
|
||||
};
|
||||
|
||||
$.each( [ "left", "top" ], function( i, dir ) {
|
||||
if ( $.ui.position[ collision[ i ] ] ) {
|
||||
$.ui.position[ collision[ i ] ][ dir ]( position, {
|
||||
targetWidth: targetWidth,
|
||||
targetHeight: targetHeight,
|
||||
elemWidth: elemWidth,
|
||||
elemHeight: elemHeight,
|
||||
collisionPosition: collisionPosition,
|
||||
collisionWidth: collisionWidth,
|
||||
collisionHeight: collisionHeight,
|
||||
offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
|
||||
my: options.my,
|
||||
at: options.at,
|
||||
within: within,
|
||||
elem : elem
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if ( $.fn.bgiframe ) {
|
||||
elem.bgiframe();
|
||||
}
|
||||
elem.offset( $.extend( position, { using: options.using } ) );
|
||||
});
|
||||
};
|
||||
|
||||
$.ui.position = {
|
||||
fit: {
|
||||
left: function( position, data ) {
|
||||
var within = data.within,
|
||||
win = $( window ),
|
||||
isWindow = $.isWindow( data.within[0] ),
|
||||
withinOffset = isWindow ? win.scrollLeft() : within.offset().left,
|
||||
outerWidth = isWindow ? win.width() : within.outerWidth(),
|
||||
overLeft = withinOffset - data.collisionPosition.left,
|
||||
overRight = data.collisionPosition.left + data.collisionWidth - outerWidth - withinOffset;
|
||||
|
||||
// element is wider than window or too far left -> align with left edge
|
||||
if ( data.collisionWidth > outerWidth || overLeft > 0 ) {
|
||||
position.left += overLeft;
|
||||
// too far right -> align with right edge
|
||||
} else if ( overRight > 0 ) {
|
||||
position.left -= overRight;
|
||||
// adjust based on position and margin
|
||||
} else {
|
||||
position.left = Math.max( position.left - data.collisionPosition.left, position.left );
|
||||
}
|
||||
},
|
||||
top: function( position, data ) {
|
||||
var within = data.within,
|
||||
win = $( window ),
|
||||
isWindow = $.isWindow( data.within[0] ),
|
||||
withinOffset = isWindow ? win.scrollTop() : within.offset().top,
|
||||
outerHeight = isWindow ? win.height() : within.outerHeight(),
|
||||
overTop = withinOffset - data.collisionPosition.top,
|
||||
overBottom = data.collisionPosition.top + data.collisionHeight - outerHeight - withinOffset;
|
||||
|
||||
// element is taller than window or too far up -> align with top edge
|
||||
if ( data.collisionHeight > outerHeight || overTop > 0 ) {
|
||||
position.top += overTop;
|
||||
// too far down -> align with bottom edge
|
||||
} else if ( overBottom > 0 ) {
|
||||
position.top -= overBottom;
|
||||
// adjust based on position and margin
|
||||
} else {
|
||||
position.top = Math.max( position.top - data.collisionPosition.top, position.top );
|
||||
}
|
||||
}
|
||||
},
|
||||
flip: {
|
||||
left: function( position, data ) {
|
||||
if ( data.at[ 0 ] === center ) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.elem
|
||||
.removeClass( "ui-flipped-left ui-flipped-right" );
|
||||
|
||||
var within = data.within,
|
||||
win = $( window ),
|
||||
isWindow = $.isWindow( data.within[0] ),
|
||||
withinOffset = isWindow ? 0 : within.offset().left,
|
||||
outerWidth = isWindow ? within.width() : within.outerWidth(),
|
||||
overLeft = data.collisionPosition.left - withinOffset,
|
||||
overRight = data.collisionPosition.left + data.collisionWidth - outerWidth - withinOffset,
|
||||
left = data.my[ 0 ] === "left",
|
||||
myOffset = data.my[ 0 ] === "left" ?
|
||||
-data.elemWidth :
|
||||
data.my[ 0 ] === "right" ?
|
||||
data.elemWidth :
|
||||
0,
|
||||
atOffset = data.at[ 0 ] === "left" ?
|
||||
data.targetWidth :
|
||||
-data.targetWidth,
|
||||
offset = -2 * data.offset[ 0 ];
|
||||
if ( overLeft < 0 || overRight > 0 ) {
|
||||
|
||||
data.elem
|
||||
.addClass( "ui-flipped-" + ( overLeft < 0 ? "right" : "left" ) );
|
||||
|
||||
position.left += myOffset + atOffset + offset;
|
||||
}
|
||||
},
|
||||
top: function( position, data ) {
|
||||
if ( data.at[ 1 ] === center ) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.elem
|
||||
.removeClass( "ui-flipped-top ui-flipped-bottom" );
|
||||
|
||||
var within = data.within,
|
||||
win = $( window ),
|
||||
isWindow = $.isWindow( data.within[0] ),
|
||||
withinOffset = isWindow ? 0 : within.offset().top,
|
||||
outerHeight = isWindow ? within.height() : within.outerHeight(),
|
||||
overTop = data.collisionPosition.top - withinOffset,
|
||||
overBottom = data.collisionPosition.top + data.collisionHeight - outerHeight - withinOffset,
|
||||
top = data.my[ 1 ] === "top",
|
||||
myOffset = top ?
|
||||
-data.elemHeight :
|
||||
data.my[ 1 ] === "bottom" ?
|
||||
data.elemHeight :
|
||||
0,
|
||||
atOffset = data.at[ 1 ] === "top" ?
|
||||
data.targetHeight :
|
||||
-data.targetHeight,
|
||||
offset = -2 * data.offset[ 1 ];
|
||||
if ( overTop < 0 || overBottom > 0 ) {
|
||||
|
||||
data.elem
|
||||
.addClass( "ui-flipped-" + ( overTop < 0 ? "bottom" : "top" ) );
|
||||
|
||||
position.top += myOffset + atOffset + offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// DEPRECATED
|
||||
if ( $.uiBackCompat !== false ) {
|
||||
// offset option
|
||||
(function( $ ) {
|
||||
var _position = $.fn.position;
|
||||
$.fn.position = function( options ) {
|
||||
if ( !options || !options.offset ) {
|
||||
return _position.call( this, options );
|
||||
}
|
||||
var offset = options.offset.split( " " ),
|
||||
at = options.at.split( " " );
|
||||
if ( offset.length === 1 ) {
|
||||
offset[ 1 ] = offset[ 0 ];
|
||||
}
|
||||
if ( /^\d/.test( offset[ 0 ] ) ) {
|
||||
offset[ 0 ] = "+" + offset[ 0 ];
|
||||
}
|
||||
if ( /^\d/.test( offset[ 1 ] ) ) {
|
||||
offset[ 1 ] = "+" + offset[ 1 ];
|
||||
}
|
||||
if ( at.length === 1 ) {
|
||||
if ( /left|center|right/.test( at[ 0 ] ) ) {
|
||||
at[ 1 ] = "center";
|
||||
} else {
|
||||
at[ 1 ] = at[ 0 ];
|
||||
at[ 0 ] = "center";
|
||||
}
|
||||
}
|
||||
return _position.call( this, $.extend( options, {
|
||||
at: at[ 0 ] + offset[ 0 ] + " " + at[ 1 ] + offset[ 1 ],
|
||||
offset: undefined
|
||||
} ) );
|
||||
}
|
||||
}( jQuery ) );
|
||||
}
|
||||
|
||||
}( jQuery ) );
|
|
@ -0,0 +1,423 @@
|
|||
/*!
|
||||
* jQuery UI Widget @VERSION
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Widget
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
var slice = Array.prototype.slice;
|
||||
|
||||
var _cleanData = $.cleanData;
|
||||
$.cleanData = function( elems ) {
|
||||
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
|
||||
$( elem ).triggerHandler( "remove" );
|
||||
}
|
||||
_cleanData( elems );
|
||||
};
|
||||
|
||||
$.widget = function( name, base, prototype ) {
|
||||
var namespace = name.split( "." )[ 0 ],
|
||||
fullName;
|
||||
name = name.split( "." )[ 1 ];
|
||||
fullName = namespace + "-" + name;
|
||||
|
||||
if ( !prototype ) {
|
||||
prototype = base;
|
||||
base = $.Widget;
|
||||
}
|
||||
|
||||
// create selector for plugin
|
||||
$.expr[ ":" ][ fullName ] = function( elem ) {
|
||||
return !!$.data( elem, name );
|
||||
};
|
||||
|
||||
$[ namespace ] = $[ namespace ] || {};
|
||||
// create the constructor using $.extend() so we can carry over any
|
||||
// static properties stored on the existing constructor (if there is one)
|
||||
$[ namespace ][ name ] = $.extend( function( options, element ) {
|
||||
// allow instantiation without "new" keyword
|
||||
if ( !this._createWidget ) {
|
||||
return new $[ namespace ][ name ]( options, element );
|
||||
}
|
||||
|
||||
// allow instantiation without initializing for simple inheritance
|
||||
// must use "new" keyword (the code above always passes args)
|
||||
if ( arguments.length ) {
|
||||
this._createWidget( options, element );
|
||||
}
|
||||
}, $[ namespace ][ name ], { version: prototype.version } );
|
||||
|
||||
var basePrototype = new base();
|
||||
// we need to make the options hash a property directly on the new instance
|
||||
// otherwise we'll modify the options hash on the prototype that we're
|
||||
// inheriting from
|
||||
basePrototype.options = $.widget.extend( {}, basePrototype.options );
|
||||
$.each( prototype, function( prop, value ) {
|
||||
if ( $.isFunction( value ) ) {
|
||||
prototype[ prop ] = (function() {
|
||||
var _super = function( method ) {
|
||||
return base.prototype[ method ].apply( this, slice.call( arguments, 1 ) );
|
||||
};
|
||||
var _superApply = function( method, args ) {
|
||||
return base.prototype[ method ].apply( this, args );
|
||||
};
|
||||
return function() {
|
||||
var __super = this._super,
|
||||
__superApply = this._superApply,
|
||||
returnValue;
|
||||
|
||||
this._super = _super;
|
||||
this._superApply = _superApply;
|
||||
|
||||
returnValue = value.apply( this, arguments );
|
||||
|
||||
this._super = __super;
|
||||
this._superApply = __superApply;
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
}());
|
||||
}
|
||||
});
|
||||
$[ namespace ][ name ].prototype = $.widget.extend( basePrototype, {
|
||||
namespace: namespace,
|
||||
widgetName: name,
|
||||
widgetEventPrefix: name,
|
||||
widgetBaseClass: fullName
|
||||
}, prototype );
|
||||
|
||||
$.widget.bridge( name, $[ namespace ][ name ] );
|
||||
};
|
||||
|
||||
$.widget.extend = function( target ) {
|
||||
var input = slice.call( arguments, 1 ),
|
||||
inputIndex = 0,
|
||||
inputLength = input.length,
|
||||
key,
|
||||
value;
|
||||
for ( ; inputIndex < inputLength; inputIndex++ ) {
|
||||
for ( key in input[ inputIndex ] ) {
|
||||
value = input[ inputIndex ][ key ];
|
||||
if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
|
||||
target[ key ] = $.isPlainObject( value ) ? $.widget.extend( {}, target[ key ], value ) : value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
$.widget.bridge = function( name, object ) {
|
||||
$.fn[ name ] = function( options ) {
|
||||
var isMethodCall = typeof options === "string",
|
||||
args = slice.call( arguments, 1 ),
|
||||
returnValue = this;
|
||||
|
||||
// allow multiple hashes to be passed on init
|
||||
options = !isMethodCall && args.length ?
|
||||
$.widget.extend.apply( null, [ options ].concat(args) ) :
|
||||
options;
|
||||
|
||||
if ( isMethodCall ) {
|
||||
this.each(function() {
|
||||
var instance = $.data( this, name );
|
||||
if ( !instance ) {
|
||||
return $.error( "cannot call methods on " + name + " prior to initialization; " +
|
||||
"attempted to call method '" + options + "'" );
|
||||
}
|
||||
if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
|
||||
return $.error( "no such method '" + options + "' for " + name + " widget instance" );
|
||||
}
|
||||
var methodValue = instance[ options ].apply( instance, args );
|
||||
if ( methodValue !== instance && methodValue !== undefined ) {
|
||||
returnValue = methodValue && methodValue.jquery ?
|
||||
returnValue.pushStack( methodValue.get() ) :
|
||||
methodValue;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.each(function() {
|
||||
var instance = $.data( this, name );
|
||||
if ( instance ) {
|
||||
instance.option( options || {} )._init();
|
||||
} else {
|
||||
object( options, this );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
};
|
||||
};
|
||||
|
||||
$.Widget = function( options, element ) {
|
||||
// allow instantiation without "new" keyword
|
||||
if ( !this._createWidget ) {
|
||||
return new $[ namespace ][ name ]( options, element );
|
||||
}
|
||||
|
||||
// allow instantiation without initializing for simple inheritance
|
||||
// must use "new" keyword (the code above always passes args)
|
||||
if ( arguments.length ) {
|
||||
this._createWidget( options, element );
|
||||
}
|
||||
};
|
||||
|
||||
$.Widget.prototype = {
|
||||
widgetName: "widget",
|
||||
widgetEventPrefix: "",
|
||||
defaultElement: "<div>",
|
||||
options: {
|
||||
disabled: false,
|
||||
|
||||
// callbacks
|
||||
create: null
|
||||
},
|
||||
_createWidget: function( options, element ) {
|
||||
element = $( element || this.defaultElement || this )[ 0 ];
|
||||
this.element = $( element );
|
||||
this.options = $.widget.extend( {},
|
||||
this.options,
|
||||
this._getCreateOptions(),
|
||||
options );
|
||||
|
||||
this.bindings = $();
|
||||
this.hoverable = $();
|
||||
this.focusable = $();
|
||||
|
||||
if ( element !== this ) {
|
||||
$.data( element, this.widgetName, this );
|
||||
this._bind({ remove: "destroy" });
|
||||
}
|
||||
|
||||
this._create();
|
||||
this._trigger( "create" );
|
||||
this._init();
|
||||
},
|
||||
_getCreateOptions: $.noop,
|
||||
_create: $.noop,
|
||||
_init: $.noop,
|
||||
|
||||
destroy: function() {
|
||||
this._destroy();
|
||||
// we can probably remove the unbind calls in 2.0
|
||||
// all event bindings should go through this._bind()
|
||||
this.element
|
||||
.unbind( "." + this.widgetName )
|
||||
.removeData( this.widgetName );
|
||||
this.widget()
|
||||
.unbind( "." + this.widgetName )
|
||||
.removeAttr( "aria-disabled" )
|
||||
.removeClass(
|
||||
this.widgetBaseClass + "-disabled " +
|
||||
"ui-state-disabled" );
|
||||
|
||||
// clean up events and states
|
||||
this.bindings.unbind( "." + this.widgetName );
|
||||
this.hoverable.removeClass( "ui-state-hover" );
|
||||
this.focusable.removeClass( "ui-state-focus" );
|
||||
},
|
||||
_destroy: $.noop,
|
||||
|
||||
widget: function() {
|
||||
return this.element;
|
||||
},
|
||||
|
||||
option: function( key, value ) {
|
||||
var options = key,
|
||||
parts,
|
||||
curOption,
|
||||
i;
|
||||
|
||||
if ( arguments.length === 0 ) {
|
||||
// don't return a reference to the internal hash
|
||||
return $.widget.extend( {}, this.options );
|
||||
}
|
||||
|
||||
if ( typeof key === "string" ) {
|
||||
// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
|
||||
options = {};
|
||||
parts = key.split( "." );
|
||||
key = parts.shift();
|
||||
if ( parts.length ) {
|
||||
curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
|
||||
for ( i = 0; i < parts.length - 1; i++ ) {
|
||||
curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
|
||||
curOption = curOption[ parts[ i ] ];
|
||||
}
|
||||
key = parts.pop();
|
||||
if ( value === undefined ) {
|
||||
return curOption[ key ] === undefined ? null : curOption[ key ];
|
||||
}
|
||||
curOption[ key ] = value;
|
||||
} else {
|
||||
if ( value === undefined ) {
|
||||
return this.options[ key ] === undefined ? null : this.options[ key ];
|
||||
}
|
||||
options[ key ] = value;
|
||||
}
|
||||
}
|
||||
|
||||
this._setOptions( options );
|
||||
|
||||
return this;
|
||||
},
|
||||
_setOptions: function( options ) {
|
||||
var self = this;
|
||||
$.each( options, function( key, value ) {
|
||||
self._setOption( key, value );
|
||||
});
|
||||
|
||||
return this;
|
||||
},
|
||||
_setOption: function( key, value ) {
|
||||
this.options[ key ] = value;
|
||||
|
||||
if ( key === "disabled" ) {
|
||||
this.widget()
|
||||
.toggleClass( this.widgetBaseClass + "-disabled ui-state-disabled", !!value )
|
||||
.attr( "aria-disabled", value );
|
||||
this.hoverable.removeClass( "ui-state-hover" );
|
||||
this.focusable.removeClass( "ui-state-focus" );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
enable: function() {
|
||||
return this._setOption( "disabled", false );
|
||||
},
|
||||
disable: function() {
|
||||
return this._setOption( "disabled", true );
|
||||
},
|
||||
|
||||
_bind: function( element, handlers ) {
|
||||
// no element argument, shuffle and use this.element
|
||||
if ( !handlers ) {
|
||||
handlers = element;
|
||||
element = this.element;
|
||||
} else {
|
||||
// accept selectors, DOM elements
|
||||
element = $( element );
|
||||
this.bindings = this.bindings.add( element );
|
||||
}
|
||||
var instance = this;
|
||||
$.each( handlers, function( event, handler ) {
|
||||
element.bind( event + "." + instance.widgetName, function() {
|
||||
// allow widgets to customize the disabled handling
|
||||
// - disabled as an array instead of boolean
|
||||
// - disabled class as method for disabling individual parts
|
||||
if ( instance.options.disabled === true ||
|
||||
$( this ).hasClass( "ui-state-disabled" ) ) {
|
||||
return;
|
||||
}
|
||||
return ( typeof handler === "string" ? instance[ handler ] : handler )
|
||||
.apply( instance, arguments );
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_hoverable: function( element ) {
|
||||
this.hoverable = this.hoverable.add( element );
|
||||
this._bind( element, {
|
||||
mouseenter: function( event ) {
|
||||
$( event.currentTarget ).addClass( "ui-state-hover" );
|
||||
},
|
||||
mouseleave: function( event ) {
|
||||
$( event.currentTarget ).removeClass( "ui-state-hover" );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_focusable: function( element ) {
|
||||
this.focusable = this.focusable.add( element );
|
||||
this._bind( element, {
|
||||
focusin: function( event ) {
|
||||
$( event.currentTarget ).addClass( "ui-state-focus" );
|
||||
},
|
||||
focusout: function( event ) {
|
||||
$( event.currentTarget ).removeClass( "ui-state-focus" );
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
_trigger: function( type, event, data ) {
|
||||
var callback = this.options[ type ],
|
||||
args;
|
||||
|
||||
event = $.Event( event );
|
||||
event.type = ( type === this.widgetEventPrefix ?
|
||||
type :
|
||||
this.widgetEventPrefix + type ).toLowerCase();
|
||||
data = data || {};
|
||||
|
||||
// copy original event properties over to the new event
|
||||
// this would happen if we could call $.event.fix instead of $.Event
|
||||
// but we don't have a way to force an event to be fixed multiple times
|
||||
if ( event.originalEvent ) {
|
||||
for ( var i = $.event.props.length, prop; i; ) {
|
||||
prop = $.event.props[ --i ];
|
||||
event[ prop ] = event.originalEvent[ prop ];
|
||||
}
|
||||
}
|
||||
|
||||
this.element.trigger( event, data );
|
||||
|
||||
args = $.isArray( data ) ?
|
||||
[ event ].concat( data ) :
|
||||
[ event, data ];
|
||||
|
||||
return !( $.isFunction( callback ) &&
|
||||
callback.apply( this.element[0], args ) === false ||
|
||||
event.isDefaultPrevented() );
|
||||
}
|
||||
};
|
||||
|
||||
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
|
||||
$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
|
||||
if ( typeof options === "string" ) {
|
||||
options = { effect: options };
|
||||
}
|
||||
var hasOptions,
|
||||
effectName = !options ?
|
||||
method :
|
||||
options === true || typeof options === "number" ?
|
||||
defaultEffect :
|
||||
options.effect || defaultEffect;
|
||||
options = options || {};
|
||||
if ( typeof options === "number" ) {
|
||||
options = { duration: options };
|
||||
}
|
||||
hasOptions = !$.isEmptyObject( options );
|
||||
options.complete = callback;
|
||||
if ( options.delay ) {
|
||||
element.delay( options.delay );
|
||||
}
|
||||
if ( hasOptions && $.effects && ( $.effects.effect[ effectName ] || $.uiBackCompat !== false && $.effects[ effectName ] ) ) {
|
||||
element[ method ]( options );
|
||||
} else if ( effectName !== method && element[ effectName ] ) {
|
||||
element[ effectName ]( options.duration, options.easing, callback );
|
||||
} else {
|
||||
element.queue(function( next ) {
|
||||
$( this )[ method ]();
|
||||
if ( callback ) {
|
||||
callback.call( element[ 0 ] );
|
||||
}
|
||||
next();
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// DEPRECATED
|
||||
if ( $.uiBackCompat !== false ) {
|
||||
$.Widget.prototype._getCreateOptions = function() {
|
||||
return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ];
|
||||
};
|
||||
}
|
||||
|
||||
})( jQuery );
|
|
@ -219,8 +219,12 @@
|
|||
.ui-icon-help { background-position: -48px -144px; }
|
||||
.ui-icon-check { background-position: -64px -144px; }
|
||||
.ui-icon-bullet { background-position: -80px -144px; }
|
||||
.ui-icon-radio-off { background-position: -96px -144px; }
|
||||
.ui-icon-radio-on { background-position: -112px -144px; }
|
||||
/*.ui-icon-radio-off { background-position: -96px -144px; }
|
||||
.ui-icon-radio-on { background-position: -112px -144px; }*/
|
||||
.ui-icon-radio-off { background: none !important; }
|
||||
.ui-icon-radio-on { background: url(/images/jqueryui/ui-icon-radio-on.png) 0 0 no-repeat !important; }
|
||||
.ui-icon-sections { background: url(/images/jqueryui/ui-icon-sections.png) 0 0 no-repeat !important; }
|
||||
.ui-icon-cog { background: url(/images/jqueryui/ui-icon-cog.png) 0 0 no-repeat !important; }
|
||||
.ui-icon-pin-w { background-position: -128px -144px; }
|
||||
.ui-icon-pin-s { background-position: -144px -144px; }
|
||||
.ui-icon-play { background-position: 0 -160px; }
|
||||
|
@ -331,75 +335,37 @@
|
|||
|
||||
/* Menu
|
||||
----------------------------------*/
|
||||
.ui-menu {
|
||||
list-style:none;
|
||||
padding: 2px;
|
||||
margin: 0;
|
||||
display:block;
|
||||
/*.ui-menu {
|
||||
list-style:none;
|
||||
padding: 2px;
|
||||
margin: 0;
|
||||
display:block;
|
||||
}
|
||||
.ui-menu .ui-menu {
|
||||
margin-top: -3px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
.ui-menu .ui-menu-item {
|
||||
margin:0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
margin:0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
}
|
||||
.ui-menu .ui-menu-item a {
|
||||
text-decoration:none;
|
||||
display:block;
|
||||
border: 0px none;
|
||||
padding:.2em .4em;
|
||||
line-height:1.5;
|
||||
-moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px;
|
||||
text-decoration:none;
|
||||
display:block;
|
||||
border: 0px none;
|
||||
padding:.2em .4em;
|
||||
line-height:1.5;
|
||||
-moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px;
|
||||
}
|
||||
.ui-menu .ui-menu-item a.ui-state-hover,
|
||||
.ui-menu .ui-menu-item a.ui-state-active {
|
||||
background: url(/images/jqueryui/button_bg.png) repeat-x left center;
|
||||
background-color: #5f83b9;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0px 1px 1px #234386;
|
||||
}
|
||||
/* Button
|
||||
----------------------------------*/
|
||||
background-color: #5f83b9;
|
||||
color: #FFFFFF;
|
||||
text-shadow: 0px 1px 1px #234386;
|
||||
}*/
|
||||
|
||||
.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; border: 0px none; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; } /* the overflow property removes extra width in IE */
|
||||
.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */
|
||||
button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */
|
||||
.ui-button-icons-only { width: 3em; }
|
||||
button.ui-button-icons-only { width: 3.2em; }
|
||||
.ui-button span { -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; border: 1px solid; }
|
||||
|
||||
.ui-state-default .ui-button-text { background: url(/images/jqueryui/button_bg.png) 0px 0px repeat-x !important; color: #4f4f4f; border-color: #b6b6b6; }
|
||||
.ui-state-hover .ui-button-text { background: url(/images/jqueryui/button_bg.png) 0px 0px repeat-x !important; color: #313131; border-color: #9d9d9d; -moz-box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); -webkit-box-shadow: 0px 0px 8px rgba(212,212,212,1); box-shadow: 0px 0px 8px rgba(212,212,212,1); }
|
||||
.ui-state-active .ui-button-text { background: url(/images/jqueryui/button_bg.png) 0px bottom repeat-x !important; color: #4f4f4f; border-color: #b6b6b6; }
|
||||
|
||||
/*button text element */
|
||||
.ui-button .ui-button-text { display: block; line-height: 1.4; font-weight: bold; font-size: 14px; text-shadow: 0px 1px 0px rgba(255,255,255,0.8); }
|
||||
.ui-button-text-only .ui-button-text { padding: 5px 12px; }
|
||||
.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: 5px; text-indent: -9999999px; }
|
||||
.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: 5px 12px 5px 25px; }
|
||||
.ui-button-text-icons .ui-button-text { padding-right: 1.8em; }
|
||||
/* no icon support for input elements, provide padding by default */
|
||||
input.ui-button { padding: .4em 1em; outline: none; }
|
||||
|
||||
/*button icon element(s) */
|
||||
.ui-button .ui-icon { border: 0px none; }
|
||||
.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; margin-left: 6px; }
|
||||
.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }
|
||||
.ui-button-text-icon .ui-icon-primary, .ui-button-text-icons .ui-icon-primary, .ui-button-icons-only .ui-icon-primary { left: .5em; }
|
||||
.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }
|
||||
|
||||
/*button sets*/
|
||||
.ui-buttonset { margin-right: 7px; }
|
||||
.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }
|
||||
.ui-buttonset, .ui-buttonset span { -moz-border-radius: 0px !important; -webkit-border-radius: 0px !important; border-radius: 0px !important; }
|
||||
.ui-corner-left .ui-button-text { -moz-border-radius-topleft: 4px !important; -webkit-border-top-left-radius: 4px !important; border-top-left-radius: 4px !important; -moz-border-radius-bottomleft: 4px !important; -webkit-border-bottom-left-radius: 4px !important; border-bottom-left-radius: 4px !important; }
|
||||
.ui-corner-right .ui-button-text { -moz-border-radius-topright: 4px !important; -webkit-border-top-right-radius: 4px !important; border-top-right-radius: 4px !important; -moz-border-radius-bottomright: 4px !important; -webkit-border-bottom-right-radius: 4px !important; border-bottom-right-radius: 4px !important; }
|
||||
.ui-buttonset .ui-state-active .ui-button-text { cursor: default; background: url(/images/jqueryui/button_bg.png) 0px -33px repeat-x !important; color: #1c4257; border-color: #7096ab; -moz-box-shadow: none !important; -webkit-box-shadow: none !important; box-shadow: none !important; }
|
||||
|
||||
/* workarounds */
|
||||
button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue