Validate array of inputs with Vee-Validate (Vuejs) - vue.js

The following works:
<li :key="index" v-for="(...) in items">
<input type="text" name="itemFields[]" v-validate="required">
</li>
// ...
<div class="vv-errors">
<ul>
// shows only for last active input
<li v-for="error in errors.collect('itemFields[]')">{{ error }}</li>
</ul>
</div>
If I make some input empty, it shows an error message. But if I then fill some other empty input with text, the error message disappears completely. That should not be the case, because the other input is still empty. To summarize, the error messages only consider the last active input.
How to achieve that the error message shows up if at least one of the inputs is empty?

Actually the issue you are facing is because the name field is same for all your inputs and that should be unique.
Hence while using v-for you could do something as below :
<div v-for="i in 5" >
<input type="text" :name="'email'+i" placeholder="Email" v-validate="'required|email'">
<span class="error" v-if="errors.has('email'+i)">{{errors.first('email'+i)}}
</span>
</div>
Here is a basic example to solve your problem.

Related

How to show vee-validate errors in custom tooltips?

In vuejs 2 app using vee-validate ^3.4.14 I have several inputs on modal form of fixed height.
On validation errors I got validation error messages below of inputs, as I have layout like :
<div class="form-group">
<ValidationProvider
name="password_confirmation"
rules="required"
v-slot="{ errors }"
>
<div class="input-group">
<input type="password"
v-model="password_confirmation"
id="password_confirmation"
name="password_confirmation"
class="form-control editable_field"
placeholder="Password confirmation"
autocomplete=off
ref="password"
>
</div>
<p class="error">{{ errors[0] }}</p>
</ValidationProvider>
</div>
But these messages break layout of modal form, as height of modal form is increased and elements
on bottom of the form are hidden. If there is a way to show these errors in some other way ?
Say a) select input with “error_border” class and b) show some tooltip message near with any input with error text?
Thanks in advance!

How to Present error's using v-for and vee-validate

Quick question, I'm probably missing something.
I have some validations using vee-validate, I'm trying to present an error's after iterating over an object, but I managed to present error only on the last input field.
Here's my code:
<ValidationProvider name="integrationParams[key]" rules="required" v-slot="{ errors }" v-for="(param, key, index) in integrationParams" :key="key">
<label class="inputLabel" :for="key">Please fill in {{ key }} param</label> <span class="redStar">*</span>
<input v-model="integrationParams[key]" :id="key">
<span class="invalid-feedback">{{ errors[0] }}</span>
</ValidationProvider>
For example I have 5 fields and I managed to present an error only on the last field. what am I missing here?

Pass data from Vue loop to laravel component

I am having this issue and I can not find my way around it without duplicating lots of code.
I have an array of entries coming from an axios request. Everything will go in an ul.
If I am doing it like this, everything is ok:
resource-index.blade.php
<ul>
<li v-for="entry in entries" :key="entry.id" >
<div>
<div>
<a :href="entry.links.show">
<x-button-icon color="gray-400">
#include('partials.svg.outline-eye')
</x-button-icon>
<span class="ml-3">{{ __('View') }}</span>
</a>
</div>
<div>
<a :href="entry.links.edit">
<x-button-icon color="gray-400">
#include('partials.svg.pencil')
</x-button-icon>
<span class="ml-3">{{ __('Edit') }}</span>
</a>
</div>
</div>
</li>
</ul>
However, in case I want to try to extract some of that stuff in different components, the details I am sending from Vue no longer get passed to the component.
resource-index.blade.php
<ul>
<li v-for="entry in entries" :key="entry.id" >
<div>
<x-grid-list-item-button label="{{ __('View') }}" :href="entry.links.show">
<x-slot name="icon">
#include('partials.svg.outline-eye')
</x-slot>
</x-grid-list-item-button>
<x-grid-list-item-button label="{{ __('Edit') }}" :href="entry.links.edit">
<x-slot name="icon">
#include('partials.svg.pencil')
</x-slot>
</x-grid-list-item-button>
</div>
</li>
</ul>
And here is the grid-list-item-button.blade.php
<div>
<a href="{{ $href }}">
#if($icon)
<x-button-icon color="gray-400">
{{ $icon }}
</x-button-icon>
#endif
<span class="ml-3">{{ $label }}</span>
</a>
</div>
I already tried:
moving the href="entry.links.show" in a named slot;
passing the data with v-bind: v-bind:href="entry.links.show";
::href="entry.links.show"
Can someone please tell what am I doing wrong or at least point me in the right direction with this?
Thanks!
If I got you right: You are trying to pass data from Vue.Js to Laravel-Components. Unfortunately this is not possible. Blade gets processed on the server-side where Vue.Js is not yet available. So the variable entry.links.show do not yet exist in Laravel (only available on client-side) and therefore cannot be passed to the Laravel-Component. After the HTML got rendered by Blade and passed to the Browser, Vue.Js can pick it up and replicate your template for the v-for and generate your list. At this point your 'link'-variables get available.
Solutions:
You could extract your code to a Vue.Js-Component rather than a Laravel-Component. This would be interpreted on client-side.
An other solution would be to generate this list through Blade so you could use Laravel-Components.

