json object is not effecting to view - html

I am using angular Formio for dynamic screen creation, as part of that when I get the screen script from database, if I change the label of the particular element in ngOnInit() I am able to change.
but once the screen is displayed, then if I change the lable it is not effecting.
html
<Formio [form]="form" [submission]="submission" (submit)="onSubmit($event)"></formio>
<div class="mb-5">
<div class="row">
<div class="col-12 mb-5">
<div class="pull-right" style="float:right;">
<button class="btn save-button" (click)="clearData()">Clear data</button>
<button class="btn save-button" (click)="showData()">Show data</button>
</div>
</div>
</div>
</div>
component
ngOnInit() {
debugger;
this.triggerRefresh = new EventEmitter();
this.http.get('http://localhost:3000/angcomp/3')
.subscribe(
response => {
debugger;
this.data = response.json();
this.form = this.data;
this.form.components[0].label = 'Changed';//it is updating the lable in view
},
err => {console.error(err)}
);
}
showData() {
this.form.components[0].label = 'Again Changed'; // here it is not changing but in this.form.components[0].label value is displaying as 'Again Changed', but not effecting in front end
}

Try the refresh property in formio
In yout HTML:
<Formio [refresh]="triggerRefresh" [form]="form" [submission]="submission" (submit)="onSubmit($event)"></formio>
In your component:
showData() {
this.form.components[0].label = 'Again Changed';
this.triggerRefresh.emit({
form: this.form
});
}
https://github.com/formio/angular-formio/wiki/Form-Renderer#updating-forms-and-submissions

Related

Why the list of Modal which is generated from fetch only show the last item?

