When i click on edit give me inputfield and 2 buttons - html

<div class="fa fa-edit clickable edit-icon" (click)="editProject()"></div>
{{project.name}}
This is the code I want, when I click on this icon, the project.name needs to turn into an input field and give me 2 buttons in the same page
I am working with html and typescript.

You can use ngIf and a property binding
In your component's class:
public isInputVisible : boolean = false;
public editProject(): void {
this.isInputVisible = true;
}
In your template:
<div class="fa fa-edit clickable edit-icon" (click)="editProject()"></div>
<ng-container *ngIf="!isInputVisible">{{project.name}}</ng-container>
<input [(ngModel)]=project.name"" *ngIf="isInputVisible" />

Related

Kendo checkbox toggle true and false states not working properly

I'm trying to get it so when one or more checkbox is clicked, I'm able to get a button to appear. I would like the toggle function to work if one or more checkbox is clicked, but instead, it will turn on when I select one checkbox, then turn off during the next selection. I'm sure I've got a couple of unnecessary properties added into here as well, but not too concerned about that. Any help would be appreciated.
HTML: Button
<button class="btn btn-primary"
*ngIf="switchCase" style="float:right"
>Save</button>
HTML: Checkbox Column
<kendo-grid-column field="checkbox" editor="boolean">
<ng-template kendoGridCellTemplate let-dataItem id="flexSwitchCheckChecked"
>
<input type="checkbox" (click)="toggleButton(dataItem, 'checkbox'
[checked]="dataItem.checkbox"
[width]="40"
>
TS: Button click method
public switchCase: boolean = false;
toggleButton() {
this.switchCase = !this.switchCase;
pass an event to your function then access its value from typescript class:
Step1(pass an $event):
on *ngFor tag level add an index var
<div *ngFor="let item of items;let i = index" >
<input type="checkbox" (change)="toggleButton($event,i)">
</div>
Step1(get its value):
toggleButton($event,i) {
let newValue = $event.target.value;
// this.switchCase =newValue;
this.items[i].checked = newValue;
}

Go to previous page and activate toggle

I'm working on an Angular 9 project and I should activate a toggle when going back to a specific page and only in that case.
So actually when I go back from page localhost:4200/y to page localhost:4200/x, I turn on the toggle, otherwise if I go through router.navigate to page localhost:4200/x, the toggle should stay turned off.
The go back button typescript is like this:
export class BackToPreviousComponent() {
#Input() labelPrevious: string;
back(): void {
history.back();
}
}
this is its HTML:
<a (click)="back()" class="btn btn-nav">
<i class="icon-back pr-1"></i>
{{ labelPrevious }}
</a>
and this is how is fitted in the application:
<div class="component">
<app-back-to-previous [labelPrevious]="'random text'"></app-back-to-previous>
...
</div>
So how can I tell the application to turn on the toggle only in this case?

Add Data Dynamically to HTML Button in HTML page

I have this button, I need to add Pendo Data that is dynamically working based on which button we chose. Mostly this is making the Button unique. When I have a button that is not changing I add like this:
<button mat-button
 data-pendo="pendo-prospects-send-application"
class='round-button'
color='primary'
type='button'
.....>
</button>
But sometime I need to add this data to one button that is changing based on CSS class. I am not sure how check for that.
For example I need to add to a button when :
if [class.fa-pencil] then data-pendo "Something"
if [class.fa-plus] then data-pendo "Something else"
This is the button that changes base on class:
<button mat-button
class='round-button'
type='button'
[class.disabled-button]='GuidId'
color='primary'
(click)='onAssignLoanOfficer()'>
<i class='fal'
[class.fa-pencil]='GuidId'
[class.fa-plus]='!GuidId'></i>
</button>
How I can do that?
Based on your comments I think this is what you want to do:
<button
(click)="onAssignLoanOfficer()"
[class.disabled-button]="GuidId"
[attr.data-pendo]="GuidId ? 'pendo-edit-loan' : 'pendo-add-loan'"
class="round-button"
color="primary"
type="button">
<i [class.fa-pencil]="GuidId"
[class.fa-plus]="!GuidId"
class="fall">
</i>
</button>
ALTERNATIVE:
As a more sophisticated alternative (I really don't know how you intend to use what you're asking for), you can build a directive to add the attribute you want based on a map of class-to-pendo-data conversion information:
#Directive({
selector: '[addPendoData]'
})
export class AddPendoDataDirective implements AfterViewInit {
constructor(private _el: ElementRef, private _renderer: Renderer2) {}
ngAfterViewInit() {
const pendoData: string | null | undefined = this._getPendoValue();
if (!pendoData) { return;}
const $button: HTMLElement = this._el.nativeElement;
this._renderer.setAttribute($button, 'data-pendo', pendoData);
}
private _getPendoValue() {
const $child: HTMLElement = this._el.nativeElement;
if(!$child) { return null; }
const $i: HTMLElement = $child.querySelector('i');
if(!$i) { return null; }
const listOfClasses: string[] = $i.className.split(' ');
if (!(listOfClasses && listOfClasses.length)) { return null; }
for(const className of listOfClasses) {
if(PENDO_MAP[className]) { return PENDO_MAP[className]; }
}
return null;
}
}
const PENDO_MAP: { [className: string]: string } = {
'fa-pencil': 'pendo-edit-loan',
'fa-plus': 'pendo-add-loan'
// add other mappings here...
};
and you can use it like this:
<button
(click)="onAssignLoanOfficer()"
[class.disabled-button]="GuidId"
addPendoData
class="round-button"
color="primary"
type="button">
<i [class.fa-pencil]="GuidId"
[class.fa-plus]="!GuidId"
class="fall">
</i>
</button>
I've put together this stackblitz demo.
You could define a directive, as julianobrasil suggests.
I want to point a different way to achieve this using Angular templates.
Define two buttons, addition and edition, separately.
Put a default where you want to be rendered
<div class="action-button" *ngIf="GuidId">
<!-- Add button -->
<button mat-button
data-pendo="pendo-add-loan"
(click)="add(...)"
class="round-button"
color="primary">
<i class="fal fa-plus"></i>
</button>
</div>
Then, define a ng-template tag with the other button definition. A completely fresh new.
<ng-template #edit-button>
<div class="action-button">
<!-- Edit button -->
<button mat-button
(click)="edit(...)"
data-pendo="pendo-edit-loan"
class="round-button"
color="primary">
<i class="fal fa-pencil"></i>
</button>
</div>
</ng-template>
Finally, just change the *ngIf statement to render either an addition button or an edition one.
<div class="action-button" *ngIf="!GuidId else edit-button">
<!-- Add button here -->
</div>
This is a way that scales in order to keep components isolated. The buttons are not related anymore, so you can implement w/o having to condition every style, action, etc.
Hope it helps.

