diff --git a/app/assets/javascripts/behaviors/requires_input.js.coffee b/app/assets/javascripts/behaviors/requires_input.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..8318fe435b3911f5ca44d8b4597e8e675a1ab65d
--- /dev/null
+++ b/app/assets/javascripts/behaviors/requires_input.js.coffee
@@ -0,0 +1,39 @@
+# Requires Input behavior
+#
+# When called on a form with input fields with the `required` attribute, the
+# form's submit button will be disabled until all required fields have values.
+#
+#= require extensions/jquery
+#
+# ### Example Markup
+#
+#   <form class="js-requires-input">
+#     <input type="text" required="required">
+#     <input type="submit" value="Submit">
+#   </form>
+#
+$.fn.requiresInput = ->
+  $form   = $(this)
+  $button = $('button[type=submit], input[type=submit]', $form)
+
+  required      = '[required=required]'
+  fieldSelector = "input#{required}, select#{required}, textarea#{required}"
+
+  requireInput = ->
+    # Collect the input values of *all* required fields
+    values = _.map $(fieldSelector, $form), (field) -> field.value
+
+    # Disable the button if any required fields are empty
+    if values.length && _.any(values, _.isEmpty)
+      $button.disable()
+    else
+      $button.enable()
+
+  # Set initial button state
+  requireInput()
+
+  $form.on 'change input', fieldSelector, requireInput
+
+# Triggered on standard document `ready` and on Turbolinks `page:load` events
+$(document).on 'ready page:load', ->
+  $('form.js-requires-input').requiresInput()
diff --git a/app/assets/javascripts/blob/edit_blob.js.coffee b/app/assets/javascripts/blob/edit_blob.js.coffee
index 2e91a06daa8b900eda0d91f1721ce26a30d842be..050888f9c158325982a9513b7b47f612256fc5c2 100644
--- a/app/assets/javascripts/blob/edit_blob.js.coffee
+++ b/app/assets/javascripts/blob/edit_blob.js.coffee
@@ -11,7 +11,6 @@ class @EditBlob
     if ace_mode
       editor.getSession().setMode "ace/mode/" + ace_mode
 
-    disableButtonIfEmptyField "#commit_message", ".js-commit-button"
     $(".js-commit-button").click ->
       $("#file-content").val editor.getValue()
       $(".file-editor form").submit()
diff --git a/app/assets/javascripts/blob/new_blob.js.coffee b/app/assets/javascripts/blob/new_blob.js.coffee
index ab8f98715e86edf03dbc0d142e079958ae50d756..1f36a53f1917ce74ce32cb6aa69ec9e6ebc4f1fa 100644
--- a/app/assets/javascripts/blob/new_blob.js.coffee
+++ b/app/assets/javascripts/blob/new_blob.js.coffee
@@ -11,7 +11,6 @@ class @NewBlob
     if ace_mode
       editor.getSession().setMode "ace/mode/" + ace_mode
 
-    disableButtonIfEmptyField "#commit_message", ".js-commit-button"
     $(".js-commit-button").click ->
       $("#file-content").val editor.getValue()
       $(".file-editor form").submit()
diff --git a/app/assets/javascripts/labels.js.coffee b/app/assets/javascripts/labels.js.coffee
index 1bc8840f9ac887233a9e5cf9ec8e394a5c6fdbf7..d05bacd749470c9134018448d19772cd164adbae 100644
--- a/app/assets/javascripts/labels.js.coffee
+++ b/app/assets/javascripts/labels.js.coffee
@@ -1,7 +1,6 @@
 class @Labels
   constructor: ->
     form = $('.label-form')
-    @setupLabelForm(form)
     @cleanBinding()
     @addBinding()
     @updateColorPreview()
@@ -14,10 +13,6 @@ class @Labels
     $(document).off 'click', '.suggest-colors a'
     $(document).off 'input', 'input#label_color'
 
-  # Initializes the form to disable the save button if no color or title is entered
-  setupLabelForm: (form) ->
-    disableButtonIfAnyEmptyField form, '.form-control', form.find('.js-save-button')
-
   # Updates the the preview color with the hex-color input
   updateColorPreview: =>
     previewColor = $('input#label_color').val()
diff --git a/app/assets/javascripts/project_new.js.coffee b/app/assets/javascripts/project_new.js.coffee
index 836269c44f93b22e3db6ac3b9a8a6756fbad2daa..fecdb9fc2e773436fe8ac193903d8d97ed2cf533 100644
--- a/app/assets/javascripts/project_new.js.coffee
+++ b/app/assets/javascripts/project_new.js.coffee
@@ -3,9 +3,3 @@ class @ProjectNew
     $('.project-edit-container').on 'ajax:before', =>
       $('.project-edit-container').hide()
       $('.save-project-loader').show()
