FIX: auto-focus input field on Safari was closing the modal
This commit is contained in:
parent
2c06db67a9
commit
48c3fa423a
|
@ -2,8 +2,8 @@ import computed from "ember-addons/ember-computed-decorators";
|
||||||
import { observes } from "ember-addons/ember-computed-decorators";
|
import { observes } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
autoCloseValid: false,
|
|
||||||
limited: false,
|
limited: false,
|
||||||
|
autoCloseValid: false,
|
||||||
|
|
||||||
@computed("limited")
|
@computed("limited")
|
||||||
autoCloseUnits(limited) {
|
autoCloseUnits(limited) {
|
||||||
|
@ -19,15 +19,14 @@ export default Ember.Component.extend({
|
||||||
|
|
||||||
@observes("autoCloseTime", "limited")
|
@observes("autoCloseTime", "limited")
|
||||||
_updateAutoCloseValid() {
|
_updateAutoCloseValid() {
|
||||||
const autoCloseTime = this.get("autoCloseTime");
|
const limited = this.get("limited"),
|
||||||
const limited = this.get("limited");
|
autoCloseTime = this.get("autoCloseTime"),
|
||||||
|
isValid = this._isAutoCloseValid(autoCloseTime, limited);
|
||||||
var isValid = this._isAutoCloseValid(autoCloseTime, limited);
|
|
||||||
this.set("autoCloseValid", isValid);
|
this.set("autoCloseValid", isValid);
|
||||||
},
|
},
|
||||||
|
|
||||||
_isAutoCloseValid(autoCloseTime, limited) {
|
_isAutoCloseValid(autoCloseTime, limited) {
|
||||||
var t = (autoCloseTime || "").toString().trim();
|
const t = (autoCloseTime || "").toString().trim();
|
||||||
if (t.length === 0) {
|
if (t.length === 0) {
|
||||||
// "empty" is always valid
|
// "empty" is always valid
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
|
import { on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Ember.TextField.extend({
|
export default Ember.TextField.extend({
|
||||||
becomeFocused: function() {
|
|
||||||
var input = this.get("element");
|
@on("didInsertElement")
|
||||||
|
becomeFocused() {
|
||||||
|
const input = this.get("element");
|
||||||
input.focus();
|
input.focus();
|
||||||
input.selectionStart = input.selectionEnd = input.value.length;
|
input.selectionStart = input.selectionEnd = input.value.length;
|
||||||
}.on('didInsertElement')
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import computed from 'ember-addons/ember-computed-decorators';
|
import computed from 'ember-addons/ember-computed-decorators';
|
||||||
|
import { on } from 'ember-addons/ember-computed-decorators';
|
||||||
import TextField from 'discourse/components/text-field';
|
import TextField from 'discourse/components/text-field';
|
||||||
|
|
||||||
export default TextField.extend({
|
export default TextField.extend({
|
||||||
@computed('searchService.searchContextEnabled')
|
@computed('searchService.searchContextEnabled')
|
||||||
placeholder: function(searchContextEnabled) {
|
placeholder(searchContextEnabled) {
|
||||||
return searchContextEnabled ? "" : I18n.t('search.title');
|
return searchContextEnabled ? "" : I18n.t('search.title');
|
||||||
},
|
},
|
||||||
|
|
||||||
focusIn: function() {
|
focusIn() {
|
||||||
Em.run.later(() => { this.$().select(); });
|
Em.run.later(() => this.$().select());
|
||||||
},
|
},
|
||||||
|
|
||||||
becomeFocused: function() {
|
@on("didInsertElement")
|
||||||
|
becomeFocused() {
|
||||||
if (this.get('hasAutofocus')) this.$().focus();
|
if (this.get('hasAutofocus')) this.$().focus();
|
||||||
}.on('didInsertElement')
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,19 +1,10 @@
|
||||||
/**
|
import computed from "ember-addons/ember-computed-decorators";
|
||||||
This is a custom text field that allows i18n placeholders
|
|
||||||
|
|
||||||
@class TextField
|
|
||||||
@extends Ember.TextField
|
|
||||||
@namespace Discourse
|
|
||||||
@module Discourse
|
|
||||||
**/
|
|
||||||
export default Ember.TextField.extend({
|
export default Ember.TextField.extend({
|
||||||
attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus', 'maxLength'],
|
attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus', 'maxLength'],
|
||||||
|
|
||||||
placeholder: function() {
|
@computed("placeholderKey")
|
||||||
if (this.get('placeholderKey')) {
|
placeholder(placeholderKey) {
|
||||||
return I18n.t(this.get('placeholderKey'));
|
return placeholderKey ? I18n.t(placeholderKey) : "";
|
||||||
} else {
|
}
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}.property('placeholderKey')
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { observes } from "ember-addons/ember-computed-decorators";
|
||||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||||
|
|
||||||
// Modal related to auto closing of topics
|
// Modal related to auto closing of topics
|
||||||
|
@ -5,31 +6,32 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
auto_close_valid: true,
|
auto_close_valid: true,
|
||||||
auto_close_invalid: Em.computed.not('auto_close_valid'),
|
auto_close_invalid: Em.computed.not('auto_close_valid'),
|
||||||
|
|
||||||
setAutoCloseTime: function() {
|
@observes("model.details.auto_close_at", "model.details.auto_close_hours")
|
||||||
var autoCloseTime = null;
|
setAutoCloseTime() {
|
||||||
|
let autoCloseTime = null;
|
||||||
|
|
||||||
if (this.get("model.details.auto_close_based_on_last_post")) {
|
if (this.get("model.details.auto_close_based_on_last_post")) {
|
||||||
autoCloseTime = this.get("model.details.auto_close_hours");
|
autoCloseTime = this.get("model.details.auto_close_hours");
|
||||||
} else if (this.get("model.details.auto_close_at")) {
|
} else if (this.get("model.details.auto_close_at")) {
|
||||||
var closeTime = new Date(this.get("model.details.auto_close_at"));
|
const closeTime = new Date(this.get("model.details.auto_close_at"));
|
||||||
if (closeTime > new Date()) {
|
if (closeTime > new Date()) {
|
||||||
autoCloseTime = moment(closeTime).format("YYYY-MM-DD HH:mm");
|
autoCloseTime = moment(closeTime).format("YYYY-MM-DD HH:mm");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set("model.auto_close_time", autoCloseTime);
|
this.set("model.auto_close_time", autoCloseTime);
|
||||||
}.observes("model.details.{auto_close_at,auto_close_hours}"),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
saveAutoClose: function() { this.setAutoClose(this.get("model.auto_close_time")); },
|
|
||||||
removeAutoClose: function() { this.setAutoClose(null); }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setAutoClose: function(time) {
|
actions: {
|
||||||
var self = this;
|
saveAutoClose() { this.setAutoClose(this.get("model.auto_close_time")); },
|
||||||
|
removeAutoClose() { this.setAutoClose(null); }
|
||||||
|
},
|
||||||
|
|
||||||
|
setAutoClose(time) {
|
||||||
|
const self = this;
|
||||||
this.send('hideModal');
|
this.send('hideModal');
|
||||||
Discourse.ajax({
|
Discourse.ajax({
|
||||||
url: '/t/' + this.get('model.id') + '/autoclose',
|
url: `/t/${this.get('model.id')}/autoclose`,
|
||||||
type: 'PUT',
|
type: 'PUT',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
data: {
|
data: {
|
||||||
|
@ -37,15 +39,15 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||||
auto_close_based_on_last_post: this.get("model.details.auto_close_based_on_last_post"),
|
auto_close_based_on_last_post: this.get("model.details.auto_close_based_on_last_post"),
|
||||||
timezone_offset: (new Date().getTimezoneOffset())
|
timezone_offset: (new Date().getTimezoneOffset())
|
||||||
}
|
}
|
||||||
}).then(function(result){
|
}).then(result => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
self.send('closeModal');
|
this.send('closeModal');
|
||||||
self.set('model.details.auto_close_at', result.auto_close_at);
|
this.set('model.details.auto_close_at', result.auto_close_at);
|
||||||
self.set('model.details.auto_close_hours', result.auto_close_hours);
|
this.set('model.details.auto_close_hours', result.auto_close_hours);
|
||||||
} else {
|
} else {
|
||||||
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('reopenModal'); } );
|
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('reopenModal'); } );
|
||||||
}
|
}
|
||||||
}, function () {
|
}).catch(() => {
|
||||||
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('reopenModal'); } );
|
bootbox.alert(I18n.t('composer.auto_close.error'), function() { self.send('reopenModal'); } );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ export default Em.Mixin.create({
|
||||||
|
|
||||||
needs: ['modal'],
|
needs: ['modal'],
|
||||||
|
|
||||||
flash: function(message, messageClass) {
|
flash(message, messageClass) {
|
||||||
this.set('flashMessage', Em.Object.create({ message, messageClass }));
|
this.set('flashMessage', Em.Object.create({ message, messageClass }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,7 +56,7 @@ const TopicRoute = Discourse.Route.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
showAutoClose() {
|
showAutoClose() {
|
||||||
showModal('edit-topic-auto-close', { model: this.modelFor('topic'), title: 'topic.auto_close_title' });
|
showModal('edit-topic-auto-close', { model: this.modelFor('topic') });
|
||||||
this.controllerFor('modal').set('modalClass', 'edit-auto-close-modal');
|
this.controllerFor('modal').set('modalClass', 'edit-auto-close-modal');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>
|
<label>
|
||||||
{{input type="checkbox" name="autoCloseBasedOnLastPost" checked=autoCloseBasedOnLastPost}}
|
{{input type="checkbox" checked=autoCloseBasedOnLastPost}}
|
||||||
{{i18n 'composer.auto_close.based_on_last_post'}}
|
{{i18n 'composer.auto_close.based_on_last_post'}}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
limited=model.details.auto_close_based_on_last_post }}
|
limited=model.details.auto_close_based_on_last_post }}
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class='btn btn-primary' type='submit' {{bind-attr disabled="auto_close_invalid"}}>{{i18n 'topic.auto_close_save'}}</button>
|
{{d-button class="btn-primary" disabled=auto_close_invalid label="topic.auto_close_save"}}
|
||||||
<a {{action "closeModal"}}>{{i18n 'cancel'}}</a>
|
<a {{action "closeModal"}}>{{i18n 'cancel'}}</a>
|
||||||
<button class='btn pull-right' {{action "removeAutoClose"}}>{{i18n 'topic.auto_close_remove'}}</button>
|
{{d-button class="pull-right" action="removeAutoClose" label="topic.auto_close_remove"}}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import ModalBodyView from "discourse/views/modal-body";
|
||||||
|
|
||||||
|
export default ModalBodyView.extend({
|
||||||
|
templateName: "modal/edit-topic-auto-close",
|
||||||
|
title: I18n.t("topic.auto_close_title"),
|
||||||
|
focusInput: false
|
||||||
|
});
|
|
@ -1,7 +1,10 @@
|
||||||
|
import { observes, on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Ember.View.extend({
|
export default Ember.View.extend({
|
||||||
focusInput: true,
|
focusInput: true,
|
||||||
|
|
||||||
_setupModal: function() {
|
@on("didInsertElement")
|
||||||
|
_setupModal() {
|
||||||
$('#modal-alert').hide();
|
$('#modal-alert').hide();
|
||||||
$('#discourse-modal').modal('show');
|
$('#discourse-modal').modal('show');
|
||||||
|
|
||||||
|
@ -14,9 +17,10 @@ export default Ember.View.extend({
|
||||||
if (title) {
|
if (title) {
|
||||||
this.set('controller.controllers.modal.title', title);
|
this.set('controller.controllers.modal.title', title);
|
||||||
}
|
}
|
||||||
}.on('didInsertElement'),
|
},
|
||||||
|
|
||||||
flashMessageChanged: function() {
|
@observes("controller.flashMessage")
|
||||||
|
flashMessageChanged() {
|
||||||
const flashMessage = this.get('controller.flashMessage');
|
const flashMessage = this.get('controller.flashMessage');
|
||||||
if (flashMessage) {
|
if (flashMessage) {
|
||||||
const messageClass = flashMessage.get('messageClass') || 'success';
|
const messageClass = flashMessage.get('messageClass') || 'success';
|
||||||
|
@ -25,6 +29,6 @@ export default Ember.View.extend({
|
||||||
.addClass("alert alert-" + messageClass).html(flashMessage.get('message'))
|
.addClass("alert alert-" + messageClass).html(flashMessage.get('message'))
|
||||||
.fadeIn();
|
.fadeIn();
|
||||||
}
|
}
|
||||||
}.observes('controller.flashMessage')
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { on } from "ember-addons/ember-computed-decorators";
|
||||||
|
|
||||||
export default Ember.View.extend({
|
export default Ember.View.extend({
|
||||||
elementId: 'discourse-modal',
|
elementId: 'discourse-modal',
|
||||||
templateName: 'modal/modal',
|
templateName: 'modal/modal',
|
||||||
|
@ -7,17 +9,19 @@ export default Ember.View.extend({
|
||||||
// We handle ESC ourselves
|
// We handle ESC ourselves
|
||||||
'data-keyboard': 'false',
|
'data-keyboard': 'false',
|
||||||
|
|
||||||
_bindOnInsert: function() {
|
@on("didInsertElement")
|
||||||
|
setUp() {
|
||||||
$('html').on('keydown.discourse-modal', e => {
|
$('html').on('keydown.discourse-modal', e => {
|
||||||
if (e.which === 27) {
|
if (e.which === 27) {
|
||||||
Em.run.next(() => $('.modal-header a.close').click());
|
Em.run.next(() => $('.modal-header a.close').click());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}.on('didInsertElement'),
|
},
|
||||||
|
|
||||||
_bindOnDestroy: function() {
|
@on("willDestroyElement")
|
||||||
|
cleanUp() {
|
||||||
$('html').off('keydown.discourse-modal');
|
$('html').off('keydown.discourse-modal');
|
||||||
}.on('willDestroyElement'),
|
},
|
||||||
|
|
||||||
click(e) {
|
click(e) {
|
||||||
const $target = $(e.target);
|
const $target = $(e.target);
|
||||||
|
|
|
@ -185,7 +185,6 @@ body {
|
||||||
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: inset 0 1px 1px rgba(0,0,0, .3);
|
box-shadow: inset 0 1px 1px rgba(0,0,0, .3);
|
||||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
|
||||||
}
|
}
|
||||||
input {
|
input {
|
||||||
&[type="text"], &[type="password"], &[type="datetime"], &[type="datetime-local"], &[type="date"], &[type="month"], &[type="time"], &[type="week"], &[type="number"], &[type="email"], &[type="url"], &[type="search"], &[type="tel"], &[type="color"] {
|
&[type="text"], &[type="password"], &[type="datetime"], &[type="datetime-local"], &[type="date"], &[type="month"], &[type="time"], &[type="week"], &[type="number"], &[type="email"], &[type="url"], &[type="search"], &[type="tel"], &[type="color"] {
|
||||||
|
@ -193,7 +192,6 @@ body {
|
||||||
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
border: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: inset 0 1px 1px rgba(0,0,0, .3);
|
box-shadow: inset 0 1px 1px rgba(0,0,0, .3);
|
||||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
textarea:focus {
|
textarea:focus {
|
||||||
|
|
Loading…
Reference in New Issue