adding attribute using knockout js with dynamic string value - html

I am working on dynamically creating the tiles like UI for showing the metrics. i want to show some color dynamically based on the id. i need to append "_flag" with the dynamic value(symptom.symId = S1). my code is given below.
<div data-bind="foreach: {data:symptomArray , as: 'symptom'}">
<div data-bind="attr:{ id : symptom.symId}"> </div>
</div>
Please help me

If I understand your question correctly, then you want to do:
attr: { id: sympton.symId + '_flag' }
or if symId is observable, then:
attr: { id: sympton.symId() + '_flag' }

Related

Angular Checkbox - Cannot get the value of database to match the checkmarks in html checkbox

Looking for your kind assistance as I am still new to coding and angular.
I have this form which allows to me do CRUD data.
In adding the data, I have a several checkbox which I can manage to successfully stored in the database.
However, when I am trying to edit the data, the checkbox are no longer showing check markings based on the data in the table.
I have a Modal form and I am having a hard time matching the data in the checkbox to the ones in database.
Component.html
<div>
<div *ngFor="let item of _placarddetails">
<input type="checkbox" name="{{item.id}}" [(ngModel)]="item.isselected">
<label> {{item.name}}</label>
</div>
</div>
Component.TS
ngOnInit(): void {
this.loadPlacardQualityList();
}
loadPlacardQualityList(){
this.service.getAllEdcmTicketNo().subscribe((data:any)=>{
this.PlacardQualityList=data;
this.PlacardQualityId=this.pq.PlacardQualityId;
this.EdcmTicketNo=this.pq.EdcmTicketNo;
this.PQDeliveryDate=this.pq.PQDeliveryDate;
this.PlacardAppearance=this.pq.PlacardAppearance;
this.PlacardDetails=this.pq.PlacardDetails ;
this.PlacardAcceptance=this.pq.PlacardAcceptance;
this.Inserts=this.pq.Inserts;
this.CheckedBy=this.pq.CheckedBy;
this.PowerProduct=this.pq.PowerProduct;
this.Comment=this.pq.Comment;});
this.
}
addPlacardQuality()
{
var val = {
PlacardQualityId:this.PlacardQualityId,
EdcmTicketNo:this.EdcmTicketNo,
PQDeliveryDate:this.PQDeliveryDate,
PlacardAppearance:this.PlacardAppearance,
PlacardDetails:this.PlacardDetails = this._placarddetails.filter(x=>x.isselected==true).map(x=>x.name).join(","),
PlacardDetailsID:this.PlacardDetails = this._placarddetails.filter(x=>x.isselected==true).map(x=>x.name).join(","),
Inserts:this.Inserts,
CheckedBy:this.CheckedBy,
PowerProduct:this.PowerProduct,
Comment:this.Comment};
this.service.addPlacardQuality(val).subscribe(res=>{alert(res.toString());
});
}
updatePlacardQuality(){
var val = {
PlacardQualityId:this.PlacardQualityId,
EdcmTicketNo:this.EdcmTicketNo,
PQDeliveryDate:this.PQDeliveryDate,
PlacardAppearance:this.PlacardAppearance,
PlacardDetails:this.PlacardDetails = this._placarddetails.filter(x=>x.isselected==true).map(x=>x.name).join(","),
Inserts:this.Inserts,
CheckedBy:this.CheckedBy,
PowerProduct:this.PowerProduct,
Comment:this.Comment}
this.service.updatePlacardQuality(val).subscribe(res=>{alert(res.toString());});
}
getPlacardDetails()
{
this._placarddetails=[
{id:1,name:"Company Name",isselected:false},
{id:2,name:"Company Logo",isselected:false},
{id:3,name:"Certification Level",isselected:false},
{id:4,name:"Year",isselected:false},
{id:5,name:"Badge Name",isselected:false},
]
}
class PDetail{
id!: number;
name!: string;
isselected!: boolean;
}
Here is the sample screenshot whenever I open the edit button.
sample screenshot
I understand that the reason why it is not showing a checkmarks is because of the getPlacardDetails() which is showing false value.
Is there a way that you can recommend a method how I can fix this?
I'm running out of resources and logic lol.
Sorry, still in-experience and I still have lots to learn.
Thank you in advance!
Use "checked" attribute of the checkbox to make it checked. Code as below:
<input type="checkbox" name="{{item.id}}" [(ngModel)]="item.isselected" [checked]="item.isselected">
Also for more details you can refer to below link:
Angular 5, HTML, boolean on checkbox is checked

