-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(tag note): load type att dynamically and allow for custom input
Type options are pulled from the schema. If the schema doesn't define the options, the default options will be displayed. If the schema allows, the user can insert a custom type, or have no type at all. The interface was changed from radiobox to dropdown to improove ux. A popup window shows up when space is hit while typing a custom type warning about this type of action on xml att. BREAKING CHANGE: options are pulled dinamically. Checks need to be done while building the dialog. #274
- Loading branch information
Showing
3 changed files
with
155 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,143 @@ | ||
var $ = require('jquery'); | ||
var DialogForm = require('dialogForm'); | ||
const $ = require('jquery'); | ||
const DialogForm = require('dialogForm'); | ||
|
||
module.exports = function(writer, parentEl) { | ||
var w = writer; | ||
|
||
const defaultTypeOptions = [ | ||
{ value: 'researchNote', label: 'Research Note', title: 'Internal to projects' }, | ||
{ value: 'scholarNote', label: 'Scholarly Note', title: 'Footnotes/endnotes' }, | ||
{ value: 'annotation', label: 'Annotation', title: 'Informal notes' }, | ||
{ value: 'other', label: 'Other', title: 'Other Notes' }, | ||
]; | ||
|
||
module.exports = (writer, parentEl) => { | ||
|
||
const type = 'note'; | ||
|
||
const atts = writer.schemaManager.getAttributesForTag(type); | ||
const typeAtt = atts.find(({name}) => name === 'type'); | ||
|
||
const typeRequired = (typeAtt.required) ? 'required' : ''; | ||
|
||
var id = w.getUniqueId('noteForm_'); | ||
var $el = $(''+ | ||
'<div class="annotationDialog">'+ | ||
'<div>'+ | ||
'<div id="'+id+'_type" data-transform="buttonset" data-type="radio" data-mapping="type">'+ | ||
'<input type="radio" id="'+id+'_re" name="'+id+'_type" value="researchNote" data-default="true" /><label for="'+id+'_re" title="Internal to projects">Research Note</label>'+ | ||
'<input type="radio" id="'+id+'_scho" name="'+id+'_type" value="scholarNote" /><label for="'+id+'_scho" title="Footnotes/endnotes">Scholarly Note</label>'+ | ||
'<input type="radio" id="'+id+'_ann" name="'+id+'_type" value="annotation" /><label for="'+id+'_ann" title="Informal notes">Annotation</label>'+ | ||
'</div>'+ | ||
'</div>'+ | ||
'<div>'+ | ||
'<label for="'+id+'_noteContent">Note text</label>'+ | ||
'<textarea id="'+id+'_noteContent" data-type="textbox" data-mapping="prop.noteContent" style="width: 98%; height: 100px;"></textarea>'+ | ||
'<p>You will be able to tag and edit the text in the main document.</p>'+ | ||
'</div>'+ | ||
'<div data-transform="accordion">'+ | ||
'<h3>Markup options</h3>'+ | ||
'<div id="'+id+'_attParent" class="attributes" data-type="attributes" data-mapping="attributes">'+ | ||
'</div>'+ | ||
'</div>'+ | ||
'</div>').appendTo(parentEl); | ||
|
||
var dialog = new DialogForm({ | ||
writer: w, | ||
$el: $el, | ||
width: 600, | ||
height: 500, | ||
type: 'note', | ||
title: 'Tag Note' | ||
const id = writer.getUniqueId('noteForm_'); | ||
const html = ` | ||
<div class="annotationDialog"> | ||
<div> | ||
<label for="${id}_type"><b>Type</b></label> | ||
<select id="${id}_type" name="${id}_type" data-type="select" data-mapping="type" ${typeRequired}></select> | ||
<div id="${id}_noteOtherTypeSlot"> | ||
<br/> | ||
<label for="${id}_noteOtherType"><b>Define Type</b></label> | ||
<input type="text" id="${id}_noteOtherType" data-type="textbox" data-mapping="otherType" style="margin-right: 10px;"/> | ||
</div> | ||
</div> | ||
<div> | ||
<label for="${id}_noteContent">Note text</label> | ||
<textarea id="${id}_noteContent" data-type="textbox" data-mapping="prop.noteContent" style="width: 98%; height: 100px;"></textarea> | ||
<p>You will be able to tag and edit the text in the main document.</p> | ||
</div> | ||
<div data-transform="accordion"> | ||
<h3>Markup options</h3> | ||
<div id="${id}_attParent" class="attributes" data-type="attributes" data-mapping="attributes"> | ||
</div> | ||
</div> | ||
`; | ||
|
||
const $el = $(html).appendTo(parentEl); | ||
|
||
const dialog = new DialogForm({ | ||
writer, | ||
$el, | ||
type, | ||
title: 'Tag Note', | ||
width: 600, | ||
height: 500, | ||
}); | ||
|
||
dialog.$el.on('beforeShow', function(e, config, dialog) { | ||
if (dialog.mode === DialogForm.EDIT) { | ||
dialog.$el.find('label[for='+id+'_noteContent]').hide(); | ||
dialog.$el.find('#'+id+'_noteContent').hide(); | ||
} else { | ||
dialog.$el.find('label[for='+id+'_noteContent]').show(); | ||
dialog.$el.find('#'+id+'_noteContent').show(); | ||
const optionsTypeElement = dialog.$el.find(`#${id}_type`); | ||
const noteOtherTypeElement = dialog.$el.find(`#${id}_noteOtherType`); | ||
|
||
dialog.$el.on('buildDynamicFields', (e, config, dialog) => { | ||
//TYPE | ||
const typeChoices = (typeAtt.choices) ? typeAtt.choices : defaultTypeOptions; | ||
const choiceOptions = generateTypeOptions(typeChoices); | ||
optionsTypeElement.html(choiceOptions) | ||
}); | ||
|
||
dialog.$el.on('beforeShow', (e, config, dialog) => { | ||
const show = dialog.mode === DialogForm.EDIT; | ||
dialog.$el.find(`label[for=${id}_noteContent]`).toggle(!show); | ||
dialog.$el.find(`#${id}_noteContent`).toggle(!show); | ||
|
||
//other type | ||
const typeValue = optionsTypeElement.val(); | ||
const showOtherTypeTextFiel = (!typeAtt.choices && typeValue === 'other') ? true : false | ||
toggleOtherTypeTextField(showOtherTypeTextFiel); | ||
|
||
}); | ||
|
||
dialog.$el.on('beforeSave', (e, dialog) => { | ||
//replace other type option for custom defined value | ||
if (!typeAtt.choices && optionsTypeElement.val() === 'other') { | ||
const otherTypeFieldValue= dialog.$el.find(`#${id}_noteOtherType`).val(); | ||
const typeCutstomOption = `<option value="${otherTypeFieldValue}" selected>${otherTypeFieldValue}</option>`; | ||
optionsTypeElement.html(typeCutstomOption); | ||
} | ||
}); | ||
|
||
return { | ||
show: function(config) { | ||
dialog.show(config); | ||
}, | ||
destroy: function() { | ||
dialog.destroy(); | ||
} | ||
//show/hide other type textfield | ||
const toggleOtherTypeTextField = (show) => { | ||
dialog.$el.find(`#${id}_noteOtherTypeSlot`).toggle(show); | ||
if (!show) dialog.$el.find(`#${id}_noteOtherType`).val(''); | ||
}; | ||
}; | ||
|
||
//toggle other type text field | ||
optionsTypeElement.change((e) => { | ||
if (typeAtt.choices) return; | ||
const target = $(e.target); | ||
const otherTypeSelected = (target.val() === 'other') ? true : false; | ||
toggleOtherTypeTextField(otherTypeSelected); | ||
}); | ||
|
||
//transfer value from 'other type 'textfied to 'other' option value on radiobox | ||
dialog.$el.find(`#${id}_noteOtherType`).change(() => { | ||
const val = dialog.$el.find(`#${id}_noteOtherType`).val(); | ||
dialog.$el.find(`#${id}_other`).attr('value', val); | ||
}); | ||
|
||
|
||
noteOtherTypeElement.keyup((e) => { | ||
if (e.code === 'Space') { | ||
writer.dialogManager.confirm({ | ||
title: 'Warning', | ||
msg: 'You hit "space"', | ||
height: 200, | ||
type: 'info', | ||
showConfirmKey: 'confirm-space-in-xml-values', | ||
}) | ||
} | ||
}); | ||
|
||
const generateTypeOptions = (choices) => { | ||
|
||
let html = '<option value="" disabled selected hidden>Please Choose...</option>'; | ||
html += '<option value=""></option>'; | ||
|
||
choices.map((choice) => { | ||
const value = (typeof choice === 'string') ? choice : choice.value; | ||
const label = (typeof choice === 'string') ? choice : choice.label; | ||
|
||
const defaultChoice = (typeAtt.defaultValue === value) ? true : false; | ||
const selected = defaultChoice ? 'selected' : ''; | ||
|
||
html += `<option value="${value}" data-default="${defaultChoice}" ${selected}>${label}</option>`; | ||
}); | ||
|
||
return html; | ||
} | ||
|
||
return { | ||
show: (config) => dialog.show(config), | ||
destroy: () => dialog.destroy(), | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters