why scope variable is not accessible in angular components - angularjs

I have written a angular directive to read the file input data. However the updated scope variable is not accessible when I click on update button. why I am unable to access the file variable that is updated in ngFileSelect directive?
JS
// Define the `changeWord` module
angular.module('changeWord', []);
/// <reference path="changeWord.component.js" />
angular.
module('changeWord').
component('changeWord', {
templateUrl: 'change-word/change-word.template.html',
controller: function ChangeWordController($scope, dictionaryService) {
var self = this;
//$rootScope.loggedIn = $cookies.get('loggedIn');
self.formShowing = false;
$scope.search = function () {
dictionaryService.getWordsStartWith(self.searchText, function (r) {
self.searchResults = r;
});
};
$scope.change = function (id) {
dictionaryService.getWord(id, result => {
self.key = id;
self.word = result.word;
self.wordInEnglish = result.wordInEnglish;
self.pronunciation = result.pronunciation;
var syns ='';
angular.forEach(result.synonyms, a =>{
syns += (syns == '') ? a.wordInEnglish : ', ' + a.wordInEnglish;
})
self.synonyms = syns;
syns = '';
angular.forEach(result.antonyms, a => {
syns += (syns == '') ? a.wordInEnglish : ', ' + a.wordInEnglish;
})
self.antonyms = syns;
});
}
$scope.clear = function () {
angular.element(document.querySelector('#pFile')).val(null);
self.word = '';
self.wordInEnglish = '';
self.pronunciation = '';
self.synonyms = '';
self.antonyms = '';
};
$scope.update = function () {
dictionaryService.deleteWord(self.key);
// unable to access the scope here
dictionaryService.addNewWord(self.word, self.wordInEnglish, self.pronunciation, $scope.file, self.synonyms, self.antonyms);
this.clear();
self.formShowing = false;
}
}
}).directive("ngFileSelect", function () {
return {
link: function ($scope, el) {
el.bind("change", function (e) {
$scope.file = (e.srcElement || e.target).files[0];
//$scope.update();
})
}
}
});
HTML
<div ng-cloak>
<form name="changeForm" button-form ng-submit="update()" ng-if="$ctrl.formShowing">
<md-card flex flex-gt-md="70">
<md-card-header>
<md-card-avatar>
<md-icon class="md-avatar-icon">edit</md-icon>
</md-card-avatar>
<md-card-header-text>
<span class="md-title">Change Existing Word</span>
<span class="md-subhead">in kannada dictionary</span>
</md-card-header-text>
</md-card-header>
<md-card-content>
<md-input-container class="md-block">
<input name="word" ng-model="$ctrl.word" placeholder="Word in Kannada" required />
<div ng-messages="changeForm.word.$error" ng-show="changeForm.word.$dirty" role="alert">
<div ng-message="required">This is required!</div>
</div>
</md-input-container>
<md-input-container class="md-block">
<input name="wordInEnglish" ng-model="$ctrl.wordInEnglish" placeholder="Word in English" disabled />
<div ng-messages="changeForm.wordInEnglish.$error" ng-show="changeForm.wordInEnglish.$dirty" role="alert">
<div ng-message="required">This is required!</div>
</div>
</md-input-container>
<p flex layout="row">
<md-input-container class="md-block" flex="50">
<input ng-model="$ctrl.pronunciation" placeholder="Pronunciation" />
</md-input-container>
<md-input-container class="md-block" flex="50">
<input id="pFile" type="file" ng-File-Select accept="audio/*" capture aria-label="Pronunciation Audio">
</md-input-container>
</p>
<md-input-container class="md-block">
<textarea ng-model="$ctrl.synonyms" placeholder="Synonyms"></textarea>
</md-input-container>
<md-input-container class="md-block">
<textarea ng-model="$ctrl.antonyms" placeholder="Antonyms"></textarea>
</md-input-container>
</md-card-content>
<md-card-actions>
<md-button class="md-raised md-primary" type="submit">Save</md-button>
<md-button class="md-accent" ng-click="$ctrl.formShowing = !$ctrl.formShowing">Cancel</md-button>
</md-card-actions>
</md-card>
</form>
<md-content class="md-padding">
<form name="searchForm" button-form ng-submit="search()">
<md-input-container md-no-float class="md-block">
<input name="searchText" ng-model="$ctrl.searchText" type="text" placeholder="Search">
<md-icon style="display:inline-block;" type="submit">search</md-icon>
<div class="hint" ng-show="searchForm.searchText.$dirty">Press Enter to search</div>
</md-input-container>
</form>
<md-list flex>
<md-list-item class="md-2-line" ng-repeat="result in $ctrl.searchResults" ng-click="null">
<div class="md-list-item-text" layout="column">
<h3>{{ result.wordInEnglish }}</h3>
<p>{{ result.word }}</p>
<md-button name="ch" class="md-raised md-primary md-secondary" ng-click="$ctrl.formShowing=!$ctrl.formShowing; change(result.$id);">Change</md-button>
</div>
</md-list-item>
</md-list>
</md-content>
</div>