Materialize: Cannot set property 'tabIndex' of null at Dropdown._makeDropdownFocusable

I am trying to test my vuejs component via jest that contains materialize select.
When performing a component test, I get the following error in materialize.js:
TypeError: Cannot set property 'tabIndex' of null at Dropdown._makeDropdownFocusable
How fix this error?
This problem can happen when the input field is not wrapped inside a div with the class input-field:
<div class="input-field">
<input type="text" class="autocomplete"></input>
</div>
Adding a div with the class "input-field might solve this problem.
use id selector instead class selector. for example call dropdown like this :
html :
<a class='dropdown-trigger' id="dropdowner" href='#' data-target='dropdown1'>Drop Me!</a>
<!-- Dropdown Structure -->
<ul id='dropdown1' class='dropdown-content'>
<li>one</li>
<li>two</li>
<li class="divider" tabindex="-1"></li>
<li>three</li>
<li><i class="material-icons">view_module</i>four</li>
<li><i class="material-icons">cloud</i>five</li>
</ul>
js:
$('#dropdowner').dropdown();
Can only be used once.
data-target="name_target" must not be repeated
Exam1.❌
<nav>
<div class="nav-wrapper">
<ul class="right hide-on-med-and-down">
<li><a class="dropdown-trigger" href="#!" data-target="name_target1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
<li><a class="dropdown-trigger" href="#!" data-target="name_target1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
</ul>
</div>
</nav>
<!-- Dropdown Structure -->
<ul id="name_target1" class="dropdown-content">
<li>one</li>
<li>two</li>
</ul>
Exam2.✔️
<nav> <div class="nav-wrapper">
Logo
<ul class="right hide-on-med-and-down">
<li><a class="dropdown-trigger" href="#!" data-target="name_target2">Dropdown<i enter code here class="material-icons right">arrow_drop_down</i></a></li>
</ul> </div> </nav> <ul id="name_target2" class="dropdown-content"> <li>one</li> <li>two</li> </ul>
When I ran into this issue I was trying to create the whole dropdown list dynamically in JS. The fix for me was creating the list and any default list elements in HTML:
<div id="select1" class=\"input-field col s12\">
<select>
<option value="" selected>Default</option>
</select>
<label>Test</label>
</div>
Then appending any dynamic values in JS:
contents.forEach(function(content) {
var buffer = "<option></option>";
var template = $(buffer);
$(template).text(content);
$("select1").find("select").append(template);
});
$("select").formSelect();
pre 1.0.0 you would use data-activates, if data-target is not specified you will get this error
My problem was, that jQuery object was not attached to the DOM yet, so inner materialise code could not init element due to inability to find element by ID:
// materializecss initing dropdown (in my case for input autocomplete), where `t` is the input element
i.id = M.getIdFromTrigger(t),
i.dropdownEl = document.getElementById(i.id),
i.$dropdownEl = h(i.dropdownEl),
M.getIdFromTrigger(t) returned some random ID (not the one I provided) and dropdownEl was inited with null, and later method _makeDropdownFocusable failed on using it `this.dropdownEl.tabIndex = 0
So my problem code looked like this:
let root = $('#root'); // root in the DOM already
let wrapper = $('<div>'); // wrapper is just created and NOT attached to the DOM yet
let input = $('<input>').appendTo(wrapper); // creating input and attaching to the wrapper, but still not in DOM
initAutocomplete(input) // M.Autocomplete.init logic here FAILS
root.append(wrapper) // too late, error above
So the quick fix is to append elements first and only than do M.Autocomplete.init
I just stumbled this issue too while using Materializecss for my Vue project. As mentioned by sajjad, using id selector instead of class works. However, this is problem for initializing multiple dropdown, since each dropdown must have unique ID.
The way I solve this is just by selecting all the elements with the '.dropdown-trigger' class, and initialize every each of those. It works for me.
$.each($('.dropdown-trigger'), function(index, value) {
$(value).dropdown();
});

Referencing v-model

I am trying to reference a v-model in one of my html files.
I've gone ahead and created a jsbin with a small example of what I'm trying to achieve:
https://jsbin.com/saqirekasa/edit?html,js,output
Essentially, what seems to be happening is that Vue gives an error like this in my actual project:
[Vue warn]: Invalid expression. Generated function body: scope.lookForUser({{scope.input_field}})
The problem (I believe) appears to be when I introduced this line:
<input type="text" class="form-control input-lg" placeholder="email-address" id = "button_email_submit" v-model = "input_field"/>
And then tried to reference the v-model 'input field' as such:
<button class="btn btn-info btn-lg" type="button" v-on= "click: lookForUser(#{{input_field}})">
Any ideas why Vue doesn't like this statement?
I figured this out with a bit more fiddling around -- the issue was I was not supposed to use #{{input_field}} but rather simply pass input_field text into the arguments.
Thanks! Here's my example code in case it helps anyone.
<div v-repeat="company: companies">
<div class="col-xs-12 col-md-6 col-lg-6">
<a href="#" v-on="click: selected_company_id = company.id">
</div>
</div>
I kept wanting to wrap the company.id in mustache brackets:
<a href="#" v-on="click: selected_company_id = {{company.id}}">
but I'm assuming that since it is already part of an expression, you don't need to do that.