Validation of select without form

2

I have a view where I have dynamically generated selects and a link. I need to make sure the selects are selected when clicking the <a id="add-cart" href="{{ route('site.add.cart', $product) }}" class="btn btn-danger mt-5">Adicionar ao Carrinho</a> link. It is working as expected, but the mandatory field warning appears at the end of the selects instead of one at each select

<div class="pages-header">
<div class="container">
    <h1 class="text-center pages-title">{{ $product->name }}</h1>
</div>
</div>
<div class="container">
<section>
    <div class="row">
        <div class="col-lg-3">
        <aside>
            <ul class="list-group pt-5 pb-5">
                <h5 class="text-uppercase font-weight-bold">Categorias</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($productCategories as $productCategory)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                        <a href="{{ route('site.product.category', $productCategory) }}">{{ $productCategory->name }}</a>   
                        <span class="badge badge-secondary badge-pill">{{ $productCategory->products->count() }}</span>
                    </li>
                @endforeach
                <h5 class="text-uppercase font-weight-bold pt-5">Subcategorias</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($subcategories as $subcategory)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                        <a href="{{ route('site.product.subcategory', $subcategory) }}">{{ $subcategory->name }}</a>  
                        <span class="badge badge-secondary badge-pill">{{ $subcategory->products->count() }}</span>
                    </li>
                @endforeach
                <h5 class="text-uppercase font-weight-bold pt-5">Marcas</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($brands as $brand)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                        <a href="{{ route('site.product.brand', $brand) }}">{{ $brand->name }}</a>  
                        <span class="badge badge-secondary badge-pill">{{ $brand->products->count() }}</span>
                    </li>
                @endforeach
                <h5 class="text-uppercase font-weight-bold pt-5">Opções</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($options as $option)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products font-weight-bold">
                        <p class="mb-0">{{ $option->name }}</p>  
                    </li>
                    @foreach($option->optionValues as $optionValue)
                        <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products ml-3">
                            <a href="{{ route('site.product.option.value', $optionValue) }}">{{ $optionValue->value }}</a> 
                            <span class="badge badge-secondary badge-pill">{{ $optionValue->products->count() }}</span>
                        </li>
                    @endforeach 
                @endforeach
            </ul>
        </aside>
        </div>
        <div class="col-lg-9 mt-5">
            <div class="row">
                <div class="col-lg-6">
                    @foreach($product->images as $image)
                    <img src="{{ asset('storage/' . $image->name) }}" class="img-fluid" alt="Responsive image"> @break @endforeach
                    <div class="row">
                        @foreach($product->images as $image)
                        <div class="col-4 mt-5">
                            <img src="{{ asset('storage/' . $image->name) }}" class="img-fluid" alt="Responsive image">
                        </div>
                        @endforeach
                    </div>
                </div>
                <div class="col-lg-6">
                    <div class="row">
                        <div class="col-12 select-option">
                            @foreach($product->options as $option)
                                <label>{{ $option->name }}</label>
                                </br>
                                <select class="form-control option" name="option">
                                    <option value="">Selecione</option>
                                    @foreach($product->optionValues as $optionValue) 
                                        @if($optionValue->option_id == $option->id)
                                            <option value="{{  $optionValue->id }}">{{ $optionValue->value }}</option>
                                        @endif 
                                    @endforeach
                                </select>
                            @endforeach
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-12 offset-lg-8">
                            <h3 class="card-text mt-5">R$ {{ number_format($product->price, 2, ',', '.') }}</h3>
                        </div>
                        <div class="col-12 offset-lg-6">
                            <a id="add-cart" href="{{ route('site.add.cart', $product) }}" class="btn btn-danger mt-5">Adicionar ao Carrinho</a>
                        </div>
                    </div>
                </div>
                <div class="col-lg-12">
                    <div class="ml-3 mt-5 mb-5">
                        <h4 class="card-title">Descrição</h4>
                        <p class="card-text">{!! $product->description !!}</p>
                    </div>
                </div>
                <div class="col-lg-12">
                    <div class="ml-3 mt-5 mb-5">
                        <h4 class="card-title">Atributos</h4>
                        @foreach($product->attributes as $attribute)
                        <p class="card-text">{{ $attribute->name }}: {{ $attribute->value }}</p>
                        @endforeach
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

<script>
$("#add-cart").click(function(event) {
    $(".option").each(function(i, v) {
        if($(this).val() == '') {
            event.preventDefault();
            $(this).addClass("parsley-error");
            $(".select-option").append('<ul class="parsley-errors-list filled" id="parsley-id-10"><li class="parsley-required">Campo obrigatório.</li></ul>');
        } else {
            $(this).removeClass("parsley-error");
        }
    });
}); 
</script>

    
asked by anonymous 17.01.2018 / 18:20

1 answer

3

Change the script:

$("#add-cart").click(function(event) {
    $(".option").each(function(i, v) {
        if($(this).val() == '') {
            event.preventDefault();
            $(this).addClass("parsley-error");
            $(".select-option").append('<ul class="parsley-errors-list filled" id="parsley-id-10"><li class="parsley-required">Campo obrigatório.</li></ul>');
        } else {
            $(this).removeClass("parsley-error");
        }
    });
});

For this:

$("#add-cart").click(function(event) {
   $("ul.parsley-errors-list").remove();
    $(".option").each(function(i, v) {
        if($(this).val() == '') {
            event.preventDefault();
            $(this).addClass("parsley-error")
            .after('<ul class="parsley-errors-list filled" id="parsley-id-10"><li class="parsley-required">Campo obrigatório.</li></ul>');
        } else {
            $(this).removeClass("parsley-error");
        }
    });
});