Perfect, $scope is not existing in component. Need to use keyword this

Related

md dialog not working properly?

I'm new to angular material:
I want to show dialog for editing records in a table:
I referenced angular material and angular aria, used ngMaterial dependency and $mdDialog service.
I have a div containing all editing fields, the div visibility is set to hidden:
<div style="visibility: hidden">
<div class="md-dialog-container" id="taskEdit">
<md-dialog style="width:100%; height:100%" layout-padding>
<md-toolbar>
<div class="md-toolbar-tools">
<h2>Edit Task</h2>
<span flex></span>
</div>
</md-toolbar>
<ng-form name="TaskForm">
<div layout-gt-sm="row">
<md-input-container>
<label>Task Title</label>
<input name="TaskTitle" ng-model="task.title" required>
<div ng-messages="TaskForm.TaskTitle.$error">
<div ng-message="required">This is required</div>
</div>
</md-input-container>
<md-input-container class="md-block" flex-gt-sm>
<label>Description</label>
<textarea ng-model="task.description" md-maxlength="150" md-select-on-focus></textarea>
</md-input-container>
<md-input-container class="md-block">
<label>Due Date</label>
<md-datepicker style="margin-top: 2px;" ng-model="task.dueDate"></md-datepicker>
</md-input-container>
<md-input-container>
<label>Task Status</label>
<input name="TaskStatus" ng-model="task.status">
</md-input-container>
</div>
</ng-form>
<input class="btn btn-primary" style="width:15%" type="submit" ng-disabled="!TaskForm.$valid" ng-click="EditTask()" value="Submit" aria-label="submit" />
</md-dialog>
</div>
</div>
here's the showDialog function::
$scope.showDialog = function () {
$mdDialog.show({
controller: DialogController,
contentElement: '#taskEdit',
parent: angular.element(document.body),
clickOutsideToClose: true
});
};
function DialogController($scope, $mdDialog) {
$scope.hide = function () {
$mdDialog.hide();
};
$scope.cancel = function () {
$mdDialog.cancel();
};
}
but when I click the button, the dialog is not appearing properly, it lacks the animation and is rendered in the same layer as the parent page:
You need to refer the angular material css
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.0.4/angular-material.css">

Angular Material DatePicker and NG-CHANGE

