1
1
mirror of https://github.com/aelve/guide.git synced 2024-12-23 12:52:31 +03:00
guide/back/templates/trait.widget
2018-12-09 23:02:03 +01:00

175 lines
5.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Description
============================================================
A list item containing a trait (pro/con), together with some JS that lets the user edit the trait.
Required context:
* item.uid
* trait.uid
trait.content.html
trait.content.text
HTML
============================================================
<li id="trait-{{trait.uid}}">
<div class="section normal editable shown noscript-shown">
{{{trait.content.html}}}
</div>
<div class="section editable">
<div class="trait-controls">
{{> small-control
src = "/arrow-thick-top.svg"
title = "move trait up"
action = [| moveTrait("up",{{{%js item.uid}}},{{{%js trait.uid}}}); |] }}
{{> small-control
src = "/arrow-thick-bottom.svg"
title = "move trait down"
action = [| moveTrait("down",{{{%js item.uid}}},{{{%js trait.uid}}}); |] }}
{{> space px=16}}
{{> small-control
src = "/pencil.svg"
title = "edit trait"
action = [| editTrait({{{%js item.uid}}}, {{{%js trait.uid}}},
{{{%js trait.content.text}}}); |] }}
{{> space px=16}}
{{> small-control
src = "/x.svg"
title = "delete trait"
action = [| deleteTrait({{{%js item.uid}}},{{{%js trait.uid}}}); |] }}
</div>
</div>
<div class="section editing">
{{! a placeholder for the editing interface created by 'editTrait' }}
</div>
</li>
CSS
============================================================
.trait-controls {
margin-left: -8px;
}
/* increase the clickable area */
.trait-controls a {
display: inline-block;
padding: 7px;
}
JS
============================================================
function moveTrait(dir, itemUid, traitUid) {
var url = "/haskell/move/item/" + itemUid + "/trait/" + traitUid;
traitNode = '#trait-' + traitUid;
$.post(url, {direction: dir})
.done(function () {
if (dir == "up") moveNodeUp(traitNode); else moveNodeDown(traitNode);
fadeIn(traitNode);
});
}
function deleteTrait(itemUid, traitUid) {
var url = "/haskell/delete/item/" + itemUid + "/trait/" + traitUid;
traitNode = '#trait-' + traitUid;
if (confirm("Confirm deletion?")) {
$.post(url)
.done(function () {
fadeOutAndRemove(traitNode);
});
}
}
function submitTrait(itemUid, traitUid, original, ours) {
var traitNode = '#trait-' + traitUid;
$.post({
url: "/haskell/set/item/" + itemUid + "/trait/" + traitUid,
data: {
original: original,
content: ours },
success: function (data) {
$.magnificPopup.close();
$(traitNode).replaceWith(data);
switchSection(traitNode, "editable"); },
statusCode: {
409: function (xhr, st, err) {
modified = xhr.responseJSON["modified"];
merged = xhr.responseJSON["merged"];
showDiffPopup(ours, modified, merged, function (x) {
submitTrait(itemUid, traitUid, modified, x) }); } }
});
}
Note [dynamic interface]
============================================================
'makeTraitEditor' creates a textbox that appears when you try to edit a pro/con; 'makeItemNotesEditor' creates a textbox that appears when you try to edit item's notes. (Both also create some buttons/etc.)
This is rather inelegant, rather hacky, and in most places we try *not* to create any HTML dynamically, instead relying on sections (see Note [show-hide]). However, in this case we have to Firefox has a bug that makes loading pages with lots of <textarea>s slow, and so we have to reduce the number of <textarea>s contained on each page.
See <https://github.com/aelve/guide/issues/24>.
JS
============================================================
function editTrait(itemUid, traitUid, traitMarkdown) {
var traitNode = '#trait-' + traitUid;
makeTraitEditor(itemUid, traitUid, traitMarkdown);
switchSection(traitNode, "editing");
autosizeTextarea(traitNode + " .editor-area");
$(traitNode + " .editor-area").focus();
}
// Dynamically creates a 'View.smallMarkdownEditor'
// (but specifically for a trait).
function makeTraitEditor(itemUid, traitUid, content) {
var traitNode = '#trait-' + traitUid;
sectionNode = traitNode + " .section.editing";
var template =
'<textarea class="fullwidth editor-area" \
autocomplete="off" rows="5"> \
</textarea> \
<br> \
<span class="text-button cancel-button"> \
<a href="#">cancel</a> \
</span> \
<span style="float:right"> \
<span class="edit-field-instruction"> \
press Ctrl+Enter or Enter to save \
</span> \
<a href="/markdown" target="_blank"><img class="markdown-supported" src="/markdown.svg" /></a> \
</span>';
$(sectionNode).html(template);
$(sectionNode + " .editor-area").text(content);
var cancel = function () {
$(sectionNode).html("");
switchSection(traitNode, "editable");
};
$(sectionNode + " .cancel-button")[0].onclick = function () {
cancel();
return false;
};
$(sectionNode + " .editor-area")[0].onkeydown = function (event) {
if (event.keyCode == 13 || event.keyCode == 10) {
submitTrait(itemUid, traitUid, content, this.value);
return false; }
if (event.keyCode == 27) {
cancel();
return false; }
};
}