Ionic V4: ion-modal just like ion-alert - ionic-framework

The following ion-alert would be exactly what we need if the input was replaced with a textarea; however, ion-alert doesn't support ion-textarea.
How can the exact same look and feel be implemented with an ion-modal?
We are using Ionic without Angular (Ionic core).
ion-alert code
const alert = await alertController.create({
header: 'Would you be willing to leave feedback?',
inputs: [
{
placeholder: 'enter text'
}],
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: _ => {
alert.dismiss();
console.log('cancel');
}
}, {
text: 'Submit',
handler: _ => {
alert.dismiss();
console.log('submit');
}
}
]
});
alert.present();
attempted ion-modal code
const modalController = $('ion-modal-controller')[0];
await modalController.componentOnReady();
const modalElement = await modalController.create({
showBackdrop: true,
component:
$(`<div>
<h2>Would you be willing to provide feedback?</h2>
<div>
<ion-button>Cancel</ion-button>
<ion-button>Submit</ion-button>
</div>
</div>`)[0]
});
await modalElement.present();

In the page where you call the modal:
async book() {
const modal = await this.modalController.create({
component: BookModal,
componentProps: { value: 123 },
showBackdrop: true,
backdropDismiss: true,
cssClass: ['booking-modal']
});
return await modal.present();
}
The key point is the cssClass. Then in theme/variable.scss, add the class at the end of the file like below:
.booking-modal {
--height: 50% !important;
}
** Note: this might not be the correct way to do it, but it works for me at this stage. Looking for a better solution.

Related

Ionic 5: Toast button dismisses the toast despite its role isn't set to 'cancel'

According to the documentation https://ionicframework.com/docs/api/toast :
Dismissing The toast can be dismissed automatically after a specific
amount of time by passing the number of milliseconds to display it in
the duration of the toast options. If a button with a role of "cancel"
is added, then that button will dismiss the toast. To dismiss the
toast after creation, call the dismiss() method on the instance.
But in the following code (from the same doc) both the CLOSE and FAVORITE buttons lead to the dismiss of the toast (and of course the call of toast.onDidDismiss()). But Only the CLOSE one has the role 'cancel'.
I would like to have a button and perform an action without closing the Toast, am I missing something ?
import { Component } from '#angular/core';
import { ToastController } from '#ionic/angular';
#Component({
selector: 'toast-example',
templateUrl: 'toast-example.html',
styleUrls: ['./toast-example.css'],
})
export class ToastExample {
constructor(public toastController: ToastController) {}
async presentToast() {
const toast = await this.toastController.create({
message: 'Your settings have been saved.',
duration: 2000
});
toast.present();
}
async presentToastWithOptions() {
const toast = await this.toastController.create({
header: 'Toast header',
message: 'Click to Close',
position: 'top',
buttons: [
{
side: 'start',
icon: 'star',
text: 'Favorite',
handler: () => {
console.log('Favorite clicked');
}
}, {
text: 'Done',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}
]
});
await toast.present();
const { role } = await toast.onDidDismiss();
console.log('onDidDismiss resolved with role', role);
}
}
Setting the role to something other than null or 'cancel', and returning false on the handler() should do what you need.
Example:
//...
buttons: [
{
icon: "copy-outline",
role: "copy",
handler: () => {
console.log("copied!");
return false;
}
}]
//...

ExtJS 7.2.0 - Form submit not working in Chrome

I'm trying to upload a file using the code below:
window = Ext.create('Ext.window.Window', {
renderTo: Ext.getBody(),
bodyPadding: '20 10',
title: 'Upload file',
autoDestroy: true,
hidden: true,
modal: true,
layout: {
type: 'hbox',
align: 'middle',
pack: 'center'
},
items: [
uploadForm = new Ext.form.Panel({
items: [
file = new Ext.form.field.File({
xtype: 'filefield',
name: 'fileName',
fieldLabel: 'File',
allowBlank: false,
buttonText: 'Select file...',
})
]
})
],
buttons: [{
text: 'Cancel',
handler: function () {
upload.hide();
}
},
{
text: 'Upload',
handler: function () {
var form = uploadForm.getForm();
if (form.isValid()) {
form.submit({
url: 'upload',
waitMsg: 'Uploading your file...',
scope: this,
success: function (form, action) {
upload.close();
var json = JSON.parse(action.response.responseText);
if (json.success) {
Ext.Msg.alert('Success', json.message);
} else {
Ext.Msg.alert('Error', json.message);
}
},
failure: function (form, action) {
upload.close();
try {
var json = JSON.parse(action.response.responseText);
Ext.create('Ext.window.MessageBox').show({
title: 'Failure',
msg: json.message
});
} catch (err) {
Ext.create('Ext.window.MessageBox')
.alert('Failure', 'Failed to parse response');
}
}
});
}
}
}]
});
The code is working in firefox and opera and I get the response successfully, but in chrome on inspect network activity, the status is canceled and in the console I get the warning: Resource interpreted as Document but transferred with MIME type application/json. Therefore, the submit always returns failure, even though the file is uploaded. Can anyone please suggest how to fix this?

How to test $ionicPopup.show