How to dynamically add options to a select element in an Angular component?

I currently have an Angular component that contains a solutions array that I want users to be able to manually alter. I already have a button that allows users to dynamically add to this array, but I'm trying to implement deletion. I want a select box to be displayed that contains all of the solutions, then when the user clicks one of the options and hits "delete solution", it will remove that element from the array.
Currently the html of my component looks as follows:
<div *ngIf="logged" class="solutionsInput">
<div>
New Solution:
<div>
<textarea id="Solution" [(ngModel)]="newSolution" placeholder="None"></textarea>
</div>
</div>
<button class="add-solutions" (click)="addSolutions(defect)">
Add Solution
</button>
<!-- BELOW IS THE PART THAT NEEDS TO BE FIXED -->
<select id = "solutions"></select>
<button class="delete-solutions" (click)="deleteSolutions(defect)">
Delete Solution
</button>
</div>
The typescript of my component looks as follows:
defect.solutions = [] //THIS IS WHAT I WANT TO ALTER
newSolution = "";
addSolutions(defect: Defect): void {
if(this.newSolution !== "") {
this.defectService.getSolutionsHelper(defect).subscribe((currSolutions) => {
//not necessary to see all of this
})
});
}
}
deleteSolutions(defect: Defect): void {
//THIS NEEDS TO BE IMLPEMENTED
}
Are there any ideas for what I should do? Thank you so much in advance for your help!
When I run into these situations, I use a multiselect drop down list. My team uses the Kendo UI for Angular pack, but there are other free choices, like this one:
https://www.npmjs.com/package/ng-multiselect-dropdown
With this approach, you can simply bind your results from the call to this.defectService.getSolutionsHelper to the control (defect.solutions), and then the user can delete individual members from easily selectable items. Since the control is bound to defect.solutions, the control will natively trim the array.
This may work for you. Good luck!

Working with custom components for input generates "No value accessor for form control with path X->0->Y"

I have a working form taking the following HTML markup. No errors or warnings.
<div class="input-element">
<div class="input-caption">Title</div>
<input type="text"
formControlName="targetField"
class="form-control">
</div>
I transformed it into a custom component, which also works, as shown below.
<app-input-text [info]="'Title'"
formControlName="targetField"
ngDefaultControl></app-input-text>
In my next view, I need to use FormArray as follows - still working code.
<div formArrayName="stuff">
<div *ngFor="let thing of form.controls.stuff.controls; let i = index;"
[formGroupName]=i>
<div class="input-element">
<div class="input-caption">Title</div>
<input type="text"
formControlName="targetField"
class="form-control">
</div>
</div>
</div>
Now, I expected that combining both (i.e. being able to use custom input component and being able to form array for components) would post no problem. However, the sample below doesn't work.
<div formArrayName="stuff">
<div *ngFor="let thing of form.controls.stuff.controls; let i = index;"
[formGroupName]=i>
<app-input-text [info]="'Title'"
formControlName="targetField"
class="col-sm-6"></app-input-text>
</div>
</div>
It generates the following error.
No value accessor for form control with path: 'stuff -> 0 -> targetField'
The custom component is design like this (although given that it works in the explicit markup example, I'm not sure if it's relevant information). The only (wild) guess I have might be that value isn't jacked into the form array field somehow.
export class InputTextComponent implements OnInit {
constructor() { this.value = new EventEmitter<string>(); }
#Input() info: string;
#Output() value: EventEmitter<string>;
onEdit(value: any): void { this.value.emit(value); }
}
The group and array creating in the current view is done like this (not sure if this is of any relevance neither, as it works for the explicit HTML markup case).
this.form = builder.group({
id: "",
stuff: builder.array([
builder.group({ targetField: "aaa" }),
builder.group({ targetField: "bbbb" }),
builder.group({ targetField: "cc" })
])
});
Is there a limitation in Angular in this regard that I'm not aware of? I'm rather sure there's not and that I'm just doing something fairly clever simply missing a tiny detail.
I do understand the error but I can't see how it relates to the code. The form can't find the 0th element in the array or that element has no field of that name. Since I do get to see a few rows, I know there must be a 0th element. Since I specified the name of the field, I know there is indeed such. What else am I missing?

