I am getting more than one Confirmation Dialog boxes in primeng - html

I am trying to implement confirm dialog using primeng in my angular web application. When I click the button which is supposed to call the method, I get the dialog twice.
I put a console log to check if the method is getting called twice, Turns out, it is getting called once on click. Below is the code.
HTML :
<div class="card">
<p>{{eachsecret.title}}</p>
<p>{{eachsecret.date}}</p>
<div class="container">
<i class="pi pi-eye"></i>
<i class="pi pi-download" (click)="download(eachsecret.sid)"></i>
<i class="pi pi-pencil"></i>
<p-confirmDialog [style]="{width: '50vw'}" [baseZIndex]="10000" rejectButtonStyleClass="p-button-text"></p-confirmDialog>
<i class="pi pi-trash" (click)="delete(eachsecret.sid)"></i>
</div>
</div>
Delete method :
delete(sid) {
console.log("confirmation dialogue method called");
this.confirmationService.confirm({
message: 'Are you sure that you want to proceed?',
header: 'Confirmation',
icon: 'pi pi-exclamation-triangle',
accept: () => {
this.httpClient.delete(environment.baseURL+'/secret/'+sid, { observe: 'response'}).subscribe(data => {});
this.messageService.add({severity:'info', summary:'Confirmed', detail:'You have accepted'});},
reject: () => {this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});}
});
}

Assign a key to both confirm method call and html code.
HTML:
<p-confirmDialog [style]="{width: '50vw'}" [baseZIndex]="10000" rejectButtonStyleClass="p-button-text" key="myDialog"></p-confirmDialog>
TS:
this.confirmationService.confirm({
message: 'Are you sure that you want to proceed?',
header: 'Confirmation',
icon: 'pi pi-exclamation-triangle',
accept: () => {
this.httpClient.delete(environment.baseURL+'/secret/'+sid, { observe: 'response'}).subscribe(data => {});
this.messageService.add({severity:'info', summary:'Confirmed', detail:'You have accepted'});},
reject: () => {this.messageService.add({severity:'error', summary:'Rejected', detail:'You have rejected'});},
key: "myDialog"
});

Related

react js form getting submitted twice

