I had a conversation with a client this week talking about records being added and users not capitalising peoples names. I thought I’d share this simple solution with the community and hope its of some use.
Hi @CarlHolmes
This is great and it will work.
This can be done simpler by doing this:
$(document).on('knack-view-render.any', function(_, { key: viewId }) {
$(`#${viewId} #first, #${viewId} #last`).on('keyup', function() {
const input = $(this);
const value = input.val();
if (value) {
input.val(value.charAt(0).toUpperCase() + value.slice(1));
}
});
});
P.S. Either way is perfectly valid and will work this keeps the event handling to a minimum. We have a much neater function to post when I’m at my computer as there are still some issues with this code i.e. McAndrew or O’Neill but they are fringe cases.
You can also add other fields to the the selector like #middle
Craig
Thanks @CSWinnall - I appreciate your kind words and bow to you far superior knowledge as a professional coder
Your version looks a lot simpler, thank you for sharing.
I don’t remember where I picked up the code but it has served me well. I’ll update my library of snippets with this version too
Here is the code that I said I’d post. This code will capitalise the first letter for any field added to the FIELDS_TO_CAPITALISE array. If you pass in a second parameter to each object in the array allCaps: true
, this will capitalise all the letters in the input. I’ve added some examples of fields you may want to capitalise:
First add the const for fields you want to capitalise first letter on
const FIELDS_TO_CAPITALISE = [
{selector: '#zip', allCaps: true},
{selector: '#first'},
{selector: '#last'},
{selector: '#middle'},
{selector: '#street'},
{selector: '#street2'},
{selector: '#city'},
{selector: '#country'},
// More fields can be added here
];
Now add these functions:
/** Capitalises the input text based on the specified criteria.
* @param {string} viewId - The ID of the view containing the input element.
* @param {string} inputSelector - The selector for the input element within the view.
* @param {boolean} [allCaps=false] - Pass in True if you want all caps. */
function capitaliseInput(viewId, inputSelector, allCaps = false) {
if (!viewId) return;
const input = $(`#${viewId} ${inputSelector}`);
if (!input.length) return;
input.on('blur', function () {
const textInput = $(this);
const str = textInput.val();
const id = textInput.attr('id');
const capitaliseWord = (word) => {
if (id === 'last') {
// Capitalise first letter, letter after hyphen, and letter after apostrophe
return word.replace(/\b\w|[-']\w/g, (match) => capitaliseString(match));
}
return capitaliseString(word.charAt(0)) + word.slice(1);
};
if (!allCaps) {
const capitalisedStr = str.split(' ').map(capitaliseWord).join(' ');
textInput.val(capitalisedStr);
} else {
textInput.val(capitaliseString(str));
}
});
}
/** Capitalises the entire string to uppercase.
* @param {string} str - The string to be capitalised.
* @returns {string} - The capitalised string. */
function capitaliseString(str) {
return str.toUpperCase();
}
Then add this code:
$(document).on('knack-view-render.any', function (event, {key: viewId}) {
for (const {selector, allCaps = false} of FIELDS_TO_CAPITALISE) {
capitaliseInput(viewId, selector, allCaps);
}
});
Let me know if you have any issues with this or would like any help.
Craig
Thanks @CSWinnall - much appreciated. I’m sure many others in the community will find this of benefit too.