Angular 5 [object HTMLDivElement]

When I click the button, I'm sending the 'copyRow' element to the 'copyItem' method. I'm equalizer the 'copyItem' element with the 'item' variable in the 'Typescript' file.
This 'item in the html file' variable when I want to show '[object htmldivelement]' I'm getting as output.
create.component.html
<div class="questions">
<div class="form-group copy-row" #copyRow>
<label>Question</label>
<input type="text" class="form-control" placeholder="Question title">
</div>
{{ item }}
</div>
<button type="button" class="btn btn-primary" (click)="copyItem(copyRow)">Add</button>
create.component.ts
item;
constructor() { }
ngOnInit() {
}
copyItem(row) {
this.item = row;
}
EDIT
My aim is to do a survey project.
When I click on the 'Add' button, the same '#copyRow' element will show in the {{ item }} section. However, I get an output like the second link.
1: http://prntscr.com/j1ncp1
2: http://prntscr.com/j1nd19
I'm not sure what you want to achieve with this but this is the explanation of what is happening in your code.
#copyRow is a reference to the HTML element & in this case it is a div element. So when you're passing the reference using copyItem function, you are actually passing an HTML element.
Putting these things together, the copyItem method gets following signature -
public item: HTMLElement;
public copyItem(row: HTMLElement): void {
this.item = row;
//this is how you get inner HTML
console.log(row.innerHTML);
//this is to get inner text
console.log(row.innerText);
}
This is the reason why you are getting [object HTMLDivElement] in the template for item binding (you are trying to display an object).
You can simply use {{item.innerHTML}} or {{item.innerText}} to display the inner content of selected HTML element.
Let me know if I'm missing anything.
EDIT - Alternative Way (Binding in Template)
If you are not doing additional stuff in the component, the binding can be as simple as assigning the HTML element reference directly to the item property in template itself -
<div class="questions">
<div class="form-group copy-row" #copyRow>
<label>Question</label>
<input type="text" class="form-control" placeholder="Question title">
</div>
{{ item?.innerHtml }}
{{ item?.innerText }}
</div>
<button type="button" class="btn btn-primary" (click)="item = copyRow">Add</button>
EDIT 2 (as per discussion in comments)
Try this template to iterate over same HTML on button click -
<div class="questions">
<ng-container *ngFor="let item of items">
<div class="form-group copy-row">
<label>Question</label>
<input type="text" class="form-control" placeholder="Question title" />
</div>
</ng-container>
<button type="button" class="btn btn-primary" (click)="items = items || []; items.push(1);">Add</button>
Just initialise your items array as -
public items: Array<number> = [1];
I hope this helps :)
Use ViewChild and ElementRef
import { Component, ViewChild, ElementRef } from '#angular/core'
#ViewChild('item')
item: ElementRef;
constructor() { }
ngOnInit() {
}
copyItem() {
// this.item -> now you have the reference of the element
}

