So I have a DatePicker that I can change a certain field with, but I want it to update the HTML only when the user confirms the change.
However, currently, when I use the (ionChange) event in my ion-datetime element, it updates the UI automatically before my confirmation alert pops up.
How can I make it so that the value in my date picker will only change when the user presses confirm?
updateStartTime(startTime) {
let alert = this.alertControl.create({
title: 'Change start time',
message: 'Are you sure you want to update the start time for this event?',
buttons: [{
text: 'Cancel',
handler: () => {
console.log('cancel');
}
}, {
text: 'Confirm',
handler: () => {
console.log(startTime);
}
}]
});
alert.present();
}
<ion-item detail-push>
<ion-label><b>Start: </b></ion-label>
<ion-datetime displayFormat="hh:mm A"
[(ngModel)]="item.EventStart"
(ionChange)="updateStartTime(item.EventStart)"></ion-datetime>
</ion-item>
You could just do a trick by keeping the old value of the EventStart. I added two code samples. First one will update the HTML but it will only keep the updated value if click on confirmation, otherwise it will set DatePicker to old value back. Second one will work as you expected but I don't know your value of item.EventStart is look like. I just guess it would something similar to this pattern '00:00'. Sample codes will worth you than explanation in words :).
First one
public oldEventStart = this.item.EventStart;
updateStartTime(startTime) {
let alert = this.alertControl.create({
title: 'Change start time',
message: 'Are you sure you want to update the start time for this event?',
buttons: [
{
text: 'Cancel',
handler: () => {
this.item.EventStart = this.oldEventStart;
console.log('cancel');
}
},
{
text: 'Confirm',
handler: () => {
this.item.EventStart = startTime;
this.oldEventStart = startTime;
console.log(startTime);
}
}
]
});
alert.present();
alert.onDidDismiss(() => { this.item.EventStart = this.oldEventStart; });
}
Second one
public oldEventStart = this.item.EventStart;
updateStartTime(startTime) {
this.item.EventStart = new Date('2000-01-01T'+this.oldEventStart+':00.00').toISOString();
let alert = this.alertControl.create({
title: 'Change start time',
message: 'Are you sure you want to update the start time for this event?',
buttons: [
{
text: 'Cancel',
handler: () => {
this.item.EventStart = this.oldEventStart;
console.log('cancel');
}
},
{
text: 'Confirm',
handler: () => {
this.item.EventStart = startTime;
this.oldEventStart = startTime;
console.log(startTime);
}
}
]
});
alert.present();
alert.onDidDismiss(() => { this.item.EventStart = this.oldEventStart; });
}
Hope this will help to solve your problem. Cheers!.
When I use a bootstrap dialog I would use a prevent default. Try to change the following: updateStartTime(startTime) to updateStartTime(startTime,e) and then on your first line in that function add e.preventDefault(); See if that helps. You should then be able to do whatever you like in your cancel and confirm handlers.
Just return false in your updateStartTime function, so that the default datepicker handler that is bound to the change event does not get called. Like this:
updateStartTime(startTime) {
let alert = this.alertControl.create({
title: 'Change start time',
message: 'Are you sure you want to update the start time for this event?',
buttons: [{
text: 'Cancel',
handler: () => {
console.log('cancel');
}
}, {
text: 'Confirm',
handler: () => {
console.log(startTime);
}
}]
});
alert.present();
/** prevent default datepicker behavior **/
return false;
}
Currently working on a personal project. I want the user to click a button and a SweetAlert prompt would be presented for the user to verify their credential. However, the code I see on the SweetAlert website only allows one input field. Here is the code I have:
swal({
title: "Authenicating for continuation",
text: "Test",
type: "input",
showCancelButton: true,
closeOnConfirm: false,
animation: "slide-from-top",
inputPlaceholder: "Write something"
}, function(inputValue) {
if (inputValue === false) return false;
if (inputValue === "") {
swal.showInputError("You need to write something!");
return false
}
// swal("Nice!", "You wrote: " + inputValue, "success");
});
So, is there a way I can get two input fields? One input field for the password and the other input field for text.
Now SweetAlert2 is available:
https://sweetalert2.github.io
As per their info on bottom:
Multiple inputs aren't supported, you can achieve them by using html
and preConfirm parameters. Inside the preConfirm() function you can
pass the custom result to the resolve() function as a parameter:
swal({
title: 'Multiple inputs',
html:
'<input id="swal-input1" class="swal2-input">' +
'<input id="swal-input2" class="swal2-input">',
preConfirm: function () {
return new Promise(function (resolve) {
resolve([
$('#swal-input1').val(),
$('#swal-input2').val()
])
})
},
onOpen: function () {
$('#swal-input1').focus()
}
}).then(function (result) {
swal(JSON.stringify(result))
}).catch(swal.noop)
Multiple inputs aren't supported, you can achieve them by using HTML and preConfirm parameters.
Inside the preConfirm() function you can return (or, if async, resolve with) the custom result:
function sweetAlert(){
(async () => {
const { value: formValues } = await Swal.fire({
title: 'Multiple inputs',
html:
'<input id="swal-input1" class="swal2-input">' +
'<input id="swal-input2" class="swal2-input">',
focusConfirm: false,
preConfirm: () => {
return [
document.getElementById('swal-input1').value,
document.getElementById('swal-input2').value
]
}
})
if (formValues) {
Swal.fire(JSON.stringify(formValues))
}
})()
}
body {
font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", Helvetica, Arial, sans-serif;
}
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#9.3.4/dist/sweetalert2.all.min.js"></script>
<button onclick="sweetAlert()">Try me!</button>
Source: INPUT TYPES
You can have inputs in the default SweetAlert type, as long as you set the html property to true. The issue is that unless the type is set to "input", SweetAlert adds a display: none to input fields.
It's a bit of a workaround, but you can change this in the js file from
<input type=\"text\" tabIndex=\"3\" />\n
to
<input id=\"swalInput\" type=\"text\" tabIndex=\"3\" />\n
And change the css file from
.sweet-alert input {
to
.sweet-alert #swalInput {
Then you can simply add your html to the text parameter when calling, like so:
swal({
title: "Log In to Continue",
html: true,
text: "Username: <input type='text'><br>Password: <input type='password'>"
});
This method simply specifies that the only input to be styled that way is the one generated by SweetAlert, so that any inputs you add to your text won't be affected by that styling.
Using the example posted by Tikky in their answer above and based on the question asked for validation on that answer. You could possibly try the following to implement validation on this method:
swal({
title: 'Multiple inputs',
html:
'<input id="swal-input1" class="swal2-input">' +
'<input id="swal-input2" class="swal2-input">',
preConfirm: function () {
return new Promise(function (resolve) {
// Validate input
if ($('#swal-input1').val() == '' || $('#swal-input2').val() == '') {
swal.showValidationMessage("Enter a value in both fields"); // Show error when validation fails.
swal.enableConfirmButton(); // Enable the confirm button again.
} else {
swal.resetValidationMessage(); // Reset the validation message.
resolve([
$('#swal-input1').val(),
$('#swal-input2').val()
]);
}
})
},
onOpen: function () {
$('#swal-input1').focus()
}
}).then(function (result) {
// If validation fails, the value is undefined. Break out here.
if (typeof(result.value) == 'undefined') {
return false;
}
swal(JSON.stringify(result))
}).catch(swal.noop)
As far as I know you can't do this off-the-shelf. You can either fork and implement, or just use a HTML element as a modal (e.g. as in Bootstrap's modals).
$(document).ready(function(){
$("a").click(function(){
swal({
title: "Teste",
text: "Test:",
type: "input",
showCancelButton: true,
closeOnConfirm: false,
animation: "slide-from-top",
inputPlaceholder: "User"
},
function(inputValue){
if (inputValue === false) return false;
if (inputValue === "") {
swal.showInputError("Error");
return false;
}
swal({
title: "Teste",
text: "E-mail:",
type: "input",
showCancelButton: true,
closeOnConfirm: false,
animation: "slide-from-top",
inputPlaceholder: "Digite seu e-mail"
},
function(inputValue){
if (inputValue === false) return false;
if (inputValue === "") {
swal.showInputError("E-mail error");
return false;
}
swal("Nice!", "You wrote: " + inputValue, "success");
});
});
});
});
Multiple inputs aren't supported, you can achieve them by using html and preConfirm parameters.
Notice that in preConfirm function you can pass the custom result to resolve():
You can do this using such manner:
swal({
title: 'Multiple inputs',
html:
'<h2>Login details for waybill generation</h2>'+
'<input id="swal-input1" class="swal2-input" autofocus placeholder="User ID">' +
'<input id="swal-input2" class="swal2-input" placeholder="Password">',
preConfirm: function() {
return new Promise(function(resolve) {
if (true) {
resolve([
document.getElementById('swal-input1').value,
document.getElementById('swal-input2').value
]);
}
});
}
}).then(function(result) {
swal(JSON.stringify(result));
})
}
The link here: https://limonte.github.io/sweetalert2/
It's very simple through the preConfirm method and using ok button as submission button in sweetalert2
swal.fire({
showCancelButton:true,
html:`input1:<input id="input1" type="text">
input2: <input id="input2" type="text">
input3: <input id="input3" type="text">`,
preConfirm:function(){
in1= $('#input1').val();
in2= $('#input2').val();
in3 = $('#input3').val();
console.log(in1,in2,in3) // use user input value freely
}
})
Here is an example using sweetalert#^2.1.0, showing one way to have multiple input fields. The example uses jQuery, but jQuery is not required for this technique to work.
// ==============================================================
//swal does not block, and the last swal wins
//so these swals are closed by later calls to swal, before you can see them
// ==============================================================
swal("aaa");
swal("bbb");
// ==============================================================
//for multiple inputs, use content: anHtmlElement
// ==============================================================
const div = document.createElement("div");
console.log(div);
$(div).html("first<input id='111' value='one'></input></br>second<input id='222' value='two'></input></br>third<input id='333' value='three'></input>");
swal({
title: "Three Inputs",
content: div,
// ==============================================================
//true means show cancel button, with default values
// ==============================================================
buttons: [true, "Do It"]
}).then(value => {
if (value) {
const outputString = `
value is true for confirm (i.e. OK); false for cancel
value: ${value}
` + $("#111").val() + " " + $("#222").val() + " " + $("#333").val();
// ==============================================================
// there are no open swals at this point, so another call to swal is OK here
// ==============================================================
swal(outputString);
} else {
swal("You cancelled");
}
});
alert("swal is not blocking: " + $("#111").val() + " " + $("#222").val() + " " + $("#333").val());
Try this way
swal({
text: 'First Input',
content: "input",
button: {
text: "Add New",
closeModal: false,
},
})
.then(name => {
swal({
text: 'Second Input',
content: "input",
button: {
text: "Add New",
closeModal: false,
},
}).then(id => {
//save code here.
})
}).catch(err => {
swal("Error");
});
On SweetAlert 2.x you can use this vanilla Javascript for getting / setting one input. Yo can chain more elements to content so you can have multiple inputs:
var slider = document.createElement("input");
slider.type = "number";
slider.value = 5;
slider.step=1;
slider.min = 5;
slider.max = 50;
this.swal({
title: 'Request time to XXX',
text: 'Select values',
content: slider,
buttons: {
cancel: "Run away!",
catch: {
text: "Throw Pokéball",
value: slider.value,
},
defeat: true,
}
}).then((value) => {
console.log(slider.value); // Here you receive the input data value
//swal(`You typed: ${value}`);
});
check this out
https://sweetalert2.github.io/
"AJAX request example" + "Chaining modals (queue) example" has inputs and you can work with them
Email and Password login double input boxes in Asp.Net Core MVC with ajax to clear application session and relogin to reassign session. The "sweetModal" function should be called in javascript for application 5mins idle timer trigger for the sweetalert modal popup. Adjust to suit your need. Please note, this applies to SweeetAlert 2.0 of https://sweetalert.js.org/ and jQuery v3.5.1
sweetModal = () => {
swal({
icon: '../../../images/yourlogo.png',
title: 'Relogin',
content: {
element: "input",
attributes: {
placeholder: "Enter username",
},
},
buttons: {
confirm: {
text: "Submit",
value: true,
visible: true,
className: "",
closeModal: false
},
cancel: {
text: "Cancel",
value: null,
visible: true,
className: "",
closeModal: true
},
},
closeOnClickOutside: false,
closeOnEsc: false,
})
.then((user) => {
if (user) {
swal({
icon: '../../../images/yourlogo.png',
title: 'Relogin',
content: {
element: "input",
attributes: {
placeholder: "Enter password",
type: "password",
},
},
buttons: {
confirm: {
text: "Submit",
value: true,
visible: true,
className: "",
closeModal: false
},
cancel: {
text: "Cancel",
value: null,
visible: true,
className: "",
closeModal: true
},
},
closeOnClickOutside: false,
closeOnEsc: false,
})
.then((pwd) => {
if (pwd) {
$.post("/account/refreshsession", { user: user, pwd: pwd }, () => swal(`Successful!`));
//swal(`The returned value is: ${user} ${pwd}`);
}
});
}
});
}
The way I add 2 or more input fields is; I set html to true and use text to write you inputs, just make sure to add the class "show" (display: block) to your inputs. Swal will hide your inputs. Example:
swal({
title: "Test",
html: true,
text: ` <input class="show" tabindex="1" placeholder="">
<input class="show" tabindex="1" placeholder="">
`
}
This is working in my case
swal({
title: "Update Score",
// type: "input",
// inputPlaceholder: "Home",
showCancelButton: true,
// cancelButtonText: "Cancel",
// closeOnConfirm: false,
// closeOnCancel: false
html: true,
text: '<input id="input1" type="text" placeholder="Home" style="display:block !important;"><br><input id="input2" type="text" placeholder="Away" style="display:block !important;">',
},
function () {
in1 = $('#input1').val();
in2 = $('#input2').val();
alert(in1 + " = " + in2)
});
Yes you can!!!
swal({
title: "An input!",
text: "Write something interesting:",
type: "input",
showCancelButton: true,
closeOnConfirm: false,
animation: "slide-from-top",
inputPlaceholder: "Write something"
},
function(inputValue){
if (inputValue === false) return false;
if (inputValue === "") {
swal.showInputError("You need to write something!");
return false
}
swal("Nice!", "You wrote: " + inputValue, "success");
});
I building a sortable table in Meteor with Reactive-Table and having trouble getting my delete button to work for removing entries from the table.
Please see my javascript code below:
Movies = new Meteor.Collection("movies");
if (Meteor.isClient) {
Template.body.events({
"submit .new-movie": function (event) {
var title = event.target.title.value;
var year = event.target.year.value;
var genre = event.target.genre.value;
Movies.insert({
title: title,
year: year,
genre: genre
});
event.target.title.value = "";
event.target.year.value = "";
event.target.genre.value = "0";
return false;
}
});
Template.moviestable.events({
"click .deletebtn": function (event) {
Movies.remove(this._id);
}
});
Template.moviestable.helpers({
movies : function () {
return Movies.find();
},
tableSettings : function () {
return {
showFilter: false,
fields: [
{ key: 'title', label: 'Movie Title' },
{ key: 'year', label: 'Release Year' },
{ key: 'genre', label: 'Genre' },
{ key: 'edit', label: 'Edit', fn: function () { return new Spacebars.SafeString('<button type="button" class="editbtn">Edit</button>') } },
{ key: 'delete', label: 'Delete', fn: function () { return new Spacebars.SafeString('<button type="button" class="deletebtn">Delete</button>') } }
]
}
}
});
}
Can anyone tell me what I'm doing wrong?
In the reactive tables docs, there's an example of how to delete rows from the table. Adapting the example in the docs for your needs, your event should look like this:
Template.moviestable.events({
'click .reactive-table tbody tr': function (event) {
event.preventDefault();
var objToDelete = this;
// checks if the actual clicked element has the class `deletebtn `
if (event.target.className == "deletebtn") {
Movies.remove(objToDelete._id)
}
}
});
The problem you are having is that you are trying to find the _id property on the button click instead of the row click.
If you do console.log(this) on your button click event (as you have it in your question above) you will get something like this Object {key: "delete", label: "", fieldId: "2", sortOrder: ReactiveVar, sortDirection: ReactiveVar} which does not contain the property _id
It is easier to register the row click, where the row object is the actual document you are trying to delete, and then check if the event's target has the delete class you added.
I cannot make jquery to grab the current value of textarea. I have several posts and each of them has "write a review" button. When I select on the button of first post, it shows the dialog box with first post title and a textarea. When I write something in the appeared textarea and press submit, it alerts nothing. Then I am clicking the same button on the first post and it shows me dialog box with the title of second post and when I type something in the textarea and press submit, it alerts the text which I typed in the previous dialog box. Could you please have a look on my code and help me to find my mistake.
Here is my view:
$data = array(
'name' => $places_id,
'class' => 'review',
'content' => 'Write a Review'
);
echo form_button($data);
<div id="write_review">
<h3><?php echo $title; ?></h3>
<textarea rows='6' cols='90' maxlength='600' id="review_text"></textarea>
</div>
Here is my JS file:
$(document).ready(function () {
$(".review").click(function () {
var self = this;
var places_id_review = $(self).attr("name");
$("#write_review").dialog({
title: "Write a Review",
modal: true,
draggable: false,
width: 600,
height: 300,
buttons: [{
text: 'Submit',
click: function () {
var review_text = $("#review_text").val();
alert(review_text);
$.post('filter/post_review', {
places_id_review: places_id_review,
review_text: review_text
}, function (data) {
alert("ok")
}, "json");
}
}, {
text: 'Cancel',
click: function () {
$(this).dialog('close')
}
}]
});
});
});
It happens because there are duplicates of your dialog in DOM
at least you can get your value like this:
var review_text = $("#review_text", this).val(); //to prevent lookup in while DOM
But you better control your dialog's duplicates( using 'destroy' on close event 'close'):
$(".review").click(function () {
var self = this;
var places_id_review = $(self).attr("name");
$("#write_review").dialog({
title: "Write a Review",
modal: true,
draggable: false,
width: 600,
height: 300,
close:function(){ $(this).dialog('destroy'); }, // DELETE dialog after close
buttons: [{
text: 'Submit',
click: function () {
$(this).dialog('close'); // do not forget close after submit
var review_text = $("#review_text").val();
alert(review_text);
$.post('filter/post_review', {
places_id_review: places_id_review,
review_text: review_text
}, function (data) {
alert("ok")
}, "json");
}
}, {
text: 'Cancel',
click: function () {
$(this).dialog('close');
}
}]
});
});