diff --git a/app/assets/javascripts/behaviors/bind_in_out.js.es6 b/app/assets/javascripts/behaviors/bind_in_out.js.es6
new file mode 100644
index 0000000..3cb8924
--- /dev/null
+++ b/app/assets/javascripts/behaviors/bind_in_out.js.es6
@@ -0,0 +1,48 @@
+class BindInOut {
+  constructor(bindIn, bindOut) {
+    this.in = bindIn;
+    this.out = bindOut;
+
+    this.eventWrapper = {};
+    this.eventType = /(INPUT|TEXTAREA)/.test(bindIn.tagName) ? 'keyup' : 'change';
+  }
+
+  addEvents() {
+    this.eventWrapper.updateOut = this.updateOut.bind(this);
+
+    this.in.addEventListener(this.eventType, this.eventWrapper.updateOut);
+
+    return this;
+  }
+
+  updateOut() {
+    this.out.textContent = this.in.value;
+
+    return this;
+  }
+
+  removeEvents() {
+    this.in.removeEventListener(this.eventType, this.eventWrapper.updateOut);
+
+    return this;
+  }
+
+  static initAll() {
+    const ins = document.querySelectorAll('*[data-bind-in]');
+
+    return [].map.call(ins, anIn => BindInOut.init(anIn));
+  }
+
+  static init(anIn, anOut) {
+    const out = anOut || document.querySelector(`*[data-bind-out="${anIn.dataset.bindIn}"]`);
+    const bindInOut = new BindInOut(anIn, out);
+
+    return bindInOut.addEvents().updateOut();
+  }
+}
+
+const global = window.gl || (window.gl = {});
+
+global.BindInOut = BindInOut;
+
+module.exports = BindInOut;
diff --git a/app/assets/javascripts/behaviors/toggler_behavior.js b/app/assets/javascripts/behaviors/toggler_behavior.js
index a718190..2d98fc5 100644
--- a/app/assets/javascripts/behaviors/toggler_behavior.js
+++ b/app/assets/javascripts/behaviors/toggler_behavior.js
@@ -22,7 +22,6 @@
     //   %div.js-toggle-content
     //
     $('body').on('click', '.js-toggle-button', function(e) {
-      e.preventDefault();
       toggleContainer($(this).closest('.js-toggle-container'));
     });
 
diff --git a/app/assets/javascripts/dispatcher.js.es6 b/app/assets/javascripts/dispatcher.js.es6
index 45aa605..f7ab9ee 100644
--- a/app/assets/javascripts/dispatcher.js.es6
+++ b/app/assets/javascripts/dispatcher.js.es6
@@ -216,6 +216,7 @@ const ShortcutsBlob = require('./shortcuts_blob');
         case 'admin:groups:edit':
         case 'admin:groups:new':
           new GroupAvatar();
+          gl.BindInOut.initAll();
           break;
         case 'projects:tree:show':
           shortcut_handler = new ShortcutsNavigation();
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 0e421b9..5b1898b 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -81,7 +81,6 @@ class GroupsController < Groups::ApplicationController
   end
 
   def update
-    byebug
     if Groups::UpdateService.new(@group, current_user, group_params).execute
       redirect_to edit_group_path(@group), notice: "Group '#{@group.name}' was successfully updated."
     else
@@ -143,7 +142,7 @@ class GroupsController < Groups::ApplicationController
       :request_access_enabled,
       :share_with_group_lock,
       :visibility_level,
-      :parent_id
+      :parent_id,
       :create_chat_team,
       :chat_team_name
     ]
diff --git a/app/views/groups/_create_chat_team.html.haml b/app/views/groups/_create_chat_team.html.haml
index 1e702c4..8b908e2 100644
--- a/app/views/groups/_create_chat_team.html.haml
+++ b/app/views/groups/_create_chat_team.html.haml
@@ -4,15 +4,13 @@
       = custom_icon('icon_mattermost')
     Mattermost
   .col-sm-10
-    .checkbox
+    .checkbox.js-toggle-container
       = f.label :create_chat_team do