When a user selects a date on the md-datepicker component, I need to call the server to check the schedule for the selected date. The thing is, I can't get my function to fire using ng-change, which seems to be the only option on doing this. Any thoughts on why this is not working?
form.html
<div
layout-padding>
<form
name="form"
novalidate
ng-submit="form.$valid && save()">
<div
layout>
<md-input-container
class="md-block"
flex="100">
<label>Nome Completo</label>
<input
name="fullName"
ng-model="costumer.fullName"
required
disabled/>
<div
ng-messages="form.fullName.$error">
<div ng-message="required">O cliente não foi específicado</div>
</div>
</md-input-container>
</div>
<div
layout>
<md-input-container
flex>
<label>Data</label>
<md-datepicker
name="date"
ng-model="appointment.when"
md-open-on-focus
md-min-date="today">
</md-datepicker>
<div
ng-messages="form.date.$error">
<div ng-message="valid">Data inválida</div>
<div ng-message="mindate">Data anterior à atual</div>
</div>
</md-input-container>
<md-input-container
flex="50">
<label>Horário</label>
<md-select
name="whatTime"
ng-model="appointment.whatTime"
required>
<md-option value="0">08:00 - 09:00</md-option>
<md-option value="1">09:00 - 10:00</md-option>
<md-option value="2">10:00 - 11:00</md-option>
<md-option value="3">13:00 - 14:00</md-option>
<md-option value="4">14:00 - 15:00</md-option>
<md-option value="5">15:00 - 16:00</md-option>
<md-option value="6">16:00 - 17:00</md-option>
<md-option value="7">17:00 - 18:00</md-option>
</md-select>
<div
ng-messages="form.whatTime.$error">
<div
ng-message="required">Selecione um horário</div>
</div>
</md-input-container>
</div>
<md-button
type="submit">Confirmar</md-button>
</form>
</div>
controller.js
angular.module('Application').controller('NewAppointmentController',
['$scope', '$routeParams', 'CostumerService', 'AppointmentService',
function($scope, $routeParams, CostumerService, AppointmentService) {
console.log('NewAppointmentController init');
console.log('Costumer: ' + $routeParams.costumerId);
$scope.today = new Date();
$scope.appointment = {};
$scope.appointment.when = $scope.today;
$scope.save = save;
$scope.checkSchedule = checkSchedule;
CostumerService.getUniqueById($routeParams.costumerId)
.then(function(data){
$scope.costumer = data;
console.log('Costumer name: ' + data.fullName);
}, function(error){
console.log('Erro');
});
function save() {
console.log('Clicked');
$scope.appointment.costumer = $scope.costumer;
AppointmentService.save($scope.appointment)
.then(function(data) {
console.log('Saved');
}, function(error){
console.log('Error');
});
}
function checkSchedule() {
console.log('Changed: ');
}
}]);
It seems to work for me. See this CodePen, ngChange with Datepicker. I added
<md-datepicker
name="date"
ng-model="appointment.when"
ng-change="checkSchedule()"
md-open-on-focus
md-min-date="today">
</md-datepicker>
Everytime you change the date, it will be logged to the console. Although, it really seems like you should be using $asyncValidators as described in Custom Validation.

How to get back data from DB after sent it from client side?

