Angular: Unable to input data in text fields - angularjs

Good Day, I'm using Angularjs 1.6.4 v with C# at back-end and I'm still new to this technology and learning.
Problem: I'm unable to input data in the text fields as given below.
<div layout="row" layout-xs="column">
<md-input-container class="md-icon-float md-block" flex>
<label>Name</label>
<md-icon md-font-icon="ion-ios-search"></md-icon>
<input ng-model="filter.name" type="text" ng-change="refreshContactTable()" ng-model-options='{ debounce: 500 }'>
</md-input-container>
<md-input-container class="md-icon-float md-block" flex>
<label>Contact No</label>
<md-icon md-font-icon="ion-ios-search"></md-icon>
<input ng-model="filter.contactNo" type="text" ng-change="refreshContactTable()" ng-model-options='{ debounce: 500 }'>
</md-input-container>
<md-input-container flex>
<label>Properties</label>
<md-icon md-font-icon="ion-ios-search"></md-icon>
<input ng-model="filter.property" type="text" ng-change="refreshContactTable()" ng-model-options='{ debounce: 500 }'>
</md-input-container>
</div>
I'm using Material angular as you can see my input fields are connected with ng-model which has filter function and it connect with resource services (model). Okay here is my angular code given below (ignore the property field)
$scope.landlordsTable = new ngTableParams(
{
page: 1,
count: 20,
filter: {
name: "",
contactNo: ""
}
},
{
getData: function ($defer, params) {
ContactsResourceService.get({
type: 'Landlord',
name: params.filter().name,
contactNo: params.filter().contactNo,
page: params.page(),
count: params.count()
}, function (data) {
if (data) {
params.total(data.total);
$defer.resolve(data.collection);
}
});
}
});
$scope.refreshContactTable = function () {
$scope.landlordsTable.reload();
}
Can anyone help me to sort out this issue. Thank you.

Related

AngularJs + Angular Material form is submitting twice

I'm creating a registration form using AngularJs + Angular Material. Trouble I'm having is that when the form is valid and it is submitted, it is submitted twice. I cannot figure out why.
I'm not declaring the controller twice. The controller is declared only in the route provider.
I'm not using ngSubmit and ngClick simultaneously.
Html code for the form
<form
ng-submit="registerForm.$valid && performRegister()"
name="registerForm"
novalidate>
<md-input-container class="md-block">
<label>Name</label>
<input
type="text"
name="name"
ng-model="register.user.name"
required>
<div ng-messages="registerForm.name.$error">
<div ng-message="required">Inserisci il tuo nome</div>
</div>
</md-input-container>
<md-input-container class="md-block">
<label>Email</label>
<input
type="email"
name="email"
ng-model="register.user.email"
ng-pattern="pattern.emailPattern"
required>
<div ng-messages="registerForm.email.$error">
<div ng-message="required">Inserisci la tua mail</div>
<div ng-message="pattern">Devi inserire una mail valida</div>
</div>
</md-input-container>
<p>
<md-button
type="submit"
class="button-block">Register</md-button>
</p>
</form>
Controller
SOS.controller("RegisterController", ["$scope", "$rootScope", "config",
function($scope, $rootScope, config) {
$scope.register = {
user: {
name: null,
email: null,
}
}
$scope.pattern = {
emailPattern: config.emailPattern
}
$scope.performRegister = function(){
console.log($scope.register.user);
}
}]);
Everytime i submit the form using the submit button, the performRegister() function is called twice, and i see the message in console twice.
If i submit the form using the Enter key it is submitted once.
Any idea why this is happening?
Thank you very much.
I had the similar problem in my application. This is what I have done to solve it.
I have added 'ng-click="performRegister()" (taking your code as example) in the md-button, & removed the same function from 'form' tag.
So finally it looks like:
<form
ng-submit="registerForm.$valid"
name="registerForm"
novalidate>
..
...
<md-button type="submit" ng-click="performRegister()"
class="button-block">Register</md-button>
Let me know, if this helps.

Using ng-repeat with ng-model modifies wrong object

