Topic: Server-side Select Validation

Andrew Ford priority asked 2 months ago


Expected behavior

When a user doesn't select a value in a dropdown, I want it to print something like "State is required" underneath the corresponding <select> field.

My form layout is; 3 text boxes, 4 select-dropdowns, then 3 more text boxes

Resources (screenshots, code snippets etc.)

With the code;

Object.entries(data.error).forEach(entry => {
    let [key, value] = entry;
    if (document.querySelector('input.form-control')) {
        document.querySelector('input[name="' + key + '"]').classList.add('is-invalid');
        document.querySelector('input + [for="' + key + '"] + .invalid-feedback').textContent = value;
    }
    if (document.querySelector('select')) {
        let selects = new mdb.Select(document.querySelector('select[name="' + key + '"]'), {
            invalidFeedback: value
        });
    }
});

I get this error in the console;

TypeError: Cannot read properties of null (reading 'classList')

After doing this, it stopped validating after the first field.

I added the data- attribute and kept the value empty, console output;

Uncaught Error: SELECT: Option "invalidFeedback" provided type "null" but expected type "string".

This breaks the rest of the page.

From the code above, when I tried the following in place of the new mdb.Select(. . .);

document.querySelector('select#' + key).setAttribute('data-mdb-invalid-feedback', value);

The console shows;

TypeError: Cannot read properties of null (reading 'setAttribute')

Quick Fix

I did client-side validation. Even though the <select> fields are essentially "empty"/"not empty", I would prefer server-side that way everything is in a single file.


Andrew Ford priority answered 2 months ago


I was now just seeing what you were trying to point out, but it still doesn't work;

Object.entries(data.error).forEach(entry => {
    let [key, value] = entry;
    let field = document.querySelector(`[id^="${prefix}"][name="${key}"]`);
    let invalidFeedback = document.querySelector(`[id^="${prefix}"][name="${key}"] + label + .invalid-feedback`);
    if (field.classList.contains('select-wrapper')) {
      // This is a select element
      field.classList.add('is-invalid');
      invalidFeedback.textContent = value;
      let select = new mdb.Select(field, {
        invalidFeedback: value
      });
    } else if (field.tagName.toLowerCase() === 'input') {
      // This is an input element
      field.classList.add('is-invalid');
      invalidFeedback.textContent = value;
    }
  });

I click the "register" button while leaving fields empty. It shows my custom "field is required" on only the text boxes but gives me the default "Invalid" message for the select fields.


Kamila Pieńkowska staff commented 2 months ago

We create input field when select is initialized so to set custom invalid messages you need to use invalidFeedback option. If you initialize select with data atribute you neet to pass it at that point using data-mdb-invalid-feedback attribute.

Using this code later on won't update options for already existing instance:

new mdb.Select(field, { invalidFeedback: value });


Andrew Ford priority answered 2 months ago


I am only initializing the <select> with the data- attribute, then running the validation programmatically.

<select id="regGender" name="gender" required data-mdb-select-init aria-required="true">
    <option value="" selected hidden></option>
    <option value="1">Male</option>
</select>

I've rearranged my if/else because I only have the two. Just doing this;

if (field.tagName.toLowerCase() === 'input') {
} else {
    new mdb.Select(document.querySelector('select[name="' + key + '"]'), {
        validation: true,
        invalidFeedback: value
    });
}

Duplicates the entire .select-wrapper container, but I now see the invalidFeedback: value.

enter image description here enter image description here


Kamila Pieńkowska staff answered 2 months ago


Here is a paragraph about select validation: https://mdbootstrap.com/docs/standard/forms/select/#section-validation


Andrew Ford priority commented 2 months ago

I saw that.

I said I had to do client-side --- so I got validation working on the <select> fields.

I would rather do server-side validation. But as I said;

I tried .setAttribute('data-mdb-invalid-feedback', value) to get the value from my PHP file doesn't work.

That says nothing about server-side validation, I want to be allowed to do server-side. It is more secure than client-side.


Kamila Pieńkowska staff answered 2 months ago


Please create working example in a snippet i am unable to recreate your setup from the description.


Andrew Ford priority commented 2 months ago

I wouldn't be able to add PHP to the snippet, so it wouldn't work. Besides, I'm just talking about a basic form.

I should be able to .setAttribute('data-mdb-invalid-feedback', value) or something on the associated <select> field using my PHP.



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue

  • ForumUser: Priority
  • Premium support: Yes
  • Technology: MDB Standard
  • MDB Version: MDB5 7.2.0
  • Device: N/A
  • Browser: N/A
  • OS: N/A
  • Provided sample code: Yes
  • Provided link: No