How to use custom apiUrl with FieldControlledVocab

Hi @NateWr ,

I have a quick question regarding FieldControlledVocab and hope you can guide me in the right direction. I created a custom FieldControlledVocab and would love to use an external apiUrl suggesting keywords to me. The field itself works and the keywords I enter are saved perfectly fine in the database. The problem I am having is how to use apiUrl with an external url since I have not found any examples online…

Example code:

$myUrl = "http://customurl/search?q=keyword";

// Create custom keyword field.
$form->addField(new FieldControlledVocab('customKeywords', [
	'label' => __('common.keywords'),
	'tooltip' => __('manager.setup.metadata.keywords.description'),
	'apiUrl' => str_replace('keyword', CONTROLLED_VOCAB_SUBMISSION_KEYWORD, $myUrl),
	'selected' => $selectedKeywords
]));

I would like to replace “keyword” in the url with whatever I am entering to receive suggestions from the API similarly how it is done in the PKPMetadataForm.
Any tips on how to achieve this? Is this even possible?

OJS Version: 3.3.0-3

Best,
Tina

The FieldControlledVocab is a special field designed to work with OJS’s existing controlled vocab API. It’s unusual in that the search request is not sent to the apiUrl. Instead, all of the keywords are loaded in once and matching is done in the browser:

This will only work for you if your API endpoint returns all possible matches in a single response JSON that looks like this:

[keyword1,keyword2,keyword3,etc]

In most cases, you don’t control the API response. Or the list of keywords will be too long for this to be reasonable. In such cases, you will need a Vue.js component that transforms the API response into the suggestions.

For this, you want to create a custom Vue.js component that extends the FieldBaseAutosuggest component. You can see an example in the Usage section of the UI Library docs here:

https://docs.pkp.sfu.ca/dev/ui-library/dev/#/component/Form/fields/FieldBaseAutosuggest

However, this assumes that you are adding a field that is built into OJS’s javascript package. It may be difficult to figure out how to do this from a plugin. At the moment, we can’t recommend a particular approach to adding Vue.js components through a plugin.

Hi @NateWr
thank you so much for your comprehensive response. Would it be also possible to change FieldControlledVocab.vue (and thus the way the response is handled) via editing of the ui-library?

Hi @vmayer, it’s possible to do but we discourage editing the core files. Any changes you make will be removed with each software update. You would need to manually re-apply your changes and rebuild the JS package each time you performed an update.

If you want to try to get a new field type added from a plugin, you can look into js/load.js and lib/pkp/js/load.js. These are the files that load the global Vue components, and an example of adding a custom global component can be found at:

window.pkp.Vue.component('field-text', FieldText);

You may be able to add similar JavaScript to your plugin to register your custom autosuggest field. In theory, I think this is possible but I’m sorry I don’t think anyone has tried it before.

1 Like