How can I inject a Vuetify form from a database into a template? - forms

Apologies if this has been answered elsewhere, I have searched but not found anything as of yet.
I have a v-form stored in a database that I wish to pull back and display on a page. However, when I do so the form is not being rendered correctly. It remains as Vuetify template code and is not converted to HTML.
The form looks like this:
<v-form>
<v-container>
<v-row>
<v-col>
<div class="text-h4">Form 1</div>
</v-col>
</v-row>
<v-row>
<v-col
cols="12"
md="6"
>
<v-text-field
:counter="255"
label="Customer ID"
required
></v-text-field>
</v-col>
<v-col
cols="12"
md="6"
>
<v-text-field
label="Amount"
></v-text-field>
</v-col>
<v-col class="text-right">
<v-btn
#click="submitForm"
>
Submit
</v-btn>
</v-col>
</v-row>
</v-container>
</v-form>
I did come across a render function, but I've either not used it correctly or it is not have the desired effect - I'm a newbie at this so it may well be something simple!
The above form is pulled back from the database using axios, and the request happens in the created() function on the page where I wish to display it, using mapGetters() to grab it from the store and v-html in a v-card to show it.
Any help on this would be much appreciated.
Thanks for your time people!

How can I inject a Vuetify form from a database into a template?
You can't.
v-html docs
Updates the element’s innerHTML. Note that the contents are inserted as plain HTML - they will not be compiled as Vue templates. If you find yourself trying to compose templates using v-html, try to rethink the solution by using components instead
Another note from docs
Note that you cannot use v-html to compose template partials, because Vue is not a string-based templating engine. Instead, components are preferred as the fundamental unit for UI reuse and composition.
So in short, you cannot insert any partial template into a template of a component at runtime.
But you can create component at runtime and use it as dynamic component
const vm = new Vue({
el: '#app',
data() {
return {
downloadedTemplate: '<div> Hello </div>', // pretend this was downloaded from the server
}
},
computed: {
myDynamicComponent() {
return Vue.component('myDynamicComponent', {
template: this.downloadedTemplate
})
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<component :is="myDynamicComponent" />
</div>
Note that to do this, you must use Vue distribution which includes the template compiler
I don`t know about your particular use case, but unless you are working with tens of different forms, storing templates in database sounds like a sub-optimal strategy - a lot of unnecessary work and hard to mainain

Related

Vue.js: Is there a way to have #submit.prevent on all the forms of a project?

I'm realizing there are some snippets that I'm repeating everytime, and sometimes I forget.
One of them is the #submit.prevent. In all forms I have to write it for preventing to submit, I'll always manage the submission through a vue method.
So can I do something that all forms have this instruction implicitly?
You can create a simple (probably functional) component and use this instead of the normal <form>.
// BaseForm.vue
<template>
<form #submit.prevent="onSubmit">
<slot />
</form>
</template>
<script>
export default {
props: {
onSubmit: {
type: Function,
required: true,
}
}
}
</script>
You won't really save a lot of code, but you won't have to think about it anymore. You could include the basic <button type=submit></button> in here as well.

How to use onclick method inside AEM component

Am having a AEM6 html component, am getting the values from dialog and using it inside the component via the .js file and using the return properties.
I could able to get the authored values but it is getting null or empty when am using it inside the onclick method. Please find below the code snippet below.
<div data-sly-unwrap data-sly-use.test="test.js"></div>
<a href="#" class="${test.testId}" id="${test.testId}" onClick="toggleDraw('${test.testId}')" >
The content I authored is getting displayed in class and Id, but it is not displaying in the onClick method.
Below is the Output am getting after authoring.
<a href="#" class="get-a-quote" id="get-a-quote" onClick="toggleDraw('')" >
Output I needed is :
<a href="#" class="get-a-quote" id="get-a-quote" onClick="toggleDraw('get-a-quote')" >
This should do the trick:
<a data-sly-test.variable123="toggleDraw('${test.testId}')" href="#" class="${test.testId}" id="${test.testId}" onclick="${variable123 # context='attribute'}" >
You need to put the function call in a variable because of the nested single quotes. And you need to manually set the context in this case. If "attribute" does some escaping you do not like, you could use "unsafe" - this will end in all escaping mechanisms being disabled. That might or might not be a security issue for your application.
HTH

Forms in reactjs with flux

I have a form, this form needs to post some data to my backend. With flux, what is the best practice for doing this, use a store?
My issue with using a store is that I have a sub component inside of my form that allows me to select a number 1-5 with buttons. I wanted that component to be reusable, but if i use a store, I have to hard code the store into the child component which means I cant really use it elsewhere. Instead do I just set the parent state from the child?
If anyone can point out some good tutorials or examples of react/flux forms let me know.
In my opinion any back end interaction should be done by using actions, but...
if you want to use store anyway then you can create additional attribute (prop) in your sub-component which will be a function (f.e. onChange) which should be passed from parent component as prop (this function should set data in store). Then you can reuse this component, because only parent needs to have access to store.
So in subcomponent:
onButtonClick(e) {
this.state.value = e.target.value;
if (this.props.onChange) this.props.onChange(e.target.value);
}
<div>
<button onClick={this.onButtonClick.bind(this)} value="1">1</button>
<button onClick={this.onButtonClick.bind(this)} value="2">2</button>
<button onClick={this.onButtonClick.bind(this)} value="3">3</button>
<button onClick={this.onButtonClick.bind(this)} value="4">4</button>
<button onClick={this.onButtonClick.bind(this)} value="5">5</button>
</div>
and in parent:
setMyStoreState(value) {
store.setNumber(value);
}
<Subcomponent onChange={this.setStoreState.bind(this)} />
or something like this.
Code not tested, but you should get the idea.

Bootstrap validator form plugin: how to change feedback icons

The bootstrap validator plugin helps validating the form fields providing a bunch of cool features. One of those features are the feedback icons, which defaults to glyphicon.
Suppose I want to replace glyphicon with font awesome.
The documentation says they can be changed by passing a "feedback" JSON object as data attribute or via JavaScript.
Via JavaScript it's easy. But as data attribute, it is unclear where and how exactly add it, because simply adding:
feedback: {
success: 'fa-check',
error: 'fa-times'
}
as data attribute to the <form> or the <div class="form-group"> or the <input> itself it doesn't work.
After some time struggling with it, I realized that the JSON feedback object should be added to the element and also it needs to be added using this syntax (which was not specified in the docs):
<form ... data-feedback='{"success": "fa-check", "error": "fa-times"}'>
Note the quotes syntax.
Also, if we are not just changing the glyphicon but replacing it with a font-awesome one (like in my example), in the <div class="form-group"> we need to replace:
<span class="glyphicon form-control-feedback" aria-hidden="true"></span>
with:
<span class="fa form-control-feedback" aria-hidden="true"></span>
This is not very well documented, and I could not make it work. I ended up using a different form validator which accomplish the same functionality and it's easier to configure success/error formats using bootstrap classes:
var validator = $('#submitForm').validate({
validClass: "is-valid",
errorClass: "is-invalid",
jQuery Validator

Create repeatable custom form fields in web2py?

I want to create twitter bootstrap compliant form. According to the docs for Twitter Bootstrap v2.2.2 (the version included with web2py) the html should look like:
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="inputEmail">Email</label>
<div class="controls">
<input type="text" id="inputEmail" placeholder="Email">
</div>
</div>
...
I'm currently using SQLFORM which outputs html that doesn't really fit with this (even using formstyle='divs'). Besides I want my html output to be clean without web2py artifacts such as class="w2p_fl". So my thought is to use a custom form. However in doing this there would be a lot of repeated code. That is, the following would basically need to be repeated for each field.
{{=form.custom.begin}}
<div class="control-group">
{{=LABEL(form.custom.label['myfield'], _class='control-label',
_for='mytable_myfield')}}
<div class="controls">{{=form.custom.widget.myfield}}</div>
</div>
...
{{=form.custom.end}}
So how can I repeat the above unit of code so I could replace it with something like {{=bootstrap_field(db.mytable.myfield)}} or some other way to adhere to DRY?
What is the web2py way to do this? Create a view function? Pass a function in the dictionary returned by the controller? Create my own html helper? Create my own widget? Another way?
If you're using Bootstrap 2, you can just do:
form = SQLFORM(..., formstyle='bootstrap')
For Bootstrap 3 (or any other custom formstyle you'd like to create), the formstyle argument can be a function (or other callable) that produces the form DOM. The function will be passed the form and a fields object, which is a list of tuples, with each tuple containing a CSS id, label, input element, and (possibly empty) comment/help text. To get an idea of what such a function should look like, check out the one used for Bootstrap 2 forms.