Show MongoDB info in HTML

I'm working on a website using a MEAN stack, and now I am trying to show some MongoDB data in my HTML pages by using Angular. But I don't seem to get it done.
This is the data in MongoDB I want to show in my HTML
{
"badkamer" : {
"block1" : {
"title" : "Badkamer",
"content" : "string"
}
}
}
This is the Angular function retrieving the data:
app.controller('cityCtrl', function($scope,$http){
$scope.specials = function(){
$scope.special = [];
$http.get('/specialdata').then(function(d){
$scope.special = d.data;
console.log(d.data);
},function(err){
console.log(err);
});
};
});
This is where I want it to show in my HTML:
<div ng-controller="cityCtrl" ng-init="specials()" ng-bind="special">
<div class="title">{{special.badkamer.block1.title}}</div>
<p>{{special.badkamer.block1.content}}</p>
</div>
</div>
When i console.log(d.data), I get this:
[Object]
0: Object
badkamer: Object
block1: Object
content: "Text",
title: "Badkamer"
But when I try it like this, the bind option shows all the data at once in my HTML. How can I get it working by using the Angular {{}} tags?
From the console.log, you can see that its an array, so you will need to use index, like this,
<div ng-controller="cityCtrl" ng-init="specials()" ng-bind="special">
<div class="title">{{special[0].badkamer.block1.title}}</div>
<p>{{special[0].badkamer.block1.content}}</p>
</div>
</div>
or change the code in controller.,
$scope.special = d.data[0];

ng-bind-html not working with my $scope.variable

I am trying to add something like dynamic HTML using ng-bind-html but its not working with $scope variable
Here is my Angular code
1)My controller
$scope.name = "Parshuram"
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Also that my string is dynamic
"<div><table class=" + "\"table table - bordered table - responsive table - hover add - lineheight table_scroll\"" + "><thead><tr><td>Name</td><td>Age</td></tr></thead><tbody><tr ng-repeat=" + "\"tr in dyna\"" + "><td>{{tr.name}}</td><td>{{tr.age}}</td></tr></tbody></table></div>"
So i cant replace every variable with $scope
2)- My HTML
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml"></div>
</div>
I got this output
{{name}}
My expected output is
Parshuram
Please can anyone help i am stuck at this point,does that $sce does not bind scope variable?? ..
I've created a working plnkr here: https://plnkr.co/edit/uOdbHjv1B7fr0Ra1kXI3?p=preview
the problem is that ng-bind-html is not bound to the scope.
you should manually compile the content.
a valid and reusable solution should be creating a directive, whitout using any external modules.
function compileTemplate($compile, $parse){
return {
link: function(scope, element, attr){
var parsed = $parse(attr.ngBindHtml);
function getStringValue() { return (parsed(scope) || '').toString(); }
scope.$watch(getStringValue, function() {
$compile(element, null, -9999)(scope);
});
}
}
}
<div ng-app="mymodule" ng-controller="myModuleController">
<div ng-bind-html="thisCanBeusedInsideNgBindHtml" compile-template></div>
</div>
ng-bind-html does what it says on the tin: it binds html. It doesn't bind angular template code into your dom.
You need to do this instead:
$scope.thisCanBeusedInsideNgBindHtml =
$sce.trustAsHtml("<div>"+$sanitize(name)+"</div>");
To do this you'll want to include the module ngSanitize from the javascript angular-sanitize.js. See https://docs.angularjs.org/api/ngSanitize
If you want to insert some html that includes angular directives then you should write your own custom directive to do it.
In your html just use
{{name}}
The {{var}} notation is to be used in the HTML code to evaluate that variable.
You can do :
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml('<div ng-bind="name"></div>');
Sorry I make another answer.
If you have
$scope.thisCanBeusedInsideNgBindHtml = $sce.trustAsHtml("<div>{{name}}</div>");
Then you can do
var str = "<div>{{name}}</div>";
var output = str.replace('{{name}}', $scope.name);
It seems to be the only option.