Cataloguing in Koha ILS is a meticulous process, and maintaining consistent data entry standards can be challenging. One common issue is ensuring proper casing for different MARC fields—like applying Title Case to author names, Sentence Case to titles, and lowercase for reminder of title.
Manually fixing these while cataloguing? Tedious.
The Solution: A Simple JavaScript Script
With a bit of custom JavaScript, we can automate this process in Koha’s cataloguing form. This script:
- Converts author names (100$a, 700$a) to Title Case
- Ensures 245$a (Title) is in Sentence Case
- Adds a leading : to 245$b (Remainder of Title) with lowercase automatically
- Converts edition statements (250$a) to lowercase
- Formats name, place of publication (260$a) in Sentence Case
How to Implement
Go to Koha Administration → System Preferences → IntranetUserJS
Paste the following JavaScript code:
function toTitleCase(str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();
});
}
function toSentenceCase(str) {
if (!str) return "";
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}
function toLowerCaseOnly(str) {
return str.toLowerCase();
}
function toUpperCaseOnly(str) {
return str.toUpperCase();
}
$(document).ready(function () {
const FIELD_CONFIGS = [
{ selector: "input[id^='tag_100_subfield_a']", caseFn: toTitleCase },
{ selector: "input[id^='tag_245_subfield_a']", caseFn: toSentenceCase },
{
selector: "input[id^='tag_245_subfield_b']",
caseFn: function (str, field) {
let cleanStr = str.trim().toLowerCase();
if (!cleanStr.startsWith(":")) {
cleanStr = `: ${cleanStr}`;
}
return cleanStr;
},
updateHandler: function (field) {
field.on("blur", function () {
const val = $(this).val();
const newVal = `: ${val.trim().toLowerCase().replace(/^:?\s*/, "")}`;
$(this).val(newVal);
});
}
},
{ selector: "input[id^='tag_245_subfield_c']", caseFn: toTitleCase },
{ selector: "input[id^='tag_250_subfield_a']", caseFn: toLowerCaseOnly },
{ selector: "input[id^='tag_260_subfield_a']", caseFn: toSentenceCase },
{ selector: "input[id^='tag_260_subfield_b']", caseFn: toSentenceCase },
{ selector: "input[id^='tag_650_subfield_a']", caseFn: toSentenceCase }, // Updated to Sentence Case
{ selector: "input[id^='tag_700_subfield_a']", caseFn: toTitleCase },
{ selector: "input[id^='tag_082_subfield_b']", caseFn: toUpperCaseOnly }, // Added this
];
const interval = setInterval(function () {
FIELD_CONFIGS.forEach(config => {
const field = $(config.selector);
if (field.length > 0 && !field.data("case-handler-attached")) {
if (config.updateHandler) {
config.updateHandler(field);
} else {
field.on("input", function () {
const cursorPos = this.selectionStart;
const updated = config.caseFn($(this).val(), field);
$(this).val(updated);
this.setSelectionRange(cursorPos, cursorPos);
});
}
field.data("case-handler-attached", true);
}
});
const allAttached = FIELD_CONFIGS.every(config =>
$(config.selector).data("case-handler-attached")
);
if (allAttached) clearInterval(interval);
}, 500);
});
Click Save, refresh the Cataloguing Module, and see the magic happen