ngFor alway returning id of first object in array - angular5

I'm trying to get the ID of an object by assigning it to a variable declared in the component when a button is clicked. However, it seems to only be getting the first objects ID every time.
Here is a link to StackBlitz which replicates the issue I am having:
https://stackblitz.com/edit/angular-vcbzxf
Any assistance would be greatly appreciated.

Update 1 : You can actually achieve what you wanted using bootstrap modal with few changes like below.
comment.component.html:
<div *ngFor="let comment of post.comments; let i = index">
{{ comment.content }}
<button data-toggle="modal" [attr.data-target]="'#confirmDeleteCommentModal' + comment.id">Get ID</button>
<div class="fade modal" [attr.id]="'confirmDeleteCommentModal' + comment.id" tabindex="-1" role="dialog" aria-labelledby="confirmDeleteCommentModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmDeleteCommentModalLabel">Delete Comment</h5>
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" (click)="checkId(comment.id)">Delete</button>
</div>
</div>
</div>
</div>
</div>
Notice [attr.data-target]="'#confirmDeleteCommentModal' + comment.id" added to Get ID button and [attr.id]="'confirmDeleteCommentModal' + comment.id" which is added to bootstrap modal. Moreover, modal is now included in *ngFor div element.
Previously, data-target of Get ID button was always set to confirmDeleteCommentModal, and we technically just had one bootstrap modal with id set to confirmDeleteCommentModal, I think that is what caused the issue, we always loaded the same (and first) bootstrap modal.
Updated stackblitz: https://stackblitz.com/edit/angular-3tmtwa
Original answer (this did not solve the issue):
If you're going with per your most recent comment (as implemented here - https://stackblitz.com/edit/angular-vcbzxf), I would just like to point out that you could write your comment.component.html as follows:
comment.component.html
<div *ngFor="let comment of post.comments">
<div>
{{showDelete ? 'Are you sure you want to delete?' : comment.content + ' id = ' + comment.id}}
<button *ngIf="showDelete" (click)="showDelete = false">Cancel</button>
<button (click)="(showDelete == false && showDelete = true) || checkId(comment.id)">Delete</button>
</div>
</div>
Stackblitz to give it a quick test : https://stackblitz.com/edit/angular-q27xn7
While this may not be a great improvement over what you've done, thought I would just point out other ways of achieving similar results.

Related

How to get ID from conditionally rendered item in modal component?

