Spiegel von
https://github.com/paviliondev/discourse-custom-wizard.git
synchronisiert 2024-11-22 09:20:29 +01:00
Add wizard field tabindex relative to field order
Dieser Commit ist enthalten in:
Ursprung
0960dda2d3
Commit
b5a6d15c9d
28 geänderte Dateien mit 146 neuen und 23 gelöschten Zeilen
3
assets/javascripts/wizard/components/wizard-date-input.js.es6
Normale Datei
3
assets/javascripts/wizard/components/wizard-date-input.js.es6
Normale Datei
|
@ -0,0 +1,3 @@
|
||||||
|
import DateInput from "discourse/components/date-input";
|
||||||
|
|
||||||
|
export default DateInput.extend();
|
14
assets/javascripts/wizard/components/wizard-date-time-input.js.es6
Normale Datei
14
assets/javascripts/wizard/components/wizard-date-time-input.js.es6
Normale Datei
|
@ -0,0 +1,14 @@
|
||||||
|
import DateTimeInput from "discourse/components/date-time-input";
|
||||||
|
import discourseComputed from 'discourse-common/utils/decorators';
|
||||||
|
|
||||||
|
export default DateTimeInput.extend({
|
||||||
|
@discourseComputed('timeFirst', 'tabindex')
|
||||||
|
timeTabindex(timeFirst, tabindex) {
|
||||||
|
return timeFirst ? tabindex : tabindex + 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed('timeFirst', 'tabindex')
|
||||||
|
dateTabindex(timeFirst, tabindex) {
|
||||||
|
return timeFirst ? tabindex + 1 : tabindex;
|
||||||
|
}
|
||||||
|
});
|
3
assets/javascripts/wizard/components/wizard-time-input.js.es6
Normale Datei
3
assets/javascripts/wizard/components/wizard-time-input.js.es6
Normale Datei
|
@ -0,0 +1,3 @@
|
||||||
|
import TimeInput from "discourse/components/time-input";
|
||||||
|
|
||||||
|
export default TimeInput.extend();
|
|
@ -8,6 +8,7 @@ export default {
|
||||||
const StepComponent = requirejs("wizard/components/wizard-step").default;
|
const StepComponent = requirejs("wizard/components/wizard-step").default;
|
||||||
const ajax = requirejs("wizard/lib/ajax").ajax;
|
const ajax = requirejs("wizard/lib/ajax").ajax;
|
||||||
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
const getUrl = requirejs("discourse-common/lib/get-url").default;
|
||||||
|
const discourseComputed = requirejs("discourse-common/utils/decorators").default;
|
||||||
const cook = requirejs("discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite").cook;
|
const cook = requirejs("discourse/plugins/discourse-custom-wizard/wizard/lib/text-lite").cook;
|
||||||
|
|
||||||
StepModel.reopen({
|
StepModel.reopen({
|
||||||
|
@ -112,6 +113,16 @@ export default {
|
||||||
if (!src) return;
|
if (!src) return;
|
||||||
return getUrl(src);
|
return getUrl(src);
|
||||||
}.property("step.banner"),
|
}.property("step.banner"),
|
||||||
|
|
||||||
|
@discourseComputed('step.fields.[]')
|
||||||
|
primaryButtonIndex(fields) {
|
||||||
|
return fields.length + 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed('step.fields.[]')
|
||||||
|
secondaryButtonIndex(fields) {
|
||||||
|
return fields.length + 2;
|
||||||
|
},
|
||||||
|
|
||||||
handleMessage: function () {
|
handleMessage: function () {
|
||||||
const message = this.get("step.message");
|
const message = this.get("step.message");
|
||||||
|
|
|
@ -56,7 +56,24 @@ export function findCustomWizard(wizardId, params = {}) {
|
||||||
if (!wizard.completed) {
|
if (!wizard.completed) {
|
||||||
wizard.steps = wizard.steps.map(step => {
|
wizard.steps = wizard.steps.map(step => {
|
||||||
const stepObj = Step.create(step);
|
const stepObj = Step.create(step);
|
||||||
|
|
||||||
|
stepObj.fields.sort((a, b) => {
|
||||||
|
return parseFloat(a.number) - parseFloat(b.number);
|
||||||
|
});
|
||||||
|
|
||||||
|
let tabindex = 1;
|
||||||
|
stepObj.fields.forEach((f, i) => {
|
||||||
|
f.tabindex = tabindex;
|
||||||
|
|
||||||
|
if (['date_time'].includes(f.type)) {
|
||||||
|
tabindex = tabindex + 2;
|
||||||
|
} else {
|
||||||
|
tabindex++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
stepObj.fields = stepObj.fields.map(f => WizardField.create(f));
|
stepObj.fields = stepObj.fields.map(f => WizardField.create(f));
|
||||||
|
|
||||||
return stepObj;
|
return stepObj;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{{d-editor
|
{{d-editor
|
||||||
tabindex="4"
|
tabindex=field.tabindex
|
||||||
value=composer.reply
|
value=composer.reply
|
||||||
placeholder=replyPlaceholder
|
placeholder=replyPlaceholder
|
||||||
previewUpdated=(action "previewUpdated")
|
previewUpdated=(action "previewUpdated")
|
||||||
|
|
10
assets/javascripts/wizard/templates/components/wizard-date-input.hbs
Normale Datei
10
assets/javascripts/wizard/templates/components/wizard-date-input.hbs
Normale Datei
|
@ -0,0 +1,10 @@
|
||||||
|
{{input
|
||||||
|
type=inputType
|
||||||
|
class="date-picker"
|
||||||
|
placeholder=placeholder
|
||||||
|
value=(readonly value)
|
||||||
|
input=(action "onChangeDate")
|
||||||
|
tabindex=tabindex
|
||||||
|
}}
|
||||||
|
|
||||||
|
<div class="picker-container"></div>
|
|
@ -0,0 +1,34 @@
|
||||||
|
{{#unless timeFirst}}
|
||||||
|
{{wizard-date-input
|
||||||
|
date=date
|
||||||
|
relativeDate=relativeDate
|
||||||
|
onChange=(action "onChangeDate")
|
||||||
|
tabindex=dateTabindex
|
||||||
|
}}
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
|
{{#if showTime}}
|
||||||
|
{{wizard-time-input
|
||||||
|
date=date
|
||||||
|
relativeDate=relativeDate
|
||||||
|
onChange=(action "onChangeTime")
|
||||||
|
tabindex=timeTabindex
|
||||||
|
}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if timeFirst}}
|
||||||
|
{{wizard-date-input
|
||||||
|
date=date
|
||||||
|
relativeDate=relativeDate
|
||||||
|
onChange=(action "onChangeDate")
|
||||||
|
tabindex=dateTabindex
|
||||||
|
}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if clearable}}
|
||||||
|
{{d-button
|
||||||
|
class="clear-date-time"
|
||||||
|
icon="times"
|
||||||
|
action=(action "onClear")
|
||||||
|
}}
|
||||||
|
{{/if}}
|
|
@ -2,5 +2,6 @@
|
||||||
categories=categories
|
categories=categories
|
||||||
whitelist=field.content
|
whitelist=field.content
|
||||||
maximum=field.limit
|
maximum=field.limit
|
||||||
onChange=(action (mut categories))}}
|
onChange=(action (mut categories))
|
||||||
|
tabindex=field.tabindex}}
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{input type='checkbox' id=field.id checked=field.value}}
|
{{input type='checkbox' id=field.id checked=field.value tabindex=field.tabindex}}
|
|
@ -1,4 +1,5 @@
|
||||||
{{date-time-input
|
{{wizard-date-time-input
|
||||||
date=dateTime
|
date=dateTime
|
||||||
onChange=(action "onChange")
|
onChange=(action "onChange")
|
||||||
|
tabindex=field.tabindex
|
||||||
}}
|
}}
|
|
@ -1,4 +1,5 @@
|
||||||
{{date-input
|
{{wizard-date-input
|
||||||
date=date
|
date=date
|
||||||
onChange=(action "onChange")
|
onChange=(action "onChange")
|
||||||
|
tabindex=field.tabindex
|
||||||
}}
|
}}
|
|
@ -2,6 +2,7 @@
|
||||||
class=fieldClass
|
class=fieldClass
|
||||||
value=field.value
|
value=field.value
|
||||||
content=field.content
|
content=field.content
|
||||||
|
tabindex=field.tabindex
|
||||||
options=(hash
|
options=(hash
|
||||||
none="select_kit.default_header_text"
|
none="select_kit.default_header_text"
|
||||||
)}}
|
)}}
|
|
@ -3,6 +3,7 @@
|
||||||
field=field
|
field=field
|
||||||
whitelist=field.content
|
whitelist=field.content
|
||||||
value=field.value
|
value=field.value
|
||||||
|
tabindex=field.tabindex
|
||||||
onChange=(action (mut field.value))
|
onChange=(action (mut field.value))
|
||||||
options=(hash
|
options=(hash
|
||||||
none='group.select'
|
none='group.select'
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{input type='number' step='0.01' id=field.id value=field.value}}
|
{{input type='number' step='0.01' id=field.id value=field.value tabindex=field.tabindex}}
|
|
@ -1 +1 @@
|
||||||
{{tag-chooser tags=field.value maximum=field.limit}}
|
{{tag-chooser tags=field.value maximum=field.limit tabindex=field.tabindex}}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{{input id=field.id value=field.value class=fieldClass placeholder=field.placeholder tabindex=field.tabindex}}
|
|
@ -0,0 +1 @@
|
||||||
|
{{textarea id=field.id value=field.value class=fieldClass placeholder=field.placeholder tabindex=field.tabindex}}
|
|
@ -1,4 +1,5 @@
|
||||||
{{time-input
|
{{wizard-time-input
|
||||||
date=time
|
date=time
|
||||||
onChange=(action "onChange")
|
onChange=(action "onChange")
|
||||||
|
tabindex=field.tabindex
|
||||||
}}
|
}}
|
|
@ -1,4 +1,4 @@
|
||||||
<label class="wizard-btn wizard-btn-upload-file {{if uploading 'disabled'}}">
|
<label class="wizard-btn wizard-btn-upload-file {{if uploading 'disabled'}}" tabindex="{{field.tabindex}}">
|
||||||
{{#if uploading}}
|
{{#if uploading}}
|
||||||
{{wizard-i18n "wizard.uploading"}}
|
{{wizard-i18n "wizard.uploading"}}
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{input type='text' id=field.id value=field.value}}
|
{{input type='text' id=field.id value=field.value tabindex=field.tabindex}}
|
|
@ -1,3 +1,4 @@
|
||||||
{{custom-user-selector
|
{{custom-user-selector
|
||||||
usernames=field.value
|
usernames=field.value
|
||||||
placeholderKey=field.placeholder}}
|
placeholderKey=field.placeholder
|
||||||
|
tabindex=field.tabindex}}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#wizard-step-form step=step}}
|
{{#wizard-step-form step=step}}
|
||||||
{{#each step.fields as |field|}}
|
{{#each step.fields as |field index|}}
|
||||||
{{wizard-field field=field step=step wizard=wizard}}
|
{{wizard-field field=field step=step wizard=wizard}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
{{/wizard-step-form}}
|
{{/wizard-step-form}}
|
||||||
|
@ -34,22 +34,22 @@
|
||||||
{{loading-spinner size='small'}}
|
{{loading-spinner size='small'}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if showQuitButton}}
|
{{#if showQuitButton}}
|
||||||
<a href {{action "quit"}} class='action-link quit' tabindex="11">{{wizard-i18n "wizard.quit"}}</a>
|
<a href {{action "quit"}} class='action-link quit' tabindex="{{secondaryButtonIndex}}">{{wizard-i18n "wizard.quit"}}</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if showBackButton}}
|
{{#if showBackButton}}
|
||||||
<a href {{action "backStep"}} class='action-link back' tabindex="11">{{wizard-i18n "wizard.back"}}</a>
|
<a href {{action "backStep"}} class='action-link back' tabindex="{{secondaryButtonIndex}}">{{wizard-i18n "wizard.back"}}</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if showNextButton}}
|
{{#if showNextButton}}
|
||||||
<button class='wizard-btn next primary' {{action "nextStep"}} disabled={{saving}} tabindex="10">
|
<button class='wizard-btn next primary' {{action "nextStep"}} disabled={{saving}} tabindex="{{primaryButtonIndex}}">
|
||||||
{{wizard-i18n "wizard.next"}}
|
{{wizard-i18n "wizard.next"}}
|
||||||
{{d-icon "chevron-right"}}
|
{{d-icon "chevron-right"}}
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if showDoneButton}}
|
{{#if showDoneButton}}
|
||||||
<button class='wizard-btn done' {{action "done"}} disabled={{saving}} tabindex="10">
|
<button class='wizard-btn done' {{action "done"}} disabled={{saving}} tabindex="{{primaryButtonIndex}}">
|
||||||
{{wizard-i18n "wizard.done"}}
|
{{wizard-i18n "wizard.done"}}
|
||||||
</button>
|
</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
13
assets/javascripts/wizard/templates/components/wizard-time-input.hbs
Normale Datei
13
assets/javascripts/wizard/templates/components/wizard-time-input.hbs
Normale Datei
|
@ -0,0 +1,13 @@
|
||||||
|
{{combo-box
|
||||||
|
value=time
|
||||||
|
content=timeOptions
|
||||||
|
tabindex=tabindex
|
||||||
|
onChange=(action "onChangeTime")
|
||||||
|
options=(hash
|
||||||
|
translatedNone="--:--"
|
||||||
|
allowAny=true
|
||||||
|
filterable=false
|
||||||
|
autoInsertNoneItem=false
|
||||||
|
translatedFilterPlaceholder="--:--"
|
||||||
|
)
|
||||||
|
}}
|
|
@ -10,7 +10,8 @@ module CustomWizardFieldExtension
|
||||||
:format,
|
:format,
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
:content
|
:content,
|
||||||
|
:number
|
||||||
|
|
||||||
def initialize(attrs)
|
def initialize(attrs)
|
||||||
super
|
super
|
||||||
|
@ -25,6 +26,7 @@ module CustomWizardFieldExtension
|
||||||
@limit = attrs[:limit]
|
@limit = attrs[:limit]
|
||||||
@property = attrs[:property]
|
@property = attrs[:property]
|
||||||
@content = attrs[:content]
|
@content = attrs[:content]
|
||||||
|
@number = attrs[:number]
|
||||||
end
|
end
|
||||||
|
|
||||||
def label
|
def label
|
||||||
|
|
|
@ -69,8 +69,8 @@ class CustomWizard::Builder
|
||||||
end
|
end
|
||||||
|
|
||||||
if step_template['fields'] && step_template['fields'].length
|
if step_template['fields'] && step_template['fields'].length
|
||||||
step_template['fields'].each do |field_template|
|
step_template['fields'].each_with_index do |field_template, index|
|
||||||
append_field(step, step_template, field_template, build_opts)
|
append_field(step, step_template, field_template, build_opts, index)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,11 +146,12 @@ class CustomWizard::Builder
|
||||||
@wizard
|
@wizard
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_field(step, step_template, field_template, build_opts)
|
def append_field(step, step_template, field_template, build_opts, index)
|
||||||
params = {
|
params = {
|
||||||
id: field_template['id'],
|
id: field_template['id'],
|
||||||
type: field_template['type'],
|
type: field_template['type'],
|
||||||
required: field_template['required']
|
required: field_template['required'],
|
||||||
|
number: index + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
params[:label] = field_template['label'] if field_template['label']
|
params[:label] = field_template['label'] if field_template['label']
|
||||||
|
|
|
@ -7,8 +7,9 @@ class CustomWizard::FieldSerializer < ::WizardFieldSerializer
|
||||||
:format,
|
:format,
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
:content
|
:content,
|
||||||
|
:number
|
||||||
|
|
||||||
def label
|
def label
|
||||||
return object.label if object.label.present?
|
return object.label if object.label.present?
|
||||||
I18n.t("#{object.key || i18n_key}.label", default: '')
|
I18n.t("#{object.key || i18n_key}.label", default: '')
|
||||||
|
@ -54,4 +55,8 @@ class CustomWizard::FieldSerializer < ::WizardFieldSerializer
|
||||||
def include_choices?
|
def include_choices?
|
||||||
object.choices.present?
|
object.choices.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def number
|
||||||
|
object.number
|
||||||
|
end
|
||||||
end
|
end
|
|
@ -33,5 +33,6 @@ describe CustomWizard::FieldSerializer do
|
||||||
).as_json
|
).as_json
|
||||||
expect(json_array[0][:format]).to eq("YYYY-MM-DD")
|
expect(json_array[0][:format]).to eq("YYYY-MM-DD")
|
||||||
expect(json_array[5][:file_types]).to eq(".jpg,.png")
|
expect(json_array[5][:file_types]).to eq(".jpg,.png")
|
||||||
|
expect(json_array[4][:number]).to eq("5")
|
||||||
end
|
end
|
||||||
end
|
end
|
Laden …
In neuem Issue referenzieren