VeeValidate form using data provided by API - vue.js

I went through many examples of VeeValidate forms.
All of them seem to focus only on the validation part and they use the initial-values attribute.
As far as I understand this can only use static data but in my case I use async API call in onMounted to load an object (with nested objects and arrays).
How do I populate the form with the data from API once it has been loaded?

The way that is closest to normal Vue is to use v-model directly on Field components.
The example from the docs that is most relevant is this one:
<Field type="text" name="name" v-model="name" />
Or if you need more complex fields:
<Field v-model="name" type="text" name="name" v-slot="{ field }">
<input v-bind="field">
</Field>

Related

how to access value from custom attr in vuejs

I am working on my firs Vue project with ASP.NET Core.
In this project, I have an input box and because I am using asp MVC validation. I am transferring error message from the server in the data-val-required attr.
Not I also using vuejs from clientside functionality and I want to validate the form in vuejs. Which is working fine but I want to reuse this same error message which available in data-val-required
so can anyone please tell the how to access value from custom attr in vuejs
<input type="email"
placeholder="Your_email#gmail.com"
data-val="true"
data-val-required="The Email field is required."
id="Email"
name="Email"
class="form-control">
thanks
You can use the Vuejs ref attribute.
<input type="email" ref="myInput"
placeholder="Your_email#gmail.com"
data-val="true"
data-val-required="The Email field is required."
id="Email"
name="Email"
class="form-control">
and then, to retrieve the element's attribute:
this.$refs.myInput.getAttribute("data-val-required")
You can use vm.attrs
Contains parent-scope attribute bindings (except for class and style) that are not recognized (and extracted) as props. When a component doesn’t have any declared props, this essentially contains all parent-scope bindings (except for class and style), and can be passed down to an inner component via v-bind="$attrs" - useful when creating higher-order components.

How to communicate between components and slots?

I'd like to know if it's possible to have a component communicate with a v-model within a slot?
<medical-form>
<input type="text" v-model="dob" />
</medical-form>
In this example the dob data is defined in the medical-form component. The contents of the slot are generated server side as it uses sensitive information to work out which fields should be presented, because of this I can't fully move the form into the medical-form component.
Yes you can give slot-scope and you will get the data
In your medical-form component bind your dynamic value.
<slot :dob="dob" />
<medical-form>
<template slot-scope="{dob}">
<input type="text" v-model="dob" />
</slot>
</medical-form>
But recently vue deprecated using of slot-scope but it is backward compatible and will work. However I would like to show you that also.
Reference - https://v2.vuejs.org/v2/guide/components-slots.html
<medical-form>
<template v-slot="{dob}">
<input type="text" v-model="dob" />
</template>
</medical-form>

Binding a separate model to the main layout

I am developing a web application on Asp.Net Core 2.0 MVC, there is a sign-up modal form that will be used across all pages and not being able to understand how should I do the user model binding since every page will have it's own model.
For example, there is a news page that will use the News model and while on that page, a user will want to either sign-up or sign-in (2 modal forms that are integrated in the main layout).
Below is the form section of the sign-up modal:
<form action="/Account/RegisterAccount" method="post">
#Html.AntiForgeryToken()
<div class="cfield">
<input name="username" type="text" placeholder="Username" />
</div>
<div class="cfield">
<input name="email" type="text" placeholder="E-mail address" />
</div>
<div class="cfield">
<input name="password" type="password" placeholder="Password" />
</div>
<div class="cfield">
<input type="password" placeholder="Confirm Password" />
</div>
<button type="submit">Register</button>
</form>
What I did so far is simply submitted the form data without a model, but I was thinking maybe it would be better to find a way to bind the model so I can also do the model validation.
Also, if someone could give me an advice on what is the best practice to manage the logged in user, would be a very good help.
This is my very first post here, and I am totally new at Core and MVC.
Never, never, never attach a model to a layout. Just don't. The correct approach here is a view component. Create a ViewComponents directory and add a class file like SignUpViewComponent.cs to that. In that file, you'll need something like:
public class SignUpViewComponent : ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync()
{
// set up your model
return View(model);
}
}
View components support injection, so you can follow the tradition DI pattern of adding a constructor with the params you want to inject and setting private fields on your class with those values. This allows you to easily bring in things like your context, if you need to utilize it to build your model.
Then, create the view Views\Shared\Components\SignUp\Default.cshtml. In that file you can set the model to the your sign up form model as you want, and then just add your signup form HTML, utilizing that model.
Finally, in your layout, add the following line where you want the signup form to appear:
#await Component.InvokeAsync("SignUp")
For more information on view components, refer to the documentation.

b-input name attribute not working buefy

I want to put a name="name" attribute in a buefy input control. I have so far, not managed to make it work.
<b-field label="Fullname">
<b-input
value=""
icon="face"
name="name">
</b-input>
</b-field>
It sends empty values and I get an error in laravel:
"Column 'name' cannot be null"
It worked when I tried using a native html input control.
I have also tried using developer tools to inspect the DOM, it appears, the b-input control does not have a name.
How do I solve this?
Edit:
I had vue#2.1.10 and for buefy you need 2.4, that's why I got this bug. Sorry, my bad.
Use v-model to bind your component to your data.
In your <template>...</template>:
<b-field label="Fullname">
<b-input
v-model="fullname"
icon="face">
</b-input>
</b-field>
In your <script>...</script>:
data () {
fullname: null,
//some more state...
},

Passing Form Data Between Components & Vue Routing

I am trying to create a step-by-step form using Components & Routing. If there is a better or easier approach to do this, please feel free to suggest, since I am new to Vue.js.
I have a and 3 templates.
<template id="step-1">
<h1>Welcome to Form</h1>
</template>
<template id="step-2">
<label>Name:</label>
<input type="text" name="name" v-model="name" />
<br />
<label>Email:</label>
<input type="email" name="email" v-model="email" />
</template>
<template id="step-3">
<p>Review:</p>
<!-- Display Step 2 Form Values -->
{{ name }}
{{ email }}
<button>Submit</button>
</template>
What I want to do is, display the input values on #step-3, and on a button click, submit the form via an ajax call.
You can view the Fiddle from here: https://jsfiddle.net/j7mwc9wk/
One way to do this is for all three components use the same data object. For the purposes of this bit of code it can be a simple javascript object. A bit more sophisticated approach is to use Vuex an official Vue data store.
You could also have these three components have the same parent in which case name and email would be properties of parent data method and therefore accessible to all children. I don't know how this would work with Vue router but it should be fine.