Thank you for your help @jardakotesovec. I followed your tip and have it working now.
use PKP\components\forms\FieldText;
class FieldTextLookup extends FieldText
{
/** @copydoc Field::$component */
public $component = 'ror-field-text-lookup';
}
- Add to the ContributorForm
function register($category, $path, $mainContextId = null): bool
{
...
Hook::add('Form::config::before', [$this, 'addFields']);
Hook::add('Template::Workflow::Publication', [$this, 'addWorkflow']);
Hook::add('Template::SubmissionWizard::Section', [$this, 'addWorkflow']);
...
}
function addFields(string $hookName, object $form): bool
{
if (!$form instanceof ContributorForm) return Hook::CONTINUE;
$form->addField(new FieldTextLookup(Constants::$idName . '_Lookup', [
'label' => __('plugins.generic.ror.input.lookup.label'),
'tooltip' => __('plugins.generic.ror.input.lookup.tooltip'),
]), [FIELD_POSITION_BEFORE, 'affiliation']);
return Hook::CONTINUE;
}
function addWorkflow(string $hookName, array &$args): void
{
/* @var TemplateManager $templateMgr */
$templateMgr = &$args[1];
$request = Application::get()->getRequest();
$templateMgr->display($this->getTemplateResource('contributor.tpl'));
}
And the contributor.tpl file as follows
<script>
let rorPluginTemplateCompiled = pkp.Vue.compile(`
<div class="pkpFormField pkpFormField--text RorPlugin_rorId_Lookup_div" :class="classes">
<div class="pkpFormField__heading">
<form-field-label :controlId="controlId"
:label="label"
:localeLabel="localeLabel"
:isRequired="isRequired"
:requiredLabel="__('common.required')"
:multilingualLabel="multilingualLabel">
</form-field-label>
<tooltip v-if="isPrimaryLocale && tooltip"
aria-hidden="true"
:tooltip="tooltip"
label="">
</tooltip>
</div>
<div class="pkpFormField__control" :class="controlClasses">
<div class="pkpFormField__control_top">
<label>
<span class='pkpSearch__icons'>
<icon icon='search' class='pkpSearch__icons--search'/>
</span>
<input class="pkpFormField__input pkpFormField--text__input"
ref="input"
v-model="searchPhrase"
:type="inputType"
:id="controlId"
:name="localizedName"
:aria-describedby="describedByIds"
:aria-invalid="errors && errors.length"
:disabled="isDisabled"
:required="isRequired"
:style="inputStyles"/>
</label>
<button class="pkpSearch__clear"
v-if="searchPhrase"
@click.prevent="clearSearchPhrase">
<icon icon="times"/>
</button>
</div>
</div>
<div v-if="searchPhrase" class="searchPhraseOrganizations">
<ul>
<li v-for="(organization, index) in organizations">
<a @click.prevent="selectOrganization(index)">{{ organization.name }} [{{ organization.id }}]</a>
</li>
</ul>
</div>
</div>
`);
pkp.Vue.component("ror-field-text-lookup", {
name: "FieldTextLookup",
extends: pkp.Vue.component("field-text"),
data() {
return {
organizations: [], // [ { id: id1, name: name1 }, ... ]
searchPhrase: "",
minimumSearchPhraseLength: 3,
}
},
methods: {
selectOrganization(index) {
let fields = this.$parent._props.fields;
fields[this.getIndex('rorId')].value = this.organizations[index].id;
let values = fields[this.getIndex('affiliation')].value;
Object.keys(values).forEach(key => {
values[key] = this.organizations[index].name;
if (typeof this.organizations[index].labels[key] !== 'undefined') {
values[key] = this.organizations[index].labels[key];
}
});
},
clearSearchPhrase() {
this.organizations = [];
this.searchPhrase = "";
},
getIndex(fieldName) {
let fields = this.$parent._props.fields;
for (let i = 0; i < fields.length; i++) {
if (fields[i].name === fieldName) {
return i;
}
}
},
apiLookup() {
fetch('https://api.ror.org/organizations?affiliation=' + this.searchPhrase + '*')
.then(response => response.json())
.then(data => {
this.organizations = [];
let items = data.items;
items.forEach((item) => {
let labels = { /* */};
for (let i = 0; i < item.organization.labels.length; i++) {
labels[item.organization.labels[i].iso639]
= item.organization.labels[i].label
}
let row = {
id: item.organization.id,
name: item.organization.name,
labels: labels
};
this.organizations.push(row);
});
})
.catch(error => console.log(error));
}
},
watch: {
searchPhrase() {
if (this.searchPhrase.length >= this.minimumSearchPhraseLength) {
this.apiLookup();
}
}
},
render: function (h) {
return rorPluginTemplateCompiled.render.call(this, h);
}
});
</script>