Javascript unobtrusive onclick with sweetalert - javascript

Good Evening,
I'm fairly new to JavaScript. I have a book and scour the internet when looking for answers. I see that the JavaScript landscape seems to have a plethora of paths and frameworks. To the question, I'm trying to use unobtrusive javascript with sweetalert. I had an issue with onclick finishing the function before an option was selected. I altered the function to return false by default and let the path nullify the onlick function and click the button. Is the following reasonable form ? Or would another method be recommended for the same effect? If so, please indicate why its better. Also, no framework/library answers for the moment please.
window.onload = function() {
function doSomething() {
var button = document.getElementById("edit");
swal({
title: 'Are you sure?',
text: 'You will not be able to recover this imaginary file!',
type: 'warning',
showCancelButton: true,
confirmButtonText: 'Yes, Update it!',
cancelButtonText: 'No, stop'
}).then((result) => {
if (result.value) {
button.onclick = null;
button.click();
// For more information about handling dismissals please visit
// https://sweetalert2.github.io/#handling-dismissals
} else if (result.dismiss === swal.DismissReason.cancel) {
swal(
'Cancelled',
'No Update Occured :)',
'error'
)
}
})
return false;
}
document.getElementById("edit").onclick = doSomething;
<form action="{{route('categories.update',$cat->id)}}" method="post">
{{method_field('patch')}}
<div class="form-group">
<label for="title">Name</label>
<input type="text" name="name" class="form-control" value="{{$cat->name}}">
<label for="description">Description</label>
<input type="text" name="description" class="form-control" value="{{$cat->description}}">
</div>
<button class="btn btn-primary" type="submit" id="edit">Edit Category</button>
{{#csrf_field()}}
</form>

Related

How to pass a variable from one method to another Vue?

Below is an example of my old code which was working. This code created a confirmation screen and on conformation deleted a user. However I want to use a toast element to help create a better confirmation screen. This toast element requires the methods to be split up into onConfirm and onReject. And im wondering if there is a way to pass the variable from my deleteUser method into the onConfirm method similar to how I pass it in the code below. (.then(this.onTeacherDeleted(user))
deleteUser(user) {
if (confirm("Are you sure you want to delete: " + user.name + "?")) {
this.working = true;
axios.delete('/teachers/' + user.id)
.then(this.onTeacherDeleted(user))}
// this.$toast.add({severity: 'warn', summary: 'Are you sure?', detail: 'Are you sure you want to delete this placement?', group: 'bc'});
},
onTeacherDeleted (user) {
this.$toast.add({severity:'success', summary: user.name + 'Deleted Successfully', detail:'The teacher was successfully delted from the database', life: 3000});
window.location.reload()
}
How do I pass the user variable into the onConfirm method from the deleteUser method?
deleteUser(user) {
this.$toast.add({severity: 'warn', summary: 'Are you sure?', detail: 'Are you sure you want to delete this placement?', group: 'bc'});
},
onConfirm(user) {
this.$toast.removeGroup('bc');
this.working = true;
axios.delete('/teachers/' + user.id)
.then(this.onTeacherDeleted(user))
},
onReject() {
this.$toast.removeGroup('bc');
},
The onConfirm and onReject are both on click events that happen earlier in the code (see below) :
<button class="btn border border-success rounded-3" type="button" #click="onConfirm" this.onTeacherDeleted(user) aria-expanded="false">
<button class="btn border border-danger rounded-3" type="button" #click="onReject" aria-expanded="false">
If you show more of your code maybe i can give a better solution, but from what i can see, you can just make a variable to track which user is being deleted at the moment and set its value in the:
deleteUser(user) {
this.$toast.add({severity: 'warn', summary: 'Are you sure?', detail: 'Are you sure you want to delete this placement?', group: 'bc'});
this.userToBeDeleted = user;
},
And then just use that variable in the onConfirm:
onConfirm() {
this.$toast.removeGroup('bc');
this.working = true;
axios.delete('/teachers/' + this.userToBeDeleted.id)
.then(this.onTeacherDeleted(this.userToBeDeleted))
},

Bootstrap V5 Form Validation & Sweetalert2 : Showing success message after successful submission

I have simple form based on Bootstrap 5 with a validation option I'm trying to display alert message if the form field is successfuly submited using Sweatalert2.
Here is my Code :
HTML
<form action="" method="POST" class="needs-validation" novalidate>
<label for="validationCustomUsername" class="form-label">Username</label>
<div class="input-group has-validation mb-3">
<span class="input-group-text" id="inputGroupPrepend">#</span>
<input type="text" class="form-control" id="validationCustomUsername" placeholder="Username *" aria-describedby="inputGroupPrepend" required />
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
JS
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
Live Example
I was having the same issue and came across this post which quite helpful.
Below code might help:
......
form.classList.add('was-validated');
if (form.reportValidity()) {
event.preventDefault()
Swal.fire({
position: 'center',
icon: 'success',
title: 'Your application has been submitted successfully!',
showConfirmButton: false,
timer: 2500
}).then((result) => {
// Reload the Page
location.reload();
});
}
It will reload the page after form submission.
This is may be too late, but I hope it can help others. I have the same issue. Then, I tried to combine bootstrap validation inside the SweetAlert Confirmation Box before submitting the form.
I create the code like below:
$('#submitForm').on('click', function (e) {
e.preventDefault();// prevent form submit
/*this part is taken from bootstrap validation*/
var forms = document.getElementsByClassName('needs-validation');
var validation = Array.prototype.filter.call(forms, function (form) {
if (form.checkValidity() === false) {
form.classList.add('was-validated');
}
else {
Swal.fire({
title: 'Are you sure?',
text: "It cannot be undone",
type: 'warning',
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, send it!'
}).then((result) => {
if (result.value) {
/*submit the form*/
$("#formsubmitsekali").submit();
}
});
}
}, false);
});
submitForm is the ID name for the button ID for submit the form.
formsubmitsekali is the form ID.
By doing so, if the required field is not filled, it will show the bootstrap validation without showing Sweetalert confirmation box. But if all of required fields are filled, the Sweetalert will show up.
The same behavior also happens if you have email input type, but it is filled by non-email, it will run the bootstrap validation first. It is also work if you use HTML5 pattern inside the input type and the user fills with the wrong pattern.

Dynamically generated input fields cannot be filled

I have encountered an issue with my code, while developing a project. I dynamically add a login form to a certain div in the DOM-Tree. It is all nice and fine, all elements are generated and all attributes are added, but I cannot access either of the fields, let alone submit it. Can somebody please spot the issue within?
loginArea.click((e) => {
e.preventDefault();
loginArea
.empty()
.append(
$(document.createElement('form'))
.attr({id: 'user__loginform'})
.append(
$(document.createElement('p'))
.addClass('user__action')
.text('Please enter your credentials!')
)
.append(
$(document.createElement('input'))
.prop({
type: 'email',
id: 'login_mail',
})
.attr({
placeholder: 'Please enter a valid e-mail adress!',
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.prop({
type: 'text',
id: 'login_pw',
})
.attr({
placeholder: 'Please enter a password!',
minglength: 9,
maxlength: 16,
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.attr({
form: 'user__loginform',
type: 'submit',
value: 'Login'
})
)
)
});
Thank you a lot in advance
EDIT:
Incorporating the input I have received, I have shortened the function to this, and added .off() at the end. This seems to solve the issue I had, as for now the dynamically generated input can be filled out.
signupArea.click((e) => {
e.preventDefault();
let formTemplate = `
<div id="form-template" class="user__action">
<form id="user__registform">
<p>Please enter your preferred credentials!</p>
<input type="email" id="regist_mail" placeholder="Please enter a valid e-mail!" required="required" form="user__registform">
<input type="text" id="regist_pw" placeholder="Please enter a password!" minglength="9" maxlength="16" required="required" form="user__registform">
<input form="user__registform" type="submit" value="Register" class="user__regist--submit">
</form>
</div>
`;
signupArea.html(formTemplate);
signupArea.off();
});
The issue is because you've bound the click handler to the loginArea element, yet every time you click that element, or importantly an element within it, the event bubbles back up and fires the event again, which clears the content and re-inserts a fresh form element.
To fix this you could add the event which adds the form to an element outside of loginArea, like this:
$('#foo').click((e) => {
e.preventDefault();
$('#loginarea')
.empty()
.append(
$(document.createElement('form'))
.attr({
id: 'user__loginform'
})
.append(
$(document.createElement('p'))
.addClass('user__action')
.text('Please enter your credentials!')
)
.append(
$(document.createElement('input'))
.prop({
type: 'email',
id: 'login_mail',
})
.attr({
placeholder: 'Please enter a valid e-mail adress!',
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.prop({
type: 'text',
id: 'login_pw',
})
.attr({
placeholder: 'Please enter a password!',
minglength: 9,
maxlength: 16,
required: true,
form: 'user__loginform'
})
)
.append(
$(document.createElement('input'))
.attr({
form: 'user__loginform',
type: 'submit',
value: 'Login'
})
)
)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="foo">Click me to add form</button>
<div id="loginarea"></div>
You should also note that the logic you're using to create the form is unnecessarily long winded and not a good separation of concerns.
A much better approach is to store a template in your HTML and use it to create the new dynamic content. This way if you need to make a change to the form layout in the future it can be done directly in the HTML. The JS becomes completely agnostic of the UI. Try this:
$('#foo').click((e) => {
e.preventDefault();
let formTemplate = $('#form-template').html();
$('#loginarea').html(formTemplate);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="foo">Click me to add form</button>
<div id="loginarea"></div>
<script type="text/html" id="form-template">
<form id="user__loginform">
<p class="user__action">Please enter your credentials!</p>
<input type="email" id="login_mail" placeholder="Please enter a valid e-mail adress!" required="required" form="user__loginform">
<input type="text" id="login_pw" placeholder="Please enter a password!" minglength="9" maxlength="16" required="required" form="user__loginform">
<input form="user__loginform" type="submit" value="Login">
</form>
</script>

Prime-NG Confirm Dialog: Hide the Button after Confirmation

I'm struggling with a problem using Angular and PrimeNG.
There is an Input Field for weight allowing numbers up to 150. If the typed in value is greater than 150, a Confirm Button appears below the Input Field.
If this button is clicked, the Confirm Dialog pops up, asking "Are you sure?". It contains two buttons to choose from, "Yes" and "No".
1.) Choosing "No" should close the Confirm Dialog and delete the previously typed-in value in the input field (this works). The Confirm Button shall vanish (fails).
2.) Choosing "Yes" should close the Confirm Dialog and leave the typed-in value (this works). Confirm button shall vanish (also fails).
Is it somehow possible to let the button disappear after the Confirm Dialog is closed?
test.component.html:
<div class="p-col-12 p-md-6 p-lg-5">
Weight:
<div class="ui-inputgroup">
<input pInputText type="number" id="weight" name="weight" [(ngModel)]="newTest.testWeight"
placeholder="---">
<span class="ui-inputgroup-addon">kg</span>
</div>
<div *ngIf="validateIfWeightOutsideRange()">
<div>
<p-confirmDialog key="confirmWeightTest"></p-confirmDialog>
<button type="button" (click)="confirmWeightTest()" pButton icon="pi pi-check"
label="Please confirm!">
</button>
<p-messages [value]="messagesWeightTest"></p-messages>
</div>
</div>
</div>
test.component.ts
messagesWeightTest: Message[] = [];
confirmWeightTest() {
this.confirmationService.confirm({
message: 'Are you sure?',
header: 'Confirmation',
icon: 'pi pi-exclamation-triangle',
key: 'confirmWeightTest',
accept: () => {
this.messagesWeightTest = [{
severity: 'info', summary: 'Confirmed', detail: 'The input is correct.'}];
},
reject: () => {
this.sessionService.newTest.testWeight = null;
}
});
}
Please note: The method "validateIfWeightOutsideRange()" works, therefore I think it's unnecessary to show it here.
Here is the link to PrimeNG's documentation: https://www.primefaces.org/primeng/#/confirmdialog
Maybe you have an idea?
You can simply take one bool variable and set it on confirmDialog button click
messagesWeightTest: Message[] = [];
public weightConfirmed: boolean = false;
confirmWeightTest() {
this.confirmationService.confirm({
message: 'Are you sure?',
header: 'Confirmation',
icon: 'pi pi-exclamation-triangle',
key: 'confirmWeightTest',
accept: () => {
this.messagesWeightTest = [{
severity: 'info', summary: 'Confirmed', detail: 'The input is correct.'}];
this.weightConfirmed = true;
},
reject: () => {
this.sessionService.newTest.testWeight = null;
this.weightConfirmed = true;
}
});
}
<div *ngIf="validateIfWeightOutsideRange()">
<div>
<p-confirmDialog key="confirmWeightTest"></p-confirmDialog>
<button *ngIf="!weightConfirmed" type="button" (click)="confirmWeightTest()" pButton icon="pi pi-check"
label="Please confirm!">
</button>
<p-messages [value]="messagesWeightTest"></p-messages>
</div>
</div>

Delete category with Sweet-alert message and Laravel 5.2

I have Categories and sub categories listed in my view. I also have a delete category button, which does work, and deletes the category and all of its sub cateories. What I want to do is before deleting a Parent category, I want the sweet alert button to pop up and ask if your sure you want to delete this category, with a yes and no button? I know I have to use ajax probably to accomplish does, but Im Not so great with ajax. Right now this is what I have, and when I click the delete button it deletes the categories, but the sweet alert message doesn't show up.
Route.php
/** Delete a category **/
Route::delete('admin/categories/delete/{id}', [
'uses' => '\App\Http\Controllers\CategoriesController#deleteCategories',
'as' => 'admin.category.delete',
'middleware' => ['auth'],
]);
CategoriesController.php:
class CategoriesController extends Controller {
/** More function here, just hidden for ease right now **/
/**
* Delete a Category
*
* #param $id
* #return \Illuminate\Http\RedirectResponse
*/
public function deleteCategories($id) {
// Find the category id and delete it from DB.
Category::findOrFail($id)->delete();
// Then redirect back.
return redirect()->back();
}
}
My form:
#foreach ($categories as $category)
{{ $category->category }}
<form method="post" action="{{ route('admin.category.delete', $category->id) }}" class="delete_form">
{{ csrf_field() }}
<input type="hidden" name="_method" value="DELETE">
<button id="delete-btn">
<i class="material-icons delete-white">delete_forever</i>
</button>
</form>
#endforeach
And My sweet alert call:
<script type="text/javascript">
$('#delete-btn').on('click', function(e){
e.preventDefault();
var self = $(this);
swal({
title: "Are you sure?",
text: "All of the sub categories will be deleted also!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes, delete it!",
closeOnConfirm: true
},
function(isConfirm){
if(isConfirm){
swal("Deleted!","Category and all sub categories deleted", "success");
setTimeout(function() {
self.parents(".delete_form").submit();
}, 2000);
}
else{
swal("cancelled","Your categories are safe", "error");
}
});
});
</script>
Bind the click event to DOM instead of the element.
$(document).on('click', '#delete-btn', function(e) { ... });
This also resolves issues with dynamically loaded elements, for eg: rendering action buttons after an ajax call.
Got it working, I had to do this for my sweet alert JavaScript:
$(document).on('click', '#delete-btn', function(e) {
e.preventDefault();
var self = $(this);
swal({
title: "Are you sure?",
text: "All of the sub categories will be deleted also!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes, delete it!",
closeOnConfirm: true
},
function(isConfirm){
if(isConfirm){
swal("Deleted!","Category and all sub categories deleted", "success");
setTimeout(function() {
self.parents(".delete_form").submit();
}, 1000);
}
else{
swal("cancelled","Your categories are safe", "error");
}
});
});
Thanks to maximl337 for the help!
Use the submit event on the DOM node instead of the jquery object:
$('.delete_form')[0].submit();

Categories

Resources