-
-    @initEvents()
-
-
-  initEvents: ->
-    disableButtonIfEmptyField '#project_name', '.project-submit'
diff --git a/app/views/admin/identities/_form.html.haml b/app/views/admin/identities/_form.html.haml
index b405aa6e8e3fbd0d9b5ff571343e80890b303000..0525552ebf86754fe31526a8152ba15c6273383c 100644
--- a/app/views/admin/identities/_form.html.haml
+++ b/app/views/admin/identities/_form.html.haml
@@ -12,7 +12,7 @@
   .form-group
     = f.label :extern_uid, "Identifier", class: 'control-label'
     .col-sm-10
-      = f.text_field :extern_uid, required: true, class: 'form-control', required: true
+      = f.text_field :extern_uid, class: 'form-control', required: true
 
   .form-actions
     = f.submit 'Save changes', class: "btn btn-save"
diff --git a/app/views/projects/blob/_remove.html.haml b/app/views/projects/blob/_remove.html.haml
index b8d8451880adb3c659477c38f4aa8ca67a54ec48..cae5ff010994f4a1b18b73513612369e49c431c2 100644
--- a/app/views/projects/blob/_remove.html.haml
+++ b/app/views/projects/blob/_remove.html.haml
@@ -9,13 +9,10 @@
           %strong= @ref
 
       .modal-body
-        = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal' do
+        = form_tag namespace_project_blob_path(@project.namespace, @project, @id), method: :delete, class: 'form-horizontal js-requires-input' do
           = render 'shared/commit_message_container', params: params,
                    placeholder: 'Removed this file because...'
           .form-group
             .col-sm-offset-2.col-sm-10
               = button_tag 'Remove file', class: 'btn btn-remove btn-remove-file'
               = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
-
-:javascript
-  disableButtonIfEmptyField('#commit_message', '.btn-remove-file')
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index e78181f880128de7c67700df7efd2674c0c75970..a12cd660fc18fb9b5d70ad285340dc6b484672ab 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -11,10 +11,9 @@
         %i.fa.fa-eye
         = editing_preview_title(@blob.name)
 
-  = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: "form-horizontal") do
+  = form_tag(namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put, class: 'form-horizontal js-requires-input') do
     = render 'projects/blob/editor', ref: @ref, path: @path, blob_data: @blob.data
-    = render 'shared/commit_message_container', params: params,
-             placeholder: "Update #{@blob.name}"
+    = render 'shared/commit_message_container', params: params, placeholder: "Update #{@blob.name}"
 
     .form-group.branch
       = label_tag 'branch', class: 'control-label' do
@@ -25,8 +24,7 @@
     = hidden_field_tag 'last_commit', @last_commit
     = hidden_field_tag 'content', '', id: "file-content"
     = hidden_field_tag 'from_merge_request_id', params[:from_merge_request_id]
-    = render 'projects/commit_button', ref: @ref,
-              cancel_path: @after_edit_path
+    = render 'projects/commit_button', ref: @ref, cancel_path: @after_edit_path
 
 :javascript
   blob = new EditBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}", "#{@blob.language.try(:ace_mode)}")
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index f7ddf74b4fc2019e31c61e9949badc42f148127c..7c2a4fece944aee7140a5304af4703fce8730ab6 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -1,7 +1,7 @@
 - page_title "New File", @ref
 %h3.page-title New file
 .file-editor
-  = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal form-new-file') do
+  = form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal form-new-file js-requires-input') do
     = render 'projects/blob/editor', ref: @ref
     = render 'shared/commit_message_container', params: params,
              placeholder: 'Add new file'
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index cac5dc91afd59b28d9e359e871e5d380a2144224..29e82b93883ac3989e1612ef98993be564ef2d63 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -6,7 +6,7 @@
 %h3.page-title
   %i.fa.fa-code-fork
   New branch
-= form_tag namespace_project_branches_path, method: :post, id: "new-branch-form", class: "form-horizontal" do
+= form_tag namespace_project_branches_path, method: :post, id: "new-branch-form", class: "form-horizontal js-requires-input" do
   .form-group
     = label_tag :branch_name, 'Name for new branch', class: 'control-label'
     .col-sm-10
@@ -20,7 +20,6 @@
     = link_to 'Cancel', namespace_project_branches_path(@project.namespace, @project), class: 'btn btn-cancel'
 
 :javascript