-        = f.check_box(:create_chat_team, { checked: @group.chat_team }, 'true', 'false')
-        Link the group to a new Mattermost team
-
-.form-group
-  = f.label :chat_team, class: 'control-label' do
-    Chat Team name
-  .col-sm-10
-    = f.text_field :chat_team, placeholder: @group.chat_team, class: 'form-control mattermost-team-name'
-    %small
-      Leave blank to match your group name
+        .js-toggle-button= f.check_box(:create_chat_team, { checked: true }, 'true', 'false')
+        Create a Mattermost team for this group
+      %br
+      %small.light.js-toggle-content
+        Team URL:
+        = Settings.mattermost.host
+        %span> /
+        %span{ "data-bind-out" => "create_chat_team"}
diff --git a/app/views/shared/_group_form.html.haml b/app/views/shared/_group_form.html.haml
index efb207b..5b8c9a6 100644
--- a/app/views/shared/_group_form.html.haml
+++ b/app/views/shared/_group_form.html.haml
@@ -18,7 +18,8 @@
       = f.text_field :path, placeholder: 'open-source', class: 'form-control',
         autofocus: local_assigns[:autofocus] || false, required: true,
         pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_SIMPLE,
-        title: 'Please choose a group name with no special characters.'
+        title: 'Please choose a group name with no special characters.',
+        "data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
       - if parent
         = f.hidden_field :parent_id, value: parent.id
 
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 37b7c20..b4bd192 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -43,6 +43,43 @@ feature 'Group', feature: true do
         expect(page).to have_namespace_error_message
       end
     end
+
+    describe 'Mattermost team creation' do
+      before do
+        Settings.mattermost['enabled'] = mattermost_enabled
+        visit new_group_path
+      end
+
+      context 'Mattermost enabled' do
+        let(:mattermost_enabled) { true }
+
+        it 'displays a team creation checkbox' do
+          expect(page).to have_selector('#group_create_chat_team')
+        end
+
+        it 'checks the checkbox by default' do
+          expect(find('#group_create_chat_team')['checked']).to eq(true)
+        end
+
+        it 'updates the team URL on graph path update', :js do
+          out_span = find('span[data-bind-out="create_chat_team"]')
+
+          expect(out_span.text).to be_empty
+
+          fill_in('group_path', with: 'test-group')
+
+          expect(out_span.text).to eq('test-group')
+        end
+      end
+
+      context 'Mattermost disabled' do
+        let(:mattermost_enabled) { false }
+
+        it 'doesnt show a team creation checkbox if Mattermost not enabled' do
+          expect(page).not_to have_selector('#group_create_chat_team')
+        end
+      end
+    end
   end
 
   describe 'create a nested group' do
