diff --git a/app/coffeescripts/calendar/EditAppointmentGroupDetails.coffee b/app/coffeescripts/calendar/EditAppointmentGroupDetails.coffee index 3a8c05866e1..d3593d3c8e8 100644 --- a/app/coffeescripts/calendar/EditAppointmentGroupDetails.coffee +++ b/app/coffeescripts/calendar/EditAppointmentGroupDetails.coffee @@ -20,7 +20,10 @@ define [ $(selector).html editAppointmentGroupTemplate({ title: @apptGroup.title contexts: @contexts - appointment_group: @apptGroup + appointment_group: _.extend( + {use_group_signup: @apptGroup.participant_type is 'Group'} + @apptGroup + ) }) @contextsHash = {} @@ -68,7 +71,7 @@ define [ @form.find(".group-signup").toggle(checked) @form.find(".group-signup-checkbox").change() - $perSlotCheckbox = @form.find('[name="per_slot_option"]') + $perSlotCheckbox = @form.find('#appointment-blocks-per-slot-option-button') $perSlotInput = @form.find('[name="participants_per_appointment"]') slotChangeHandler = (e) => @perSlotChange($perSlotCheckbox, $perSlotInput) $.merge($perSlotCheckbox, $perSlotInput).on 'change', slotChangeHandler @@ -149,7 +152,7 @@ define [ 'appointment_group[location_name]': data.location } - if data.max_appointments_per_participant_option + if data.max_appointments_per_participant_option is '1' if data.max_appointments_per_participant < 1 $('[name="max_appointments_per_participant"]').errorBox( I18n.t('bad_max_appts', 'You must allow at least one appointment per participant')) @@ -167,7 +170,7 @@ define [ $.dateToISO8601UTC($.unfudgeDateForProfileTimezone(range[1])) ]) - if data.per_slot_option + if data.per_slot_option is '1' if data.participants_per_appointment < 1 $('[name="participants_per_appointment"]').errorBox( I18n.t('bad_per_slot', 'You must allow at least one appointment per time slot')) diff --git a/app/coffeescripts/calendar/EditApptCalendarEventDialog.coffee b/app/coffeescripts/calendar/EditApptCalendarEventDialog.coffee index 259696bf5b1..342c1db8e89 100644 --- a/app/coffeescripts/calendar/EditApptCalendarEventDialog.coffee +++ b/app/coffeescripts/calendar/EditApptCalendarEventDialog.coffee @@ -9,7 +9,7 @@ define [ .html(editApptCalendarEventTemplate(@event)) .appendTo('body') - $maxParticipantsOption = @form.find('[name=max_participants_option]') + $maxParticipantsOption = @form.find('[type=checkbox][name=max_participants_option]') @$maxParticipants = @form.find('[name=max_participants]') $maxParticipantsOption.change => @@ -36,7 +36,7 @@ define [ save: => formData = @dialog.getFormData() - limit_participants = formData.max_participants_option == "on" + limit_participants = formData.max_participants_option == "1" max_participants = formData.max_participants if limit_participants and max_participants <= 0 diff --git a/app/coffeescripts/calendar/EditEventView.coffee b/app/coffeescripts/calendar/EditEventView.coffee index 21ddb9c8259..c41568b233b 100644 --- a/app/coffeescripts/calendar/EditEventView.coffee +++ b/app/coffeescripts/calendar/EditEventView.coffee @@ -21,7 +21,7 @@ define [ events: 'submit form': 'submit' - 'change [name="use_section_dates"]': 'toggleUseSectionDates' + 'change #use_section_dates': 'toggleUseSectionDates' 'click .delete_link': 'destroyModel' 'click .switch_event_description_view': 'toggleHtmlView' @@ -75,12 +75,11 @@ define [ submit: (event) -> event?.preventDefault() eventData = unflatten @$el.getFormData() - # force use_section_dates to boolean, so it doesnt cause 'change' if it is '1' - eventData.use_section_dates = !!eventData.use_section_dates + eventData.use_section_dates = eventData.use_section_dates is '1' _.each [eventData].concat(eventData.child_event_data), @setStartEnd delete eventData.child_event_data if eventData.remove_child_events == '1' - if $('[name=use_section_dates]').prop('checked') + if $('#use_section_dates').prop('checked') dialog = new MissingDateDialogView validationFn: -> $fields = $('[name*=start_date]:visible').filter -> $(this).val() is '' diff --git a/app/coffeescripts/conversations/MessageForm.coffee b/app/coffeescripts/conversations/MessageForm.coffee index 83c14fd6a22..9a1417b8895 100644 --- a/app/coffeescripts/conversations/MessageForm.coffee +++ b/app/coffeescripts/conversations/MessageForm.coffee @@ -128,7 +128,7 @@ define [ for key, enabled of options $node = @$form.find(".#{key}_info") $node.showIf(enabled) - $node.find("input[name=#{key}]").prop('checked', false) unless enabled + $node.find("input[type=checkbox][name=#{key}]").prop('checked', false) unless enabled toggle: (state) -> @$form[if state then 'addClass' else 'removeClass']('disabled') diff --git a/app/coffeescripts/handlebars_helpers.coffee b/app/coffeescripts/handlebars_helpers.coffee index b7b598089f1..491431c7887 100644 --- a/app/coffeescripts/handlebars_helpers.coffee +++ b/app/coffeescripts/handlebars_helpers.coffee @@ -245,9 +245,14 @@ define [ # checked="true" # name="likes[tacos]" # class="foo bar" > - checkbox : (propertyName, {hash}) -> + checkbox: (propertyName, {hash}) -> splitPropertyName = propertyName.split(/\./) snakeCase = splitPropertyName.join('_') + + if hash.prefix + splitPropertyName.unshift hash.prefix + delete hash.prefix + bracketNotation = splitPropertyName[0] + _.chain(splitPropertyName) .rest() .map((prop) -> "[#{prop}]") @@ -260,11 +265,19 @@ define [ name: bracketNotation , hash - unless inputProps.checked - value = _.reduce splitPropertyName, ((memo, key) -> memo[key]), this + unless inputProps.checked? + value = _.reduce(splitPropertyName, ((memo, key) -> memo[key] if memo?), this) inputProps.checked = true if value - attributes = _.map inputProps, (val, key) -> "#{htmlEscape key}=\"#{htmlEscape val}\"" + for prop in ['checked', 'disabled'] + if inputProps[prop] + inputProps[prop] = prop + else + delete inputProps[prop] + + attributes = for key, val of inputProps when val? + "#{htmlEscape key}=\"#{htmlEscape val}\"" + new Handlebars.SafeString """ diff --git a/app/coffeescripts/jquery/serializeForm.coffee b/app/coffeescripts/jquery/serializeForm.coffee index 9730097497e..b6022dd97d3 100644 --- a/app/coffeescripts/jquery/serializeForm.coffee +++ b/app/coffeescripts/jquery/serializeForm.coffee @@ -1,52 +1,58 @@ -define [ - 'jquery' - 'underscore' -], ($, _) -> +define ['jquery'], ($) -> + + rselectTextarea = /^(?:select|textarea)/i + rCRLF = /\r?\n/g + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week|file)$/i + # radio / checkbox are not included, since they are handled by the @checked check + + elements = -> + if @elements + $.makeArray @elements + else + elements = $(this).find(':input') + if elements.length + elements + else + this + + isSerializable = -> + @name and not @disabled and ( + @checked or + rselectTextarea.test(@nodeName) or + rinput.test(@type) + ) + + resultFor = (name, value) -> + value = value.replace(rCRLF, "\r\n") if typeof value is 'string' + {name, value} + + getValue = -> + $input = $(this) + value = if @type == 'file' + this if $input.val() + else if $input.hasClass 'datetime_field_enabled' + # datepicker doesn't clear the data date attribute when a date is deleted + if $input.val() is "" + null + else + $input.data('date') or null + else if $input.data('rich_text') + $input.editorBox('get_code', false) + else + $input.val() + + if $.isArray(value) + resultFor(@name, val) for val in value + else + resultFor(@name, value) + + ## + # identical to $.fn.serializeArray, except: + # 1. it works on non-forms (see elements) + # 2. it handles file, date picker and tinymce inputs (see getValue) $.fn.serializeForm = -> - rselectTextarea = /^(?:select|textarea)/i - rcheckboxOrRadio = /checkbox|radio/i - rCRLF = /\r?\n/g - rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week|checkbox|radio|file)$/i - - isInput = (el) -> - el.name && !el.disabled && rselectTextarea.test(el.nodeName) or rinput.test(el.type) - - if this.is('[serialize-radio-value]') - rcheckboxOrRadio = /checkbox/i # return val for radio boxes - rRadio = /radio/i - - _isInput = isInput - isInput = (el) -> # only include the checked radio input - _isInput(el) && (!rRadio.test(el.type) || el.checked) - - getValue = (el) -> - resultFor = (val) -> - name: el.name - el: el - value: if _.isString(val) then val.replace( rCRLF, "\r\n" ) else val - - $input = $(el) - val = if rcheckboxOrRadio.test(el.type) - el.checked - else if el.type == 'file' - el if $input.val() - else if $input.hasClass 'datetime_field_enabled' - # datepicker doesn't clear the data date attribute when a date is deleted - if $input.val() == "" - null - else - $input.data('date') || null - else if $input.data('rich_text') - $input.editorBox('get_code', false) - else - $input.val() - - if _.isArray val - _.map val, resultFor - else - resultFor val - - _.chain(this[0].elements || this.find(':input')) - .filter(isInput) + @map(elements) + .filter(isSerializable) .map(getValue) - .value() + .get() + diff --git a/app/coffeescripts/views/DiscussionTopics/EditView.coffee b/app/coffeescripts/views/DiscussionTopics/EditView.coffee index 5bcf0a717b0..f8f94e593c3 100644 --- a/app/coffeescripts/views/DiscussionTopics/EditView.coffee +++ b/app/coffeescripts/views/DiscussionTopics/EditView.coffee @@ -55,7 +55,8 @@ htmlEscape, DiscussionTopic, Announcement, Assignment, $, preventDefault, Missin isAnnouncement: => @model.constructor is Announcement toJSON: -> - json = _.extend super, @options, + data = super + json = _.extend data, @options, showAssignment: !!@assignmentGroupCollection useForGrading: @model.get('assignment')? isTopic: @isTopic() @@ -64,6 +65,7 @@ htmlEscape, DiscussionTopic, Announcement, Assignment, $, preventDefault, Missin canAttach: @permissions.CAN_ATTACH canModerate: @permissions.CAN_MODERATE isLargeRoster: ENV?.IS_LARGE_ROSTER || false + threaded: data.discussion_type is "threaded" json.assignment = json.assignment.toView() json @@ -130,14 +132,14 @@ htmlEscape, DiscussionTopic, Announcement, Assignment, $, preventDefault, Missin getFormData: -> data = super data.title ||= I18n.t 'default_discussion_title', 'No Title' - data.discussion_type = if data.threaded then 'threaded' else 'side_comment' - data.podcast_has_student_posts = false unless data.podcast_enabled + data.discussion_type = if data.threaded is '1' then 'threaded' else 'side_comment' + data.podcast_has_student_posts = false unless data.podcast_enabled is '1' assign_data = data.assignment delete data.assignment - if assign_data?.set_assignment - data.set_assignment = true + if assign_data?.set_assignment is '1' + data.set_assignment = '1' data.assignment = @updateAssignment(assign_data) data.delayed_post_at = '' data.lock_at = '' @@ -146,12 +148,9 @@ htmlEscape, DiscussionTopic, Announcement, Assignment, $, preventDefault, Missin # DiscussionTopics get a model created for them in their # constructor. Delete it so the API doesn't automatically # create assignments unless the user checked "Use for Grading". - # We're doing this here because syncWithMultipart doesn't call - # the model's toJSON method unfortunately, so assignment params - # would be sent in the response, creating an assignment. # The controller checks for set_assignment on the assignment model, # so we can't make it undefined here for the case of discussion topics. - data.assignment = {set_assignment: false} + data.assignment = {set_assignment: '0'} # these options get passed to Backbone.sync in ValidatedFormView @saveOpts = multipart: !!data.attachment, proxyAttachment: true @@ -203,7 +202,7 @@ htmlEscape, DiscussionTopic, Announcement, Assignment, $, preventDefault, Missin ) validateBeforeSave: (data, errors) => - if @isTopic() && data.set_assignment + if @isTopic() && data.set_assignment is '1' if @assignmentGroupSelector? errors = @assignmentGroupSelector.validateBeforeSave(data, errors) unless ENV?.IS_LARGE_ROSTER diff --git a/app/coffeescripts/views/assignments/EditView.coffee b/app/coffeescripts/views/assignments/EditView.coffee index 6ca07ded700..d4296373adb 100644 --- a/app/coffeescripts/views/assignments/EditView.coffee +++ b/app/coffeescripts/views/assignments/EditView.coffee @@ -35,11 +35,12 @@ AssignmentGroupSelector, GroupCategorySelector, toggleAccessibly) -> SUBMISSION_TYPE = '[name="submission_type"]' ONLINE_SUBMISSION_TYPES = '#assignment_online_submission_types' NAME = '[name="name"]' - ALLOW_FILE_UPLOADS = '[name="online_submission_types[online_upload]"]' - RESTRICT_FILE_UPLOADS = '#restrict_file_extensions_container' + ALLOW_FILE_UPLOADS = '#assignment_online_upload' + RESTRICT_FILE_UPLOADS = '#assignment_restrict_file_extensions' + RESTRICT_FILE_UPLOADS_OPTIONS = '#restrict_file_extensions_container' ALLOWED_EXTENSIONS = '#allowed_extensions_container' ADVANCED_ASSIGNMENT_OPTIONS = '#advanced_assignment_options' - TURNITIN_ENABLED = '[name="turnitin_enabled"]' + TURNITIN_ENABLED = '#assignment_turnitin_enabled' ADVANCED_TURNITIN_SETTINGS = '#advanced_turnitin_settings_link' ASSIGNMENT_TOGGLE_ADVANCED_OPTIONS = '#assignment_toggle_advanced_options' GRADING_TYPE_SELECTOR = '#grading_type_selector' @@ -61,6 +62,7 @@ AssignmentGroupSelector, GroupCategorySelector, toggleAccessibly) -> els["#{NAME}"] = '$name' els["#{ALLOW_FILE_UPLOADS}"] = '$allowFileUploads' els["#{RESTRICT_FILE_UPLOADS}"] = '$restrictFileUploads' + els["#{RESTRICT_FILE_UPLOADS_OPTIONS}"] = '$restrictFileUploadsOptions' els["#{ALLOWED_EXTENSIONS}"] = '$allowedExtensions' els["#{ADVANCED_ASSIGNMENT_OPTIONS}"] = '$advancedAssignmentOptions' els["#{TURNITIN_ENABLED}"] = '$turnitinEnabled' @@ -142,14 +144,14 @@ AssignmentGroupSelector, GroupCategorySelector, toggleAccessibly) -> @$externalToolsNewTab.prop('checked', data['item[new_tab]'] == '1') toggleRestrictFileUploads: => - @$restrictFileUploads.toggleAccessibly @$allowFileUploads.prop('checked') + @$restrictFileUploadsOptions.toggleAccessibly @$allowFileUploads.prop('checked') toggleAdvancedTurnitinSettings: (ev) => ev.preventDefault() @$advancedTurnitinSettings.toggleAccessibly @$turnitinEnabled.prop('checked') handleRestrictFileUploadsChange: => - @$allowedExtensions.toggleAccessibly @$restrictFileUploads.find('input').prop('checked') + @$allowedExtensions.toggleAccessibly @$restrictFileUploads.prop('checked') handleGradingTypeChange: (gradingType) => @$gradedAssignmentFields.toggleAccessibly gradingType != 'not_graded' @@ -169,9 +171,11 @@ AssignmentGroupSelector, GroupCategorySelector, toggleAccessibly) -> this toJSON: => - _.extend @assignment.toView(), + data = @assignment.toView() + _.extend data, kalturaEnabled: ENV?.KALTURA_ENABLED || false isLargeRoster: ENV?.IS_LARGE_ROSTER || false + submissionTypesFrozen: _.include(data.frozenAttributes, 'submission_types') _attachEditorToDescription: => @$description.editorBox() @@ -229,7 +233,7 @@ AssignmentGroupSelector, GroupCategorySelector, toggleAccessibly) -> assignmentData.submission_types = ['not_graded'] else if assignmentData.submission_type == 'online' types = _.select _.keys(assignmentData.online_submission_types), (k) -> - assignmentData.online_submission_types[k] + assignmentData.online_submission_types[k] is '1' assignmentData.submission_types = types else assignmentData.submission_types = [assignmentData.submission_type] @@ -240,7 +244,7 @@ AssignmentGroupSelector, GroupCategorySelector, toggleAccessibly) -> _filterAllowedExtensions: (data) => restrictFileExtensions = data.restrict_file_extensions delete data.restrict_file_extensions - if restrictFileExtensions + if restrictFileExtensions is '1' data.allowed_extensions = _.select data.allowed_extensions.split(","), (ext) -> $.trim(ext.toString()).length > 0 else diff --git a/app/coffeescripts/views/assignments/GroupCategorySelector.coffee b/app/coffeescripts/views/assignments/GroupCategorySelector.coffee index e29fd7f55c1..98f56975007 100644 --- a/app/coffeescripts/views/assignments/GroupCategorySelector.coffee +++ b/app/coffeescripts/views/assignments/GroupCategorySelector.coffee @@ -51,16 +51,20 @@ define [ @showGroupCategoryCreateDialog() toJSON: => + frozenAttributes = @parentModel.frozenAttributes() + groupCategoryId: @parentModel.groupCategoryId() groupCategories: @groupCategories gradeGroupStudentsIndividually: @parentModel.gradeGroupStudentsIndividually() - frozenAttributes: @parentModel.frozenAttributes() + frozenAttributes: frozenAttributes + groupCategoryIdFrozen: _.include(frozenAttributes, 'group_category_id') nested: @nested + prefix: 'assignment' if @nested filterFormData: (data) => hasGroupCategory = data.has_group_category delete data.has_group_category - unless hasGroupCategory + unless hasGroupCategory is '1' data.group_category_id = null data.grade_group_students_individually = false data diff --git a/app/coffeescripts/views/assignments/PeerReviewsSelector.coffee b/app/coffeescripts/views/assignments/PeerReviewsSelector.coffee index a181d198e01..4434e3a1594 100644 --- a/app/coffeescripts/views/assignments/PeerReviewsSelector.coffee +++ b/app/coffeescripts/views/assignments/PeerReviewsSelector.coffee @@ -46,9 +46,13 @@ define [ @$peerReviewsAssignAt.datetime_field() toJSON: => + frozenAttributes = @parentModel.frozenAttributes() + peerReviews: @parentModel.peerReviews() automaticPeerReviews: @parentModel.automaticPeerReviews() peerReviewCount: @parentModel.peerReviewCount() peerReviewsAssignAt: @parentModel.peerReviewsAssignAt() - frozenAttributes: @parentModel.frozenAttributes() + frozenAttributes: frozenAttributes + peerReviewsFrozen: _.include(frozenAttributes, 'peer_reviews') nested: @nested + prefix: 'assignment' if @nested diff --git a/app/coffeescripts/views/assignments/TurnitinSettingsDialog.coffee b/app/coffeescripts/views/assignments/TurnitinSettingsDialog.coffee index 04cf9e286ea..2307e653a18 100644 --- a/app/coffeescripts/views/assignments/TurnitinSettingsDialog.coffee +++ b/app/coffeescripts/views/assignments/TurnitinSettingsDialog.coffee @@ -11,7 +11,7 @@ define [ tagName: 'div' EXCLUDE_SMALL_MATCHES_OPTIONS = '.js-exclude-small-matches-options' - EXCLUDE_SMALL_MATCHES = '[name="exclude_small_matches"]' + EXCLUDE_SMALL_MATCHES = '#exclude_small_matches' EXCLUDE_SMALL_MATCHES_TYPE = '[name="exclude_small_matches_type"]' events: do -> diff --git a/app/coffeescripts/views/content_migrations/subviews/CourseFindSelectView.coffee b/app/coffeescripts/views/content_migrations/subviews/CourseFindSelectView.coffee index dbcb9b82ae2..472b8301eb8 100644 --- a/app/coffeescripts/views/content_migrations/subviews/CourseFindSelectView.coffee +++ b/app/coffeescripts/views/content_migrations/subviews/CourseFindSelectView.coffee @@ -16,7 +16,7 @@ define [ events: 'change #courseSelect' : 'updateSearch' - 'change [name=include_completed_courses]' : 'toggleConcludedCourses' + 'change #include_completed_courses' : 'toggleConcludedCourses' render: -> super diff --git a/app/coffeescripts/views/conversations/MessageFormDialog.coffee b/app/coffeescripts/views/conversations/MessageFormDialog.coffee index 30772775381..b6d437bfac6 100644 --- a/app/coffeescripts/views/conversations/MessageFormDialog.coffee +++ b/app/coffeescripts/views/conversations/MessageFormDialog.coffee @@ -366,5 +366,5 @@ define [ # for key, enabled of options # $node = @$form.find(".#{key}_info") # $node.showIf(enabled) -# $node.find("input[name=#{key}]").prop('checked', false) unless enabled +# $node.find("input[type=checkbox][name=#{key}]").prop('checked', false) unless enabled # diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index 8fd82c547ee..cdd7db62ffd 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -801,7 +801,7 @@ class ConversationsController < ApplicationController :forwarded_message_ids => params[:forwarded_message_ids], :root_account_id => @domain_root_account.id, :media_comment => infer_media_comment, - :generate_user_note => params[:user_note] + :generate_user_note => value_to_boolean(params[:user_note]) ) end diff --git a/app/views/content_migrations/index.html.erb b/app/views/content_migrations/index.html.erb index eac78bc18e2..9caa2fd753d 100644 --- a/app/views/content_migrations/index.html.erb +++ b/app/views/content_migrations/index.html.erb @@ -7,5 +7,5 @@ jammit_css :content_migrations %> -
+
diff --git a/app/views/jst/AssignmentGroupWeightsDialog.handlebars b/app/views/jst/AssignmentGroupWeightsDialog.handlebars index a5995b9638e..a71ae142da3 100644 --- a/app/views/jst/AssignmentGroupWeightsDialog.handlebars +++ b/app/views/jst/AssignmentGroupWeightsDialog.handlebars @@ -1,6 +1,6 @@