This question already has answers here:
Reactjs: page refreshing upon `onClick` handle of Button?
(5 answers)
Closed 3 years ago.
I have a ButtonActor.js for Buttons:
import React from 'react';
import '../../css/index.css';
import '../../css/App.css';
import '../../css/bootstrap.min.css';
import '../../css/font-awesome.css';
import '../../css/floating-labels.css';
import Home from "../view/Home";
import { Route, BrowserRouter as Router } from 'react-router-dom'
class ButtonActor extends React.Component {
isPrimaryButton;
hLink;
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
console.log("clicked");
}
render() {
if(this.props.isPrimaryButton==="true")
{
return (
<div>
<button className="btn btn-lg btn-primary btn-block btn-animated" type="submit">
{this.props.name}
</button>
</div>
);
}
else
{
return (
<div>
<button className="btn btn-sm btn-secondary btn-block btn-animated" type="submit" onClick={this.handleClick}>
{this.props.name}
</button>
</div>
);
}
}
}
export default ButtonActor;
And the have this piece of code in Login.js :
<div className="row justify-content-start">
<form className="form-signin">
<ButtonActor name="Don't Have An Account?" isPrimaryButton="false">
</ButtonActor>
</form>
</div>
Whenever I click on the Button this page just reloads the current page with a ? mark at the end.
How can I resolve this issue ?
As it reloads I can't even see if it is printing in the console or not.
Usually there is no need to insert form tag in your case, this error related to this, when you click on button with type submit, it submit form, and reload the page but if you need to use this tag, and fixed this error, you need add onSubmit eventListener to form tag.
<div className="row justify-content-start">
<form className="form-signin" onSubmit={(event) => event.preventDefault()}>
<ButtonActor name="Don't Have An Account?" isPrimaryButton={false}>
</ButtonActor>
</form>
</div>
and its better to set isPrimaryButton prop as boolean props and edit your ButtonActor.js as below:
render() {
if(this.props.isPrimaryButton===true)
{
return (
<div>
<button className="btn btn-lg btn-primary btn-block btn-animated" type="submit">
{this.props.name}
</button>
</div>
);
}
else
{
return (
<div>
<button className="btn btn-sm btn-secondary btn-block btn-animated" type="submit" onClick={this.handleClick}>
{this.props.name}
</button>
</div>
);
}
}
Related
Below there's the function I use in my JavaScript file. It works sometimes when I clicked the button, but sometimes it doesn't.
How can I fix this issue?
function getEditForm(id) {
console.log("masuk editform")
$.ajax({
url: `${baseUrl}/todos/${id}`,
method: "GET",
headers: {
access_token: localStorage.getItem("access_token")
}
})
.done(todos => {
editPage()
$("#edit-title").val(`${todos.title}`)
$("#edit-description").val(`${todos.description}`)
$("#edit-due-date").val(`${(todos.due_date)}`)
$("#edit-todo-button").on("click", (e) => {
e.preventDefault()
editTodo(id)
})
})
.fail((xhr, text) => {
swal("Oops!", xhr.responseJSON.error[0], "error")
console.log(xhr.responseJSON.error[0])
})
}
Below the code inside document ready, it should be jus like that, right?
$("#btn-edit").on("click", (e) => {
e.preventDefault()
getEditForm(id)
})
below the html code, using append method to make m app dynamic:
$("#card-content").append(`
<div class="col-sm-6" id="todo-${el.id}">
<div class="card mt-3 mx-1 shadow" style="width:auto">
<div class="card-body">
<h5 class="card-title">${el.title}</h5>
<h6 class="card-subtitle mb-2 text-muted">${el.description}</h6>
<p class="card-text">Due date: ${el.due_date}</p>
<span>
<button type="button" class="btn btn-secondary btn-block d-inline mt-2" id="btn-status-${el.id}" style="width:auto;" onclick="updateStatus(${el.id})"><i class="bi bi-x-square"></i> Not Done</button>
<button type="button" class="btn btn-warning btn-block d-inline" id="btn-edit-${el.id}" style="width:auto;"><i class="bi bi-pencil" onclick="getEditForm(${el.id})"></i> Update</button>
<button type="button" class="btn btn-danger btn-block d-inline" id="btn-delete-${el.id}" style="width:auto;"><i class="bi bi-trash" onclick="deleteTodo(${el.id})"></i> Delete</button>
</span>
</div>
</div>
</div>
`)
See here you have an onclick function inside your fontawesome icon(i) tag so the getEditForm() function will be called only when you click on icon not on button part,
also the id you have given in button tag is dynamic
id="btn-edit-${el.id}"
so I think the below code will not work
$("#btn-edit").on("click", (e) => {
e.preventDefault()
getEditForm(id)
})
Workaround is just include onclick event on button tag instead of icon tag and pass id as a parameter to it
Html code:
<div class="col-md-4" *ngFor="let card of allCards">
<p class="card-text">Card Color: {{card.color}}</p>
<button type="button" class="btn btn-sm btn-primary product-btn" (click)="addCard()">Add Card</button>"
Here I also want to bind the value "card.color" into another variable (maybe using ngModel) so that I can use it inside my typescript file in angular 8.
I tried the below but not working:
<p class="card-text" [(ngModel)]="cardColor">Card Color: {{card.color}}</p>
You could send the contents to the button click event's handler.
Template (*.html)
<div class="col-md-4" *ngFor="let card of allCards">
<p class="card-text">Card Color: {{card.color}}</p>
<button
type="button"
class="btn btn-sm btn-primary product-btn"
(click)="addCard(card.color)"
>
Add Card
</button>
Controller (*.ts)
addCard(color: any) {
// use `color` here
}
I am working on signature pad dialogue box and for the dialogue box i am using bootstrap modal. In this activity when i click on complete activity a dialogbox should open asking yes or no on clicking yes a dialog box with signaturepad in modal body and clear button in modal footer.
the problem is when clicking on clear button from modal footer the clear method of signaturepad module is not working Any suggestions would be of great help
import { Component, OnInit, ViewChild, Directive } from '#angular/core';
import { NgbModalConfig, NgbModal } from '#ng-bootstrap/ng-bootstrap';
import {SignaturePad} from 'angular2-signaturepad/signature-pad';
import { ClickOutsideModule } from 'ng-click-outside';
#Component({
selector: 'app-modal',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
})
export class ModalComponent {
#ViewChild('SignaturePad1', { static: true })signaturepad: SignaturePad;
public signaturepadoption = {
minWidth: 2,
penColor: 'rgb(255,0,0)',
backgroundColor: 'rgb(0,0,0)',
canvasWidth: 250,
canvasHeight: 300,
};
closeResult: string;
constructor(private modalService: NgbModal) {}
openSm(content) {
this.modalService.open(content, { centered: true });
}
SignaturepadPopUp(longContent) {
this.modalService.open(longContent, { scrollable: true, centered: true });
}
onClear() {
this.signaturepad.clear();
}
saveSignature() {
const base64 = this.signaturepad.toDataURL('image\png', 0.1);
console.log(base64);
const blob = this.base64toblob(base64);
console.log(blob);
}
base64toblob(base64) {
const bytestring = atob(base64.split(',')[1]);
const stringtype = base64.split(',')[0].split(':')[1].split(':')[0];
const size = bytestring.length;
const saveString: any[] = new Array(size);
for (let i = 0; i < bytestring.length; i++) {
saveString[i] = bytestring.charAt(i);
}
const ia = new Uint8Array(saveString);
return new Blob([ia], {type: stringtype});
}
}
<ng-template #content let-modal>
<div class="modal-header">
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure You want to complete Activity?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" (click)="modal.close('Close click')">No</button>
<button type="button" class="btn btn-primary" (click)="SignaturepadPopUp(longContent)">Yes</button>
</div>
</ng-template>
<ng-template #longContent let-modal>
<div class="modal-header">
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="col-md-12">
<div class="m-signature-pad">
<div class="m-signature-pad-body">
<signature-pad #SignaturePad1 [options]="signaturepadoption"></signature-pad>
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="onClear()">clear</button>
</ng-template>
<button class="btn btn-secondary" (click)="openSm(content)">Complete Activity</button>
The reason this happens is because ng-template is not rendered yet and thus the signature pad will be undefined. A way I found to work around this is to create my signature pad in a separate component and then add that component to the ngbModal.
So in your example:
<ng-template #longContent let-modal>
<div class="modal-header">
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="col-md-12">
<div class="m-signature-pad">
<div class="m-signature-pad-body">
<!-- <signature-pad #SignaturePad1 [options]="signaturepadoption"></signature-pad> -->
<app-my-signature-pad-component></app-my-signature-pad-component> <!-- In this component you add the above commented out line and then do your functionality for the signature pad there. -->
</div>
</div>
</div>
</div>
<button type="button" class="btn btn-primary" (click)="onClear()">clear</button>
</ng-template>
I found that with this approach, you are able to use the ViewChild and don't get the undefined issue.
Hope this makes sense!
My modal window is blocking my time picker on Angular
Component.ts
open() {
const amazingTimePicker = this.atp.open();
amazingTimePicker.afterClose().subscribe(time => {
console.log(time);
});
}
// Triggering the modal window
createApplication(content) {
this.modalService.open(content, {centered: true, size: 'lg'});
}
Modal html
<ng-template #create let-modal>
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">Job Application</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form #createApplicationForm="ngForm" (ngSubmit)="createApplicationForm.form.valid && createForm(createApplicationForm)" >
<div class="form-group">
<div class="input-group">
<input class="form-control" id="preferredContactDate" name="preferredContactDate"
[(ngModel)]="newApplicationFormDateModel" ngbDatepicker #preferredContactDate="ngbDatepicker">
<div class="input-group-append">
//Open time picker here
<button class="btn btn-secondary" (click)="open()"
type="button"></button>
</div>
</div>
</div>
<div class="modal-footer">
<!-- Submit button -->
<input class="btn btn-dark" type="submit" value="Create" />
<button type="button" class="btn btn-dark" (click)="modal.dismiss('Cross click')">Cancel</button>
</div>
</form>
</div>
</ng-template>
However, when i do this, the time picker gets blocked by the modal.
Any ideas?
Stackbliz for timepicker - https://stackblitz.com/edit/amazing-timepicker-example
Referenced to: https://www.npmjs.com/package/amazing-time-picker
Modal: https://ng-bootstrap.github.io/#/components/modal/examples
Update based on answer:
<div class="time-picker">
<input atp-time-picker value="19:00"/>
</div>
CSS
.time-picker {
position:absolute;
z-index : 99999999;
}
.my-custom-class{
z-index: 900;
}
I also tried inline style as well
<input style= "z-index: 99999999;" atp-time-picker value="19:00"/>
We need to get the bootstrap's z-index dynamically and increment it with some arbitrary number and set to the time-picket something like below:
$(document).on('show.bs.modal', '.modal', function (event) {
const zIndex = 1045 + (10 * $('.modal:visible').length);
// this zIndex can be assigned to the time-picker
$(this).css('z-index', zIndex);
setTimeout(function () {
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
}, 0);
});
you can specify a custom class for the modal to overwrite the z-index.
example:
in your js/ts:
this.modalService.open(content, {backdropClass: 'my-custom-class'});
css:
.my-custom-class{
z-index: 900;
}
Your issue is similar to the one mentioned here : https://github.com/owsolutions/amazing-time-picker/issues/129
The proposed solution, as think win win explained, was to increase the timepicker's z-index :
time-picker {
position:absolute;
z-index : 99999999;
}
I want to know, how to hide below shown Bootstrap modal form, after submitting the value to the service. I have tried with commented code, but didn't help me. Is there any alternatives.?
settings.component.ts
import { Component, OnInit} from '#angular/core';
import { CategoryVM } from '../view-models/category';
import { AppDataService } from '../services/app-data.service';
import { NgForm } from '#angular/forms';
import { FormControl, FormGroup, Validators } from '#angular/forms';
import { Location } from '#angular/common';
//declare var $: any;
#Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.css']
})
export class SettingsComponent implements OnInit {
categories: CategoryVM[] = [];
form: FormGroup;
errorMessage: string;
//visible: boolean;
//private visibleAnimate = false;
// public visible = true;
constructor(private dataService: AppDataService, private location: Location) {
dataService.getCountries().subscribe((data) => this.categories = data);
}
ngOnInit() {
this.dataService.vm = { ParentId: 0, Name: "" };
// this.visible = true;
}
onBack() {
this.errorMessage = null;
this.location.back();
}
onCancel() {
this.onBack();
}
onSubmit(form: NgForm) {
this.dataService.createCategory(form.value)
.subscribe(data => {
alert("Value Added Successfully");
//$("#myModal").hide();
//$("#myModal").modal("hide");
// this.visible = false;
this.categories.push(data);
//document.getElementById("openModalButton").click();
});
}
}
Please focus in OnSubmit() event of form in above and Below is the template
settings.component.html
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">start here</button>
<!--<button id="openModalButton" [hidden]="true" type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">start here</button>-->
<div id="myModal" class="modal fade" role="dialog">
<!--<div id="myModal" class="modal fade" role="dialog" *ngIf="visible">-->
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Login</h4>
</div>
<div class="modal-body">
<form class="cat-form" #categoryForm="ngForm" (ngSubmit)="onSubmit(categoryForm)">
<!--<form class="cat-form" #categoryForm="ngForm" (ngSubmit)="onSubmit(categoryForm);visible=false;">-->
<label>Name</label>
<div class="form-group">
<input class="form-control" name="Name" placeholder="Name" #Name="ngModel" [(ngModel)]="dataService.vm.Name">
</div>
<div class="form-row">
<div class="form-group col-md-8">
<button type="submit" class="btn btn-lg btn-block btn-primary">Create</button>
</div>
<div class="form-group col-md-4">
<button type="button" class="btn btn-lg btn-block" (click)="onCancel()" data-dismiss="modal">Cancel</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
If I use commented line of code Modal-form will hide, but opacity remains as shown in this image
Your commented code is a jQuery code, so I assume you don't use an Angular Framework (like ng-bootstrap for example).
You should have a look and integrate one of the abstraction of Bootstrap.
Use jQuery in your component means you manipulate directly the dom and this is really not the good way to do.
https://ng-bootstrap.github.io/
https://github.com/valor-software/ngx-bootstrap