I have <md-button>My button</md-button> and want to use <md-progress-circular>, when I enter on the button, but content hasn't uploaded yet, so I want show on the button this spinner, but I don't know how :(
This is a very basic example of how to do this, you can either use ng-show or ng-if
<div ng-app='home'>
<div ng-controller="MainCtrl">
<md-button class="md-primary md-accent md-raised" ng-click="func()">
My button<md-progress-circular ng-show="processing" md-mode="indeterminate"></md-progress-circular>
</md-button>
</div>
</div>
and this goes in your controller
$scope.func = function(){
$scope.processing = true;
$timeout(function(){
$scope.processing = false;
},3000);
};
note that the $timeout is to simulate a promise or the time required to "upload content as you say"
Related
Our team is using mdDialog to pull up a modal that allows a user to edit answers to a questionnaire.
$scope.editQuestionFnct = function(val){
$scope.editWidget = {};
//alert(val);
spUtil.get("gateway_questionnaire_widget", {//call new instance of this widget
//sys_id: $scope.params.refID,
task_id: $scope.data.task_id,
quest_id: val,
request: 'edit',
taskTable: $scope.data.task_table,
questionnaire_table: $scope.params.questionnaireTable,
serviceID: $scope.params.serviceID,
refID: $scope.params.refID,
taskCompleted: false,
editRequest: true
}).then(function(response) {
$scope.editWidget = response;//var to hold widget response to display in modal
$scope.showPrerenderedDialog('#editQuestion');
});
}
$scope.showPrerenderedDialog = function(name) {
$mdDialog.show({
templateUrl: name,
parent: angular.element(document.body),
clickOutsideToClose:true
});
};
$scope.closeDialog = function($scope){ //closes angular dialog window
$mdDialog.hide($scope);
}
$scope.closeSummDialog = function($scope){ //closes angular dialog window
$mdDialog.hide($scope);
}
<script type="text/ng-template" id="editQuestion">
<div class="md-dialog-container" >
<md-dialog style="background-color: #ffffff;" aria-label="edit dialog">
<md-toolbar style="background-color: #022C68; width: 100%;">
<h1 class="md-toolbar-tools" style="color: #ffffff;">Edit Response</h1>
</md-toolbar>
<md-dialog-content style="background-color: #ffffff;">
<div id="editQuestDiv" style="min-width: 700px;">
<sp-widget widget="editWidget"></sp-widget>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<span flex></span>
<md-button ng-click="closeDialog()" style="background-color: #022C68; color: #ffffff;">
Close
</md-button>
</md-dialog-actions>
</md-dialog>
</div>
</script>
We are experiencing two problems with the above code:
First, instead of using templateUrl, we were using contentElement, which worked. Using contentElement pulled up a modal with the question that required editing. However, when a user clicks out of that first click, and clicks on another question, the same question that appeared in the first click shows up. Every click afterwards will only pull up the question from the first click.
After doing some reading, we decided to try and use templateUrl instead, but using that above opens up a modal with nothing in it:
Can someone explain what we're doing wrong? Are we doing something wrong with contentElement where only the question from the first click persists? If we were to use templateUrl, why isn't our modal showing up?
Thanks!
ng-click is not working as it should. I tried looking at documentation and tutorials but couldn't find the reason.
I have a JavaScript variable storing html template. which by using
document.getElementById('someId').innerHTML = emptypage;
where emptypage is a JavaScript variable, is implemented inside a div with id=someId.
My Code:
var emptypage=` <md-toolbar `+ this.createID() +` class="md-accent
soopsObject" ng-app="vdApp">
<span class="example-spacer ng-controller="vdNav">
<md-sidenav class="md-sidenav-left" md-component-id="left" md-
disable-backdrop md-whiteframe="4">
<md-content layout-margin>
<p>
About
</p>
<p>
Contact
</p>
<md-button ng-click="toggleLeft()" class="md-accent">
Close
</md-button>
</md-content>
</md-sidenav>
<div>
<md-button ng-click="toggleLeft()">
<md-icon>menu</md-icon> Menu
</md-button>
</div>
</span>
</md-toolbar>`;
My Controller:
var nav=angular.module("vdApp", []);
nav.controller("vdNav", function($scope, $mdSidenav) {
alert("inside leftToggle");
$scope.toggleLeft = buildToggler('left');
function buildToggler(componentId){
return function(){
$mdSidenav(componentId).toggle();
};
}
});
Even alert isn't working.
What am I doing wrong? Any help or suggestion is appreciated.
I am trying to use a progress bar when I am uploading a video, but the progress bar appears on load page and sty forever.
<div ng-show="!$ctrl.setNewVideoRecord()">
<md-progress-circular md-mode="indeterminate" md-diameter="100">
</md-progress-circular>
</div>
<md-button class="md-raised md-primary" ng-click="$ctrl.setNewVideoRecord()"> Add video</md-button>
self.setNewVideoRecord = function () {
adminService.setNewVideoRecord(self.fileForUpload)
.then(function () {
});
};
The best way is to apply a scope variable. and set the value of that scope variable accordingly inside the function. Right now you are calling a function to apply ng-show but that function should return either true or false based on which you will show progress bar . The best way is :
<div ng-show="$ctrl.videoUploading">
<md-progress-circular md-mode="indeterminate" md-diameter="100">
</md-progress-circular>
</div>
<md-button class="md-raised md-primary" ng-click="$ctrl.setNewVideoRecord()"> Add video</md-button>
self.videoUploading = false;
self.setNewVideoRecord = function () {
self.videoUploading = true;
adminService.setNewVideoRecord(self.fileForUpload)
.then(function () {
// your code here, and when the video uploading is completed again set the variable false
self.videoUploading = false;
});
};
Using angular & material, I have a sidenav on the left used to provide user's function (login, signup...).
Working fine, but I want the bar to be closed automatically once the user clicks on a menu. Currently, the bar stays open.
The sidebar code:
<md-sidenav md-component-id="user_sidenav" class="md-sidenav-left" flex>
<md-menu-content flex>
<md-menu-item>
<md-button ui-sref="app.user-state()">
<span>
User
</span>
</md-button>
</md-menu-item>
<md-menu-item>
<md-button ui-sref="vlg.user-other-state()">
<span>
Other
</span>
</md-button>
</md-menu-item>
...
Any idea?
What I have done is create a function in the controller for closing the sidenav and then on clicking of an element calling the function.
app.controller('AppController', ['$scope', '$mdSidenav',
function ($scope, $mdSidenav) {
$scope.close = function () {
$mdSidenav('left').close();
};
}]);
and then in html
<div ng-controller="AppController">
<!-- Add in code for sidenav-->
<md-button ng-href="#/path" ng-click="close()"></md-button>
</div>
You could also just add the below code to a function if your elements already have a ng-click attached.
.then(function () {
$mdSidenav('left').close();
});
I'm trying to automate my tests with Protractor and Appium for an AngularJS site with jasmine framework in iPad simulator, sendkeys() function is working for username and password, but when i click into the login button the test is passed, but the action isn't done : no redirection to home page, and no on click effect is displayed for login button, i'm sure that element is located correctly ! because when i expect the gettext() to be equal to"LOGIN" it is passed but no redirection even if i put browser.sleep(8000);
Here my test script :
"use strict";
require("jasmine-expect");
var wd = require("wd");
describe('my app', function() {
it('should make the login test',function() {
// browser.ignoresynchronization=true;
browser.get("http://10.0.22.82:8080/jws/fetablet");
expect(browser.getCurrentUrl()).toEqual(("http://10.0.22.82:8080/jws/fetablet/#/login"));
element(by.model('credentials.username')).sendKeys('RET02').then(function(){
element(by.model('credentials.password')).sendKeys('RET02').then(function(){
element(by.css('.login-button')).click().then(function(){
browser.sleep(8000); expect(browser.getCurrentUrl()).not.toEqual("http://10.0.22.82:8080/jws/fetablet/#/login");
});
});
});
});
});
Is there another method to locate the click button correctly?
Here my html code :
<div class="login_lang"> <md-button class="lang_button" ng-click="changeLang()">{{lang}}</md-button> </div>
<div layout="column" flex layout-align="center center" class="md-padding splash-background"> <div class="login-logo"> <img src="{{logoSrc}}"> </div> <form class="login-form" name="loginForm" ng-submit="login()">
<fieldset> <md-input-container class="md-block">
<label translate="login.USERNAME" ng-class="{'floating-label-rtl':dir==='rtl'}"
class="login-label">Username</label>
<input required ng-model="credentials.username" ng-focus="onFocus()" type="text">
<div ng-messages="loginForm.credentials.username.$error" ng-show="loginForm.credentials.username.$dirty">
<div ng-message="required" trans
late="login.MESSAGE_REQUIRED">This is required.</div> </div> </md-input-container> <md-input-container class="md-block"> <label translate="login.PASSWORD" ng-class="{'floating-label-rtl':dir==='rtl'}"
class="login-label">Password</label> <input required ng-model="credentials.password" ng-focus="onFocus()" type="pa
ssword">
<div ng-messages="loginForm.credentials.password.$error" ng-show="loginForm.credentials.password.$dirty"> <div ng-message="required" translate="login.MESSAGE_REQUIRED">This is required.</div> </div> </md-input-container>
<div layout-align="center center" layout="column" ng-if="oneTimePassword"> <p class="login-otp-message" translate="login.OTP_MESSAGE">Enter the code which you received by SMS</p> <md-button class="md-warn login-otp-retry" translate="login.OTP_RETRY" ng-click="retry()">Retry</md-button> </div> <md-input-container class="md-block" ng-if="oneTimePassword"> <label translate="login.SECURITY_CODE" class="login-label">Security code</label> <input required ng-model="credentials.securityCode" ng-focus="onFocus()" type="password"> <div ng-messages="loginForm.credentials.securityCode.$error" ng-show="loginForm.credentials.securityCode.$dirty"> <div ng-message="required" translate="login.MESSAGE_REQUIRED">This is required.</div> </div> </md-input-container> <div layout-align="center"> <section layout-align="center" layout="row" layout-sm="column"> <div id="login-error" md-caption class="msg-error" ng-show="error" class="label">{{error}}</div>
<md-button type="submit" class="md-raised login-button" ng-disabled="clicked" translate="login.LOGIN">Login</md-button> </section>
</div> </fieldset> </form> <md-divider></md-divider> <footer class="login-footer"> <div layout="row" layout-align="center center"> <md-button ng-click="goToCustomerCare()" class="login-footer-link" translate="login.CUSTOMER_CARE">Contact Customer Care</md-button> <div> | </div> <md-button ng-click="showDisclaimer()" class="login-footer-link" translate="login.DISCLAIMER">Disclaimer</md-button> </div> </footer> </div>
I put the details of Appium recorder about the login button
There might be multiple reasons for that and it is going to be a guessing game anyway.
it could be that there is an another element matching the .login-button locator and you are clicking a different element. Let's improve the locator:
element(by.css(".login-form .login-button")).click();
wait for the element to be clickable:
var EC = protractor.ExpectedConditions;
element(by.model('credentials.username')).sendKeys('RET02');
element(by.model('credentials.password')).sendKeys('RET02');
var loginButton = element(by.css('.login-form .login-button'));
browser.wait(EC.elementToBeClickable(loginButton), 5000);
loginButton.click();
add a small delay before clicking the element (silly, but I see that helped sometimes):
element(by.model('credentials.username')).sendKeys('RET02');
element(by.model('credentials.password')).sendKeys('RET02');
browser.sleep(500);
element(by.css('.login-form .login-button')).click();
another silly try, click 2 times (I cannot believe I actually advise that):
var loginButton = element(by.css('.login-form .login-button'));
loginButton.click();
loginButton.click();
disable angular animations
click the button via browser.actions() moving to the element before the click:
var loginButton = element(by.css('.login-form .login-button'));
browser.actions().mouseMove(loginButton).click().perform();
sort of an extension to the previous approach. Move to element, sleep for half a second and then click:
browser.actions.mouseMove(loginButton).perform();
browser.sleep(500);
loginButton.click();
Or, if you would introduce a custom sleep() action, you can do:
browser.actions.mouseMove(loginButton).sleep(500).click().perform();
click the element via javascript:
var loginButton = element(by.css('.login-form .login-button'));
browser.executeScript("arguments[0].click();", loginButton);
And, after the form is submitted, instead of browser.sleep(), you can wait for URL to change explicitly, please see:
Protractor- Generic wait for URL to change
As a side note, in Protractor, you use the $ and $$ shortcuts for the CSS locators:
var loginButton = $('.login-form .login-button');
Try executing those commands without using the promise chain. It can be a problem in the previous chain.
"use strict";
require("jasmine-expect");
var wd = require("wd");
describe('my app', function() {
it('should make the login test',function() {
browser.get("http://10.0.22.82:8080/jws/fetablet");
expect(browser.getCurrentUrl()).toEqual(("http://10.0.22.82:8080/jws/fetablet/#/login"));
element(by.model('credentials.username')).sendKeys('RET02');
element(by.model('credentials.password')).sendKeys('RET02');
element(by.css('.login-button')).click();
browser.sleep(8000);
expect(browser.getCurrentUrl()).not.toEqual("http://10.0.22.82:8080/jws/fetablet/#/login");
});
PS: You can avoid using the 'then' function when you do not need to use the result of the method. It is controlled by the control flow
Just adding browser.sleep after the click worked for me:
it('Some test', function () {
element(by.css("button[type='submit']")).click();
browser.sleep(1000);
});
I have one more suggestion, you can expect particular element need to be displayed and clear the text-box. You can actually write in promise, that is the best way.
var loginButton = element(by.css('.md-raised.login-button'));
var userName = element(by.model('credentials.username'));
var password = element(by.model('credentials.password'));
this.username = function(sendUserName) {
expect(userName.isDisplayed()).toBeTruthy();
userName.clear().then(function(){
userName.sendKeys(sendUserName).then(function(){
expect(password.isDisplayed()).toBeTruthy();
});
});
};
this.password = function(password) {
expect(password.isDisplayed()).toBeTruthy();
password.clear().then(function(){
password.sendKeys(password).then(function(){
browser.wait(EC.elementToBeClickable(loginButton), 10000);
});
});
};
this.clickloginbutton = function() {
expect(loginButton.isDisplayed()).toBeTruthy();
loginButton.click().then(function(){
expect('something').not.toBeNull();
});
}
Tried to click the button twice and functionality wise it worked but throwed NoSuchElementError for the second click.
Made below adjustment and it worked for me
await browser.wait(EC.elementToBeClickable(element(by.css('selector')), 5000);
await $('selector').click();
if(await $(selector).isDisplayed())
await $(selector).click();