How to validate textbox using reactive form validation - angular5

I have created custom text component for textbox and i am trying to validate by reactive form validation but not working.
Getting Error:
ERROR
Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup
directive and pass it an existing FormGroup instance (you can create one in your class).
Anyone can help to resolve this issue?
https://stackblitz.com/edit/angular-6-reactive-form-validation-9pu6hq?file=app%2Fapp.component.html
app.component.html:
<app-textbox formControlName="password"></app-textbox>
app.component.ts:
this.registerForm = this.formBuilder.group({
firstName: ['', Validators.required],
password: ['', [Validators.required, Validators.minLength(6)]]
});

You need to put the app-textbox in between a form element that is assigned to the form group:
<form [group]="registerForm">
<app-textbox formControlName="password"></app-textbox>
</form>

Related

Vee Validate validation too aggressive

I have a form where I use vee validate to validate it, the thing is, whenever I click on an input and then click somewhere else the error triggers, how can I make the error only to trigger after something has been typed in?
Form(#submit="handleSubmit" :validation-schema="schema" v-slot="{ errors }")
.pb-2.pt-4
Field#email.border-none.text-black.shadow-lg(type='email' as="input" name='email' placeholder='Email' v-model="email")
span.text-red-500(v-if="errors.email") Email too short
const schema = yup.object().shape({
email: yup.string().required().min(3),
nick: yup.string().required().min(4),
password: yup.string().required().min(6),
});

Vue recognize text pattern and replace by href to correct resource

I'm working on a project where I keep a log of key actions by users. For example a log entry is made when a user logs in to the application. I use a Laravel API as backend that takes care of the logging the event in the database and takes care of retrieving log entries to be displayed in the application. An example of a log entry returned for display is the following:
{{user|123|"John Doe"}} logged in at 2020-01-03 11:00:05
Now, I'd like Vue to automatically recognize that this should be replaced by the following:
<router-link to="/user/123">John Doe</router-link> logged in at 2020-01-03 11:00:05
So it automatically becomes a clickable link that navigates to the user profile in this case.
Does Vue offer any such functionality? Any ideas on how to approach this?
Thanks!
Yes, you can bind to to a computed property that will build the path string or data property (then you need to save the builded path in a data section when receving your response):
Template:
<router-link :to="path">{{userName}}</router-link>
script:
export default {
data() {
return {
path: '',
userName: ''
}
},
// OR
computed: {
path() {
<build your path from entry variable>
return <your builded path>
},
userName() {
<extract your user name>
return <extracted user name>
}
}
}
<div v-for="user in users" :key="user.id">
<router-link :to="user.path">{{user.name}}</router-link>
logged in at {{ user.loginTime }}
</div>
I think I will use a v-for to do this, I am wondering what data you got from your Ajax api ?

Custom widget js doesn't recognize template from qweb

I try to test custom widget from js reference and I get error in debugger:
Error: QWeb2: Template 'some.template' not found
qweb.xml was properly set in manifest, because when I extend ListController and use another template, it works correctly.
Here is template definition, which I use in qweb.xml:
<?xml version="1.0" encoding="UTF-8"?>
<template>
<div t-name="some.template">
<span class="val"><t t-esc="widget.count"/></span>
<button>Increment</button>
</div>
</template>
I tried to change <template> -> <templates>, totally removed tag "template" but still get the same error message.
JS:
odoo.define('working.test', function (require) {
var Widget = require('web.Widget');
var Counter = Widget.extend({
template: 'some.template',
events: {
'click button': '_onClick',
},
init: function (parent, value) {
this._super(parent);
this.count = value;
},
_onClick: function () {
this.count++;
this.$('.val').text(this.count);
},
});
// Create the instance
var counter = new Counter(this, 4);
// Render and insert into DOM
counter.appendTo(".o_nocontent_help");
})
Manifest:
# -*- coding: utf-8 -*-
{
'name': "testwidget",
'summary': """
Short (1 phrase/line) summary of the module's purpose, used as
subtitle on modules listing or apps.openerp.com""",
'description': """
Long description of module's purpose
""",
'author': "My Company",
'website': "http://www.yourcompany.com",
# Categories can be used to filter modules in modules listing
# Check https://github.com/odoo/odoo/blob/12.0/odoo/addons/base/data/ir_module_category_data.xml
# for the full list
'category': 'Uncategorized',
'version': '0.1',
# any module necessary for this one to work correctly
'depends': ['base'],
'qweb': ['static/qweb.xml'],
# always loaded
'data': [
# 'security/ir.model.access.csv',
'views/views.xml',
'views/web_asset.xml',
],
# only loaded in demonstration mode
'demo': [
'demo/demo.xml',
],
}
Any idea how I need to modify this template to make the widget working correctly and in which table in db odoo stores these templates?
I was running into this same issue and needed to put my QWeb code into static/src/xml/base.xml in order for Odoo to recognize it.
You can check to see if Odoo is loading the QWeb by going to this URL on your Odoo instance:
<odoo_instance>/web/webclient/qweb?mods=<my_module_name>
Such as:
localhost:8069/web/webclient/qweb?mods=test
For comparison, you can see a successful output by using mods=web to load the QWeb assets for the web module.
You can try changing
'qweb': ['static/qweb.xml'],
to
'qweb': ['static/*.xml'],
It happens with me sometimes, by specifying static xml file name, it does not render that template. But by just loading all .xml files by using *, templates are loaded.
To solve this issue I used as workaround Widget.xmlDependencies:
xmlDependencies: ['/test/static/qweb.xml']
but the main reason I think was cache in PyCharm which I didn't invalidate.
After having done some code reading, IMO, I realized the official documentation might not have pointed out clearly how to use templates in frontend.
To summarize my understanding:
The 'qweb' field in manifest is mainly designed for webclient (i.e. the backoffice), not the website. When entering webclient, a request to /web/webclient/qweb is made to retrieve all the templates of installed modules.
In order to use templates in website (i.e. frontend), synchronous and asynchronous ways both exist.
Synchronous way: Use qweb.add_template. When parameter is template content itself or a DOM node, template is loaded in a synchronous way. (While param is a URL, then it fires up an ajax request to server to fetch content.)
qweb.add_template is mentioned in https://www.odoo.com/documentation/13.0/reference/qweb.html
Asynchronous way:
Use ajax.loadXML which you can use anywhere you want to start loading template from a URL.
Use xmlDependencies which you specify in widget definition. And if you dig into the code in widget.js, you can see ajax.loadXML is being used in willStart.
There are discussions regarding qweb.add_template vs ajax.loadXML
See https://github.com/OCA/pylint-odoo/issues/186 and https://github.com/odoo/odoo/issues/20821
FYI.
I guess you may need to make sure that the js definition refers to the module name correctly
odoo.define('MODULE TECHNICAL NAME SHOULD BE HERE.test', function (require) {});
you should also register your js function with something like:
core.action_registry.add("module_name.name", Widget_Extend);
for more info https://www.odoo.com/documentation/11.0/reference/javascript_reference.html#registries
In Odoo 14 make sure
dashboard.js
odoo.define('library_managment.dashboard', function(require) {
"use strict";
// alert("hello odoo...............")
console.log("Hello My Module........!!")
var widgetRegistry = require('web.widget_registry');
var Widget = require('web.Widget');
var Counter = Widget.extend({
template: 'library_managment.template',
xmlDependencies: ['/library_managment/static/src/xml/template.xml'],
events: {
'click button': '_onClick',
},
init: function (parent, value) {
this._super(parent);
this.count = 4*9+5;
console.log("parent is", parent)
console.log("counter is..", this.count)
},
_onClick: function () {
this.count++;
this.$('.val').text(this.count);
},
});
widgetRegistry.add('library_counter', Counter);
return Counter;
});
template.xml
add this
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<div t-name="library_managment.template">
<span class="val">
<t t-esc="widget.count"/>
</span>
<button class="bg-danger">Increment</button>
</div>
</odoo>
then add js file in assets.xml inside youe views
<odoo>
<template id="assets_backend" name="Library assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/library_managment/static/src/js/dashboard.js"></script>
</xpath>
</template>
</odoo>
then add in manifest like this:
'js': ['/static/src/js/dashboard.js'],
'qweb': ['/static/src/xml/template.xml']
then inside form view add this line
<widget="library_counter"/>
I had the same problem but with "hr_org_chart" template idk why everything works fine in another computer but in mine it returned this problem, I solved it by installing this module hr-org-chart

Add custom errors to vee validator(ErrorBag)

Is it possible to add custom errors into the ErrorBag
I am using nuxtjs. i have registered vee-validate into my plugin via nuxt.config.js
It works fine However
I want to use the same error code within the template
ex:
<template>
<div v-if="errors.all().length>0">
//loop through
</div>
</template>
i am using axios to fetch user information.
if the request doesnt return my expected data set. i was thinking i could simply
this.errors.push('this is my error message') //-> or some variant of this
When i do this i get that this.errors.push is not a function
I know that
this.errors = ErrorBag{ __ob__: Observer} //-> has items and a vmId attributes
If i amend the code to push onto ErrorBag i get push of undefined
It is documented in the API of ErrorBag. You can add custom messages such as:
// For example, you may want to add an error related to authentication:
errors.add({
field: 'auth',
msg: 'Wrong Credentials'
});
Check the documentation here for more info: https://vee-validate.logaretm.com/v2/api/errorbag.html

Vue.js form file input Error in event handler

I am trying to upload a file in my form using the bootstrap-vue form file component
template
<b-form-group id="userInputGroup8" label="User Picture:">
<b-form-file id="userPictureInput" ref="fileinput" #input="userPictureSelected" v-model="userPictureFile" choose-label="Select" accept=".jpg, .png"></b-form-file>
<br> Selected file : {{ userPictureFile.name }}
</b-form-group>
Once the file is selected , the name is displayed in the browser, but it does not appear in the input field, and even if the userPictureSelected method is fired, I don't get its value in the console
script
data () {
return {
...
userPictureFile: '',
}
},
methods: _.extend({}, mapActions(['createUser']), {
userPictureSelected: () => {
console.log('Selected: ', this.userPictureFile.name)
}
}
I get the error
[Vue warn]: Error in event handler for "input": "TypeError: _this2.userPictureFile is undefined"
What could be wrong ? where can I get a good and recent example for uploading such file into my server backend static files directory ?
thanks for update
seems to be an issue not yet solved with bootstrap-vue
Custom input file after choice file nothing change.