-  disableButtonIfAnyEmptyField($("#new-branch-form"), ".form-control", ".btn-create");
   var availableTags = #{@project.repository.ref_names.to_json};
 
   $("#ref").autocomplete({
diff --git a/app/views/projects/compare/_form.html.haml b/app/views/projects/compare/_form.html.haml
index a0e904cfd8bfb0b4242bae5860f015cb3168cb6c..3019893d12c3fa584c7b87805278735dd6d8b87f 100644
--- a/app/views/projects/compare/_form.html.haml
+++ b/app/views/projects/compare/_form.html.haml
@@ -1,16 +1,16 @@
-= form_tag namespace_project_compare_index_path(@project.namespace, @project), method: :post, class: 'form-inline' do
+= form_tag namespace_project_compare_index_path(@project.namespace, @project), method: :post, class: 'form-inline js-requires-input' do
   .clearfix.append-bottom-20
     - if params[:to] && params[:from]
       = link_to 'switch', {from: params[:to], to: params[:from]}, {class: 'commits-compare-switch has_tooltip', title: 'Switch base of comparison'}
     .form-group
       .input-group.inline-input-group
         %span.input-group-addon from
-        = text_field_tag :from, params[:from], class: "form-control"
+        = text_field_tag :from, params[:from], class: "form-control", required: true
     = "..."
     .form-group
       .input-group.inline-input-group
         %span.input-group-addon to
-        = text_field_tag :to, params[:to], class: "form-control"
+        = text_field_tag :to, params[:to], class: "form-control", required: true
     &nbsp;
     = button_tag "Compare", class: "btn btn-create commits-compare-btn"
     - if create_mr_button?
@@ -26,5 +26,3 @@
     source: availableTags,
     minLength: 1
   });
-
-  disableButtonIfEmptyField('#to', '.commits-compare-btn');
diff --git a/app/views/projects/labels/_form.html.haml b/app/views/projects/labels/_form.html.haml
index d791ed3410cf0ba0df76535b66fe3a9677a016a2..534c545329b0a85f01bb45dc942020ab7915bc08 100644
--- a/app/views/projects/labels/_form.html.haml
+++ b/app/views/projects/labels/_form.html.haml
@@ -1,4 +1,4 @@
-= form_for [@project.namespace.becomes(Namespace), @project, @label], html: { class: 'form-horizontal label-form' } do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @label], html: { class: 'form-horizontal label-form js-requires-input' } do |f|
   -if @label.errors.any?
     .row
       .col-sm-offset-2.col-sm-10
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index 8f225a432e4e576d22718ecde7920e1631d1f58c..9cf389dbe3874e79ab6d82184b1beb574c9aa247 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -1,9 +1,8 @@
-= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form js-requires-input' } do |f|
   .merge-request-form-info
     = render 'shared/issuable/form', f: f, issuable: @merge_request
 
 :javascript
-  disableButtonIfEmptyField("#merge_request_title", ".btn-save");
   $('.assign-to-me-link').on('click', function(e){
     $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
     e.preventDefault();
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml
index e611b23bca6022e347b6d328ec0a379a590ecce9..ff9c0cdb283c6953922e01c99a4fbe36c4cc674d 100644
--- a/app/views/projects/merge_requests/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/_new_compare.html.haml
@@ -1,6 +1,6 @@
 %p.lead Compare branches for new Merge Request
 
-= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: new_namespace_project_merge_request_path(@project.namespace, @project), method: :get, html: { class: "merge-request-form form-inline" } do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: new_namespace_project_merge_request_path(@project.namespace, @project), method: :get, html: { class: "merge-request-form form-inline js-requires-input" } do |f|
   .hide.alert.alert-danger.mr-compare-errors
   .merge-request-branches.row
     .col-md-6
@@ -8,9 +8,9 @@
         .panel-heading
           %strong Source branch
         .panel-body
-          = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted? })
+          = f.select(:source_project_id, [[@merge_request.source_project_path,@merge_request.source_project.id]] , {}, { class: 'source_project select2 span3', disabled: @merge_request.persisted?, required: true })
           &nbsp;
-          = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2'})
+          = f.select(:source_branch, @merge_request.source_branches, { include_blank: "Select branch" }, {class: 'source_branch select2 span2', required: true})
         .panel-footer
           .mr_source_commit
 
@@ -20,9 +20,9 @@
           %strong Target branch
         .panel-body
           - projects =  @project.forked_from_project.nil? ? [@project] : [@project, @project.forked_from_project]
