ngx- date picker not showing in angular6 form - ngx-bootstrap

I am trying to import the ngx Bootstrap datepicker in my Angular6 Application for that I followed the following steps
to npm install ngx-bootstrap
npm install ngx-bootstrap --save
Installed bootstrap 4
npm install bootstrap#4 --save
In angular.json file and specify the path to the Bootstrap stylesheet (bootstrap.min.css) in the styles property
"styles": [
"src/styles.css",
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"node_modules/ngx-bootstrap/datepicker/bs-datepicker.css"
],
For Using ngx-bootstrap datepicker in Angular :
In app.module.ts file, imported BsDatepickerModule
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import {FormsModule, ReactiveFormsModule} from '#angular/forms';
import { FormGroup } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StudentParentRegistrationComponent } from './student-parent-registration/student-parent-registration.component';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
#NgModule({
declarations: [
AppComponent,
StudentParentRegistrationComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
BsDatepickerModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
html file
<nav class="navbar navbar-expand-lg">Header
</nav>
<div class="container">
<h2 class="text-center">Registration</h2>
<h3>Student Registration</h3>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="usn" class="control-label">USN</label>
<input type="usn" class="form-control" id="usn" name="usn" placeholder="USN">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="firstName" class="control-label">First Name</label>
<input type="firstName" class="form-control" id="firstName" name="firstName" placeholder="FirstName">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="dateOfBirth" class="control-label">Date Of Birth</label>
<input type="text" class="form-control" id="dateOfBirth" name="dateOfBirth" bsDatePicker [(ngModel)]="dateOfBirth" placeholder="DateOfBirth">
</div>
</div>
</div>
</div>
<div class="card-footer">
footer
</div>
After following these steps, date picker not showing. Anybody please help me to solve this.

you need to call the show method.
you can call it directly in the template like so:
<input type="text" class="form-control" id="dateOfBirth" name="dateOfBirth" bsDatePicker #dp="bsDatepicker" [(ngModel)]="dateOfBirth" placeholder="DateOfBirth">
// call the dp.show() method either by attaching the click event on the input or add a button alongside it
Alternatively inject it in the component or service and call the method within

Related

How to send props in Vue

I am quite new in vue so I haven't understood the logic completely. My question is I have ticket and ticketlist components. So I am not on my ticket list component I am creating some tickets data and I want to show them according to the ticket component. To make it more clear here is my ticketlist component:
<template>
<section class="tickets">
<div class="container">
<div class="row">
<div class="col-12 col-md-3 mb-3">
<Ticket v-for="ticket in tickets" :key="ticket.id" :product="ticket"/>
</div>
</div>
</div>
</section>
</template>
<script>
import Ticket from './Ticket'
export default {
components: {
Ticket
},
data() {
return {
tickets: [
{
id: 0,
category: "Einzelkarte",
price: "€3,50",
tariff: [
"Wählen Sie eine Option",
"Erwachsene",
"Erwachsener erm.",
"Kinder / Jugendliche",
"Kinder / Jugendliche erm.",
],
available_amount: 23,
article_number: "2021.05.04-2673990197-1",
},
],
};
},
}
</script>
And also ticket component:
<template>
<widget type="ticket" class="--flex-column">
<div class="top --flex-column">
<div class="bandname -bold">Ghost Mice</div>
<div class="tourname">Home Tour</div>
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/199011/concert.png" alt="" />
<div class="deetz --flex-row-j!sb">
<div class="event --flex-column">
<div class="date">3rd March 2017</div>
<div class="location -bold">Bloomington, Indiana</div>
</div>
<div class="price --flex-column">
<div class="label">Price</div>
<div class="cost -bold">€{{ ticket.price }}</div>
</div>
</div>
</div>
<div class="rip"></div>
<div class="bottom --flex-row-j!sb">
<a class="btn button" href="#">ADD TO CART</a>
</div>
</widget>
</template>
<script>
export default {
props: ['ticket'],
}
</script>
<style scoped>
#import 'https://i.koya.io/flex/1.1.0.css';
*, ::after, ::before {
box-sizing: unset;
}
</style>
So, I am showing TicketList component in one of the page but the thing is it doesnt show anything. So I wonder how can I connect them together and show tickets data according to ticket component. I hope I am clear but if I am not I can answer you in the comments.
The probleme is the props name, you need to pass ticket as props and not product
...
<Ticket v-for="ticket in tickets" :key="ticket.id" :ticket="ticket"/>
...
or the contrary inside you Ticket component set :
props: ['product']

PrimeVue Toast displaying html tags

How can I implement displaying a link in a primevue toast message? I cannot use v-html directive and triple brackets do not work. Does anybody has another idea how to solve it?
A hacky way is to extends Toast component:
Here a codesandbox : https://codesandbox.io/s/extend-primevue-toast-o5o1c?file=/src/CustomToastMessage.vue
1. On your component
Import your custom toast component where you need to call this.$toast:
<template>
<div>
<CustomToast />
<CustomToast position="top-left" group="tl" />
<CustomToast position="bottom-left" group="bl" />
<CustomToast position="bottom-right" group="br" />
<div class="card">
<Button #click="test" label="test" />
</div>
</div>
</template>
<script>
import CustomToast from "./CustomToast.vue";
export default {
components: {
CustomToast,
},
data() {
return {
messages: [],
};
},
methods: {
test() {
this.$toast.add({
severity: "success",
summary: "Test",
detail: "<b>Test Bold</b>",
});
},
},
};
</script>
2. CustomToast.vue (extend primevue toast)
<template>
<Teleport to="body">
<div ref="container" :class="containerClass" v-bind="$attrs">
<transition-group name="p-toast-message" tag="div" #enter="onEnter">
<CustomToastMessage
v-for="msg of messages"
:key="msg.id"
:message="msg"
#close="remove($event)"
/>
</transition-group>
</div>
</Teleport>
</template>
<script>
import Toast from "primevue/toast/Toast.vue";
import CustomToastMessage from "./CustomToastMessage.vue";
export default {
extends: Toast,
components: {
CustomToastMessage,
},
};
</script>
3. CustomToastMessage (extend primevue toastmessage)
Add v-html where you want to have html
<template>
<div
:class="containerClass"
role="alert"
aria-live="assertive"
aria-atomic="true"
>
<div class="p-toast-message-content">
<span :class="iconClass"></span>
<div class="p-toast-message-text">
<span class="p-toast-summary">{{ message.summary }}</span>
<div class="p-toast-detail" v-html="message.detail"></div>
</div>
<button
class="p-toast-icon-close p-link"
#click="onCloseClick"
v-if="message.closable !== false"
type="button"
v-ripple
>
<span class="p-toast-icon-close-icon pi pi-times"></span>
</button>
</div>
</div>
</template>
<script>
import ToastMessage from "primevue/toast/ToastMessage.vue";
export default {
extends: ToastMessage,
};
</script>
There is an easiest solution.
Just implement your own template.
Example:
<Toast :position="toastPosition">
<template #message="slotProps">
<span :class="iconClass"></span>
<div class="p-toast-message-text">
<span class="p-toast-summary">{{slotProps.message.summary}}</span>
<div class="p-toast-detail" v-html="slotProps.message.detail" />
</div>
</template>
</Toast>

Test a form which used veevalidate on that form

i using vee-validate version 3.0.11 for validate my form like below
<validation-observer v-slot="{ invalid }" slim>
<validation-provider rules="required" v-slot="{ errors, dirty, invalid}" slim>
<div class="form-group">
<label class="sr-only" for="txtUsername"></label>
<input
autocomplete="off"
id="txtUsername"
name="username"
type="text"
class="form-control txtUsername"
placeholder="Email or Username"
v-model="username"
v-bind:class="{ 'is-invalid': invalid && dirty,'is-valid': !invalid }" />
</div>
</validation-provider>
<validation-provider rules="required" v-slot="{ errors, dirty, invalid}" slim>
<div class="form-group">
<label class="sr-only" for="txtPassword"></label>
<input
id="txtPassword"
name="password"
type="password"
class="form-control"
placeholder="Password"
v-model="password"
v-bind:class="{ 'is-invalid': invalid && dirty,'is-valid': !invalid }" />
</div>
</validation-provider>
<div >
<button
type="button"
name="login"
class="btn btn-primary"
v-on:click="doLogin()"
:disabled="invalid">
Login
</button>
</div>
</validation-observer>
and i wrote some test with chai and mocha
in my test i need to find the button
but when i using find method for find button all html tag between validation-observer tag is not loaded in my wrapper.
my test code is:
// i change it to shallowMount to mount but problem is exist,
// mount does not render any thing between validation-observer tag
const wrapper = mount(LoginView, { sync: false });
describe('Login.vue', () => {
it('some text, () => {
console.log(wrapper.html());
// my log include all of tag except tags between the validation-observer tag
});
});
can some one tell me how i can find my button by using warraper.find(), please?
You are trying to shallow mount a component that needs to be mounted in order to render its children. If you want to ignore ValidationProvider all together you can provide a fake one as shown below.
ContactForm.vue
<template>
<div>
<ValidationProvider rules="required" name="input" v-slot="{ errors }">
<p :style="{color: 'red'}">To be, or not to be</p>
<input type="text" v-model="value">
<span id="error">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</template>
<script>
import { ValidationProvider } from "vee-validate";
export default {
name: "ContactForm",
components: {
ValidationProvider
},
data: () => ({
value: ""
})
};
</script>
ContactForm.test.js
import { shallowMount, createLocalVue } from "#vue/test-utils";
import ContactForm from "./ContactForm";
import FakeValidationProvider from "./FakeValidationProvider";
test("Test shallow mount renders what's inside validation provider", async () => {
const localVue = createLocalVue();
var wrapper = shallowMount(ContactForm, {
stubs: {
ValidationProvider: FakeValidationProvider
},
localVue
});
expect(wrapper.text()).toContain("To be, or not to be");
});
FakeValidationProvider.vue
<template>
<div v-bind="{ ...$props, ...$attrs }">
<slot :errors="errors"></slot>
</div>
</template>
<script>
export default {
name: "FakeValidationProvider",
data() {
return {
errors: []
};
}
};
</script>
Feel free to extend the slot with any other parameters you need besides errors. If you want to make those parameters dynamic as well, check out this article on rendering slots

