Reusable function for a validation process
The basic idea that I suggest is to decompose every bit of logic into small reusable functions. In my answer, I will touch only on validation logic because that part of your code has the most code duplication.
The following code is how I would like to see validation:
$('#addSubmit').on('click', function (e) {
    e.preventDefault();

    const validator = getValidator([
        [$('#addcity'), [
            combine(empty, emptyError),
            combine(notCapitalized, notCapitalizedError)]
        ],
        [$('#addregion'), [
            combine(emptyOrNull, emptyError)]
        ],
    ]);

    if (validator.hasErrors()) {
        const { element, error } = validator.getFirstError();
        $('.message').text(error.message);
        $('#errorModal').modal('show').on('hidden.bs.modal', element.focus.bind(element));
    } else {
        // Post request...
    }
});

Here we use the validator object to check if there are any errors and to get the first occurred error to display its message on the modal dialog. For the getValidator function we need to provide an element that we want to validate and a list of functions that find errors. Since functions that check for errors and actual errors are independent we need the ability to combine them. For example, the line combine(empty, emptyError) means that we want to check if a value is empty and return emptyError if so.
Also, I've made additional validation for the city field (see notCapitalizedError) to show how easy is to add new validation logic. To not hardcode error messages I've added data-name=&quot;&quot; attributes to all inputs:
&lt;input type=&quot;text&quot; id=&quot;addcity&quot; data-name=&quot;City&quot; placeholder=&quot;City&quot;&gt;
&lt;input type=&quot;text&quot; id=&quot;addregion&quot; data-name=&quot;Region&quot; placeholder=&quot;Region&quot;&gt;

The implementation code is a bit hard to read and the following:
const empty = (str) =&gt; (str === &quot;&quot;);
const emptyError = ($el) =&gt; ({ name: &quot;empty&quot;, message: `You must enter a ${$el.data('name')}.` });
const notCapitalized = (str) =&gt; (!empty(str) &amp;&amp; str[0] === str[0].toLowerCase());
const notCapitalizedError = ($el) =&gt; ({ name: &quot;not-capitalized&quot;, message: `${$el.data('name')} should be capitalized.` });
const emptyOrNull = (val) =&gt; (empty(val) || val == null);


const combine = (hasError, createErr) =&gt; function($el) {
    return (hasError($el.val()) ? createErr($el) : null);
}

const getErrors = ($element, fns) =&gt; fns.map((fn) =&gt; fn($element)).filter(res =&gt; res !== null);
const getValidator = (data) =&gt; {
    const map = new Map();
    data.forEach(([$el, functions]) =&gt; {
        map.set($el, functions);
    })

    const elements = Array.from(map.keys());
    const getFunctions = ($el) =&gt; map.get($el) || [];
    const elErrors = ($el) =&gt; getErrors($el, getFunctions($el));
    const elHasErrors = ($el) =&gt; (elErrors($el).length &gt; 0);
    const hasErrors = () =&gt; elements.some(elHasErrors);

    return {
        hasErrors,
        getFirstError: () =&gt; {
            if (hasErrors()) {
                const $element = elements.find(elHasErrors);
                return { element: $element, error: elErrors($element)[0]};
            }

            return null;
        }
    }
}