Instead of using .append , use .after . With .append you are trying to insert the element in select . Before the .each loop, remove all error messages with $("ul.parsley-errors-list").remove(); for revalidation.

It was also necessary to change $(".select-option") by $(this) by referring to the loop element.

Example:

$("#add-cart").click(function(event) {
   $("ul.parsley-errors-list").remove();
    $(".option").each(function(i, v) {
        if($(this).val() == '') {
            event.preventDefault();
            $(this).addClass("parsley-error")
            .after('<ul class="parsley-errors-list filled" id="parsley-id-10"><li class="parsley-required">Campo obrigatório.</li></ul>');
        } else {
            $(this).removeClass("parsley-error");
        }
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><linkrel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>

<div class="pages-header">
<div class="container">
    <h1 class="text-center pages-title">{{ $product->name }}</h1>
</div>
</div>
<div class="container">
<section>
    <div class="row">
        <div class="col-lg-3">
        <aside>
            <ul class="list-group pt-5 pb-5">
                <h5 class="text-uppercase font-weight-bold">Categorias</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($productCategories as $productCategory)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                        <a href="{{ route('site.product.category', $productCategory) }}">{{ $productCategory->name }}</a>   
                        <span class="badge badge-secondary badge-pill">{{ $productCategory->products->count() }}</span>
                    </li>
                @endforeach
                <h5 class="text-uppercase font-weight-bold pt-5">Subcategorias</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($subcategories as $subcategory)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                        <a href="{{ route('site.product.subcategory', $subcategory) }}">{{ $subcategory->name }}</a>  
                        <span class="badge badge-secondary badge-pill">{{ $subcategory->products->count() }}</span>
                    </li>
                @endforeach
                <h5 class="text-uppercase font-weight-bold pt-5">Marcas</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($brands as $brand)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                        <a href="{{ route('site.product.brand', $brand) }}">{{ $brand->name }}</a>  
                        <span class="badge badge-secondary badge-pill">{{ $brand->products->count() }}</span>
                    </li>
                @endforeach
                <h5 class="text-uppercase font-weight-bold pt-5">Opções</h5>
                <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products">
                    <a href="{{ route('site.products') }}">Todos</a>   
                    <span class="badge badge-secondary badge-pill">{{ $productsCount }}</span>
                </li>
                @foreach($options as $option)
                    <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products font-weight-bold">
                        <p class="mb-0">{{ $option->name }}</p>  
                    </li>
                    @foreach($option->optionValues as $optionValue)
                        <li class="list-group-item d-flex justify-content-between align-items-center list-aside-products ml-3">
                            <a href="{{ route('site.product.option.value', $optionValue) }}">{{ $optionValue->value }}</a> 
                            <span class="badge badge-secondary badge-pill">{{ $optionValue->products->count() }}</span>
                        </li>
                    @endforeach 
                @endforeach
            </ul>
        </aside>
        </div>
        <div class="col-lg-9 mt-5">
            <div class="row">
                <div class="col-lg-6">
                    @foreach($product->images as $image)
                    <img src="{{ asset('storage/' . $image->name) }}" class="img-fluid" alt="Responsive image"> @break @endforeach
                    <div class="row">
                        @foreach($product->images as $image)
                        <div class="col-4 mt-5">
                            <img src="{{ asset('storage/' . $image->name) }}" class="img-fluid" alt="Responsive image">
                        </div>
                        @endforeach
                    </div>
                </div>
                <div class="col-lg-6">
                    <div class="row">
                        <div class="col-12 select-option">
                            @foreach($product->options as $option)
                                <label>{{ $option->name }}</label>
                                </br>
                                <select class="form-control option" name="option">
                                    <option value="">Selecione</option>
                                    @foreach($product->optionValues as $optionValue) 
                                        @if($optionValue->option_id == $option->id)
                                            <option value="{{  $optionValue->id }}">{{ $optionValue->value }}</option>
                                        @endif 
                                    @endforeach
                                </select>
                                <select class="form-control option" name="option">
                                    <option value="">Selecione</option>
                                    @foreach($product->optionValues as $optionValue) 
                                        @if($optionValue->option_id == $option->id)
                                            <option value="{{  $optionValue->id }}">{{ $optionValue->value }}</option>
                                        @endif 
                                    @endforeach
                                </select>
                            @endforeach
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-12 offset-lg-8">
                            <h3 class="card-text mt-5">R$ {{ number_format($product->price, 2, ',', '.') }}</h3>
                        </div>
                        <div class="col-12 offset-lg-6">
                            <a id="add-cart" href="{{ route('site.add.cart', $product) }}" class="btn btn-danger mt-5">Adicionar ao Carrinho</a>
                        </div>
                    </div>
                </div>
                <div class="col-lg-12">
                    <div class="ml-3 mt-5 mb-5">
                        <h4 class="card-title">Descrição</h4>
                        <p class="card-text">{!! $product->description !!}</p>
                    </div>
                </div>
                <div class="col-lg-12">
                    <div class="ml-3 mt-5 mb-5">
                        <h4 class="card-title">Atributos</h4>
                        @foreach($product->attributes as $attribute)
                        <p class="card-text">{{ $attribute->name }}: {{ $attribute->value }}</p>
                        @endforeach
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>
    
30.01.2018 / 16:34