diff options
author | Steven Burr <steve@bestpractical.com> | 2021-06-03 16:06:29 +0300 |
---|---|---|
committer | Steven Burr <steve@bestpractical.com> | 2021-06-03 16:06:29 +0300 |
commit | 44d33a2b40a70dd8375f359d9ee01a5de645b3bc (patch) | |
tree | f20f6c5788b13144eb142c79def45ea6ec864048 | |
parent | ef71d493e435d91080a69600e46a61ff3f74ca27 (diff) |
more WIPgui-help
-rw-r--r-- | share/html/Elements/PopupHelp | 4 | ||||
-rw-r--r-- | share/html/Ticket/Display.html | 1 | ||||
-rw-r--r-- | share/html/Ticket/Elements/ShowBasics | 24 | ||||
-rw-r--r-- | share/static/js/popup-help.js | 109 |
4 files changed, 135 insertions, 3 deletions
diff --git a/share/html/Elements/PopupHelp b/share/html/Elements/PopupHelp index 67cf857aeb..0b7b06c7d4 100644 --- a/share/html/Elements/PopupHelp +++ b/share/html/Elements/PopupHelp @@ -55,7 +55,5 @@ if ($key) { } </%init> % if ($has_help) { -<a class="popup-help" tabindex="0" role="button" data-toggle="popover" title="<% $key %>" data-content="<% $help_content %>" data-html="true" data-trigger="focus"> - <img src="/static/images/question.svg" data-toggle="popover" title="<% $key %>" data-content="<% $help_content %>" data-html="true" data-trigger="focus" /> -</a> +<span data-help="<% $key %>" data-content="<% $help_content %>" data-action="replace" style="display: none;"/> % } diff --git a/share/html/Ticket/Display.html b/share/html/Ticket/Display.html index 192d333fbb..f0548d879f 100644 --- a/share/html/Ticket/Display.html +++ b/share/html/Ticket/Display.html @@ -59,6 +59,7 @@ <div border="2px solid #1278c6; margin: 10px; padding: 10px;"> <button class="btn btn-danger" id="show-help">Show Help</button> <button class="btn btn-danger" id="hide-help">Hide Help</button> +<button class="btn btn-danger" id="add-help">Add Help</button> </div> % $m->callback( %ARGS, Ticket => $TicketObj, Transactions => $transactions, Attachments => $attachments, CallbackName => 'BeforeShowSummary' ); diff --git a/share/html/Ticket/Elements/ShowBasics b/share/html/Ticket/Elements/ShowBasics index e3574f86c5..3ef1713944 100644 --- a/share/html/Ticket/Elements/ShowBasics +++ b/share/html/Ticket/Elements/ShowBasics @@ -46,11 +46,35 @@ %# %# END BPS TAGGED BLOCK }}} +<script src="/static/js/popup-help.js"></script> <script> +function quoteattr(s, preserveCR) { + preserveCR = preserveCR ? ' ' : '\n'; + return ('' + s) /* Forces the conversion to string. */ + .replace(/&/g, '&') /* This MUST be the 1st replacement. */ + .replace(/'/g, ''') /* The 4 other predefined entities, required. */ + .replace(/"/g, '"') + .replace(/</g, '<') + .replace(/>/g, '>') + /* + You may add other replacements here for HTML only + (but it's not necessary). + Or for XML, only if the named entities are defined in its DTD. + */ + .replace(/\r\n/g, preserveCR) /* Must be before the next replacement. */ + .replace(/[\r\n]/g, preserveCR) +} + jQuery(document).ready(function () { jQuery('[data-toggle="popover"]').popover({trigger: 'focus'}) jQuery('#show-help').click(function(e) { jQuery('.popup-help').show() }) jQuery('#hide-help').click(function(e) { jQuery('.popup-help').hide() }) + jQuery('#add-help').click(function(e) { + console.log("==> Adding a custom rule to helpify all submit buttons...") + addPopupHelpItems( { selector: 'input.button.form-control.btn.btn-primary', title: 'Submit button', content: 'You probably already know this, but submit buttons will submit stuff', action: "prepend" } ) + console.log("==> Adding help items as would be done in the page footer...") + renderPopupHelpItems() + }) }) </script> <style> diff --git a/share/static/js/popup-help.js b/share/static/js/popup-help.js new file mode 100644 index 0000000000..3005a24f61 --- /dev/null +++ b/share/static/js/popup-help.js @@ -0,0 +1,109 @@ +function applySelectorQueryOrFunc( sel ) { + if ( sel ) { + if ( typeof(sel) === "string" ) { + return jQuery(sel) + } else if ( typeof(sel) === "function" ) { + return sel(jQuery) + } + } +} + +function getPopupHelpAction( entry={} ) { + entry.action = entry.action || "append" + if ( typeof(entry.action) === "string" ) { + const funcMap = { + "append": appendPopupHelp, + "prepend": prependPopupHelp, + "offset": offsetPopupHelp, + "replace": replacePopupHelp + } + return funcMap[entry.action] + } else if ( typeof(entry.action) === "function" ) { + return entry.action + } +} + +function getPopupHelpActionArgs( entry={}, $els ) { + return entry.actionArgs ? [ $els, entry, entry.actionArgs ] : [ $els, entry ] +} + +function appendPopupHelp( $els, item={}, options={} ) { + item.action = options.action = "append" + return helpify( $els, item, options ) +} + +function prependPopupHelp( $els, item={}, options={} ) { + item.action = options.action = "prepend" + return helpify( $els, item, options ) +} + +function offsetPopupHelp( $els, item={}, options={} ) { + item.action = options.action = "offset" + return helpify( $els, item, options ) +} + +function replacePopupHelp( $els, item={}, options={} ) { + item.action = options.action = "replace" + return helpify( $els, item, options ) +} + +function helpify($els, item={}, options={}) { + $els.each(function(index) { + const $el = jQuery($els.get(index)) + const action = $el.data("action") || item.action || options.action + const title = $el.data("help") || $el.data("title") || item.title + const content = $el.data("content") || item.content + switch(action) { + case "prepend": + $el.parent().prepend( buildPopupHelpEl( title, content ) ) + break + case "offset": + $el.parent().append( buildPopupHelpEl( title, content ) ).offset( options ) + break + case "replace": + $el.replaceWith( buildPopupHelpEl( title, content ) ) + break + case "append": // intentionally fallthrough, as 'append' is the default + default: + $el.parent().append( buildPopupHelpEl( title, content ) ) + } + }) +} + +function buildPopupHelpEl(title, content) { + return '<a class="popup-help" tabindex="0" role="button" data-toggle="popover" title="' + title + '" data-content="' + quoteattr(content) + '" data-html="true" data-trigger="focus"><img src="/static/images/question.svg" /></a>' +} + +function invokePopupHelpAction( entry, $els ) { + if ( entry ) { + const fn = getPopupHelpAction( entry ) + const args = getPopupHelpActionArgs( entry, $els ) + fn.apply(this, args) + } +} + +// a list of entries to process for the page +var pagePopupHelpItems = [ + { selector: "[data-help]", action: helpify } // by default, anything with data-help attributes gets processed +] + +// add one or more items to the list of help entries to process for the page +function addPopupHelpItems() { + const args = [].slice.call(arguments) + pagePopupHelpItems = pagePopupHelpItems || [] + pagePopupHelpItems = pagePopupHelpItems.concat(args) +} + +// render all the help icons and popover-ify them +function renderPopupHelpItems( list ) { + list = list || pagePopupHelpItems + if (list && Array.isArray(list) && list.length) { + list.forEach(function(entry) { + const $els = applySelectorQueryOrFunc(entry.selector) + if ( $els ) { + invokePopupHelpAction( entry, $els ) + } + }) + jQuery('[data-toggle="popover"]').popover({trigger: 'focus'}) + } +} |