TLDR: Here's a plnkr of the issue: https://plnkr.co/edit/HfRoCgPfdoZNxmTtDLf7?p=preview
I have a form with checkboxes:
<div class="form-group">
<div class="input-group">
<div class="checkbox">
<label>
<input type="checkbox" ng-model="rental.car2go.airport.berlin"> Berlin
</label>
<br/>
<label>
<input type="checkbox" ng-model="rental.car2go.airport.hamburg"> Hamburg
</label>
<br/>
</div>
</div>
</div>
that is modifying the rental object. This is how the controller looks like:
angular.module('c2gyoApp', []).controller('c2gyoAppController', [
'$scope',
'state',
function($scope, state) {
$scope.airports = [{
"name": "Berlin",
"model": "rental.car2go.airport.berlin"
}, {
"name": "Hamburg",
"model": "rental.car2go.airport.hamburg"
}, ];
$scope.rental = state.rental;
}]).factory('state', function() {
var rental = {
car2go: {
airport: {
berlin: false,
hamburg: false
}
}
};
return {
rental: rental
};
});
Now I want to use ng-repeat:
<div class="form-group">
<div class="input-group">
<div class="checkbox">
<span ng-repeat="airport in airports">
<label>
<input type="checkbox"
ng-model="airport.model">
{{airport.name}}
</label>
<br>
</span>
</div>
</div>
</div>
With ng-repeat the form is modifying the airports object (airports[1].model=true/false and airports[2].model=true/false).
It should only use the string of that airport object(rental.car2go.airport.berlin and rental.car2go.airport.hamburg ) and modify the rental object. I'm looking for a way to pass the string to ng-model, not the airports object. How can I do this?
Edit: removed the directive, new plnkr
The JSON you are changing is:
$scope.airports = [{
"airport": "Berlin",
"model": "rental.car2go.airport.berlin"
}, {
"airport": "Hamburg",
"model": "rental.car2go.airport.hamburg"
}, ];
where `airports[0].model="rental.car2go.airport.berlin", meaning the string rental.car2go.airport.berlin. This string is replaced with TRUE or FALSE. I guess that you were expecting rental.car2go.airport.berlin to be interpreted as a structure, right? Well, it is not a structure but just a string.
Indeed as #Claies suggested I had to copy the value to the rental array. I used a ng-change function for that. New ng-repeat:
<span ng-repeat="airport in airports">
<label>
<input type="checkbox"
ng-model="airport.model"
ng-change="changeAirport(airport)">
{{airport.name}}
</label>
<br>
</span>
In the controller:
$scope.changeAirport = function(airport) {
var airportName = $filter('lowercase')(airport.name);
state.rental.car2go.airport[airportName] = airport.model;
}

How can I add Firebase Storage to my web app?

I have created a small blog app using angular firebase so that registered user can login and post a blog with article and title. I want to make use of firebase storage so that user can upload images along with the article and title and user can also view the images related to post(store and retrieve feature) in real time.
Here is my html :
<div flex-xs="100" flex-md="80" layout="row" layout-wrap >
<h3 flex="100">Create Post</h3>
<md-input-container flex="40" >
<label>Title</label>
<input ng-model="article.title" type="text" />
</md-input-container>
<md-input-container flex="100" >
<label>Article</label>
<textarea ng-model="article.post" ></textarea>
</md-input-container>
<md-button class="md-raised md-primary" ng-click="AddPost()" ng-disabled="!article.title || !article.post">Publish</md-button>
</div>
Here is my controller :
.controller('AddPostCtrl', ['$scope','$firebase','$firebaseObject', '$firebaseArray', function($scope,$firebase,$firebaseObject,$firebaseArray) {
$scope.AddPost = function() {
var title = $scope.article.title;
var post = $scope.article.post;
var childRef = rootRef.child("Blog-One");
var list = $firebaseArray(childRef);
list.$add({
title: title,
post: post,
}).then(function(childRef) {
console.log(childRef);
}, function(error) {
console.log("Error:", error);
});
}
}])
Can anyone help me with how to implement firebase storage, please? Thanks in advance.
<div flex-xs="100" flex-md="80" layout="row" layout-wrap >
<h3 flex="100">Create Post</h3>
<md-input-container flex="40" >
<label>Title</label>
<input ng-model="article.title" type="text" />
</md-input-container>
<md-input-container flex="100" >
<label>Article</label>
<textarea ng-model="article.post" ></textarea>
</md-input-container>
Add these tags in your html
<progress value="0" max="100" id="uploader"></progress>
<input type="file" value="upload" id="fileButton"><br>
<md-button class="md-raised md-primary" ng-click="AddPost()" ng-disabled="!article.title || !article.post">Publish</md-button>
In your controller
var uploader=document.getElementById('uploader'),
imageUrl,
fileButton=document.getElementById('fileButton');
fileButton.addEventListener('change', function(e) {
var file=e.target.files[0];
var storageRef=firebase.storage().ref('firebase').child(file.name);
var task=storageRef.put(file);
task.on('state_changed',
function progress(snapshot){
var percentage=( snapshot.bytesTransferred / snapshot.totalBytes )*100;
uploader.value=percentage;
if (percentage==100){
storageRef.getDownloadURL().then(function(url) {
Here you will get download url
imageUrl=url;
});
}).catch(function(error) {
// Uh-oh, an error occurred!
});
}
},
function error(err){
},
function complete(){
}
);
});
So you can allow all the users to post the article with an image. But keep one thing wait until the image uploaded in the storage, and then show the publish article button. To do that wait until the progress bar to get 100% then show the publish article button

I can't scope anything onto my angular dialog(reviewForm) from the DialogController?

Below I have a button that is attached to each venue list item. So each list item has its own button. Also, each list item is a object. So when I click one of buttons I need to somehow grab the ID from that specific list item and be able to use it in my dialogcontroller.
<div class="results">
<div class="searchbox col-md-6 form-group">
<input type="text" placeholder="search venues" class="form-control" ng-model="filterTerm">
<ul class="list-unstyled">
<li class="well" ng-repeat="venues in venues | filter: filterTerm">
<h3>{{venues.name}}</h3>
<p>{{venues.info}}</p>
<md-button class="md-primary md-raised" ng-click="showAdvanced($event, venues)" flex-sm="100" flex-md="100" flex-gt-md="auto">Add a Review</md-button>
<button>See Reviews</button>
</li>
</ul>
</div>
My get call to my JSON file. Also, This is my ng-click function that is using mdDialog (which opens a popup window with a reviewForm.html as its content.
$http.get('/getMarkers').success(function(response) {
$scope.venues = response;
console.log($scope.venues);
});
$scope.showAdvanced = function(ev, venues){
$mdDialog.show({
controller: DialogController(ev,venues),
templateUrl: 'views/reviewForm.html',
parent:angular.element(document.body),
targetEvent: ev,
clickOutsideToClose:true
})
};
This is my DialogController which is handling the content(reviewForm.html) that is being rendered in my mdDialog window.
function DialogController($scope, venues, $mdDialog) {
console.log(venues);
$scope.rate = 0;
$scope.max = 5;
$scope.hoveringStaff = function (value) {
$scope.overStar = value;
$scope.percent = 100 * (value / $scope.max);
console.log($scope.overStar);
};
}
This is the html that is going into the dialog
<md-dialog aria-label="Review Form">
{{something}}
<md-toolbar>
{{venues}}
<div class="md-toolbar-tools">
<h2>Review Form</h2>
<span flex></span>
</div>
</md-toolbar>
<md-dialog-content>
{{$scope.something}}
<label>{{something}}Show Attended: </label><input type="text" ng-model="show"><br/>
<label>Date: </label><input type="date" ng-model="date"><br/>
<label>Staff Friendliest: </label><uib-rating ng-model="rate" max="max" on-hover="hoveringStaff(value)" on-leave="overStar = null" titles="['one','two','three']" aria-labelledby="default-rating"></uib-rating><br/>
<label>Sound Quality: </label><input type="text" ng-model="sound"><br/>
<label>Favorite Drink/Cocktail: </label><input type="text" ng-model="drink"><br/>
<label>Nearby Bar/Food Recommendations: </label><input type="text" ng-model="nearby"><br/>
<label>Comments: </label><input type="text" ng-model="comments"><br/>
<label>Venue Rating: </label><br/>
<md-button class="md-raised md-primary" ng-click="sendReview()">Primary</md-button>
</md-dialog-content>
I need the ID because I am going to posting a form to the database and need to add the form content to the selected list item. Sorry if this is confusing, let me know if you have any questions. Thanks!
I think you might need to use locals or resolve to pass objects to the new controllers, because of angular's dependency injection, passing objects to the controller will not work (i.e MyController($scope, a, b)).
ex:
$mdDialog.show({
locals: {
venue: venue
}
});
or with resolve
$mdDialog.show({
resolve: {
venue: function(){return venue;}
}
});
Another issue which I think is a typo, is in the ng-repeat directive venues in venues which should be venue in venues.
Reference the view values to venue object(i.e venue.drink, venue.date, ...ect) instead of $scope, will make it easier to pass it back to the parent controller.
function MainCtrl($http, $scope, $mdDialog) {
/*
$http.get('/getMarkers').success(function(response) {
$scope.venues = response;
console.log($scope.venues);
});
*/
$scope.venues = [{
name: 'Venue #1',
info: 'Info',
date: new Date(),
drink: 'A drink'
}];
$scope.showAdvanced = function(ev, venue) {
$mdDialog.show({
controller: 'DialogController',
template: '<md-dialog aria-label="Review Form">\
{{venue.name}}\
<md-toolbar>\
{{venue}}\
<div class="md-toolbar-tools">\
<h2>Review Form</h2>\
<span flex></span>\
</div>\
</md-toolbar>\
<md-dialog-content>\
{{venue.name}}\
<label>{{venue.name}}Show Attended: </label><input type="text" ng-model="venue.show"><br/>\
<label>Date: </label><input type="date" ng-model="venue.date"><br/>\
<label>Staff Friendliest: </label><uib-rating ng-model="venue.rate" max="max" on-hover="hoveringStaff(value)" on-leave="overStar = null" titles="[\'one\',\'two\',\'three\']" aria-labelledby="default-rating"></uib-rating><br/>\
<label>Sound Quality: </label><input type="text" ng-model="venue.sound"><br/>\
<label>Favorite Drink/Cocktail: </label><input type="text" ng-model="venue.drink"><br/>\
<label>Nearby Bar/Food Recommendations: </label><input type="text" ng-model="venue.nearby"><br/>\
<label>Comments: </label><input type="text" ng-model="venue.comments"><br/>\
<label>Venue Rating: </label><br/>\
<md-button class="md-raised md-primary" ng-click="sendReview()">Primary</md-button>\
</md-dialog-content>',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true,
locals: {
venue: venue
}
})
};
}
function DialogController($scope, venue, $mdDialog) {
$scope.venue = venue;
console.log(venue);
$scope.rate = 0;
$scope.max = 5;
$scope.hoveringStaff = function(value) {
$scope.overStar = value;
$scope.percent = 100 * (value / $scope.max);
console.log($scope.overStar);
};
}
angular.module('MyApp', ['ngAria', 'ngAnimate', 'ngMaterial'])
.controller('MainCtrl', MainCtrl)
.controller('DialogController', DialogController);
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-aria.min.js"></script>
</head>
<body ng-app="MyApp" ng-controller="MainCtrl">
<div class="results">
<div class="searchbox col-md-6 form-group">
<input type="text" placeholder="search venues" class="form-control" ng-model="filterTerm">
<ul class="list-unstyled">
<li class="well" ng-repeat="venue in venues | filter: filterTerm">
<h3>{{venue.name}}</h3>
<p>{{venue.info}}</p>
<md-button class="md-primary md-raised" ng-click="showAdvanced($event, venue)" flex-sm="100" flex-md="100" flex-gt-md="auto">Add a Review</md-button>
<button>See Reviews</button>
</li>
</ul>
</div>
</div>
</body>
</html>

Angular directive multiple inputs one model

HTML:
<html ng-app="app">
<div class="container" style="margin-top: 30px">
<input type="text" ng-model="newName" key-filter/>
<input type="text" ng-model="newName" key-filter/>
<input type="text" ng-model="newName" key-filter/>
<input type="text" ng-model="newName" key-filter/>
</div>
</html>
JS:
var app = angular.module('app', []);
app.directive('keyFilter', function() {
var pattern = /([\s !$%^&*()_+|~=`{}\[\]:";'<>?,.\/])/;
function link(scope) {
scope.$watch('model', function() {
if(scope.model === undefined)
return
if(pattern.test(scope.model)) {
scope.model = scope.model.replace(pattern, '');
Materialize.toast('Denied symbol', 4000, 'rounded');
}
});
}
return {
restrict: 'A',
scope: {
model: '=ngModel'
},
link: link
}
});
I have many inputs which are bind to the same model, and I am filtering user input, when user press a denied key I wanted to show a toast to inform him that he can't use this symbol, but the count of toasts is equal to the count of inputs bind to the same model.
I thought i'm working only with model which is one.
Example here:
http://codepen.io/anon/pen/XbLjVY?editors=101
How can I fix that, or change the logic how it works
p.s. angular beginner
If they are all bind to the same model every change in one is send to the others, so just put your directive on one input not all of them.
Here is a working plunkr :
http://plnkr.co/edit/dI5TMHms2wsPHc9Xqewf?p=preview
using :
<input type="text" ng-model="newName" key-filter/>
<input type="text" ng-model="newName" />
<input type="text" ng-model="newName" />
<input type="text" ng-model="newName" />
You can see in the console the message being displayed only once and from any input field

Resources