After I login in my app which I made in Angularjs, first step is that initial function show confirmation box. That is regular confirmation box, without any style. My question is how I can stylize that box with CSS, and add some text too, if my function is :
function versionCheck() {
if ($window.confirm("Are you sure?")) {
vm.starting = true;
dataService.restartVersion()
.then(function onSuccess(data) {
vm.data = data.response;
}).catch(function onReject(response) {
}).finally(function () {
vm.starting = false;
});
}
}
Again I will remind that I immediately start with this function after login, without press button or something else, automatically.
Any helps?
//---------------------------------------------------------------------------------------------------------------
# This is the Angular Material Design way of customizing dialog boxes.
# $mdDialog.confirm() and $mdDialog.show will solve this issue.
# I would create a totally different function to handle the dataService
# And have the versionCheck() just handling the confirmation dialog
# as shown below.
function versionCheck() {
var confirm = $mdDialog.confirm()
.title('Cancel confirmation')
.textContent('Are you sure?')
.ariaLabel('Are you sure?')
.ok('Ok')
.cancel('Cancel');
$mdDialog.show(confirm).then(
function() {
$state.go('login');
);
}
);
}
//---------------------------------------------------------------------------------------------------------------
Related
My workmate is working with Angular Material and he's using the mdToast this way: (in the else statements)
$scope.login = () => {
$scope.loading = true;
authService.login($scope.username, $scope.password, (result) => {
if (result) {
if (result === true) {
$location.path('/');
} else {
$mdToast.show($mdToast.simple().textContent($filter('capitalize')($filter('translate')('passwordNotValid'))).position('top right').hideDelay(3000));
$scope.loading = false;
$("#input_username_login").focus();
}
} else {
//error callback from server
$mdToast.show($mdToast.simple().textContent($filter('capitalize')($filter('translate')('passwordNotValid'))).position('top right').hideDelay(3000));
$scope.loading = false;
$("#input_username_login").focus();
}
});
};
I need to test the text of the resulted toast but it seems like Angular Material's mdToast uses ng-if. My workmate hasn't any HTML code for the toast (he's just using the controller above to generate it) even so when the toast is triggered the next code appears for a few seconds in the DOM:
screenshot of the generated md-toast
I've tried, among other things, slowing down the toast's disappearance with browser.wait, waitForAngular and so on, but didn't work. I'm stuck with:
it("should show error toast in English when user fails login", function(){
login.email_address_field.sendKeys('random_user#correo.com');
login.password_field.sendKeys('hardest_pass_123');
login.login_button.click();
expect(element(by.tagName('md-toast')).element(by.tagName('span')).getText()).toBe('Incorrect username and/or password');
});
I found a solution using this answer as an example. My spec is:
it("should show error toast in English when user fails login", function(){
login.email_address_field.sendKeys('random_user#correo.com');
login.password_field.sendKeys('hardest_pass_123');
login.login_button.click();
browser.ignoreSynchronization = true;
browser.sleep(1000);
expect(element(by.tagName('md-toast')).element(by.tagName('span')).getText()).toBe('Incorrect username and/or password');
browser.ignoreSynchronization = false;
});
You can use ExpectedConditions to make your script wait till the toaster message is displayed.Once the toaster is displayed then you can validate the message as well.
var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.tagName('md-toast'))),5000);
expect(element(by.tagName('md-toast')).element(by.tagName('span')).getText()).toEqual('Incorrect username and/or password');
This spec worked for me and it does not use sleeps. The important thing to note here is that the browser.ignoreSynchronization flag must be set while the browser is waiting. Due to the asynchronous nature of the browser.wait, changing ignoreSynchronization must be done after the browser.wait promise resolves or else it could have no effect.
// a close button that appears on the md-toast template
const closeToastButton = $('[data-automation="toast-close"]')
const cond = protractor.ExpectedConditions
function waitToastShow() {
return browser.wait(cond.elementToBeClickable(closeToastButton), 5000)
}
function waitToastHide() {
return browser.wait(cond.invisibilityOf(closeToastButton), 5000)
}
screenshot = name => browser.takeScreenshot().then(/* save fn */)
describe('a suite ... ', () => {
it('takes screenshots of an md-toast once shown and after hidden', function () {
// ... actions that launch an md-toast using $mdToast.show({ ... })
browser.ignoreSynchronization = true
waitToastShow().then(() => {
screenshot('toast-showing.png')
waitToastHide().then(() => {
screenshot('toast-hidden.png')
browser.ignoreSynchronization = false;
})
})
});
}
I have a web application window where I'am required to press a button to remove some stuff many times (the button is easily click-able with JS by selecting it with getElementbyClassName()[i]). But after each click I have to manually press the "OK" button on the window.alert("Are you sure?"); box.
I can't change the websites mechanism as I'm not the owner or developer. But I want somehow to be able to automate this stuff.
JS I use for clicking on the element:
var el = document.getElementsByClassName('ruleAddButton');
for (var i = 0; i < el.length; i++) {
el[i].click();
}
Since alert is only to show info to the user (you can't get user input from an alert), I think you maybe want to monkey patch confirm function this way:
var originalConfirm = window.confirm;
window.confirm = function(msg) {
if (msg.match(/Are you sure/) {
// this confirm should return always true
return true;
} else {
// we want other confirms works as normal
return originalConfirm.bind(window)(msg);
}
}
Just in case, I would do the same trick for alert function
var originalAlert = window.alert;
window.alert = function(msg) {
if (msg.match(/Are you sure/) {
// this is what alert always returns after user clicks OK
return undefined;
} else {
// we want other alerts works as normal
return originalAlert.bind(window)(msg);
}
}
EDIT
Also, you can do something as simple as:
window.confirm = function() { return true; };
But on this case, be aware that ALL confirm calls will be intercepted
You can't click the OK button in a dialog created by window.alert. That dialog is created by the browser and is not controllable from the webpage's JavaScript context. However, what you can do is just monkey-patch the alert function to not show a dialog at all:
window.alert = function() {
// Do nothing.
};
You can override the alert function:
window.alert = function(){}
But it will disable all alerts on this page.
I have a series of buttons that execute different functions when clicked. The function checks whether the user is logged in, and if so proceeds, if not it displays an overlay with ability to log in/create account.
What I want to do is re-execute the button click after log-in, without the user having to reclick it.
I have it working at the moment, but I'm pretty sure that what I'm doing isn't best practice, so looking for advice on how I can improve...
Here's what I'm doing: setting a global variable "pending_request" that stores the function to be re-run and in the success part of the log-in ajax request calling "eval(pending_request)"
Example of one of the buttons:
jQuery('#maybe_button').click(function() {
pending_request = "jQuery('#maybe_button').click()"
var loggedin = get_login_status();
if (loggedin == true) {
rec_status("maybe");
}
});
.
success: function(data) {
if(data === "User not found"){
alert("Email or Password incorrect, please try again");
}else{
document.getElementById('loginscreen').style.display = 'none';
document.getElementById('locationover').style.display = 'none';
eval(pending_request);
pending_request = "";
}
}
Register a function to handle the click and then invoke that func directly without eval().
jQuery('#maybe_button').on('click', myFunction)
This executes myFunction when the button is clicked. Now you can "re-run" the function code every time you need it with myFunction().
And btw since you are using jQuery you can do $('#loginscreen').hide() where $ is an alias for jQuery that's auto defined.
EDIT
Please, take a look at the following code:
var pressedButton = null;
$('button1').on('click', function() {
if (!isLoggedIn()) {
pressedButton = $(this);
return;
}
// ...
});
And, in your success handler:
success: function() {
// ...
if (pressedButton) pressedButton.trigger('click');
// ...
}
Users can edit their profile information. If they attempt to navigate away from the page while changes are present, the desired functionality should be that they are presented with a confirmation box. When I use Durandal's canDeactivate, it is only triggered when I try to navigate to another Durandal page. When I use window.onbeforeunload it is only triggered when I either hard refresh or type in a new URL etc.
Is there any universal solution (unified look and feel) that can catch both of these classes of events in order to prevent users from immediately navigating away from a page?
My two approaches are displayed below:
Durandal canDeactivate
canDeactivate: function () {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
var title = 'Warning';
var msg = 'Do you want to leave this page and lose all of your edits to this form?';
return app.showMessage(msg, title, ['Yes', 'No'])
.then(function (selectedOption) {
return selectedOption === 'Yes';
});
}
return false;
}
window.onbeforeunload
window.onbeforeunload = function() {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
var title = 'Warning';
var msg = 'Do you want to leave this page and lose all of your edits to this form?';
return app.showMessage(msg, title, ['Yes', 'No'])
.then(function (selectedOption) {
return selectedOption === 'Yes';
});
}
return true;
};
I have found in practice that you need both approaches to be sure of the desired behavior. window.onbeforeunload is considered by many to be a bad practice for web applications.
We finally abandoned this approach in our web application in favor of a Work in Progress pattern, where changes are saved (out to a back-end) every 3 seconds. That way, users can freely move from page to page without ever fearing the loss of their work. It does require adjusting one's data model, and the ability to turn off validation for works in progress. A Project document collection--or Projects table, depending on your approach to data--would have a corresponding ProjectDraft document collection or table.
But that's a topic of another discussion. In the meantime, if you have to take the approach you've given, why not encapsulate the logic in another require-able module? In other words:
var onNavigateOrShutdown = function () {
var title = 'Warning';
var msg = 'Do you want to leave this page and lose all of your edits to this form?';
return app.showMessage(msg, title, ['Yes', 'No'])
.then(function (selectedOption) {
return selectedOption === 'Yes';
});
}
and then
canDeactivate: function () {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
onNavigateOrShutdown();
return false;
}
and
window.onbeforeunload = function() {
if ($("#saveButtonsBottom").css('visibility') === 'visible') {
onNavigateOrShutdown();
}
return true;
};
Now, let's move this functionality into a new singleton module called, say, navigation.manager. Then, it's simply a matter of requiring the module wherever you need this logic. Of course, you can elaborate on navigation.manager and have it contain an evented hub that's capable of responding to messages and/or publishing them.
When a user leaves a JSP page, I need to display a confirmation with yes no button "You have unsaved changes. Do you want to leave it without saving?". If the user presses "ok", then the user goes to the page s/he is navigating to. Otherwise, if "no" is pressed, the user stays on the page. My code is here:
var formdata_original=false;
jQuery(".outConfirmPlugin").click(function () {
if (formdata_original == false) {
con();
}
return formdata_original;
});
function con() {
$.confirm({
'title':'',
'message':settings.jsMessage,
'buttons':{
'Yes':{
'class':'blue',
'action':function () {
formdata_original = true;
}
},
'No':{
'class':'gray',
'action':function () {
}
}
}
});
};
I know my error is: function "con" and "return formdata_original;" - they are not synchronized. How can i do this?
try return simple value from you function, i mean
action':function () {
return true;
}
and when you call 'con' function you will be able to write
formdata_original = con();
In this case you can not worry about sinhronize
The second option is creation global object that belongs ot window or $. So try
window["formdata_original"] = false
and in your code inside confirm dialog
window["formdata_original"]=true.