I have a conditionally-rendered notes and I want to delete specific note, depends on ID.
I have no problem with deleting without modal, but my problem is that I want to delete note only when modal is accepted.
There is modal component:
<DeleteModal
:modalVisible="modalVisible"
:restore="modalType"
#closeModal="modalVisible = false"
#deleteItem="deleteNote(note.id)"
#restoreItem="restore()"
/>
Delete method:
const deleteNote = (id) => {
Inertia.delete(route('notes.destroy', id));
getNotes();
};
and there is how I render notes:
<div class="my-4" v-for="note in notesForIssue" :key="note">
<div class="flex flex-row justify-between"></div>
<div class="bg-gray-100 w-full min-h-16 mt-2 rounded whitespace-normal">
<div class="px-8 py-4">
<p>{{ note.text }}</p>
<div class="flex flex-row items-center justify-between">
<div class="flex flex-row text-xs">
<span class="text-[#2563EB]">{{ note.updated_at }}</span>
<p class="ml-2">{{ __('history.by') }}</p>
<p class="font-bold ml-2 text-[#2563EB]">{{ note.updated_by }}</p>
</div>
<div #click="modalType=false; modalVisible=true;">
</div>
</div>
</div>
</div>
</div>
But I have no access to note.id here: #deleteItem="deleteNote(note.id)". Any ideas, how to solve this problem?
Try this approach.
When you click on the div, instead of set visibality of modal,
set selectedItem
set visibility
then you accept by modal, you have a `selectedItem' for delete
After delete, clear the selectedItem.
First the key attribute is not accpet object type variable. Second maybe you should check what is notesForIssue first ,then find out why you can't access note.id

Text not getting copied in modal in ngx clipboard

I am using ngx clipboard to copy my value to clipboard which is working fine if I do that in the main page but I want that functionality in my modal which is neither throwing any error nor copying anything.
Angular-5.2.3
ngx-clipboard-9.1.3
Below is the code:
<span>
<img src="../../assets/img/copy-icon.png" ngxClipboard [cbContent]="myvalue" (click)="copyToClipboard()">
</span>
and my ts file:
copyToClipboard(){
console.log("copyToClipboard")
}
For all those who are getting this error below is the answer:
TLDR;
Make your own textarea to hold the value to copy and hook ngxClipboard to it.
Longer Explanation
I had a couple of issues with this plugin that seemed to happen a lot in Chrome (v64). I was getting intermittent successes.. most of the time the 'copy to clipboard' would fail to actually copy anything, and the 'success' callback would also be called. So it was the worst of both.. nothing in the logs, no copy, cbOnSuccess called. The above seemed exacerbated by large amounts of text. Safari seemed to work just fine. In Chrome, I noticed some messages in the console in the 'verbose' mode that were timeout kinds of errors.
Now I don't know the full story, but it seemed like the code in ngx-clipboard that was 'creating a text area' was showing me (in the debugger) a message like 'Uncaught SyntaxError: Unexpected end of input'.
I also use a Bootstrap modal but I'm not sure if that was really causing much of an issue. In the end, I was able to get everything going when I:
made my own
used the [ngxClipboard]="textAreaName" format
html template
<div class="modal fade" id="export-bundle-modal-{{bundleToExport.id}}" tabindex="-1" role="dialog"
aria-labelledby="modal-content modal-header title">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" #exportBundleModalClose data-dismiss="modal">×</button>
<span id="title">Export {{bundleToExport.name}}</span>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12">
<textarea class="form-control text-area" readonly="readonly"
rows="10" #bundleJson style="resize: none">{{bundleWithDependencies | json}}</textarea>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-success" type="submit" data-dismiss="modal"
[disabled]="!taxonomiesLoaded || !componentTypesLoaded || !configurationsLoaded"
[ngxClipboard]="bundleJson" (cbOnSuccess)="copied()">
<small *ngIf="!(taxonomiesLoaded && componentTypesLoaded && configurationsLoaded)">
LOADING...
</small>
<small *ngIf="taxonomiesLoaded && componentTypesLoaded && configurationsLoaded">
COPY TO CLIPBOARD
</small>
</button>
</div>
</div>
</div>
</div>
Notice the button and how bundleJson is attached to the via the #bundleJson and the 'value' of the textarea is a pipe calculated value. Doing the calculation here (as opposed to when the 'copy to clipboard' was clicked also was necessary.. in essence, make sure the string in the textarea is correct before trying to send it to the clipboard.
We also use the bootstrap.js + jQuery integration instead of a native Angular bootstrap solution (don't ask), so notice that the data-dismiss="modal" is also attached to the button. When the button is clicked both the copied() function as well as the close of the modal happen.. there didn't seem to be any chaining/timing issues.
Add #container in modal div.
<div class="modal fade" id="addAddressSuccessModal" tabindex="-1" role="dialog" aria-hidden="true" #container>
And to copy =>
<div ngxClipboard [cbContent]="createdAddress" [container]="container" ><label class="fbold color-bluey-grey font-10 cursor-pointer">TAP TO COPY</label></div>

Modal memory leak as more modals added

I am developing an Angular 4 application using ngx-bootstrap modals heavily. I am currently using the template + modalService way of opening up modals. During a click event, this line of code is called:
#ViewChild() worklistTemplate;
// ...
this.modalRef = this.modalService.show(this.worklistTemplate, this.config);
And the worklist template looks like this:
<ng-template #worklistTemplate>
<app-action-view
[leftButtons]="leftButtons"
[labelHeader]="modalHeader"
[labelIcon]="modalIcon"
[modalRef]="modalRef">
<div class="row modal-info-panel">
<div class="col-xs-4 modal-user-info">
<fa name="mars" class="gender-icon"></fa>
<div class="field-panel">
<input type="text"
[ngModel]="rowInfo.lastName"
[ngClass]="{ 'modal-editable-field': modalFieldsEditable }"
[disabled]="!modalFieldsEditable">
<input type="text"
[ngModel]="rowInfo.firstName"
[ngClass]="{ 'modal-editable-field': modalFieldsEditable }"
[disabled]="!modalFieldsEditable">
<div>
<label for="modal-mrn">MRN --</label>
<input id="modal-mrn" type="text"
[ngModel]="rowInfo.mrn"
[ngClass]="{ 'modal-editable-field': modalFieldsEditable }"
[disabled]="!modalFieldsEditable">
</div>
<div>
<label for="modal-dob">DOB --</label>
<input id="modal-dob" type="text"
[ngModel]="rowInfo.birthDate"
[ngClass]="{ 'modal-editable-field': modalFieldsEditable }"
[disabled]="!modalFieldsEditable">
</div>
<div class="edit-panel">
<fa *ngIf=modalFieldsEditable class="worklist-edit-buttons green-hover link" name="floppy-o" tooltip="Save" (click)=saveChanges()></fa>
<fa *ngIf=modalFieldsEditable class="worklist-edit-buttons red-hover link" name="times" tooltip="Cancel" (click)=toggleModalFields()></fa>
</div>
</div>
</div>
<div class="col-xs-8 modal-id-info">
Associated ID
<div class="full-width">
<div class="row" *ngFor="let i of rowInfo.associatedIDs">
<div class="col-xs-6 cell">{{i.id}}</div><div class="col-xs-6 cell">{{i.source}}</div>
</div>
</div>
</div>
</div>
<div class="row" id="modal-table">
<app-table-view
[columns]="objDetailsCols"
[tableData]="objDetailsData"
[expandTemplate]="rowImageContainer"
[expandColStyle]="expandColStyle">
</app-table-view>
</div>
<div *ngIf="resolvePanelVisible" class="resolve-panel"
[#slideRight]>
<div class="resolve-label">
<fa class="lt-icon" name="wrench"></fa>
Resolve QA Issue
</div>
<div class="resolve-body">
Hello, World!
</div>
<div class="resolve-footer">
<a>Validate</a>
<a>Resolve</a>
<a>Reload</a>
<a (click)="toggleResolvePanel()">Close</a>
</div>
</div>
</app-action-view>
</ng-template>
The modal can be closed by clicking outside of the modal boundaries or there is a button inside the ActionViewComponent that calls modalRef.hide().
Memory usage increases drastically as more and more modals are opened. In fact, if I open the modal around 5 times, the application becomes sluggish and almost unusable. This is especially apparent if there are many rows in our TableViewComponent.
Is there a problem with the way I am using the modals, or is this an issue related to ngx-bootstrap modals? OR, is the issue related to the browser and unavoidable? I am developing on Chrome 62 right now.
I have verified that onDestroy is never called on the TableViewComponent inside the modal. It is not even called if I navigate to a different page component, though another table (not in the template) does have onDestroy called when navigating from the page.
Any feedback is appreciated greatly- I have been stuck for way too long on this.
This is an issue of ngx-bootstrap, unfortunately. I created a pull request (https://github.com/valor-software/ngx-bootstrap/pull/3179) so this will be fixed as soon as my PR is merged and new version is released.

Twitter Bootstrap Alert won't close

I'm using the Twitter Bootstrap Framework for some design parts od my page.
I try to set up an alert that can be closed. My code looks just like that:
<div id="index-alert" class="alert alert-danger .alert-dismissible">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<b>An Error occured</b>
</div>
There is an X at the upper right corner that's clickable, but nothing happens.
The firebug console doesn't give me any errors either.
I'm using the Bootstrap Version 3.2.0
Does anybody know what i'm doing wrong?
Try this
<div id="index-alert" class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<b>An Error occured</b>
</div>
If that fails, ensure you have referenced <script src="js/bootstrap.min.js"></script>
You should write alert-dismissible instead of .alert-dismissible ;)
And don't forget to add both jQuery.js and bootstrap.js files before the </body> closing tag. jQuery must be added first:
<script src="/jquery-3.2.1.min.js"></script>
<script src="/bootstrap.min.js"></script>
In case none of these answers workout, you can always put inline javascript inside the HTML tag.
Disclaimer: This is a bad practice and don't write code like this if at all possible.
Now try this out:
<div class="alert alert-info alert-dismissible fade show" role="alert">
<button type="button" class="close" onclick="this.parentElement.style.display='none';"><span>×</span></button> This is a dismissable message.
</div>
I know that the answer may no longer serve you, but the following worked for me:
<div class="alert alert-warning alert-dismissible fade show" role="alert">
<strong>XXXXXX</strong> XXXXXX.
<button type="button" class="btn-close" data-dismiss="alert" aria-label="Close"></button>
</div>

Can I specify multiple data targets for Twitter Bootstrap collapse?

I'd like to target two divs for expand when clicking on a single trigger? Is that possible?
You can simply add all the ids separated by commas in data-target:
<button type="button" data-toggle="collapse" data-target="#demo,#demo1,#demo2">
Hide them all
</button>
Use the same class for both div's and set your data-target according this. Give your div's also the same parent (can also be a class) and set data-parent according this.
<button type="button" data-parent="#wrap" data-toggle="collapse" data-target=".demo">
simple collapsible
</button>
<div id="wrap">
<div class="demo collapse">
test1
</div>
<div class="demo collapse">
test1
</div>
</div>
From the Bootstrap 3 documentation:
The data-target attribute accepts a CSS selector to apply the collapse to.
Therefore you can use a comma-separated list of id's, class selector etc. for the data-target attribute value:
<button class="btn btn-primary"
type="button"
data-toggle="collapse"
data-target="#target1,#target2,#target3"
aria-expanded="false"
aria-controls="target1,target2,target3">
You can see an extensive list of valid CSS selectors on the w3schools website.
If you want to hide one element and show another (like the bootstrap accordion but without a panel) you can add multiple targets but also add the class 'in' to have one element expanded on load!
<div class="collapse text-center clearfix in" id="section1">
<h1>This is section 1</h1>
<p>Are you excited about toggling?</p>
</div>
<div class="collapse text-center clearfix alert-warning" id="section2">
<h1>Boo!!</h1>
<p>This is a new sentence</p>
</div>
<button class="btn btn-block btn-primary" data-toggle="collapse" data-target="#section1,#section2">Toggle</button>
Live demo here
There is a solution in Bootstrap 4:
Bootstrap 4 documentation: Multiple targets
The least you need is:
data-toggle="collapse" data-target=".multi-collapse" for the toggle
button
class="collapse multi-collapse" for each element you need to
toggle
(While multiple ids in data-target indeed don't work).
The data-target answer did not work for me. However you can use JavaScript to do this.
Make your button call some JavaScript like:
$('.collapse-class').collapse('toggle')
See: https://getbootstrap.com/javascript/#via-javascript-3.
Bootstrap 4 uses document.querySelector instead of document.querySelectorAll. If this changes, then everything works.
In Bootstrap 4 using the same class for each respective div seemed to work over using id.
<button type="button" class="btn" data-toggle="collapse" data-target=".collapse-group">
Reveal Items</button>
<div class="row">
<h3>Visible Row div 1</h3>
<div class="collapse-group collapse">
<p>hidden item</p>
</div>
<h3>div 2</h3>
<div class="collapse-group collapse">
<p>hidden item 2</p>
</div>
</div>
I faced the same problem but bootstrap won't let data-toggle="tab" beside data-toggle="collapsed" so my problem was like this.
I have:
<a type="button" class="btn btn-default btn-lg btn-block " href="#ld-tab-pane-eye" aria-expanded="false" aria-controls="ld-tab-pane-eye" role="tab" data-toggle="tab" aria-haspopup="true" aria-expanded="false" style=" border: 0px ;"> </a>
and this was switching tabs:
<button type="button" class="navbar-toggle collapsed nav-trigger style-mobile" data-toggle="collapse" data-target="#main-header-collapse" aria-expanded="false" data-changeclassnames='{ "html": "mobile-nav-activated overflow-hidden" }'>
</button>
But this one closes the modal because the switch tab button was in the modal.
To solve the problem I add id="popout"(to first button) and id="popoutTrigger" (to secend button).
And this script (jQuery):
$( "#popout" ).click(function() {
$( "#popoutTrigger" ).trigger( "click" );
});
When the user clicked the switch button in the modal, after switching modal will close.
This a view of what I've done.
I hope my solution will help.