Why do bootstrap tooltips not work in bootstrap modals?

My tooltips are working on the mainpage perfectly. In a modal which is generated later by an ajax call the tooltips won't work.
I have included the following code inside the generated modal (result of the ajax call).
To re-ini the tooltips
<script>
$('.tooltips').tooltip();
</script>
In the html of the modal
<button class="btn btn-lg default tooltips blue-madison" type="submit"
name="O" data-container="body" data-placement="top"
data-original-title="THIS TEXT FOR TOOLTIPS">
<i class="fa fa-industry blue-madison"></i> BUTTON1
</button>
<button class="btn btn-lg default tooltips green-jungle" type="submit"
name="P" data-container="body" data-placement="top"
data-original-title="THIS TEXT FOR TOOLTIPS">
<i class="fa fa-user green-jungle "></i> BUTTON2
</button>
Why don't the tooltips show- what I'm doing wrong?
The issue is because of the z-index of modal and tooltip. You can try this,
.tooltip {
z-index: 100000000;
}
Probably it's because you should call $('.tooltips').tooltip(); after the modal's content have been inserted in the document.
Otherwise, please post a fiddle with your current code where we can test it.
Another solution is to bind the tooltip to the modal using the container option:
$('#modal').on('shown.bs.modal', function() {
console.log("modal show");
$('.tooltips').tooltip({
container: $(this)
});
});
Maybe this helps someone: I had a case when needed with ajax to populate & display a bootstrap modal (render view) on click (calling showModal(url, event) below); bootstrap tooltip and also fengyuanchen/datepicker were unresponsive, so I managed to trigger them after detecting modal loading, like this:
function showModal(url, event) {
$.when(
$.ajax({
url: url,
method: 'GET',
success: function (data) {
$('#modal-wrapper').html(data);
}
})
).then(function() {
$('.loaded_modal').modal().on('shown.bs.modal', function() {
$('[data-toggle="datepicker"]').datepicker({
format: "dd/mm/yyyy",
autoclose: true,
todayHighlight: true,
zIndex: 1070,
container: '.modal'
});
$('.modal [data-toggle="tooltip"]').tooltip({trigger: 'hover'});
// could also be on click {trigger: 'hover click'}
});
});
If you are using react I had success with a different answer. All you have to
do is give the parent container a ref and then in the overlayTrigger component you just have to pass in the ref as a param to the container.
import React, { Component } from 'react';
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
class random extends Component {
constructor(props) {
super(props);
this.ref= React.createRef()
}
render() {
return (
<div ref={this.ref}>
<OverlayTrigger
placement="top"
container={this.ref}
overlay={
<Tooltip data-container="body">Some text</Tooltip>
}
>
<span className="d-inline-block">
<i className="mdi mdi-help-circle pointer"></i>
</span>
</OverlayTrigger>
</div>
);
}
}
Best way to fix this behaviour is by adding this prop inside your md-tooltip:
md-z-index="9999"
or a different z-index.
No need to hardcode this in the css.
You can also define the z-index in your scope variable inside your controller as the following
// in controller
$scope.btnOptions = {
isOpen:false,
label: 'test button',
class: 'md-scale',
zIndex: 99999
};
in you html ( normally I would use {{}} to print the variable, but I'm on laravel so I used <% %> instead
<md-button aria-label="Édit" class="md-fab md-raised md-mini">
<md-tooltip md-direction="top" md-z-index="<% btnOptions.zIndex %>">Mode édition</md-tooltip>
<i class="far fa-edit"></i>
</md-button>