Angular2 typescript set selected dropdown button value on page load - twitter-bootstrap-3

Ref : trying to use Dropdown component https://github.com/valor-software/ng2-bootstrap/tree/development/components/dropdown
I can pull the drop down values on clicking button and persist on selection using Typescript but couldn't set the selected value on page load like we do using select option like :
<option [selected]="value.id == value.statusId">
Parent template :
<dropdownst [values]="releaseNames" [selectedReleaseId]="item.releaseId"></dropdownst>
Object : releaseName.ts
export class ReleaseName {
releaseId: number;
name: string;
}
Dropdown Component :
#Component({
selector: 'dropdownst',
template: `<div (click)="$event.preventDefault()">
<div>
<button type="button" class="btn btn-warning btn-sm" (click)="dropdownMenu($event)">
RELEASE (Toggle)
</button>
</div>
<div class="btn-group" dropdown [(isOpen)]="status.isopen">
<button id="dropdown-list" class="btn btn-default" dropdownToggle >
{{title}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="dropdown-list">
<li role="menuitem" *ngFor="let data of values">
<a class="dropdown-item" [id]="data.releaseId" #val [title]="data.name"
(click)="updatePbiRelease(val.id, val.title)" >
{{data.name}}
</a>
</li>
</ul>
</div>
</div> `,
directives: [ DropdownDirective, DropdownMenuDirective, DropdownToggleDirective, CORE_DIRECTIVES],
styles:['.scrollable-menu {height: auto;max-height: 200px;overflow-x: hidden;}']
})
export class Angular2Dropdown implements OnInit{
#Input()
selectedReleaseId: number;
#Input()
values: ReleaseName[];
#Input()
title: string;
private disabledMenu:boolean = false;
appComponent: AppComponent;
private status:{isopen:boolean} = {isopen: false};
constructor(#Inject(forwardRef(() => AppComponent)) private _parent:AppComponent){
this.appComponent = _parent;
}
updatePbiRelease(releaseValue, title){
this.appComponent.updatePbiRelease(releaseValue);
this.title = title;
}
private dropdownMenu($event:MouseEvent):void {
$event.preventDefault();
$event.stopPropagation();
this.status.isopen = !this.status.isopen;
}
ngOnInit() {
}
}
Html Template :
<div (click)="$event.preventDefault()">
<div>
<button type="button" class="btn btn-warning btn-sm" (click)="dropdownMenu($event)">
RELEASE (Toggle)
</button>
</div>
<div class="btn-group" dropdown [(isOpen)]="status.isopen">
<button id="dropdown-list" class="btn btn-default" dropdownToggle >
//Trying to set dropdown selected value here on page load as title from DB on TS Angular 2
{{title}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="dropdown-list">
//Iterate through releaseName has values passed from parent template
//to get name (i.e title) matchng releaseId and Id from DB(i.e item.releaseId)
<li role="menuitem" *ngFor="let data of values">
<a class="dropdown-item" [id]="data.releaseId" #val [title]="data.releaseId == selectedReleaseId ? data.name : data.name"
(click)="updatePbiRelease(val.id, val.title)" >
{{data.name}}
</a>
</li>
</ul>
</div>
Any help would be great.

Did the following changes to Template and ngOnInit() to work
Template :
template: `<div (click)="$event.preventDefault()">
<div>
<button type="button" class="btn btn-warning btn-sm" (click)="dropdownMenu($event)">
RELEASE (Toggle)
</button>
</div>
<div class="btn-group" dropdown [(isOpen)]="status.isopen">
<button id="dropdown-list" class="btn btn-default" dropdownToggle >
{{title}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu scrollable-menu" role="menu" aria-labelledby="dropdown-list">
<li role="menuitem" *ngFor="let data of values">
<a class="dropdown-item" [id]="data.releaseId" #val [title]="data.name"
(click)="updatePbiRelease(val.id, val.title)" >
{{data.name}}
</a>
</li>
</ul>
</div>
</div> `,
Added a if condition on releaseName on parent template
<dropdown *ngIf="releaseNames" [values]="releaseNames" [selectedReleaseId]="item.releaseId">
Set the title value on page load onInit using the id passed from parent template selectedReleaseId
ngOnInit() {
for (var x = 0; x < this.values.length; x++) {
if(this.values[x].releaseId == this.selectedReleaseId) {
this.title = this.values[x].name;
}
}
}

Related

Layout page in dot net core not showing changes on click from Index page

I have menus on Layout page and I need to make them enabled on click of button which is there on Index view
On Index button click I have called controller action which sets the flag using view bag and then I am enabling menu if the flag is set by checking condition on layout page, condition is checked correctly but still menu is not enabled, but if I am clicking any other button then menu is enabling
Layout.cshtml
#if (#ViewBag.Enable == "true" || Context.Session.GetString("CustomerCode") == null)
{
<a href="#OCLegacy" data-toggle="collapse" aria-expanded="false" style="color:gray" class="bg-dark list-group-item list-group-item-action flex-column align-items-start disabled">
<div class="d-flex w-100 justify-content-start align-items-center">
<span class="bi bi-diamond-fill fa-fw mr-3"></span>
<span class="menu-collapsed">OC-Legacy</span>
<span class="submenu-icon ml-auto"></span>
</div>
</a>
}
Index.cshtml
<a asp-action="Index" style="align-self:self-end" data-id="#customer.CustomerCode"
class="btn btn-primary ManageSelect">
calling index action from controller
Here is a demo with ViewBag.Enable. pass #customer.CustomerCode to action,if the it is not null,set ViewBag.Enable to true.Else,set ViewBag.Enable to false.If ViewBag.Enable is true,male the menu enable.
Layout:
#if (#ViewBag.Enable != "true")
{
<a href="#OCLegacy" data-toggle="collapse" aria-expanded="false" style="color:gray" class="bg-dark list-group-item list-group-item-action flex-column align-items-start disabled">
<div class="d-flex w-100 justify-content-start align-items-center">
<span class="bi bi-diamond-fill fa-fw mr-3"></span>
<span class="menu-collapsed">OC-Legacy</span>
<span class="submenu-icon ml-auto"></span>
</div>
</a>
}
else {
<a href="#OCLegacy" data-toggle="collapse" aria-expanded="false" style="color:gray" class="bg-dark list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-start align-items-center">
<span class="bi bi-diamond-fill fa-fw mr-3"></span>
<span class="menu-collapsed">OC-Legacy</span>
<span class="submenu-icon ml-auto"></span>
</div>
</a>
}
Index(asp-route-id will pass #customer.CustomerCode as a parameter id to action):
<a asp-action="Index" style="align-self:self-end" asp-route-id="#customer.CustomerCode" data-id="#customer.CustomerCode"
class="btn btn-primary ManageSelect">
Action:
public IActionResult Index(string id)
{
if (id != null)
{
ViewBag.Enable = "true";
}
else
{
ViewBag.Enable = "false";
}
return View();
}
result:

Returning multiple vue class using one method

I'm using vue and in my vue page I have the bootstrap pill nav.
My page has 2 pills. One is "Approved" and the other is "Declined".
What I'm tring to do is that if you've been declined then you will only see the "Declined" pill and if you've been approved then you can
see the "Approved" pill.
The problem I'm having is that I'm not sure how I can return 2 classes, because the bootstrap uses 2 classes to show the information "show active"
and I would like to be able to use one method to be able to display those classes.
<ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
<li class="nav-item">
<a class="nav-link" :class="showApprovedClass" id="pills-approved-tab" data-toggle="pill" href="#pills-approved" role="tab" aria-controls="pills-approved" aria-selected="true">Approved</a>
</li>
<li class="nav-item">
<a class="nav-link" :class="showDeclinedClass" id="pills-declined-tab" data-toggle="pill" href="#pills-declined" role="tab" aria-controls="pills-declined" aria-selected="false">Declined</a>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade" :class="showApprovedClass" id="pills-approved" role="tabpanel" aria-labelledby="pills-approved-tab">
approved stuff
</div>
<div class="tab-pane fade" :class="showDeclinedClass" id="pills-declined" role="tabpanel" aria-labelledby="pills-declined-tab">
Declined stuff
</div>
</div>
export default {
data() {
show: false,
active: false
},
computed: {
showDeclinedClass(){
if(user.stage === 'declined'){
return 'show active'
}
},
showApprovedClass(){
if(user.stage === 'approved'){
return 'show active'
}
}
}
}
You can update Approved and Declined pill elements class like:
<a class="nav-link" :class="getClass('approved')" .... >Approved</a>
<a class="nav-link" :class="getClass('declined')" .... >Declined</a>
and then create a new method like:
methods:{
getClass( stage ){
return user.stage === stage ? 'show active' : '';
}
}
Demo:
new Vue({
el: "#myApp",
data: {
user: { stage: 'approved' }
},
methods: {
getClass(stage) {
return this.user.stage === stage ? 'btn-primary' : 'btn-secondary';
},
toggle() {
this.user.stage = this.user.stage === 'approved' ? 'declined' : 'approved';
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet">
<div id="myApp">
<div class="row">
<div class="col">
<button :class="getClass('approved')" class="btn btn-md btn-block m-3">Approved</button>
</div>
<div class="col">
<button :class="getClass('declined')" class="btn btn-md btn-block m-3">Declined</button>
</div>
</div>
<div class="row">
<div class="col">
<button class="btn btn-md btn-success m-3" #click="toggle()">Click Me!</button>
</div>
</div>
</div>

passing data between components not working

i have been struggling for hours on this one, i am a newbie in vuejs basically i have a modal based on tabs and i want to show some data into the modal-content of my modal, the place where click event of open modal occurs is in another vue file and the place where i want to populate the modal content is in another vue,here's my code
main blade file
#section('main-content')
<div class="full-page-taps">
<div class="page-head p-4 mb-lg-4">
<h3>Directory</h3>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<employee-search :inplaceholder="'Search Techs'"></employee-search>
</div>
</div>
<employee-card-section :indata="{{ $employees }}"></employee-card-section>
</div>
<modal name="employee-modal"
:width="'94%'"
:height="'94%'"
>
<employee-modal-content v-on:custom="customHandler"></employee-modal-content>
</modal>
</div>
#endsection
employeecard.vue
methods: {
openEmployee() {
// if(this.viewEmployees) {
this.$modal.show('employee-modal');
// this.$emit("passdata",this.employee.id);
this.$emit('chalja');
// this.$emit('custom', 'somedata');
// this.$eventHub.$emit("passdata");
// })
// }
}
},
employee-modal-content.vue
<template>
<div>
<div class="secondary-header no-margin">
<h2>UNEEB</h2>
</div>
<div class="customer-panel">
<input type="hidden" id="eid" value="" />
<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#profile" role="tab">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#bio" role="tab">Bio</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#audit" role="tab">Audit</a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div class="tab-pane active" id="profile" role="tabpanel">
</div>
<div class="tab-pane" id="bio" role="tabpanel">
</div>
<div class="tab-pane" id="audit" role="tabpanel">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
methods:{
customHandler : function(e){
console.log(e);
console.log("works");
}
},
mounted(){
this.$eventHub.$on('chalja', ()=> {
alert("agya");
});
}
}
</script>
i basically want to pass in the ID from employeecard.vue to directory-modal-content.vue. i have tried many solutions but none worked for me, any help?
Should be so:
1.Pass your id as dynamic prop of component
<employee-modal-content :id="employee.id"></employee-modal-content>
2.In your child component u have to use props to receive the id variable
<template>
<div>
{{ id }}
</div>
</template>
<script>
export default {
props: ['id'],
methods:{
//...
}
}
</script>

Angular How to toggle the color of a button which is inside a button group if it is clicked?

I have a group of buttons in an angular 6 component:
<div class="container">
<div class="row">
<div class="clearfix text-center" [hidden]="!searchTerm">
<span class="inline">Filter results by :</span>
<div class="float-right">
<button type="submit" class="btn btn-primary" (click)="performSearch(searchTerm)">All</button>
<button type="submit" class="btn btn-secondary" (click)="domainesFilter(searchTerm)">Domaines</button>
<button type="submit" class="btn btn-secondary" (click)="sectionsFilter(searchTerm)">Sections</button>
<button type="submit" class="btn btn-secondary" (click)="groupsFilter(searchTerm)">Groups</button>
<button type="submit" class="btn btn-secondary" (click)="documentFilter(searchTerm)">Documents</button>
</div>
</div>
</div>
</div>
I want to change the color of the button to primary if it is clicked and set the color of the other buttons to secondary, how can I achieve that?
You can do something like this:
Component ts
#Component({
selector: 'app-my',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class MyComponent implements OnInit {
selBtn: string;
constructor() { }
ngOnInit() {
}
performA(): void {
this.selBtn = 'a';
}
performB(): void {
this.selBtn = 'b';
}
performC(): void {
this.selBtn = 'c';
}
performD(): void {
this.selBtn = 'd';
}
performE(): void {
this.selBtn = 'e';
}
}
Template
<div class="container">
<div class="row">
<div class="clearfix text-center">
<span class="inline">Filter results by :</span>
<div class="float-right">
<button type="submit" class="btn {{ selBtn === 'a' ? 'btn-primary' : 'btn-secondary' }}" (click)="performA()">A</button>
<button type="submit" class="btn {{ selBtn === 'b' ? 'btn-primary' : 'btn-secondary' }}" (click)="performB()">B</button>
<button type="submit" class="btn {{ selBtn === 'c' ? 'btn-primary' : 'btn-secondary' }}" (click)="performC()">C</button>
<button type="submit" class="btn {{ selBtn === 'd' ? 'btn-primary' : 'btn-secondary' }}" (click)="performD()">D</button>
<button type="submit" class="btn {{ selBtn === 'e' ? 'btn-primary' : 'btn-secondary' }}" (click)="performE()">E</button>
</div>
</div>
</div>
</div>
Otherwise you could assign .btn-secondary to all your buttons, then adding btn-primary only if necessary like this:
<button type="submit" class="btn btn-secondary" [ngClass]="{'btn-primary' : selBtn === 'e'}" (click)="performE()">E</button>
With this solution you may need to adjust your css to be sure that btn-primary class overrides all of the properties of btn-secondary class
<div class="container">
<div class="row">
<div class="clearfix text-center" >
<span class="inline">Filter results by :</span>
<div class="float-right">
<button type="submit" class="btn" [ngClass]="{'btn-primary':ActiveButton=='All', 'btn-secondary':ActiveButton!='All'}" (click)="Search(searchTerm, 'All')">All</button>
<button type="submit" class="btn" [ngClass]="{'btn-primary':ActiveButton=='Domaines', 'btn-secondary':ActiveButton!='Domaines'}" (click)="Search(searchTerm, 'Domaines')">Domaines</button>
<button type="submit" class="btn" [ngClass]="{'btn-primary':ActiveButton=='Sections', 'btn-secondary':ActiveButton!='Sections'}" (click)="Search(searchTerm, 'Sections')">Sections</button>
<button type="submit" class="btn" [ngClass]="{'btn-primary':ActiveButton=='Groups', 'btn-secondary':ActiveButton!='Groups'}" (click)="Search(searchTerm, 'Groups')">Groups</button>
<button type="submit" class="btn" [ngClass]="{'btn-primary':ActiveButton=='Documents', 'btn-secondary':ActiveButton!='Documents'}" (click)="Search(searchTerm, 'Documents')">Documents</button>
</div>
</div>
</div>
</div>
And js code is like this.
Search(searchTerm, btn) {
this.ActiveButton = btn;
switch ( btn ) {
case 'All':
console.log('All');
break;
case 'Domaines':
console.log('Domaines');
break;
case 'Sections':
console.log('Sections');
break;
case 'Groups':
console.log('Groups');
break;
case 'Documents':
console.log('Documents');
break;
}
}

Using vue js with selectpicker

I'm using Vue.js to add multiple rows, each row contain two datetimepicker inputs and a bootstrap-select.
My problem is when I fill the inputs and click to add a new row the previous ones clear out, the reason is each time I add a new row I'm using setTimeout to referesh the selectpicker and the datetimepicker.
So I want to know if there is a way to trigger the last added element them without refreshing the previous ones.
Here is my code :
HTML
<div class="cols" id="app">
<ul style="list-style-type: none;">
<li>
<button style="float: right;margin-right: 20px;margin-top: 5px;" type="button" class="btn btn-success btn-xs" v-on:click="addRow()">
<i class="fa fa-plus"></i> Ajouter
</button>
</li>
<li v-for="(row, id) in rows">
<div class="form-inline cp-out" style="padding-bottom: 9px;border-radius:4px;background-color:white;margin-left:-20px;display:inline-block;width:100%;margin-top:10px;">
<div class="col-md-3">
<label :for="['time_start'+id]" class="control-label">start time</label>
<div class="input-group date form_time" style="width:100%;" data-date="" data-date-format="hh:ii" :data-link-field="['time_start'+id]" data-link-format="hh:ii">
<input v-model="row.startTime" :name="'rows['+id+'][startTime]'" class="form-control" :id="['startTime' + id]" size="16" type="text" value="" >
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
</div>
</div>
<div class="col-md-3">
<label :for="['time_end'+id]" class="control-label" style="margin-left:7px;">end time</label>
<div class="input-group date form_time" style="width:100%;" data-date="" data-date-format="hh:ii" :data-link-field="['time_end'+id]" data-link-format="hh:ii">
<input v-model="row.endTime" :name="'rows['+id+'][endTime]'" class="form-control" :id="['endTime'+id]" size="16" type="text" value="" >
<span class="input-group-addon"><span class="glyphicon glyphicon-time"></span></span>
</div>
</div>
<div class="col-md-4">
<div class="form-group select_group" style="margin-left:5px;">
<label :for="['status' + id]" class="control-label">Status</label>
<select data-width="100%" v-model="row.status" :name="'rows['+id+'][status]'" :id="['status' + id]" class="select_picker" data-live-search="true" multiple >
<option value="Status 1">Status 1</option>
<option value="Status 2">Status 2</option>
</select>
</div>
</div>
<div class="col-xs-1">
<button type="button" class="btn btn_delete btn-xs btn-danger" v-on:click="delRow(id)">
<i class="fa fa-remove"></i> delete
</button>
</div>
</div>
</li>
</ul>
</div>
JS
app = new Vue({
el: '#app',
data: {
rows: []
},
methods: {
addRow: function () {
this.rows.push({startTime: '', endTime: '', status: []});
setTimeout(function () {
$('.select_picker').selectpicker('refresh');
$('.form_time').datetimepicker({format: 'LT'});
}.bind(this), 10);
},
delRow: function (id) {
this.rows.splice(id, 1);
}
},created:function() {
this.addRow();
}
});
This is the example : https://jsfiddle.net/rypLz1qg/9/
You really need to write a wrapper component. Vue expects to control the DOM and not to have you making DOM-changing things like the *picker calls at arbitrary times. However, a component gives you the opportunity to tell your component how to interact with the DOM in each of its lifecycle hooks so that its behavior can be consistent. See the JavaScript tab on the wrapper component example page.