Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Safari/Chrome won't scroll up to show validation error message on radio input

I'm setting up a questionnaire for clients that needs to be mobile-friendly.

When the form is submitted/validated, and a question is not answered, it scrolls to the first invalid field - whether it is a text input or radio input. This is only on desktop browsers and Android.

On iOS Safari/Chrome, the text input works as is should, just like on desktop browsers and Android.

But for radio inputs, it focuses on the question that hasn't been answered and shows the validation error message, but does not scroll up to the focused question if it is not in the current display.

This question has been asked, but was never answered. Is there a workaround for this?

        <form name="myForm" id="myForm"method="post">  
            <div class="form-row" id="info">
                <div class="col-md-3 mb-3">
                    <label for="name">Name</label>
                    <input type="text" class="form-control" id="name" placeholder="Name" value="Tony Stark" required>
                </div> <!-- NAME -->
                <div class="col-md-3 mb-3">
                    <label for="company">Company</label>
                    <input type="text" class="form-control" id="company" placeholder="Company" value="Stark Industries">
                </div> <!-- COMPANY -->
                <div class="col-md-3 mb-3">
                    <label for="address">Address</label>
                    <input type="text" class="form-control" id="address" placeholder="Address" value="10880 Malibu Point" required>
                </div> <!-- ADDRESS -->
                <div class="col-md-3 mb-3">
                    <label for="address2">Apt / Suite / Other (Optional)</label>
                    <input type="text" class="form-control" id="address2" placeholder="Apt / Suite / Other">
                </div> <!-- ADDRESS2 -->
            </div>

            <div class="form-row" id="citystzip">
                <div class="col-md-6 mb-3">
                    <label for="city">City</label>
                    <input type="text" class="form-control" id="city" placeholder="City" value="Malibu" required>
                </div> <!-- CITY -->

                <div class="col-md-3 mb-3">
                    <label for="state">State</label>
                    <select class="form-control" id="state" placeholder="State" value="CA" required>
                        <option value="AL">AL</option>
                        <option value="AK">AK</option>
                        <option value="AZ">AZ</option>
                        <option value="AR">AR</option>
                        <option value="CA">CA</option>
                        <option value="CO">CO</option>
                        <option value="CT">CT</option>
                        <option value="DE">DE</option>
                        <option value="DC">DC</option>
                        <option value="FL">FL</option>
                        <option value="GA">GA</option>
                        <option value="HI">HI</option>
                        <option value="ID">ID</option>
                        <option value="IL">IL</option>
                        <option value="IN">IN</option>
                        <option value="IA">IA</option>
                        <option value="KS">KS</option>
                        <option value="KY">KY</option>
                        <option value="LA">LA</option>
                        <option value="ME">ME</option>
                        <option value="MD">MD</option>
                        <option value="MA">MA</option>
                        <option value="MI">MI</option>
                        <option value="MN">MN</option>
                        <option value="MS">MS</option>
                        <option value="MO">MO</option>
                        <option value="MT">MT</option>
                        <option value="NE">NE</option>
                        <option value="NV">NV</option>
                        <option value="NH">NH</option>
                        <option value="NJ">NJ</option>
                        <option value="NM">NM</option>
                        <option value="NY">NY</option>
                        <option value="NC">NC</option>
                        <option value="ND">ND</option>
                        <option value="OH">OH</option>
                        <option value="OK">OK</option>
                        <option value="OR">OR</option>
                        <option value="PA">PA</option>
                        <option value="RI">RI</option>
                        <option value="SC">SC</option>
                        <option value="SD">SD</option>
                        <option value="TN">TN</option>
                        <option value="TX">TX</option>
                        <option value="UT">UT</option>
                        <option value="VT">VT</option>
                        <option value="VA">VA</option>
                        <option value="WA">WA</option>
                        <option value="WV">WV</option>
                        <option value="WI">WI</option>
                        <option value="WY">WY</option>
                    </select>
                </div> <!-- STATE -->
                <div class="col-md-3 mb-3">
                    <label for="zip">Zip</label>
                    <input type="text" class="form-control" id="zip" placeholder="Zip" value="90265" required>
                </div> <!-- ZIP -->
            </div>

            <div class="form-row" id="contact">
                <div class="col-md-7 mb-3">
                    <label for="email">Email</label>
                    <input type="email" class="form-control" id="email" placeholder="Email" value="[email protected]" required>
                </div> <!-- EMAIL -->

                <div class="col-md-5 mb-3">
                    <label for="phone">Phone Number</label>
                    <input type="tel" class="form-control" id="phone" placeholder="Phone Number" value="678-136-7092" required>
                </div> <!-- PHONE -->
            </div>


        <h1>Please answer all survey questions and click submit at the bottom to submit <br>your updated information and survey answers.</h1>
            <legend>1. Question 1</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation1" name="question1" value="1a" required>
                <label class="custom-control-label" for="customControlValidation1">1a</label>
            </div>
            <div class="custom-control custom-radio mb-3">
                <input type="radio" class="custom-control-input" id="customControlValidation2" name="question1" value="1b" required>
                <label class="custom-control-label" for="customControlValidation2">1b</label>
            </div>

            <legend>2. Question 2</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation3" name="question2"  value="2a" required>
                <label class="custom-control-label" for="customControlValidation3">2a</label>
            </div>
            <div class="custom-control custom-radio mb-3">
                <input type="radio" class="custom-control-input" id="customControlValidation4" name="question2" value="2b" required>
                <label class="custom-control-label" for="customControlValidation4">2b</label>
            </div>

            <legend>3. Question 3</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation5" name="question3" value="3a" required>
                <label class="custom-control-label" for="customControlValidation5">3a</label>
            </div>
            <div class="custom-control custom-radio mb-3">
                <input type="radio" class="custom-control-input" id="customControlValidation6" name="question3" value="3b" required>
                <label class="custom-control-label" for="customControlValidation6">3b</label>
            </div>

            <legend>4. Question 4</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation7" name="question4" value="4a" required>
                <label class="custom-control-label" for="customControlValidation7">4a</label>
            </div>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation8" name="question4" value="4b" required>
                <label class="custom-control-label" for="customControlValidation8">4b</label>
            </div>


            <legend>5. Question 5</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation9" name="question5" value="5a" required>
                <label class="custom-control-label" for="customControlValidation9">5a</label>
            </div>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation10" name="question5" value="5b" required>
                <label class="custom-control-label" for="customControlValidation10">5b</label>
            </div>

            <legend>6. Question 6</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation11" name="question6" value="6a" required>
                <label class="custom-control-label" for="customControlValidation11">6a</label>
            </div>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation12" name="question6" value="6b" required>
                <label class="custom-control-label" for="customControlValidation12">6b</label>
            </div>

            <legend>7. Question 7</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation13" name="question7" value="7a" required>
                <label class="custom-control-label" for="customControlValidation13">7a</label>
            </div>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation14" name="question7" value="7b" required>
                <label class="custom-control-label" for="customControlValidation14">7b</label>
            </div>

            <legend>8. Question 8</legend>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation15" name="question8" value="8a" required>
                <label class="custom-control-label" for="customControlValidation15">8a</label>
            </div>
            <div class="custom-control custom-radio">
                <input type="radio" class="custom-control-input" id="customControlValidation16" name="question8" value="8b" required>
                <label class="custom-control-label" for="customControlValidation16">8b</label>
            </div>
like image 942
Marina Avatar asked May 14 '19 19:05

Marina


1 Answers

Since OP is still looking for a workaround and I was actively looking for a solution, here is my current workaround:

First I test if an iPhone/iPad is used (please check the note below), then attach EventListeners to the radio and checkbox inputs that monitor the focus event. Since the focus is set correctly on the first invalid input, the only thing left to do is to scroll that input into the visible area.

if (/^iPad|iPhone$/.test(navigator.platform)) {
    var inputs = form.querySelectorAll('input[type="radio"], input[type="checkbox"]');
    inputs.forEach(i => {
        i.addEventListener('focus', function (e) {
            e.target.scrollIntoView({
                block: 'center',
                behavior: "smooth"
            });
        })
    })
}

Note: Since iPadOS (/^iPad|iPhone$/.test(navigator.platform)) doesn't seem to work anymore. Tell iPadOS from macOS on the web lists solutions for this, but since I currently don't have an iPad which is able to run iPadOS I couldn't test them yet.

like image 136
coreuter Avatar answered Nov 03 '22 14:11

coreuter