I have below code which calls save form
<div className="col-md-4">
<button onClick={saveCredit} className="btn btn-success">
Submit
</button>
I have onclick handler function as
const saveCredit = () =>{
//validate form
// call api to save form attributes
CreditTransactionDataService.create(data)
.then(response => {
setSubmitted(true);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
after successful save , I will show successful message as below.
{submitted ? (
<div>
<h4>You submitted successfully!</h4>
<button className="btn btn-success mr-2" onClick={newCreditTransaction}>
Add
</button><Link style={{ fontWeight: 'bold' }} className="btn btn-warning" to={"/creditTransactionList"}>
return to List
</Link>
</div>
)
but the problem is, my form is getting submitted twice, and creating duplicate records with same values.... couple of save options, i restricted with unique key column at database level, but few tables still need to handled at code level..
I´m unable to reproduce it in codepen, but one solution a little bit hacky could be check in the method if it is submitted already
const saveCredit = {
//Check if it is submitted
if(!submitted){
//validate form
// call api to save form attributes
CreditTransactionDataService.create(data)
.then(response => {
setSubmitted(true);
console.log(response.data);
})
.catch(e => {
console.log(e);
});
}
}
This may not be the best but could do the job
Also a thing I did notice is that your saveCredit function not look like a function.
Why not declare as an arrow function? Like:
const saveCredit = () => { //Your code }
Your button doesn't need onClick event handler if it's responsible for submitting a certain form. You should add type="submit" to button and onSubmit to form tag itself.
You should go for this approach to handle submitting correctly (clicking of the button or hitting enter by the user are covered).

How to make a .cshtml pop window in ASP .NET Core MVC web application

I am a newbie to programming & I am trying to make a ASP .NET Core MVC web application. There I have to upload a user profile image. To do this I should make a pop up window like in Facebook. (As an example, when user clicked on camera icon instead of going to another page, a pop window to upload image has to be appeared.)
Following is the line in the Profile.cshtml page that redirects to the UploadUserImage.cshtml page that should appear as a popup window. (that file is very large that is why I thought to publish only this line)
<a asp-action="UploadUserImage" asp-controller="UserImages"><i class="fas fa-camera camera-icon-profile"></i></a>
And following is the .cshtml file that has to be appear as popup upon clicking the above link.
UploadUserImage.cshtml
#model IEnumerable<WebApp.Models.User>
#{
Layout = "/Views/Shared/_Profile.cshtml";
ViewData["Title"] = "Upload your photo";
}
<div class="container">
<div class="row">
#using (Html.BeginForm("UploadProfilePicture", "UserImageUpload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">Upload your picture</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<input type="file" name="file" />
<input type="submit" class="btn btn-primary form-control" value="Save Photo" />
</div>
</div>
</div>
</div>
}
</div>
}
</div>
</div>
I got to know that by a front end jQuery can be used to make the popup window appear. but I do not know how to apply it. Can please somebody let me know how to do it?
Thank you very much for your time.
Create a PartialView to your UploadPage
Search and install Magnific-Popup packages
Create a Function to call the Popup Window in the Html
<script>
function ShowPopup(idUserProfile) {
$.ajax({
type: 'POST',
url: "#Url.Action("Method", "Controller")",
data: { idUserProfile },
success: function (response) {
$.magnificPopup.open({
items: {
src: response
},
type: 'inline',
modal: true,
closeOnBgClick: false,
focus: '#btnDismiss'
});
},
error: function (xhr, ajaxOptions, thrownError) {
}
});
}
</script>
maybe you don´t use the idUserProfile
In the Controller class call the partial View
public ActionResult Upload()
{
return PartialView("_UploadPage");
}
In Html to call the Function
<button class="btn btn-primary" onclick="ShowPopup()">Show Upload</button>

Vue.js edit post by id

I'm starting with vue.js and I was reading this question to help me loading some posts from DB with v-for.
Below each post there are Edit and Delete buttons. I can delete each post by its ID correctly. And I can open the input to edit post title correctly too.
But I cannot save input changes when I click on save button. It returns to the initial text.
And when I click to edit it opens all the inputs titles.
Is there a way to open the specific post title and keep the changes after save it?
<div id="app" class="row mb-50">
<div v-for="(item, index) in tours" v-bind:key="item.id" id="tours" class="col-md-12 mb-30">
<div class="tour-list">
<div class="tour-list-title">
<p>
<input type="text" ref="item.id" :value="item.title" :disabled="!editingTour"
:class="{view: !editingTour}" />
</p>
</div>
<div class="tour-list-description">
<p>
{{ item.description }}
</p>
</div>
<div class="tour-list-options">
<div class="row">
<div class="col-md-6">
<span>
<button #click="editingTour = !editingTour" v-if="!editingTour"
class="btn border btn-circle tour-list-edit-btn">Edit</button>
</span>
<span>
<button #click="save" v-if="editingTour"
class="btn border btn-circle tour-list-edit-btn">Save</button>
</span>
<span>
<button #click="editingTour = false" v-if="editingTour"
class="btn border btn-circle tour-list-delete-btn">Cancel</button>
</span>
<span>
<button #click="deleteTour(item.id, index)" v-if="!editingTour"
class="btn border btn-circle tour-list-delete-btn">Delete</buton>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
vue.js:
let app = new Vue({
el: '#app',
data: {
editingTour: false,
tours: null,
errored: false,
edited: false,
deleted: false,
item: {
title: null,
description: null
}
},
created: function () {
this.searchTour()
},
methods: {
searchTour: function () {
axios.post('getPosts.php', { "token": param }).then((response) => {
this.tours = response.data;
}).catch((error) => {
this.errored = error;
});
},
editTour: function (id) {
axios.post('editPosts.php', { "token": token, "tourID": id }).then((response) => {
this.edited = response.data;
}).catch((error) => {
this.errored = error;
});
},
deleteTour: function (id) {
if (confirm('Are You sure?')) {
const index = this.tours.findIndex(item => item.id === id);
if (~index) {
axios.post('deletePosts.php', { "token": token, "tourID": id }).then((response) => {
this.deleted = response;
this.tours.splice(index, 1);
}).catch((error) => {
this.errored = error;
});
}
}
},
save: function () {
this.item.title = this.$refs['item.id'].value;
this.editingTour = !this.editingTour;
console.log(this.item.title);
}
}
});
In console.log(this.item.title); is returning undefined.
I have changed ref="item.id" to ref="title" and this.item.title = this.$refs['item.id'].value; to this.item.title = this.$refs['title'].value; but it did not work.
You should use in your input v-model instead of ref it will bind your model with the value you are editing, in general in vue we avoid direct DOM manipulation when possible, like so:
<input type="text" ref="item.id" v-model="item.title" :disabled="!editingTour"
:class="{view: !editingTour}" />
Where calling your function e.g. editTour you can pass it the item (if it's in the template to save the updated version like so:
#click="editTour(item)"
You can use the v-model directive to create two-way data bindings on form input, textarea, and select elements. It automatically picks the correct way to update the element based on the input type. Although a bit magical, v-model is essentially syntax sugar for updating data on user input events, plus special care for some edge cases.
Source : https://v2.vuejs.org/v2/guide/forms.html
Example:
<input v-model="description" placeholder="my description">
The above input value will then be binded to the description element of your data object and vice-versa - if one changes, the other is updated to the same value:
data:{
description: "default value"
}
So, when you DB request is ready you can update the value of the description within the DB method:
this.description=db.result.description
and the value of the input will also update.
Likewise, if the user changes the value of the input field, the value bound to the data element will be updated also. So, when saving back to DB:
db.update({description:this.description})
(note: the db methods here are for example purposes only. Replace with the relevant DB methods for your backend service.)

Ionic : NavControlller.setRoot redirect me back to my page

I have a problem on my ionic application : when I try to navigate back to my HomePage after doing a PayPal payment I get directly redirected back to my page.
This only occurs when the app is deployed on my iOS device and the weird part is that if I don't proceed to any PayPal payment the navigation work perfectly.
Here some part of my code :
html :
[...]
<div id="page7" [hidden]="hidePage7">
<h1>Order summary</h1>
[...]
<button class="bigButton" (click)="validatePage7()">VALIDER</button>
</div>
<div id="payment" [hidden]="hidePayment">
<div class="upperPart">
<h1>Paiement</h1>
</div>
<div id="paypal-button"></div>
</div>
<div id="page9" [hidden]="hidePage9">
<div class="upperPart">
<h1>Paiement</h1>
</div>
<div class="midPart">
<h3>{{endMessage}}</h3>
</div>
<div class="bottomPart">
<button class="bigButton" (click)="goToHome()">ACCUEIL</button>
</div>
</div>
typescript :
validatePage7(){
this.bookingService.create(this.booking).subscribe((response) => {
this.hidePage7 = true;
this.hidePayment = false;
paypal.Button.render({
env: 'sandbox',
payment: (data, actions) => {
return actions.request.post(Api.API_URL + '/payment/create-payment', {
bookingId: response.id
})
.then(function (res) {
return res.id;
});
},
onAuthorize: (data, actions) => {
return actions.request.post(Api.API_URL + '/payment/execute-payment', {
paymentID: data.paymentID,
payerID: data.payerID
})
.then((res) => {
this.endMessage = "Commande réalisée avec succès !";
this.hidePayment = true;
this.hidePage9 = false;
});
}
}, '#paypal-button');
});
}
goToHome(){
this.navController.setRoot(MainPage);
}
Try Using this: this.navController.popTo(this.navCtrl.getByIndex(0));//pops to menu page
If the Menu Page is your root page you can use that function, if not you can change the index number and it will pop in the order of your page stack.
Edit: Alternative solution as stated in the comments would be to create a success page using .push(); and once navigated there allow user to pop back to MainPage.

Durandaljs generating sub menu from json

Alright, I am fairly new to durandal. I am really struggling getting trying to accomplish this.
Here is what I am trying to do: There is a main navigation that is compromised of an inbox, draft, submitted, etc. Clicking on these, gives the user a submenu that comes out to the side of the main navigation. This submenu is generated by json data that I get from the server. Clicking an an option from the submenu should open the document in a viewer viewmodel based on the id of the document.
Ex.
User clicks on inbox
2. Menu comes out that has documents from their inbox. User clicks on view
3. Document that is clicked is displayed to the user.
4. So when they get to this point, I want the url to be mysite.com/#inbox/viewer/123456 (123456 is documentid)
I just haven't been able to find decent examples that are similar to this, and was wondering if someone could help point me in the right direction.
I kind of did it by making each main navigation link to a module, and have a document window in each of those modules, but I thought there had to be a better way. So what I am trying to do is keep my subnavigation in the shell. I don't want to have a module for each of my main navigation items.
Here is my shell code right now:
shell.js
define(['durandal/system', 'services/logger', 'plugins/router', 'durandal/activator'], function (system, logger, router, activator) {
//#region Internal Methods
function log(msg, data, showToast) {
logger.log(msg, data, system.getModuleId(shell), showToast);
}
function logError(msg, data, showToast) {
logger.logError(msg, data, system.getModuleId(shell), showToast);
}
function navigateRoute(hashValue) {
var target = hashValue.hash;
$("body").addClass("subnav-active");
document.cookie = "subNav=true";
$(target).addClass("current");
router.navigate(target, {replace: true, trigger: false });
}
var routes = [
{ route: '', hash: '#home', moduleId: 'home', title: '', nav: false, cssClass: 'icon-inbox' },
{ route: 'inbox', hash: '#inbox', moduleId: 'inbox', title: 'Inbox', nav: true, cssClass: 'icon-inbox' },
{ route: 'drafts', hash: '#drafts', moduleId: 'drafts', title: 'Drafts', nav: true, cssClass: 'icon-file-alt' },
{ route: 'submitted', hash: '#submitted', moduleId: 'submitted', title: 'Submitted', nav: true, cssClass: 'icon-hand-right' },
{ route: 'completed', hash: '#completed', moduleId: 'completed', title: 'Completed', nav: true, cssClass: 'icon-check' },
{ route: 'settings', hash: '#settings', moduleId: 'settings', title: 'Settings', nav: true, cssClass: 'icon-cog' }
];
//#endregion
var shell = {
activate: function () {
router.on('router:route:not-found', function (fragment) {
logError('No Route Found', fragment, true);
});
return router.makeRelative({ moduleId: 'viewmodels' }) // router will look here for viewmodels by convention
.map(routes) // Map the routes
.buildNavigationModel() // Finds all nav routes and readies them
.activate(); // Activate the router
}
,
router: router,
navigateRoute: navigateRoute
};
return shell;
});
shell.html
<div class="main-wrapper wrapper">
<div class="container_template">
<header class="pageheader">
<nav class="mobile-nav">
<a class="menu-button" href="#main-navigation">
<i class="icon-reorder"></i><span>Menu</span>
</a>
</nav>
<h1 class="logo">template</h1>
<nav class="nav-user">
<a class="close" href="#">
<i class="icon-chevron-right"></i>
<span>Main</span>
</a>
</nav>
</header>
<!-- Begin Header/Navigation -->
<div class="main-navigation" role="banner">
<div class="main-navigation-inner inner">
<nav class="navigation">
<ul data-bind="foreach: router.navigationModel">
<li>
<a class="nav-button" data-bind="attr: {'data-target': hash,}, css: {'nav-button' : isActive, active: isActive }, click: function(hash) { $root.navigateRoute(hash);return true},">
<i data-bind="css: cssClass"></i>
<span data-bind="html: title"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- End Header/Navigation -->
<!-- Sub Navigation Elements -->
<!--This is my sbumenu-->
<div id="inbox" class="navigation-sub">
<div class="navigation-sub-inner inner">
<div class="navigation-sub-header">
<a class="close" href="#">×</a>
<h3>Inbox</h3>
</div>
<div class="navigation-sub-search">
<form>
<input type="text" placeholder="Search" />
<button>Go</button>
</form>
</div>
<ul data-bind="contentsOfInbox">
<li>
<a data-bind="href : linktoDocuemntViewer" href="" class="form-open">
<i class="icon-file-alt"></i><span data-bind="html: NameofDocumentHere"></span>
<span class="date" data-bind="html: DateOfDocumentHere"></span>
</a>
</li>
</ul>
</div>
</div>
<!-- End SUB NAV -->
<!--Begin Main-->
<!--Documents would appear here-->
<div class="main" data-bind=" router: { cacheViews: false }">
</div>
<!-- End Main -->
</div>
Thanks for any help
For what you are trying to do it sounds like using the navigationModel will not work. From my experience, the navigationModel and route are a 1 to 1 relationship. What you are trying to do is have one route with parameters tied to multiple menu items. To do this you should separate your menus and routes. Remember at the heart of everything you are just binding javascript objects and collections to html elements. The router.navigationModel property is just that, a collection of javascript objects that is built from your defined routes. When you call .buildNavigationModel() that is what it is doing, building up a new collection of javascript objects for you to bind to your menu html. There is nothing stopping you from creating a completely new property on your shell viewmodel that contains your own custom collection of javascript menu objects and binding that to your UL/LI navigation html. If you make this new menu collection a computedObservable you could then add to it in a lazy fashion as you needed to and since it is bound with knockout, changes would appear in the UI automatically. I have done this on a number of different projects and it works fine. I build a menu table in the backend and then just return only the items that the user has access to and use that to build my UI menu. To make navigation work, I keep the urlhash in the table and bind that to the anchor tags. When you are creating routes, you don't have to set the hash property, the router plugin will take care of that for you. So for your requested example, create a menu collection like this:
{ displayname: 'Inbox' cssClass: 'icon-inbox', urlHash: '' children[
{ displayname: 'Doc 1' cssClass: 'icon-message', urlHash: 'inbox/viewer/12345' },
{ displayname: 'Doc 2' cssClass: 'icon-message', urlHash: 'inbox/viewer/12346' },
{ displayname: 'File 1' cssClass: 'icon-message', urlHash: 'inbox/viewer/12347' }]}
create a route like this:
{ route: 'inbox/viewer/:messageId', moduleId: 'home', title: '', nav: false, cssClass: 'icon-inbox' },
see the durandal docs for info on passing parameters to routes
expose this menu as a computedObesrvable from your shell and bind that to you UL/LI menu html instead of the router.NavigationModel. When needed, change the contents of the children property of the inbox menu with new data from the server.