I have profile page in angular js, after I filled and sent them to DB. Then once again if I come back to the same profile page I didn't get any values in the field.
profile.html
<form name="profileForm">
<br/>
<div flex style="max-width:700px;">
<md-input-container class="md-block">
<label>Name</label>
<input ng-model="vm.name"></input>
</md-input-container>
</div>
<div flex style="max-width:700px;">
<md-input-container class="md-block">
<label>Mobile Number</label>
<input ng-model="vm.mobile"></input>
</md-input-container>
</div>
<div flex style="max-width:700px;">
<md-input-container class="md-block">
<label>Email</label>
<input ng-model="vm.email"></input>
</md-input-container>
</div>
<div flex style="max-width:700px;">
<label>DOB:</label>
<md-datepicker ng-model="vm.profileForm.dob" md-placeholder="Enter date">
</md-datepicker>
</div>
<div flex style="max-width:700px;">
<md-input-container class="md-block" >
<label>Country</label>
<md-select ng-model="vm.profileForm.Country" ng-change="vm.getCountryStates()">
<md-option ng-repeat="countryName in vm.countries" value="{{countryName.id}}" >
{{countryName.country}}
</md-option>
</md-select>
</md-input-container>
</div>
<div flex style="max-width:700px;">
<md-input-container class="md-block" >
<label>State</label>
<md-select ng-model="vm.profileForm.State" ng-change = "vm.getStateCities()">
<md-option ng-repeat="stateName in vm.states" value="{{stateName.Id}}">
{{stateName.state}}
</md-option>
</md-select>
</md-input-container>
</div>
<div flex style="max-width:700px;">
<md-input-container class="md-block" >
<label>City</label>
<md-select ng-model="vm.profileForm.City">
<md-option ng-repeat="cityName in vm.cities" value="{{cityName.Id}}">
{{cityName.city}}
</md-option>
</md-select>
</md-input-container>
</div>
<div flex style="max-width:700px;">
<md-input-container class="md-block" >
<label>Postal Code</label>
<input name="postalCode" ng-model="vm.profileForm.postalCode" ng-pattern="/^[0-9]{6}$/" md-maxlength="6">
</md-input-container>
</div>
<span style="color:green; font-size:20px;">{{vm.message}}</span>
<div layout="row" layout-align="space-between center">
<div>
<img src="assets/icons/fonts/backArrow.png" alt="image caption" style="width:18px; height:18px">
<a ng-href ng-click="vm.nextTab()" >Back</a>
</div>
<div style="margin-right:300px">
<a ng-href="http://localhost:3000/pages/dashboard">Skip</a>
<md-button class="md-raised md-primary" ng-click="vm.profileInfo(vm.profileForm);">Save & Continue</md-button>
</div>
</div>
</form>
In the picture first 3 values getting through ngStorage, after filled remaining fields data stored in DB. For chekcBox I have used cascading dropdown.
profile.js
(function ()
{
'use strict';
angular
.module('app.invite-friends')
.controller('InviteFriendsController', InviteFriendsController);
/** #ngInject */
function InviteFriendsController(Friendslist, $localStorage, $scope, $http, $location, CustomerService)
{
var vm = this;
vm.countries = CustomerService.getCountry();
vm.getCountryStates = function(){
vm.states = CustomerService.getCountryState(vm.profileForm.Country);
vm.cities =[];
}
vm.getStateCities = function(){
vm.cities = CustomerService.getStateCity(vm.profileForm.State);
}
vm.uid = $localStorage._id;
vm.profileInfo = function(userData){
$http({
url:'http://192.168.2.8:7200/api/profile_save',
method:'POST',
data: {info:userData, loginId:vm.uid}
}).then(function(res){
if(res.data.success){
vm.message = 'Your profile information has been saved successfully.';
$location.path('/pages/dashboard')
}
}, function(error){
alert(error.data);
});
};
$http({
url:'http://192.168.2.8:7200/api/checkIfExists',
method:'POST',
data: {userId: vm.uid}
}).success(function(res){
vm.name = res.result[0].name;
vm.mobile = res.result[0].mobile;
vm.email = res.result[0].email;
vm.DOB = res.result[0].DOB;
vm.Country = res.result[0].Country;
vm.State = res.result[0].State;
vm.City = res.result[0].City;
vm.postalCode = res.result[0].PostCode;
}, function(error){
alert(error.data);
});
}
})();
All you ng-model is getting or updating data to vm.profileForm in the view where as while you setting data to view form controller you are adding properties to vm, not to vm.profileForm
Change the following code in $http success
from
vm.DOB = res.result[0].DOB;
vm.Country = res.result[0].Country;
vm.State = res.result[0].State;
vm.City = res.result[0].City;
vm.postalCode = res.result[0].PostCode;
to
vm.profileForm.dob = res.result[0].DOB;
vm.profileForm.Country = res.result[0].Country;
vm.profileForm.State = res.result[0].State;
vm.profileForm.City = res.result[0].City;
vm.profileForm.postalCode = res.result[0].PostCode;

get ng-model $resource in controller

