app/javascript/spotlight/admin/blocks/resources_block.js in blacklight-spotlight-4.2.0 vs app/javascript/spotlight/admin/blocks/resources_block.js in blacklight-spotlight-4.3.0

- old
+ new

@@ -6,30 +6,53 @@ return Core.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'" @@ -56,10 +79,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> @@ -92,10 +116,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 ""; }, @@ -124,12 +149,68 @@ 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() { SpotlightNestable.init($('[data-behavior="nestable"]', this.inner));