-          = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted? })
+          = f.select(:target_project_id, options_from_collection_for_select(projects, 'id', 'path_with_namespace', f.object.target_project_id), {}, { class: 'target_project select2 span3', disabled: @merge_request.persisted?, required: true })
           &nbsp;
-          = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2'})
+          = f.select(:target_branch, @merge_request.target_branches, { include_blank: "Select branch" }, {class: 'target_branch select2 span2', required: true})
         .panel-footer
           .mr_target_commit
 
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index 2f147f9095dbdd639a9c3f54da743c2073798d05..633a54f3620cc132e8e932a40bc8b8d8cc7c3802 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -9,7 +9,7 @@
   %span.pull-right
     = link_to 'Change branches', mr_change_branches_path(@merge_request)
 %hr
-= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form' } do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], html: { class: 'merge-request-form form-horizontal gfm-form js-requires-input' } do |f|
   .merge-request-form-info
     = render 'shared/issuable/form', f: f, issuable: @merge_request
     = f.hidden_field :source_project_id
diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml
index 41aa66dd76b7abfb00c7de1a12040908b94d76b5..f5bacaf280a6c9af3d171e073e0a0c819e58a8a7 100644
--- a/app/views/projects/merge_requests/widget/open/_accept.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml
@@ -1,4 +1,4 @@
-= form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form' } do |f|
+= form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
   = hidden_field_tag :authenticity_token, form_authenticity_token
   .accept-merge-holder.clearfix.js-toggle-container
     .accept-action
@@ -25,8 +25,6 @@
       = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
 
   :coffeescript
-    disableButtonIfEmptyField '#commit_message', '.accept_merge_request'
-
     $('.accept-mr-form').on 'ajax:before', ->
       btn = $('.accept_merge_request')
       btn.disable()
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 5650607f31fcab015ed5007f952c3c7fb09745f9..b93462e5bdf9091ce9fe963225aaacbb4f5f3a6f 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -5,7 +5,7 @@
 
 %hr
 
-= form_for [@project.namespace.becomes(Namespace), @project, @milestone], html: {class: 'form-horizontal milestone-form gfm-form'}  do |f|
+= form_for [@project.namespace.becomes(Namespace), @project, @milestone], html: {class: 'form-horizontal milestone-form gfm-form js-requires-input'}  do |f|
   -if @milestone.errors.any?
     .alert.alert-danger
       %ul
@@ -16,7 +16,7 @@
       .form-group
         = f.label :title, "Title", class: "control-label"
         .col-sm-10
-          = f.text_field :title, maxlength: 255, class: "form-control"
+          = f.text_field :title, maxlength: 255, class: "form-control", required: true
           %p.hint Required
       .form-group.milestone-description
         = f.label :description, "Description", class: "control-label"
@@ -45,7 +45,6 @@
 
 
 :javascript
