Skip to content

Commit

Permalink
save tinymce content to textarea
Browse files Browse the repository at this point in the history
  • Loading branch information
davidcam-src committed Oct 15, 2024
1 parent 68f2969 commit 1419870
Show file tree
Hide file tree
Showing 2 changed files with 200 additions and 0 deletions.
13 changes: 13 additions & 0 deletions app/assets/javascripts/hyrax/save_work/required_fields.es6
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,17 @@ export class RequiredFields {
this.requiredFields = this.form.find(':input[required], input[name*="date_issued"]');
this.requiredFields.change(this.callback)
}

// [hyc-override] Save TinyMCE content to the textarea before checking for required fields
// Important for required fields that are TinyMCE editors
saveTinyMCEContent() {
// Loop through each TinyMCE instance in the form
$(this.form).find('.tinymce').each((index, elem) => {
const id = $(elem).attr('id');
// If the TinyMCE instance exists, save the content
if (id && tinymce.get(id)) {
tinymce.get(id).save();
}
});
}
}
187 changes: 187 additions & 0 deletions app/assets/javascripts/hyrax/save_work/save_work_control.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { RequiredFields } from './required_fields'
import { ChecklistItem } from './checklist_item'
import { UploadedFiles } from './uploaded_files'
import { DepositAgreement } from './deposit_agreement'
import VisibilityComponent from './visibility_component'

/**
* Polyfill String.prototype.startsWith()
*/
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position){
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
}

export default class SaveWorkControl {
/**
* Initialize the save controls
* @param {jQuery} element the jquery selector for the save panel
* @param {AdminSetWidget} adminSetWidget the control for the adminSet dropdown
*/
constructor(element, adminSetWidget) {
if (element.length < 1) {
return
}
this.element = element
this.adminSetWidget = adminSetWidget
this.form = element.closest('form')
element.data('save_work_control', this)
this.activate();
}

/**
* Keep the form from submitting (if the return key is pressed)
* unless the form is valid.
*
* This seems to occur when focus is on one of the visibility buttons
*/
preventSubmitUnlessValid() {
this.form.on('submit', (evt) => {
if (!this.isValid())
evt.preventDefault();
})
}

/**
* Keep the form from being submitted many times.
*
*/
preventSubmitIfAlreadyInProgress() {
this.form.on('submit', (evt) => {
if (this.isValid())
this.saveButton.prop("disabled", true);
})
}

/**
* Keep the form from being submitted while uploads are running
*
*/
preventSubmitIfUploading() {
this.form.on('submit', (evt) => {
if (this.uploads.inProgress) {
evt.preventDefault()
}
})
}

/**
* Is the form for a new object (vs edit an existing object)
*/
get isNew() {
return this.form.attr('id').startsWith('new')
}

/*
* Call this when the form has been rendered
*/
activate() {
if (!this.form) {
return
}
this.requiredFields = new RequiredFields(this.form, () => this.formStateChanged())
this.uploads = new UploadedFiles(this.form, () => this.formStateChanged())
this.saveButton = this.element.find(':submit')
this.depositAgreement = new DepositAgreement(this.form, () => this.formStateChanged())
this.requiredMetadata = new ChecklistItem(this.element.find('#required-metadata'))
this.requiredFiles = new ChecklistItem(this.element.find('#required-files'))
this.requiredAgreement = new ChecklistItem(this.element.find('#required-agreement'))
new VisibilityComponent(this.element.find('.visibility'), this.adminSetWidget)
this.preventSubmit()
this.watchMultivaluedFields()
this.formChanged()
this.addFileUploadEventListeners();
}

addFileUploadEventListeners() {
let $uploadsEl = this.uploads.element;
const $cancelBtn = this.uploads.form.find('#file-upload-cancel-btn');

$uploadsEl.on('fileuploadstart', () => {
$cancelBtn.hidden = false;
});

$uploadsEl.on('fileuploadstop', () => {
$cancelBtn.hidden = true;
});
}

preventSubmit() {
this.preventSubmitUnlessValid()
this.preventSubmitIfAlreadyInProgress()
this.preventSubmitIfUploading()
}

// If someone adds or removes a field on a multivalue input, fire a formChanged event.
watchMultivaluedFields() {
$('.multi_value.form-group', this.form).on('managed_field:add', () => this.formChanged())
$('.multi_value.form-group', this.form).on('managed_field:remove', () => this.formChanged())
}

// Called when a file has been uploaded, the deposit agreement is clicked or a form field has had text entered.
formStateChanged() {
this.saveButton.prop("disabled", !this.isSaveButtonEnabled);
}

// called when a new field has been added to the form.
formChanged() {
this.requiredFields.reload();
this.formStateChanged();
}

// Indicates whether the "Save" button should be enabled: a valid form and no uploads in progress
get isSaveButtonEnabled() {
return this.isValid() && !this.uploads.inProgress;
}

isValid() {
// avoid short circuit evaluation. The checkboxes should be independent.
let metadataValid = this.validateMetadata()
let filesValid = this.validateFiles()
let agreementValid = this.validateAgreement(filesValid)
return metadataValid && filesValid && agreementValid
}

// sets the metadata indicator to complete/incomplete
validateMetadata() {
// [hyc-override] Update textarea for fields using TinyMCE for rich text editing
this.requiredFields.saveTinyMCEContent()

if (this.requiredFields.areComplete) {
this.requiredMetadata.check()
return true
}
this.requiredMetadata.uncheck()
return false
}

// sets the files indicator to complete/incomplete
validateFiles() {
if (!this.uploads.hasFileRequirement) {
return true
}
if (!this.isNew || this.uploads.hasFiles) {
this.requiredFiles.check()
return true
}
this.requiredFiles.uncheck()
return false
}

validateAgreement(filesValid) {
if (filesValid && this.uploads.hasNewFiles && this.depositAgreement.mustAgreeAgain) {
// Force the user to agree again
this.depositAgreement.setNotAccepted()
this.requiredAgreement.uncheck()
return false
}
if (!this.depositAgreement.isAccepted) {
this.requiredAgreement.uncheck()
return false
}
this.requiredAgreement.check()
return true
}
}

0 comments on commit 1419870

Please sign in to comment.