I need to set the ng-model via controller by selecting one of the listed images in Dialog and insert the ng-model of the form to record it in json-server.
My resource is provide by json-server.
Is there any way to do this? Or there's no way .. or some other way?
Template:
<form class="form-horizontal" role="form" ng-submit="addItem($stateParams.section)" enctype="multipart/form-data">
<div layout="row" layout-wrap>
<div flex="75">
<md-card>
<md-card-content>
<h2>Adicionar novo Post</h2>
<md-input-container>
<label>Digite o título aqui</label>
<input ng-model="item.title">
</md-input-container>
<md-input-container>
<label>Introdução</label>
<input ng-model="item.subtitle">
</md-input-container>
<md-input-container>
<label>Link permanente</label>
<input ng-model="item.slug">
</md-input-container>
<text-angular ng-model="item.content"></text-angular>
<md-input-container>
<label>Resumo</label>
<input ng-model="item.excerpt">
</md-input-container>
</md-card-content>
</md-card>
</div>
<div flex="25">
<md-card>
<md-card-content>
<h2>Configurações do Post</h2>
<md-input-container ng-controller="PublishedControl">
<md-select name="situation" ng-model="item.situation" placeholder="Status do Post">
<md-option ng-repeat="pub in publisheds" ng-value="{{pub.id}}">{{pub.name}}</md-option>
</md-select>
</md-input-container>
<div layout layout-sm="column">
<md-input-container flex>
<label>Date</label>
<input type="date" ng-model="item.posted">
</md-input-container>
<md-input-container flex>
<label>Time</label>
<input type="time" ng-model="item.posted">
</md-input-container>
</div>
<md-card-footer layout="row" layout-sm="column" layout-align="center center" layout-wrap>
<md-button class="md-raised md-primary" type="submit">Salvar</md-button>
<md-button class="md-raised" ui-sref="listItems({section: $stateParams.section})">Cancelar</md-button>
</md-card-footer>
</md-card-content>
</md-card>
<md-card ng-if="categorias[0].cats">
<md-card-content>
<h2>Categorias</h2>
<div layout-padding>
<!-- <checkbox ng-repeat="cat in categorias[0].cats" value="{{cat.id}}" ng-checked="{{item.cats.indexOf(cat.id) > -1}}" ng-model="item.cats">{{cat.name}}</md-checkbox> -->
<label ng-repeat="cat in categorias[0].cats" style="display:block;" layout="row" flex="100">
<input type="checkbox" checklist-model="item.cats" checklist-value="cat.id"> {{cat.name}}
</label>
</div>
</md-card-content>
</md-card>
<md-card>
<md-card-content ng-controller="MediaController">
<h2>Imagem em Destaque</h2>
<div class="input-group form-group">
<figure ng-if="item.image"><img ng-model="item.image" ng-src="item.image" alt=""></figure>
<md-button class="md-raised" type="button" ng-click="chooseMedia($event)">Escolha uma Imagem</md-button>
</div>
</md-card-content>
</md-card>
</div>
</div>
</form>
Controller:
module.controller('MediaController', ['$scope', '$mdDialog', 'Media', function($scope, $mdDialog, Media) {
$scope.chooseMedia = function(ev){
$mdDialog.show({
parent : angular.element(document.body),
controller : chooseMediaControl,
ariaLabel : 'Choose Media',
targetEvent : ev,
clickOutsideToClose : true,
templateUrl : 'partials/tpl/media.html'
})
function chooseMediaControl($scope, $mdDialog, Media) {
$scope.media = Media.query();
$scope.cancelMedia = function() {
$mdDialog.cancel();
};
$scope.applyMedia = function() {
$scope.item.image = $scope.image;
$mDialog.hide();
};
$scope.inserMedia = function(imageurl){
$scope.image = imageurl;
};
}
}
}])
Service:
.factory('Media',function($resource){
return $resource('http://localhost:5000/media/:id',{id:'#id'},{
update: {
method: 'PUT'
}
});
})

Angular Material 0.9.7 Form Validation Example