I have an ionicPopup like so:
function editNotifications() {
var popUp = $ionicPopup.show({
template: '<ion-checkbox ng-repeat="item in vm.notifications" ng-model="item.notification" ng-checked="item.notification">' +
'<span class="notificationsFont">{{item.settingsText}}</span></ion-checkbox>',
title: 'Notification Settings',
scope: $scope,
buttons: [
{
text: 'Cancel',
onTap: function(e) {
vm.notifications = localStorageManager.get('notificationStatus');
}
},
{
text: '<b>Ok</b>',
type: 'button-positive',
onTap: function(e) {
localStorageManager.set('notificationStatus', vm.notifications);
vm.notificationText = "Notifications off";
setNotificationValuesBasedOnUserInput(vm.notifications);
}
}]
});
};
Here is what I have so far;
it('Should edit notifications', function() {
spyOn($ionicPopup, 'show').and.callFake(function() {
return $q.resolve(true);
})
spyOn(localStorageManager, 'set');
controller = createController();
controller.editNotifications();
$scope.$apply();
expect(localStorageManager.set).toHaveBeenCalled();
// expect(localStorageManager.set).toHaveBeenCalledWith('notificationStatus');
});
I basically have no idea how to test this thing. There doesn't seem to be much on the internet. I would think I need to do something in my callFake function but I'm a bit stuck. Anyone ever successfully tested this beast before?
Go through this answer: https://stackoverflow.com/a/52565500/7943457
And modify your code something like this:
function editNotifications() {
var popUp = $ionicPopup.show({
template: '<ion-checkbox ng-repeat="item in vm.notifications" ng-model="item.notification" ng-checked="item.notification">' +
'<span class="notificationsFont">{{item.settingsText}}</span></ion-checkbox>',
title: 'Notification Settings',
scope: $scope,
buttons: [
{
text: 'Cancel',
onTap: function(e) {
return false;
}
},
{
text: '<b>Ok</b>',
type: 'button-positive',
onTap: function(e) {
return true;
}
}]
});
popup.then(function(response){
if(response){ //when response is true
localStorageManager.set('notificationStatus', vm.notifications);
vm.notificationText = "Notifications off";
setNotificationValuesBasedOnUserInput(vm.notifications);
}else{ //when response is false
vm.notifications = localStorageManager.get('notificationStatus');
}
})
};
You can test it like this:
it('Should edit notifications', function() {
spyOn($ionicPopup, 'show').and.callFake(function() {
return $q.resolve(true);
})
spyOn(localStorageManager, 'set');
controller = createController();
controller.editNotifications();
$scope.$apply();
expect(localStorageManager.set).toHaveBeenCalled();
// expect(localStorageManager.set).toHaveBeenCalledWith('notificationStatus');
});
it('Should get notifications', function() {
spyOn($ionicPopup, 'show').and.callFake(function() {
return $q.resolve(false);
})
spyOn(localStorageManager, 'get');
controller = createController();
controller.editNotifications();
$scope.$apply();
expect(localStorageManager.get).toHaveBeenCalled();
// expect(localStorageManager.get).toHaveBeenCalledWith('notificationStatus');
});
Hope it helps.

How to give validation for alert alert input in ionic?

I have add one alert input field to change password,But How can we give validation to input field in ionic?
account.ts
changePassword(){
let alert = this.alertCtrl.create({
title: 'Change Password',
buttons: [
'Cancel']
});
alert.addInput({
name: 'Password',
value: this.password,
placeholder: 'password'
});
alert.addButton({
text: 'Ok',
handler: (data: any) => {
this.userData.setUsername(data.username);
let accountData=new FormData();
accountData.append('userid',this.userid),
accountData.append('password',data.Password)
this.works.changePassword(accountData).subscribe(res=>{
console.log(res),
err=>{
console.log(err)
}
})
}
});
alert.present();
}
You can use alert.setMessage('text') method to show validation message and don't forgot to add return false after validation to prevent alert dismiss.
public displayToAlert(title, subTitle) {
let alert = this.alertCtrl.create({
title: title,
subTitle: subTitle,
message: '',
enableBackdropDismiss: false,
inputs: [
{name: 'userEmail',
placeholder: 'Email Id'}
],
buttons: [{
text: 'Cancel',
handler: () => {
}
},{
text: 'Send',
handler: datas => {
if(datas.userEmail != null && datas.userEmail.length > 0){
this.onExportNew();
}else{
alert.setMessage('<b style="color: red;">Enter valid email id.</b>');
return false;
}
}
}]
});
alert.present();
}
For Reference : Alert controller input box validation

How to pass selected Value form Popup to normal controller page in ionic framework

How to pass selected Value form Popup to normal controller page in ionic framework
`$scope.showprofpopup = function()
{
$scope.data = {}
var myPopup = $ionicPopup.show
({
templateUrl: 'templates/popover.html',
title: 'Please Choose Category',
scope: $scope,
buttons: [ { text : 'Cancel' }, { text: 'Select', type: 'button-dark', onTap: function(e) { return $scope.data; } }, ]
});
myPopup.then(function(res)
{
//$scope.create(res.category);
//$state.go('app.userdetails');
//$scope.contactMessage = { text: res };
if(!res.category)
{
$ionicLoading.show({ template: '<ion-spinner icon="android"></ion-spinner>', animation: 'fade-in', showBackdrop: true, maxWidth: 100,showDelay: 50 });
$scope.showprofpopup();
$timeout(function () { $ionicLoading.hide(); }, 3000);
//$ionicPopup.alert({ title: "Please Choose Category" });
}
else
{
$scope.SelectedProfessional = { text: res.category};
//alert(res.category);
$state.go('app.userdetails');
}
});
};`
I want to send the result re.category to app.userdetails page.kindly anyone help me.
using $stateParams
$state.go('app.userdetails',{'category': res.category});