Replace empty string in field using javascript
I have used the code supplied under "Example: Item Field Changes" on this page: https://www.zotero.org/support/dev/client_coding/javascript_api to successfully change field content. But I receive the message "No items found" if the oldValue is set to empty: "" Is there a way to populate only empty fields using javascript? What I want to do is add "en" to the language field only for those items where the language field is empty.
Editing 5000 items via the JS API is no problem: you just need to be very careful to check that the code will do exactly what you want before running it for serious.
oldValue = "%";
...
s.addCondition(fieldName, 'contains', oldValue);
does that not work?
doesNotContain
. This should work:s.addCondition(fieldname, 'doesNotContain', '%');
It might be good to add the most common search predicates to the instructions.
(A search for '%' with
contains
will find all entries that already have content, which are definitely not the desired targets.)(It's a leaky abstraction from SQLite that the percent character even has meaning, and that will likely be fixed in the future in favor of more standard wildcards. In the meantime, the search term is already wrapped with '%' on both sides, so '%' just becomes '%%%', which is the same as '%%'.)
var fieldName = "language";
var oldValue = "%";
var newValue = "en";
and
s.addCondition(fieldname, 'doesNotContain', '');
It does not matter whether I enter oldValue, '%' or '' at the end of the line above. I receive the same error. I am no programmer and feeling adventurous.
s.addCondition('itemType', 'isNot', 'note');
s.addCondition('itemType', 'isNot', 'attachment');
It is these two lines that are causing me trouble:
var oldValue = "%";
s.addCondition(fieldName, 'doesNotContain', oldValue);
My code is as follows:
var fieldName = "language";
var oldValue = "%";
var newValue = "en";
var fieldID = Zotero.ItemFields.getID(fieldName);
var s = new Zotero.Search();
s.libraryID = Zotero.Libraries.userLibraryID;
s.addCondition('itemType', 'isNot', 'note');
s.addCondition('itemType', 'isNot', 'attachment');
s.addCondition(fieldName, 'doesNotContain', '');
var ids = await s.search();
if (!ids.length) {
return "No items found";
Zotero.ItemFields.isValidForType(fieldID, itemTypeID)
, but you could just add a try/catch around the save.It turns out that the "language" field shown in the Computer Program type is actually the "programmingLanguage." That type doesn't have an ordinary language field, which is why edits to that type are failing for you. If you add this line to the conditions, it should help:
s.addCondition('itemType', 'isNot', 'computerProgram');
var fieldName = "language";
var oldValue = "%";
var newValue = "en";
var fieldID = Zotero.ItemFields.getID(fieldName);
var s = new Zotero.Search();
s.libraryID = Zotero.Libraries.userLibraryID;
s.addCondition('itemType', 'isNot', 'note');
s.addCondition('itemType', 'isNot', 'attachment');
s.addCondition('itemType', 'isNot', 'computerProgram');
s.addCondition(fieldName, 'doesNotContain', oldValue);
var ids = await s.search();
if (!ids.length) {
return "No items found";
}
await Zotero.DB.executeTransaction(async function () {
for (let id of ids) {
let item = await Zotero.Items.getAsync(id);
let mappedFieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(item.itemTypeID, fieldName);
item.setField(mappedFieldID ? mappedFieldID : fieldID, newValue);
await item.save();
}
});
return ids.length + " item(s) updated";
Remember to back up your database before trying and turn off automatic syncing!