diff --git a/spec/javascripts/behaviors/bind_in_out_spec.js.es6 b/spec/javascripts/behaviors/bind_in_out_spec.js.es6
new file mode 100644
index 0000000..69d2460
--- /dev/null
+++ b/spec/javascripts/behaviors/bind_in_out_spec.js.es6
@@ -0,0 +1,189 @@
+const BindInOut = require('~/behaviors/bind_in_out');
+const ClassSpecHelper = require('../helpers/class_spec_helper');
+
+describe('BindInOut', function () {
+  describe('.constructor', function () {
+    beforeEach(function () {
+      this.in = {};
+      this.out = {};
+
+      this.bindInOut = new BindInOut(this.in, this.out);
+    });
+
+    it('should set .in', function () {
+      expect(this.bindInOut.in).toBe(this.in);
+    });
+
+    it('should set .out', function () {
+      expect(this.bindInOut.out).toBe(this.out);
+    });
+
+    it('should set .eventWrapper', function () {
+      expect(this.bindInOut.eventWrapper).toEqual({});
+    });
+
+    describe('if .in is an input', function () {
+      beforeEach(function () {
+        this.bindInOut = new BindInOut({ tagName: 'INPUT' });
+      });
+
+      it('should set .eventType to keyup ', function () {
+        expect(this.bindInOut.eventType).toEqual('keyup');
+      });
+    });
+
+    describe('if .in is a textarea', function () {
+      beforeEach(function () {
+        this.bindInOut = new BindInOut({ tagName: 'TEXTAREA' });
+      });
+
+      it('should set .eventType to keyup ', function () {
+        expect(this.bindInOut.eventType).toEqual('keyup');
+      });
+    });
+
+    describe('if .in is not an input or textarea', function () {
+      beforeEach(function () {
+        this.bindInOut = new BindInOut({ tagName: 'SELECT' });
+      });
+
+      it('should set .eventType to change ', function () {
+        expect(this.bindInOut.eventType).toEqual('change');
+      });
+    });
+  });
+
+  describe('.addEvents', function () {
+    beforeEach(function () {
+      this.in = jasmine.createSpyObj('in', ['addEventListener']);
+
+      this.bindInOut = new BindInOut(this.in);
+
+      this.addEvents = this.bindInOut.addEvents();
+    });
+
+    it('should set .eventWrapper.updateOut', function () {
+      expect(this.bindInOut.eventWrapper.updateOut).toEqual(jasmine.any(Function));
+    });
+
+    it('should call .addEventListener', function () {
+      expect(this.in.addEventListener)
+        .toHaveBeenCalledWith(
+          this.bindInOut.eventType,
+          this.bindInOut.eventWrapper.updateOut,
+        );
+    });
+
+    it('should return the instance', function () {
+      expect(this.addEvents).toBe(this.bindInOut);
+    });
+  });
+
+  describe('.updateOut', function () {
+    beforeEach(function () {
+      this.in = { value: 'the-value' };
+      this.out = { textContent: 'not-the-value' };
+
+      this.bindInOut = new BindInOut(this.in, this.out);
+
+      this.updateOut = this.bindInOut.updateOut();
+    });
+
+    it('should set .out.textContent to .in.value', function () {
+      expect(this.out.textContent).toBe(this.in.value);
+    });
+
+    it('should return the instance', function () {
+      expect(this.updateOut).toBe(this.bindInOut);
+    });
+  });
+
+  describe('.removeEvents', function () {
+    beforeEach(function () {
+      this.in = jasmine.createSpyObj('in', ['removeEventListener']);
+      this.updateOut = () => {};
+
+      this.bindInOut = new BindInOut(this.in);
+      this.bindInOut.eventWrapper.updateOut = this.updateOut;
+
+      this.removeEvents = this.bindInOut.removeEvents();
+    });
+
+    it('should call .removeEventListener', function () {
+      expect(this.in.removeEventListener)
+        .toHaveBeenCalledWith(
+          this.bindInOut.eventType,
+          this.updateOut,
+        );
+    });
+
+    it('should return the instance', function () {
+      expect(this.removeEvents).toBe(this.bindInOut);
+    });
+  });
+
+  describe('.initAll', function () {
+    beforeEach(function () {
+      this.ins = [0, 1, 2];
+      this.instances = [];
+
+      spyOn(document, 'querySelectorAll').and.returnValue(this.ins);
+      spyOn(Array.prototype, 'map').and.callThrough();
+      spyOn(BindInOut, 'init');
+
+      this.initAll = BindInOut.initAll();
+    });
+
+    ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'initAll');
+
+    it('should call .querySelectorAll', function () {
+      expect(document.querySelectorAll).toHaveBeenCalledWith('*[data-bind-in]');
+    });
+
+    it('should call .map', function () {
+      expect(Array.prototype.map).toHaveBeenCalledWith(jasmine.any(Function));
+    });
+
+    it('should call .init for each element', function () {
+      expect(BindInOut.init.calls.count()).toEqual(3);
+    });
+
+    it('should return an array of instances', function () {
+      expect(this.initAll).toEqual(jasmine.any(Array));
+    });
+  });
+
+  describe('.init', function () {
+    beforeEach(function () {
+      spyOn(BindInOut.prototype, 'addEvents').and.callFake(function () { return this; });
+      spyOn(BindInOut.prototype, 'updateOut').and.callFake(function () { return this; });
+
+      this.init = BindInOut.init({}, {});
+    });
+
+    ClassSpecHelper.itShouldBeAStaticMethod(BindInOut, 'init');
+
+    it('should call .addEvents', function () {
+      expect(BindInOut.prototype.addEvents).toHaveBeenCalled();
+    });
+
+    it('should call .updateOut', function () {
+      expect(BindInOut.prototype.updateOut).toHaveBeenCalled();
+    });
+
+    describe('if no anOut is provided', function () {
+      beforeEach(function () {
+        this.anIn = { dataset: { bindIn: 'the-data-bind-in' } };
+
+        spyOn(document, 'querySelector');
+
+        BindInOut.init(this.anIn);
+      });
+
+      it('should call .querySelector', function () {
+        expect(document.querySelector)
+          .toHaveBeenCalledWith(`*[data-bind-out="${this.anIn.dataset.bindIn}"]`);
+      });
+    });
+  });
+});
diff --git a/spec/javascripts/helpers/class_spec_helper.js.es6 b/spec/javascripts/helpers/class_spec_helper.js.es6
index d3c37d3..61db27a 100644
--- a/spec/javascripts/helpers/class_spec_helper.js.es6
+++ b/spec/javascripts/helpers/class_spec_helper.js.es6
@@ -7,3 +7,5 @@ class ClassSpecHelper {
 }
 
 window.ClassSpecHelper = ClassSpecHelper;
+
+module.exports = ClassSpecHelper;