I want to validate form using angularjs and angular-material built-in directives including messages under field like, input, select, radio buttons.
There are some specific requirements:
The Form fields should have equal heights
The radio buttons i.e. md-radio should be inline
The location of messages under fields should be similar
The angular-material select i.e. md-select should be width = 100%
I did some tweaks to Salal Aslam answer:
submit button is enable
erorr messages aren't shown on untouched form
validate on submit
validate on touching element
Example on JSFiddle and below.
HTML:
<form name="myForm" ng-app="myApp" ng-controller="myController" class="container-fluid" ng-submit="myForm.$valid && submit()" novalidate>
<div class="row">
<div class="col-xs-8">
<md-input-container md-is-error="myForm.name.$invalid && (myForm.$submitted || myForm.name.$dirty)">
<label>Name</label>
<input name="name" id="name" ng-model="obj.name" ng-required="true">
<div ng-messages="myForm.name.$error" ng-if="myForm.$submitted || myForm.name.$touched">
<div ng-message="required">Campaign Name is required.</div>
</div>
</md-input-container>
</div>
<div class="col-xs-8">
<md-input-container md-is-error="myForm.myselect.$invalid && (myForm.$submitted || myForm.myselect.$dirty)">
<md-select name="myselect" id="myselect" placeholder="myselect" ng-model="obj.myselect" ng-required="true">
<md-option ng-repeat="o in options" ng-value="o">{{o}}</md-option>
</md-select>
<div ng-messages="myForm.myselect.$error" ng-if="myForm.$submitted || myForm.myselect.$touched">
<div ng-message="required">myselect is required.</div>
</div>
</md-input-container>
</div>
<div class="col-xs-8">
<md-input-container md-is-error="myForm.status.$invalid && (myForm.$submitted || myForm.status.$dirty)">
<md-radio-group name="status" id="status" ng-model="obj.status" ng-required="true" class="">
<md-radio-button ng-repeat="s in statuses" ng-value="s">{{s}}</md-radio-button>
</md-radio-group>
<div ng-messages="myForm.status.$error" ng-if="myForm.$submitted || myForm.status.$touched">
<div ng-message="required">status is required.</div>
</div>
</md-input-container>
</div>
</div>
<md-button type="button" ng-click="reset()">RESET</md-button>
<md-button type="submit" class="md-primary">SUBMIT</md-button>
</form>
JS:
var app = angular
.module('myApp', ['ngAnimate', 'ngAria', 'ngMaterial', 'ngMessages'])
.controller('myController', function ($scope) {
$scope.statuses = ['Planned', 'Confirmed', 'Cancelled'];
$scope.options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', '...'];
$scope.submit = function() {
// submit code goes here
};
$scope.reset = function() {
$scope.obj = {
name: "",
myselect: "",
status: ""
}
};
$scope.reset();
});
I created this fiddle for the requirements mentioned. I am posting this here to help someone new to angularjs or angular-material
<form name="myForm" ng-app="myApp" ng-controller="myController" class="container-fluid" ng-submit="submit()">
<div class="row">
<div class="col-xs-8">
<md-input-container>
<label>Name</label>
<input name="name" id="name" ng-model="obj.name" ng-required="true">
<div ng-messages="myForm.name.$error">
<div ng-message="required">Campaign Name is required.</div>
</div>
</md-input-container>
</div>
<div class="col-xs-8">
<md-input-container>
<md-select name="myselect" id="myselect" placeholder="myselect" ng-model="obj.myselect" ng-required="true">
<md-option ng-repeat="o in options" ng-value="o">{{o}}</md-option>
</md-select>
<div ng-messages="myForm.myselect.$error">
<div ng-message="required">myselect is required.</div>
</div>
</md-input-container>
</div>
<div class="col-xs-8">
<md-input-container>
<md-radio-group name="status" id="status" ng-model="obj.status" ng-required="true" class="">
<md-radio-button ng-repeat="s in statuses" ng-value="s">{{s}}</md-radio-button>
</md-radio-group>
<div ng-messages="myForm.status.$error">
<div ng-message="required">myselect is required.</div>
</div>
</md-input-container>
</div>
</div>
<md-button type="button" ng-click="reset()">RESET</md-button>
<md-button class="md-primary" ng-disabled="myForm.$invalid">SUBMIT</md-button>
</form>
var app = angular
.module('myApp', ['ngAnimate', 'ngAria', 'ngMaterial', 'ngMessages'])
.controller('myController', function ($scope) {
$scope.statuses = ['Planned', 'Confirmed', 'Cancelled'];
$scope.options = ['Option 1', 'Option 2', 'Option 3', 'Option 4', '...'];
$scope.submit = function() {
// submit code goes here
};
$scope.reset = function() {
$scope.obj = {
name: "",
myselect: "",
status: ""
}
}
$scope.reset();
});
md-input-container > md-select {
margin-top: 0;
padding-bottom: 0; }
md-input-container > md-select > md-select-label {
width: 100%; }
md-input-container > md-radio-group {
padding: 24px 2px 0; }
md-input-container > md-radio-group > md-radio-button {
margin: 8px 5px 0;
display: inline-block; }
fiddle link
Update 1: Created this pen for angular 1.4.2 and angular-material v0.10.0

Resources