app/assets/javascripts/spotlight/spotlight.js in blacklight-spotlight-4.2.0 vs app/assets/javascripts/spotlight/spotlight.js in blacklight-spotlight-4.3.0
- old
+ new
@@ -5139,10 +5139,11 @@
$this.data('scrollTimeout', setTimeout(callback, 250, self));
});
};
// Place all the behaviors and hooks related to the matching controller here.
+ // All this logic will automatically be available in application.js.
class Pages {
connect(){
SirTrevor.setDefaults({
iconUrl: Spotlight.sirTrevorIcon,
@@ -5605,11 +5606,13 @@
}
}
}
// Visibility toggle for items in an exhibit, based on Blacklight's bookmark toggle
+ // See: https://github.com/projectblacklight/blacklight/blob/main/app/javascript/blacklight/bookmark_toggle.js
+
const VisibilityToggle = (e) => {
if (e.target.matches('[data-checkboxsubmit-target="checkbox"]')) {
const form = e.target.closest('form');
if (form) {
new CheckboxSubmit(form).clicked(e);
@@ -5931,30 +5934,53 @@
return Spotlight$1.Block.extend({
type: "resources",
formable: true,
autocompleteable: true,
show_heading: true,
+ show_alt_text: true,
title: function() { return i18n.t("blocks:" + this.type + ":title"); },
description: function() { return i18n.t("blocks:" + this.type + ":description"); },
-
+ alt_text_guidelines: function() {
+ if (this.show_alt_text) {
+ return i18n.t("blocks:alt_text_guidelines:intro");
+ }
+ return "";
+ },
+ alt_text_guidelines_link: function() {
+ if (this.show_alt_text) {
+ var link_url = i18n.t("blocks:alt_text_guidelines:link_url");
+ var link_label = i18n.t("blocks:alt_text_guidelines:link_label");
+ return '<a target="_blank" href="' + link_url + '">' + link_label + '</a>';
+ }
+ return "";
+ },
icon_name: "resources",
blockGroup: function() { return i18n.t("blocks:group:items") },
primary_field_key: "primary-caption-field",
show_primary_field_key: "show-primary-caption",
secondary_field_key: "secondary-caption-field",
show_secondary_field_key: "show-secondary-caption",
display_checkbox: "display-checkbox",
+ decorative_checkbox: "decorative-checkbox",
+ alt_text_textarea: "alt-text-textarea",
globalIndex: 0,
_itemPanelIiifFields: function(index, data) {
return [];
},
+ _altTextFieldsHTML: function(index, data) {
+ if (this.show_alt_text) {
+ return this.altTextHTML(index, data);
+ }
+ return "";
+ },
+
_itemPanel: function(data) {
var index = "item_" + this.globalIndex++;
var checked;
if (data.display == "true") {
checked = "checked='checked'";
@@ -5981,10 +6007,11 @@
<img class="img-thumbnail" src="${(data.thumbnail_image_url || ((data.iiif_tilesource || "").replace("/info.json", "/full/!100,100/0/default.jpg")))}" />
</div>
<div class="main">
<div class="title card-title">${data.title}</div>
<div>${(data.slug || data.id)}</div>
+ ${this._altTextFieldsHTML(index, data)}
</div>
<div class="remove float-right float-end">
<a data-item-grid-panel-remove="true" href="#">${i18n.t("blocks:resources:panel:remove")}</a>
</div>
</div>
@@ -6017,10 +6044,11 @@
},
createItemPanel: function(data) {
var panel = this._itemPanel(data);
+ this.attachAltTextHandlers(panel);
$(panel).appendTo($('.panels > ol', this.inner));
$('[data-behavior="nestable"]', this.inner).trigger('change');
},
item_options: function() { return ""; },
@@ -6049,15 +6077,71 @@
editorHTML: function() {
return `<div class="form resources-admin clearfix">
<div class="widget-header">
${this.description()}
+ ${this.alt_text_guidelines()}
+ ${this.alt_text_guidelines_link()}
</div>
${this.content()}
</div>`
},
+ _altTextData: function(data) {
+ const isDecorative = data.decorative;
+ const altText = isDecorative ? '' : (data.alt_text || '');
+ const altTextBackup = data.alt_text_backup || '';
+ const placeholderAttr = isDecorative ? '' : `placeholder="${i18n.t("blocks:resources:alt_text:placeholder")}"`;
+ const disabledAttr = isDecorative ? 'disabled' : '';
+
+ return { isDecorative, altText, altTextBackup, placeholderAttr, disabledAttr };
+ },
+
+ altTextHTML: function(index, data) {
+ const { isDecorative, altText, altTextBackup, placeholderAttr, disabledAttr } = this._altTextData(data);
+ return `<div class="mt-2 pt-2 d-flex">
+ <div class="me-2 mr-2">
+ <label class="col-form-label pb-0 pt-1" for="${this.formId(this.alt_text_textarea + '_' + data.id)}">${i18n.t("blocks:resources:alt_text:alternative_text")}</label>
+ <div class="form-check mb-1 justify-content-end">
+ <input class="form-check-input" type="checkbox"
+ id="${this.formId(this.decorative_checkbox + '_' + data.id)}" name="item[${index}][decorative]" ${isDecorative ? 'checked' : ''}>
+ <label class="form-check-label" for="${this.formId(this.decorative_checkbox + '_' + data.id)}">${i18n.t("blocks:resources:alt_text:decorative")}</label>
+ </div>
+ </div>
+ <div class="flex-grow-1 flex-fill d-flex">
+ <input type="hidden" name="item[${index}][alt_text_backup]" value="${altTextBackup}" />
+ <textarea class="form-control w-100" rows="2" ${placeholderAttr}
+ id="${this.formId(this.alt_text_textarea + '_' + data.id)}" name="item[${index}][alt_text]" ${disabledAttr}>${altText}</textarea>
+ </div>
+ </div>`
+ },
+
+ attachAltTextHandlers: function(panel) {
+ if (this.show_alt_text) {
+ const decorativeCheckbox = $('input[name$="[decorative]"]', panel);
+ const altTextInput = $('textarea[name$="[alt_text]"]', panel);
+ const altTextBackupInput = $('input[name$="[alt_text_backup]"]', panel);
+
+ decorativeCheckbox.on('change', function() {
+ const isDecorative = this.checked;
+ if (isDecorative) {
+ altTextBackupInput.val(altTextInput.val());
+ altTextInput.val('');
+ } else {
+ altTextInput.val(altTextBackupInput.val());
+ }
+ altTextInput
+ .prop('disabled', isDecorative)
+ .attr('placeholder', isDecorative ? '' : i18n.t("blocks:resources:alt_text:placeholder"));
+ });
+
+ altTextInput.on('input', function() {
+ $(this).data('lastValue', $(this).val());
+ });
+ }
+ },
+
onBlockRender: function() {
Module.init($('[data-behavior="nestable"]', this.inner));
$('[data-input-select-target]', this.inner).selectRelatedInput();
},
@@ -6243,11 +6327,11 @@
return panel;
},
item_options: function() { return `
- '<label>
+ <label>
<input type="hidden" name="display-item-counts" value="false" />
<input type="checkbox" name="display-item-counts" value="true" checked />
${i18n.t("blocks:browse_group_categories:item_counts")}
</label>`
},
@@ -6678,11 +6762,11 @@
SirTrevor.Blocks.SolrDocumentsEmbed = (function(){
return SirTrevor.Blocks.SolrDocumentsBase.extend({
type: "solr_documents_embed",
-
+ show_alt_text: false,
icon_name: "item_embed",
item_options: function() { return "" },
afterPreviewLoad: function(options) {
@@ -6842,10 +6926,11 @@
</div>
<div class="field row mr-3 me-3">
<label for="${this.formId('link_' + dataId)}" class="col-form-label col-md-3">${i18n.t("blocks:uploaded_items:link")}</label>
<input type="text" class="form-control col" id="${this.formId('link_' + dataId)}" name="item[${index}][link]" data-field="link"/>
</div>
+ ${this._altTextFieldsHTML(index, data)}
</div>
<div class="remove float-right float-end">
<a data-item-grid-panel-remove="true" href="#">${i18n.t("blocks:resources:panel:remove")}</a>
</div>
</div>
@@ -6869,10 +6954,12 @@
editorHTML: function() {
return `<div class="form oembed-text-admin clearfix">
<div class="widget-header">
${this.description()}
+ ${this.alt_text_guidelines()}
+ ${this.alt_text_guidelines_link()}
</div>
<div class="row">
<div class="form-group mb-3 col-md-8">
<div class="panels dd nestable-item-grid" data-behavior="nestable" data-max-depth="1">
<ol class="dd-list">
@@ -6888,10 +6975,28 @@
</div>
${this.text_area()}
</div>`
},
+ altTextHTML: function(index, data) {
+ const { isDecorative, altText, altTextBackup, placeholderAttr, disabledAttr } = this._altTextData(data);
+ return `
+ <div class="field row mr-3 me-3">
+ <div class="col-lg-3 ps-md-2 pl-md-2">
+ <label class="col-form-label text-nowrap pb-0 pt-1 justify-content-md-start justify-content-lg-end d-flex" for="${this.formId(this.alt_text_textarea + '_' + data.id)}">${i18n.t("blocks:resources:alt_text:alternative_text")}</label>
+ <div class="form-check d-flex justify-content-md-start justify-content-lg-end">
+ <input class="form-check-input" type="checkbox"
+ id="${this.formId(this.decorative_checkbox + '_' + data.id)}" name="item[${index}][decorative]" ${isDecorative ? 'checked' : ''}>
+ <label class="form-check-label" for="${this.formId(this.decorative_checkbox + '_' + data.id)}">${i18n.t("blocks:resources:alt_text:decorative")}</label>
+ </div>
+ </div>
+ <input type="hidden" name="item[${index}][alt_text_backup]" value="${altTextBackup}" />
+ <textarea class="col-lg-9" rows="2" ${placeholderAttr}
+ id="${this.formId(this.alt_text_textarea + '_' + data.id)}" name="item[${index}][alt_text]" ${disabledAttr}>${altText}</textarea>
+ </div>`
+ },
+
zpr_key: 'zpr_link'
});
})();
(function() {
@@ -7098,10 +7203,15 @@
resources: {
panel: {
drag: "Drag",
display: "Display?",
remove: "Remove"
+ },
+ alt_text: {
+ decorative: "Decorative",
+ alternative_text: "Alternative text",
+ placeholder: "Enter alt text for this item..."
}
},
rule: {
title: "Horizontal Rule"
@@ -7163,9 +7273,15 @@
},
group: {
undefined: "Standard widgets",
items: "Exhibit item widgets"
+ },
+
+ alt_text_guidelines: {
+ intro: 'For each item, please enter alternative text or appropriately check the decorative box. ',
+ link_label: 'Guidelines for writing alt text.',
+ link_url: 'https://www.w3.org/WAI/tutorials/images/'
}
});
// These scripts are in the vendor directory