Tengo un escenario que trataré de explicar, perdón por mi inglés.
Creé un formulario para enviar algunos valores, dentro del formulario, el usuario puede seleccionar una opción, pero una opción es " Otros especifican... " cuando se selecciona, se muestra el área de texto oculta y el usuario puede completar algunos datos. En el caso de que se seleccione y el usuario no complete ningún dato, el formulario se devuelve debido a un error de validación, pero el área de texto ya no está visible porque onchange="selectOption();" no se activa. Todo funciona bien, pero en mi caso estoy tratando de hacer visible el área de texto con un mensaje de error de validación cuando se devuelve. ¿Cómo realizo esto?
<form method="POST" action="{{route('employer-section-b.store')}}"> @csrf <div class="col-md-12"> <select name="b3" id="sector" class="form-control @error('b3') is-invalid @enderror" onchange="selectOption();"> <option value="" disabled selected>select</option> <option value="1" @if (old('b3')=="1" ) {{ 'selected' }} @endif>Agriculture, forestry, and fishing </option> <option value="2" @if (old('b3')=="2" ) {{ 'selected' }} @endif>Mining and quarrying</option> <option value="14" @if (old('b3')=="3" ) {{ 'selected' }} @endif>Others specify……</option></select> <div class="col-md-12 mt-2" id="specify" style="display: none"> <div class="form-floating mb-3"> <textarea rows="2" name="b3" class="form-control @error('b3') is-invalid @enderror" placeholder="Type here.."> {{ old('b3') }}</textarea> </div></div> </div> </form>Script para mostrar el área de texto si se seleccionan otros
<script> function selectOption() { var sector = document.getElementById("sector").value; var y = document.querySelector("#specify"); if (sector == 3) { y.removeAttribute("style") } else if (sector != 3) { y.setAttribute("style", "display:none"); } } </script>Lo que sucede es que cuando envía el formulario, la página se vuelve a cargar y todos los datos del formulario se restablecen.
Lo que debe hacer es crear un detector de eventos de submit en javascript y ejecutar event.preventDefault() para evitar que el formulario vuelva a cargar la página y luego manejar lo que sucedería si el formulario se enviara cuando el área de texto está vacía.
document.querySelector('form').addEventListener('submit', (event) => { // Prevent form from reloading the page event.preventDefault(); // Get content written inside textarea let textareaValue = document.querySelector('.form-floating > .form-control').value; // Check if textarea is empty if (!textareaValue.trim()) { // Show a message to the user that an error has occured console.log('Validation error'); } else { // Route to "employer-section-b.store" route('employer-section-b.store'); } });¿Por qué no mostrar explícitamente el área de textarea cuando se selecciona la opción b3 con valor 3 ? De esta manera, ya no es necesario cambiar el código JS .
Vea el ejemplo a continuación:
Tiene un nombre duplicado en uso,
b3, por lo que cambié el segundo duplicado que se encuentra en el área detextareaab4.
<form method="POST" action="{{ route('employer-section-b.store') }}"> @csrf <div class="col-md-12"> <select name="b3" id="sector" class="form-control{{ $errors->has('b3') ? ' is-invalid':'' }}" onchange="selectOption()"> <option value="" disabled selected>select</option> <option value="1"{{ old('b3') == 1 ? ' selected':'' }}>Agriculture, forestry, and fishing </option> <option value="2"{{ old('b3') == 2 ? ' selected':'' }}>Mining and quarrying</option> <option value="3"{{ old('b3') == 3 ? ' selected':'' }}>Others specify……</option> </select> <div class="col-md-12 mt-2" id="specify"{!! ($hasB4Error = $errors->has('b4') || old('b3') == 3) ? '':' style="display: none"' !!}> <div class="form-floating mb-3"> <textarea rows="2" name="b4" class="form-control{{ $hasB4Error ? ' is-invalid':'' }}" placeholder="Type here..">{{ old('b3') }}</textarea> </div> </div> </div> </form>
{!! $errors->has('b4') || old('b3') == 3 ? '':' style="display: none"' !!}
Esta línea de código hace el truco, le dice a Blade que solo coloque el CSS que oculta el área de textarea solo cuando no se encuentran errores en los elementos b3 ni b4 .