-  disableButtonIfEmptyField("#milestone_title", ".btn-save");
   $( ".datepicker" ).datepicker({
     dateFormat: "yy-mm-dd",
     onSelect: function(dateText, inst) { $("#milestone_due_date").val(dateText) }
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index c67a7d256a84b04bcd97ef4312c0ff81a5825fae..a88cf16751127dbf1ef7f0154e198cf1902d5025 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -4,8 +4,8 @@
   .controls
     = form_tag namespace_project_network_path(@project.namespace, @project, @id), method: :get, class: 'form-inline network-form' do |f|
       = text_field_tag :extended_sha1, @options[:extended_sha1], placeholder: "Input an extended SHA1 syntax", class: 'search-input form-control input-mx-250 search-sha'
-      = button_tag class: 'btn btn-success btn-search-sha' do
-        %i.fa.fa-search
+      = button_tag class: 'btn btn-success' do
+        = icon('search')
       .inline.prepend-left-20
         .checkbox.light
           = label_tag :filter_ref do
@@ -16,8 +16,6 @@
     = spinner nil, true
 
 :javascript
-  disableButtonIfEmptyField('#extended_sha1', '.btn-search-sha')
-
   network_graph = new Network({
     url: '#{namespace_project_network_path(@project.namespace, @project, @ref, @options.merge(format: :json))}',
     commit_url: '#{namespace_project_commit_path(@project.namespace, @project, 'ae45ca32').gsub("ae45ca32", "%s")}',
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index e56d8615132f256c4ddd806b06d6bea6d7c12e64..5114e63c05f96301b58fc8facf946e1a57d7047a 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -5,13 +5,13 @@
     = render 'projects/errors'
   .project-edit-content
 
-    = form_for @project, html: { class: 'new_project form-horizontal' } do |f|
+    = form_for @project, html: { class: 'new_project form-horizontal js-requires-input' } do |f|
       .form-group.project-name-holder
         = f.label :path, class: 'control-label' do
           %strong Project path
         .col-sm-10
           .input-group
-            = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 1, autofocus: true
+            = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 1, autofocus: true, required: true
             .input-group-addon
               \.git
 
diff --git a/features/project/forked_merge_requests.feature b/features/project/forked_merge_requests.feature
index ad1160e334347baa1d24323ad270a80e77753042..10bd6fec80373d7682281760535ac5d66f8e8581 100644
--- a/features/project/forked_merge_requests.feature
+++ b/features/project/forked_merge_requests.feature
@@ -26,7 +26,6 @@ Feature: Project Forked Merge Requests
     #And I save the merge request
     #Then I should see the edited merge request
 
-  @javascript
   Scenario: I cannot submit an invalid merge request
     Given I visit project "Forked Shop" merge requests page
     And I click link "New Merge Request"
diff --git a/spec/javascripts/behaviors/requires_input_spec.js.coffee b/spec/javascripts/behaviors/requires_input_spec.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..61a176321739d59fa916777fb8e6d767ed9e382b
--- /dev/null
+++ b/spec/javascripts/behaviors/requires_input_spec.js.coffee
@@ -0,0 +1,49 @@
+#= require behaviors/requires_input
+
+describe 'requiresInput', ->
+  fixture.preload('behaviors/requires_input.html')
+
+  beforeEach ->
+    fixture.load('behaviors/requires_input.html')
+
+  it 'disables submit when any field is required', ->
+    $('.js-requires-input').requiresInput()
+
+    expect($('.submit')).toBeDisabled()
+
+  it 'enables submit when no field is required', ->
+    $('*[required=required]').removeAttr('required')
+
+    $('.js-requires-input').requiresInput()
+
+    expect($('.submit')).not.toBeDisabled()
+
+  it 'enables submit when all required fields are pre-filled', ->
+    $('*[required=required]').remove()
+
+    $('.js-requires-input').requiresInput()
+
+    expect($('.submit')).not.toBeDisabled()
+
+  it 'enables submit when all required fields receive input', ->
+    $('.js-requires-input').requiresInput()
+
+    $('#required1').val('input1').change()
+    expect($('.submit')).toBeDisabled()
+
+    $('#optional1').val('input1').change()
+    expect($('.submit')).toBeDisabled()
+
+    $('#required2').val('input2').change()
+    $('#required3').val('input3').change()
+    $('#required4').val('input4').change()
+    $('#required5').val('1').change()
+
+    expect($('.submit')).not.toBeDisabled()
+
+  it 'is called on page:load event', ->
+    spy = spyOn($.fn, 'requiresInput')
+
+    $(document).trigger('page:load')
+
+    expect(spy).toHaveBeenCalled()
diff --git a/spec/javascripts/fixtures/behaviors/requires_input.html.haml b/spec/javascripts/fixtures/behaviors/requires_input.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..c3f905e912ebd81b34ef9d2f8501fce9510e4eaa
--- /dev/null
+++ b/spec/javascripts/fixtures/behaviors/requires_input.html.haml
@@ -0,0 +1,18 @@
+%form.js-requires-input
+  %input{type: 'text', id: 'required1', required: 'required'}
+  %input{type: 'text', id: 'required2', required: 'required'}
+  %input{type: 'text', id: 'required3', required: 'required', value: 'Pre-filled'}
+  %input{type: 'text', id: 'optional1'}
+
+  %textarea{id: 'required4', required: 'required'}
+  %textarea{id: 'optional2'}
+
+  %select{id: 'required5', required: 'required'}
+    %option Zero
+    %option{value: '1'} One
+  %select{id: 'optional3', required: 'required'}
+    %option Zero
+    %option{value: '1'} One
+
+  %button.submit{type: 'submit', value: 'Submit'}
+  %input.submit{type: 'submit', value: 'Submit'}
diff --git a/spec/javascripts/merge_request_spec.js.coffee b/spec/javascripts/merge_request_spec.js.coffee
index a4735af03435f302bd21c136b8b9aed9075498db..22ebc7039d1eaf2cad654606063abdf2a9d8f9d5 100644
--- a/spec/javascripts/merge_request_spec.js.coffee
+++ b/spec/javascripts/merge_request_spec.js.coffee
@@ -1,7 +1,5 @@
 #= require merge_request
 
-window.disableButtonIfEmptyField = -> null
-
 describe 'MergeRequest', ->
   describe 'task lists', ->
     fixture.preload('merge_requests_show.html')