I'm creating a list of modal through fetching local json file, but when I clicked the learn more button, all cards had the information of the last item.
const cards = document.querySelector(".cards");
async function getData() {
const response = await fetch("./modals/modal.json");
const data = await response.json();
console.log(data);
data
.map((item) => {
cards.innerHTML += `
<div class="card slide">
<img
src="${item.image}"
alt="${item.name}"
class="card--img"
/>
<h3>${item.name}</h3>
<button class="card--btn-light open-modal">Learn more</button>
</div>
<div class="modal">
<div class="modal-content">
<div class="modal--img">
<img src="${item.image}" alt="${item.name}" />
</div>
<div class="modal-desc">
<h3>${item.name}</h3>
<h4>${item.type}</h4>
<p>
${item.desc}
</p>
<p><strong>Age: </strong> ${item.age} months</p>
<p><strong>Inoculations: </strong>none</p>
<p><strong>Diseases: </strong> none</p>
<p><strong>Parasites: </strong> none</p>
</div>
<div class="close-modal">✕</div>
</div>
</div>
`;
})
.join("");
// ---------------modal
// works but only show last item
const modal = cards.querySelectorAll(".modal");
console.log(modal);
modal.forEach((item) => {
cards.addEventListener("click", (e) => {
if (e.target.classList.contains("open-modal"))
item.style.display = "flex";
if (e.target.classList.contains("close-modal")) {
item.style.display = "none";
}
window.addEventListener("click", (e) => {
if (e.target === modal) {
item.style.display = "none";
}
});
});
});
I am wondering how to show the right information of the clicked card. I have seen the solution of the modal issue but the content was generated from HTML, it's a little different from this which the content was generated from fetching.

Delete the entire div including subdiv's on clicking the remove button

I am new to reactjs development and I'm trying real hard to delete the entire division including sub divisions on clicking "remove" button. The addition of entire div is working smoothly, but I am not sure how can I perform deletion of entire div on clicking remove button.
class Createloc extends Component {
constructor(props) {
super(props);
this.state = {
count: 1,
rows: [],
}
this.addRow = this.addRow.bind(this)
this.deleteRow = this.deleteRow.bind(this)
}
// divID = nextId();
addRow() {
this.setState({ count: this.state.count + 1 })
console.log(`Increase count: ${this.state.count}`)
};
deleteRow(e) {
// ==> not sure
// console.log("delete");
};
addingDivs() {
let count = this.state.count, uiItems = [];
while (count--)
uiItems.push(
<div className="newHost" id={this.divID}>
<div className="hostInput">
<input type="text" placeholder="Enter Building Name" />
</div>
<div className="hostInput">
<input type="text" placeholder="Enter Employee Name" />
</div>
<div className="hostInput">
<button className="btn btn-danger" type="button" onClick={this.deleteRow}>Remove</button>
</div>
</div>
)
return uiItems;
}
render() {
return (
<form className="form">
<div className="addButton">
<button type="button" onClick={this.addRow}>Add</button>
{this.addingDivs()}
</div>
</form>
)
}
}
export default Createloc;
PS: I have not included the pseudo I tried to delete just to avoid confusion.
I was able to delete the added row as a stack by applying below:
deleteRow(e) {
this.setState({ count: this.state.count - 1 })
};
Thanks!

Dynamic Form issue with Reactive Form

I want to create a Dynamic input field on button press and successfully I am able to create new input field on button press with the help of reactive form but now I want to set predefined value in input field as per API data. Like if from API if I am getting 6 names, I want to create that 6 input fields on Init and then I want to able to new input field on button press. Here is my code which I tried, I am able to create new input field but not able create input fields as per API data on Init.
Component.ts
export class ScreenmodalComponent implements OnInit {
#Input() screendetails;
personalForm : FormGroup;
arrayItems: any = [];
screenList: string;
constructor(private activeModal: NgbActiveModal, private formbuilder: FormBuilder, private pagesService: PagesService, private utilService: UtilService) { }
ngOnInit() {
this.personalForm = this.formbuilder.group({
other: this.formbuilder.array([ this.addanotherForm()])
});
// Api call
this.pagesService.GetScreens('').then(res => {
console.log('get screens api', res);
for (let i = 0; i < res['data']['length']; i++) {
this.arrayItems = res['data'][i]['name'] //names which I want to set as input field value and generate input fields for every name
}
}).catch(error => {
this.utilService.showError('Something went wrong', 'Error');
console.log('err is', error);
});
}
addanother():void {
(<FormArray>this.personalForm.get('other')).push(this.addanotherForm());
}
addanotherForm(): FormGroup{
return this.formbuilder.group({
screenname: [''],
});
}
clear(i : number){
(<FormArray>this.personalForm.get('other')).removeAt(i);
}
onSubmit(): void {
console.log(this.personalForm.value);
}
closeModel() {
this.activeModal.close();
}
}
Componenent.html code
<div class="custom_modal pb-3">
<div class="modal-header border-0 p-1 pl-3 pr-3 d-flex justify-content-between align-items-center">
<h3 class="m-0">Project: {{screendetails.name}}</h3>
<button type="button" class="close" data-dismiss="modal" (click)="closeModel()">×</button>
</div>
<div class="modal-body p-3">
<div class="body_top d-flex justify-content-between mb-4 mt-2 align-items-center">
<h3 class="title m-0">Add Screens</h3>
</div>
<form [formGroup]="personalForm" (ngSubmit)="onSubmit()">
<div formArrayName="other" class="form-group" *ngFor="let other of personalForm.get('other').controls; let i = index" >
<div [formGroupName] = "i">
<div class="screen_row mb-4">
<div class="row">
<div class="col-md-3 col-sm-3 d-flex align-items-center">
<label>Screen Name</label>
</div>
<div class="col-md-8 col-sm-8 pl-0 pl-sm-3">
<input type="text" class="form-control rounded-0" formControlName="screenname" name="screenname">
</div>
<div class="col-md-1 col-sm-1 d-flex align-items-center justify-content-center pl-0 pl-sm-3">
<button type="button" class="close" (click)="clear(i)">×</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer border-0 d-table w-100">
<button type="button" class="btn-primary float-left" (click)="addanother()">Add New Screen</button>
<div class="float-right">
<button type="button" class="btn-primary mr-3" data-dismiss="modal" (click)="onSubmit();">Apply</button>
<button type="button" class="btn-primary cancle" data-dismiss="modal" (click)="closeModel()">Cancel</button>
</div>
</div>
</form>
</div>
</div>
This is my code. Please help me setting up by default input fields as per the number of names in API call.Thannk you
Normally, you change your function addAnotherForm to allow pass data
addanotherForm(data:any): FormGroup{
return this.formbuilder.group({
screenname: [data],
});
}
In your case you must change the function addanother
addanother(data:any):void {
(<FormArray>this.personalForm.get('other')).push(this.addanotherForm(data));
}
So, your ngOnInit can be like.
//at first an Empty FormArray
this.personalForm = this.formbuilder.group({
other: this.formbuilder.array([])
});
// Api call
this.pagesService.GetScreens('').then(res => {
console.log('get screens api', res);
for (let i = 0; i < res['data']['length']; i++) {
this.arrayItems = res['data'][i]['name']
this.addanother(res['data'][i]['name'] //fill the array
}
}).catch(error => {
this.utilService.showError('Something went wrong', 'Error');
console.log('err is', error);
});
Well, really you can simply all the code -and really you needn't this.arrayItems- and we use a map
this.pagesService.GetScreens('').then(res => {
this.personalForm=new FormGroup({
other:new FormArray(
res['data'].map(d>=>{
return new FormGroup({
screenname:new FormControl(d.name))
})
})
)
})
}).catch(error => {
this.utilService.showError('Something went wrong', 'Error');
console.log('err is', error);
});
NOTE: You needn't make a ForGroup if you only want yo control a FormArray, and your formArray can be only a formArray of formControls not a FormArray of FormGroup

Angular how to post data with a button using (change) detector?

I am trying to post data to my REST server. When I use a (change) it sends the data to my rest server. When I try to activate the method on my button it doesnt even try to make a POST call. How can I solve this problem? I can't find anything about it.
HTML file:
<div class="container py-5">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-6 mx-auto">
<div class="card rounded-0">
<div class="card-header">
<h3 class="mb-0">Organize</h3>
</div>
<div class="form-group">
<label for="codes" class="m-2">Choose a restaurant:</label>
<form #f="ngForm">
<input
type="text"
list="codes"
class="m-2"
(change)="saveCode($event)">
<datalist id="codes">
<option *ngFor="let c of codeList" [value]="c.name">{{c.name}}</option>
</datalist>
</form>
<button
type="submit"
class="btn btn-primary btn-lg float-none m-2"
id="btnAanmaken"
routerLink="/menu"
(change)="saveCode($event)"
>Aanmaken</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Typescript file:
// Method to post data to backend
public saveCode(e): void {
const name = e.target.value;
const list = this.codeList.filter(x => x.name === name)[0];
this.restaurant.name = list.name;
this.restaurant.address = list.address;
console.log(list.name);
console.log(list.address);
// Additional information to the server content type
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
// Making an array with the values of the restaurant
const data = {
name: list.name,
address: list.address
};
console.log(data);
// POST method
this.http.post('http://localhost:8080/aquadine-jee/resources/restaurant',
JSON.parse(JSON.stringify(data)) , httpOptions)
// wait till it gets posted to the backend
.subscribe( // subscribe to observable http.post
res => {
console.log("response" + " " + res); // log results otherwise log error
},
err => {
console.log('Error occured');
}
);
}
I tried to call the method by:
<button
type="submit"
class="btn btn-primary btn-lg float-none m-2"
id="btnAanmaken"
routerLink="/menu"
(change)="saveCode($event)"
>Aanmaken</button>
and:
<button
type="submit"
class="btn btn-primary btn-lg float-none m-2"
id="btnAanmaken"
routerLink="/menu"
(click)="saveCode($event)"
>Aanmaken</button>
In addition to the answer by #Moslem, change the button type from submit to button
<button type="button" .. > instead of <button type="submit" ...>
Conflict using routerLink routerLink="/menu" and click event.
change routing when back response.
Inject router: Router class and use this.router.navigateByUrl(url: string)
Router
constructor(private router: Router){
}
public saveCode(e): void{
// POST method
this.http.post('http://localhost:8080/aquadine-jee/resources/restaurant',
JSON.parse(JSON.stringify(data)) , httpOptions)
// wait till it gets posted to the backend
.subscribe( // subscribe to observable http.post
res => {
console.log("response" + " " + res); // log results otherwise log error
this.router.navigateByUrl("/menu")
},
err => {
console.log('Error occured');
}
);
}

How to Update data in Modal using Angular2?

This is My Angular2 part.Here Updateuser function for update data in database
export class UserprofileComponent
{
getdata : string;
public data;
Username : any ;
Firstname :any;
updateuser(){
let re = /[?&]([^=#&]+)=([^&#]*)/g;
let match;
let isMatch = true;
let matches = {};
while (isMatch)
{
match = re.exec(window.location.href);
if (match !== null)
{
matches[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
if (match.index === re.lastIndex)
{
re.lastIndex++;
}
}
else {
isMatch = false;
}
}
console.log(matches);
var headers= new Headers({'Content-Type' : 'application/x-www-form-urlencoded '});
var body = JSON.stringify({
username1 : this.user.Username,
firstname1 : this.user.Firstname,
})
this.http.post('../widgets/Update.php?ID='+matches['ID'],body, {
headers:headers; })
.map(res => res.json())
.map(res => {
if(res.success)
{
this.m=res.Message;
}
else{
this.m="wrong";
}
})
.subscribe(
data =>this.getdata = JSON.stringify(data),
err => console.error(err),
() => console.log('done'));
}
}
This is My html part:
<ngl-modal header=" Edit Profile" [(open)]="opened" [size]="size">
<div body>
<div class="form-horizontal" style="margin:auto;" id="editForm" *ngFor="#user of getdata">
<div class="form-group">
<label class="col-md-3 control-label">Username:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="cname" [(ngModel)]="user.Username" />
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label">Firstname:</label>
<div class="col-md-8">
<input type="text" class="form-control" id="ads" [(ngModel)]="user.Firstname"/>
</div>
</div>
<span>{{m}}</span>
<button class="slds-button slds-button--neutral" (click)="cancel()">Cancel</button>
<button class="slds-button slds-button--neutral slds-button--brand" (click)="updateuser()">Save</button>
</ngl-modal>
Here I'd use modal for displaying the data which is display by ngFor.But I want to update this display data so how to do it?Because data is display by ngModel and when I'm taking the whole ngModel value for example if [(ngModel)]="user.name" then it showing the error that user is not define so what to do in this case??
My first guess would be trying let user of getdata instead of #user of getdata.
My second guess would be creating an Array of users getdata: Array<any> as a property of your class, instead of getdata:string, then assign to it.
My third guess: before you get the data, there are no users, so:
<div *ngIf='getdata' class="form-horizontal" style="margin:auto;" id="editForm" *ngFor="#user of getdata"> to make sure you don't try to access the object before it's there.
Before you call updateUser() there are no objects you could show, that's why users are undefined, as far as I can see.
Hope some of this helps, good luck.