Can't use import modules in main.js on Vue Framework

Can't install package in Vue App
I wanna use package vue-tel-input https://www.npmjs.com/package/vue-tel-input for my login form Vue but when i import and install global component I got this error:
'Uncaught SyntaxError: Unexpected identifier".
This the import code
import Vue from 'vue';
import VueTelInput from 'vue-tel-input';
Vue.use(VueTelInput);
Vue.component('js-login', {
template: `
<div>
<div class="js-login-wrap">
<form class="js-login">
<h2 class="js-login-heading">Login to Loket</h2>
<label for="name">Name</label>
<input type="text" id="field_name" class="form-control" placeholder="Name" required autofocus>
<label for="email">Email</label>
<input type="email" id="field_email" class="form-control" placeholder="Email" required autofocus>
</form>
</div>
</div>`,
})
new Vue({
el: '#app',
})
My directory:
enter image description here
What should i do?
As mentioned in their docs:
'ESM for browsers (2.6+ only): intended for direct imports in modern browsers via .' reference
So try to add type="module" to your main.js:
<script type="module" src="main.js"></script>

How to use dynamic component loader to instantiate a child component on a click?

I am using angular2.0.0-beta.15. Basically I am trying to load a modal window on click of a button in header. I have put template for modal in an html.What I am trying is, on click of button in parent component, a parameter which indicates which button is pressed, is passed to child component. Based on that I am getting data of modal from db and putting that in modal window.Below is the piece of code.
parent.html
<modal-child id="ContactModal"></modal-child>
<-- code goes here-->
<li [style.display]="!showContact?'none':'inherit'"><a (click)="getContact()" data-remote="false"
data-toggle="modal" data-target="#ContactModal"><i class="fa fa-question"></i>Contact</a></li>
<-- code goes here-->
parent.component.ts
import {Component, Input, provide, DynamicComponentLoader, Injector} from 'angular2/core';
import {ModalChildComponent} from './modal.child.component';
export class ParentComponent{
private id: string;
constructor(private dcl: DynamicComponentLoader, private injector: Injector) {}
getContact() {
this.id = 'Contact';
this.dcl.loadAsRoot(ModalChildComponent, '#ContactModal', this.injector);
}
}
modal.child.component
import {Component, Input} from 'angular2/core';
import {UserService} from '../services/data-services.service';
#Component({
selector: 'modal-child',
templateUrl: './views/templates/modalTemplate.html'
})
export class ModalComponent {
#Input('id') modalId: string;
private contactData: string;
constructor(private _dataService: DataService) {
console.log('id:' + this.modalId);
if (this.modalId === 'Contact') {
this.getContactData();
}
}
getContactData() {
this._dataService.getContact().subscribe(data => {
console.log('contact:' + data);
this.contactData = data;
});
}
}
modalTemplate.html
<!-- Contact -->
<div id="ContactModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content -->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Contact</h4>
</div>
<div class="modal-body">
<div [innerHTML]="contactData"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
When i try above code, it gives me exception like 'Unexpected directive value '[object Object]' on the View of component 'ParentComponent'. Can somebody guide me?