I have built a small angular App into my website whereby a user enters a searchterm into an input field and then values are returned via an Angular service. When I attempt to submit a value however, the form does not submit and will only submit on the 2nd attempt. I cannot figure out why this is happening.
Here is my code:
<div ng-app="clubFilter" class="col-lg-12">
<div class="col-lg-3">
</div>
<div class="col-lg-9" ng-controller="clubController">
<form ng-submit="filterClubs()">
<input type="text" name="location" ng-model="searchTerm" placeholder="Search..." />
<input type="submit" name="submit" value="Submit" />
</form>
<ul class="leisure-centres">
<li ng-repeat="club in clubs">
<div class="centre">
<a class="link" ng-href="{club.link}">More info</a>
<div class="image" ng-show="club.image > 0">
<img src="{{image}}" alt="{{club.title}}" />
</div>
<div class="details">
<div class="title">
<h3>{{club.title}}<span ng-show="club.distance > 0"> - {{club.distance}} miles away</span></h3>
</div>
<div class="address">
{{club.building}},
{{club.street}},
{{club.city}},
{{club.county}},
{{club.postcode}}
</div>
<div class="tel">
<strong>Tel: </strong>
</div>
<div class="email">
<strong>Email: </strong>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
var JSONItems = <?php echo $this->JSONItems; ?>;
var searchTerm = "<?php echo $this->searchTerm; ?>";
And here is my angular controller
angular.module('clubFilter.controllers', []).
controller('clubController', function($scope, $http, googleMapService) {
$scope.keyWord = "SEARCH";
$scope.clubsJSON = JSONItems;
if(searchTerm == "") {
$scope.clubs = $scope.clubsJSON;
} else {
$scope.searchTerm = searchTerm;
googleMapService.setLatLng($scope.searchTerm, $scope.clubsJSON).then(function(sortedArray) {
$scope.$apply(function() {
$scope.clubs = sortedArray;
});
}, function(err) {
alert("no");
});
}
$scope.filterClubs = function() {
googleMapService.setLatLng($scope.searchTerm, $scope.clubsJSON).then(function(sortedArray) {
$scope.clubs = sortedArray;
}, function(err) {
alert("no");
});
}
});
As far as I am aware I have everything defined as it should be?
Thanks
Try this one;
<div class="col-lg-9" ng-controller="clubController as club">
<form ng-submit="club.filterClubs()">
<input type="text" name="location" ng-model="club.searchTerm" placeholder="Search..." />
<input type="submit" name="submit" value="Submit" />
</form>
And in your controller;
this.filterClubs = function() {
googleMapService.setLatLng(this.searchTerm, $scope.clubsJSON).then(function(sortedArray) {
$scope.clubs = sortedArray;
}, function(err) {
alert("no");
});
}
Related
I have an angularJS component that displays alerts when something goes wrong while submitting, these alerts are not auto dismissed by design.
But, when the user fix all errors (there can be many alerts displayed on the screen) and submit I want to dismiss these alerts.
Based on this example https://jsfiddle.net/uberspeck/j46Yh/
I did something like this:
(function(){
var mainApp = angular.module("myApp");
function AlertsCtrl($scope, alertsManager) {
$scope.alerts = alertsManager.alerts;
}
mainApp.factory('alertsManager', function() {
return {
alerts: {},
addAlert: function(message, type) {
this.alerts[type] = this.alerts[type] || [];
this.alerts[type].push(message);
},
clearAlerts: function() {
for(var x in this.alerts) {
delete this.alerts[x];
}
}
};
mainApp.controller("addUserCtrl", ['Restangular', 'alertsManager', '$alert', 'roles', '$window' , function(Restangular, alertsManager, $alert, roles, $window) {
var that = this;
init();
that.submit = function() {
var data = {
user : that.name,
role : that.role.serverName,
credentials : that.password1
}
Restangular.all("admin").all("user").all("add").post(data).then(function() {
//$alert({title: 'Add User:', content: 'Completed succefully', type: 'success', container: '#alert', duration: 5, show: true});
alertsManager.addAlert('Completed succefully', 'alert-success');
init();
alertsManager.clearAlerts();
}, function(reason) {
//$alerts{title: 'Add User:', content: reason.data.error, type: 'danger', container: '#alert', show: true});
alertsManager.addAlert(reason.data.error, 'alert-error');
});
}
function init() {
that.name = "";
that.roles = roles;
that.role = that.roles[0];
that.password1 = "";
that.password2 = "";
}
}]);
})();
HTML:
<div ng-controller="addUserCtrl as ctrl">
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<form class="form-horizontal" ng-submit="ctrl.submit()">
<div class="panel-heading">Add User</div>
<div class="panel-body">
<div class="form-group">
<label for="name" class="col-sm-3 control-label">User Name: <span class="required">*</span></label>
<div class="col-sm-8">
<input type="text" class="form-control" id="name" ng-model="ctrl.name"></input>
</div>
</div>
<div class="form-group">
<label for="role" class="col-sm-3 control-label">Role: <span class="required">*</span></label>
<div class="col-sm-8">
<select class="form-control" id="role" ng-model="ctrl.role" ng-options="opt.displayName for opt in ctrl.roles"></select>
</div>
</div>
<div class="form-group">
<label for="password1" class="col-sm-3 control-label">Password: <span class="required">*</span></label>
<div class="col-sm-8">
<input type="password" class="form-control" id="password1" ng-model="ctrl.password1"></input>
</div>
</div>
<div class="form-group">
<label for="password2" class="col-sm-3 control-label">Re-enter Password: <span class="required">*</span></label>
<div class="col-sm-8" ng-class="{'has-error' : ctrl.password1 != ctrl.password2}">
<input type="password" class="form-control" id="password2" ng-model="ctrl.password2"></input>
<p class="help-block" ng-if="ctrl.password1 != ctrl.password2">Passwords don't match</p>
</div>
</div>
</div>
<div class="panel-footer">
<button type="submit" class="btn btn-default" ng-disabled="!ctrl.name || !ctrl.password1 || !ctrl.password2 || ctrl.password1 != ctrl.password2">OK</button>
</div>
<div ng-controller="AlertsCtrl">
<div ng-repeat="(key,val) in alerts" class="alert {{key}}">
<div ng-repeat="msg in val">{{msg}}</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
But I'm getting:
Uncaught SyntaxError: Unexpected end of input
angular.js:14747 Error: [ng:areq] http://errors.angularjs.org/1.4.3/ng/areq?p0=addUserCtrl&p1=not%20aNaNunction%2C%20got%20undefined
You did not complete all brackets correctly.
Below should be like this:
mainApp.factory('alertsManager', function() {
return {
alerts: {},
addAlert: function(message, type) {
this.alerts[type] = this.alerts[type] || [];
this.alerts[type].push(message);
},
clearAlerts: function() {
for(var x in this.alerts) {
delete this.alerts[x];
}
}
}
});
You forgot to complete the factory by });.
And that is why indentation is so important.
Hope this may help you.
i am working with dynamic forms with ng-repeat .i am getting dynamic forms according to my userid. each form has delete button. my requirement is once i am clicking delete button i need to delete that particular form and those values from my user obj and remaining values i need to send to server. in this example i want to delete id 2 (2nd form), and 1st and 2nd form data i need to store one variable.
please send some fiddle for this .
my html code
<div ng-app="myApp">
<div ng-controller="myCtrl">
<form role="form" name='userForm' novalidate>
<div class="container">
<div class="row" ng-repeat="user in users">
<div class="form-group">
<div class="col-md-3">
<label>ID</label>
<input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
</div>
<div class="col-md-3">
<label>Comments</label>
<textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
</div>
<div class="col-md-3 ">
<label>Location</label>
<select ng-model="user.location" ng-options="v for v in locations" ng-init='initLocation(user)' name="select2" required>
</select>
</div>
<div>
<button>delete</button>
</div>
</div>
</div>
</div>
<div class="buttonContainer text-center btn-container">
<br>
<button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
<button type="button" class="btn button--default btn--small pull-center">Close</button>
</div>
</form>
</div>
js file
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope, $timeout) {
$scope.ids = [1, 2, 3];
$scope.users = $scope.ids.map(function(id) {
return {
id: id,
comment: "",
location: ""
};
});
$scope.locations = ['india', 'usa', 'jermany', 'china', 'Dubai'];
$scope.initLocation = (user) => {
$timeout(() => {
user.location = $scope.locations[0];
});
}
$scope.adduser = function() {
var data = $scope.users.map(function(user) {
return {
"userid": user.id,
"manualcomment": user.comment,
"location": user.location
}
});
console.log("data", data)
}
});
As per your requirement i am adding ng-click to delete button and adding removeSelForm method and pass your user object into that function parameter. in controller i am removing that particular form values from users object.
var myApp = angular.module('myApp', []);
myApp.controller('myCtrl', function($scope, $timeout) {
$scope.ids = [1, 2, 3];
$scope.users = $scope.ids.map(function(id) {
return {
id: id,
comment: "",
location: ""
};
});
$scope.locations = ['india', 'usa', 'jermany', 'china', 'Dubai'];
$scope.initLocation = (user) => {
$timeout(() => {
user.location = $scope.locations[0];
});
}
$scope.removeSelForm = function(item) {
var index = $scope.users.indexOf(item)
$scope.users.splice(index, 1);
}
$scope.adduser = function() {
var data = $scope.users.map(function(user) {
return {
"userid": user.id,
"manualcomment": user.comment,
"location": user.location
}
});
console.log("data", data)
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<form role="form" name='userForm' novalidate>
<div class="container">
<div class="row" ng-repeat="user in users">
<div class="form-group">
<div class="col-md-3">
<label>ID</label>
<input ng-model="user.id" id="user.id" name="user.id" placeholder="Enter bugid" type="text" required readonly disabled>
</div>
<div class="col-md-3">
<label>Comments</label>
<textarea ng-model="user.comment" id="textarea1" rows="1" required></textarea>
</div>
<div class="col-md-3 ">
<label>Location</label>
<select ng-model="user.location" ng-options="v for v in locations" ng-init='initLocation(user)' name="select2" required>
</select>
</div>
<div>
<button ng-click="removeSelForm(user)">delete</button>
</div>
</div>
</div>
</div>
<div class="buttonContainer text-center btn-container">
<br>
<button ng-disabled="userForm.$invalid" type="button" id="adduser" ng-click="adduser()">Add user</button>
<button type="button" class="btn button--default btn--small pull-center">Close</button>
</div>
</form>
</div>
Here im using Bootstrap validations with AngularJs when my form is submitted the columns is reset but its shows all validation..But my aim is its should not display validations
Bootstrap
<div class="modal" id="modal1">
<div class="modal-dialog">
<div class="modal-content">
<form name="f1" novalidate ng-submit="Save(Auth.emp)">
<div class="modal-body">
<div class="form-horizontal">
<div class="form-group">
<div class="row">
<div class="col-sm-4">
Email
</div>
<div class="col-sm-8">
<input type="text" name="email" class="form-control" ng-model="Auth.Email" ng-class="Submitted?'ng-dirty':''" required />
<span class="Error" ng-show="(f1.email.$dirty ||Submitted) && f1.email.$error.required">Email REq</span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-sm-4">
Password
</div>
<div class="col-sm-8">
<input type="text" name="psw" class="form-control" ng-model="Auth.Password" ng-class="Submitted?'ng-dirty':''" required />
<span class="Error" ng-show="(f1.psw.$dirty ||Submitted) && f1.psw.$error.required">Password REq</span>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="{{LoginAction}}" />
</div>
</form>
</div>
</div>
</div>
AngularCode.Js
$scope.Save = function (emp) {
if ($scope.LoginAction = "Login") {
$scope.Submitted = true;
if ($scope.isFormValid == true) {
var ss = {
Email: $scope.Auth.Email,
Password: $scope.Auth.Password,
}
var xxer = myServices.GetLogin(ss);
xxer.then(function (msg) {
$scope.msg = msg.data;
$('#modal2').modal('show')
Reset();
})
}
}
}
Reset
function Reset() {
$scope.Email = '';
$scope.Password = '';
}
I think you looking for this:
function Reset() {
$scope.Auth.Email = ''
$scope.Auth.Password = '';
}
You can set a model at the same level as the form tag and make all other inputs sub properties. Then set form model at the root level to an empty object when you click on reset. Here's a codepen.
function exampleController($scope) {
$scope.reset = function() {
$scope.form = {};
};
}
angular
.module('app', [])
.controller('exampleController', exampleController);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div class="row" ng-app="app" ng-controller="exampleController">
<form novalidate ng-model="form">
<input ng-model="form.email" type="email" />
<input ng-model="form.password" type="password" />
</form>
<button ng-click="reset()">Reset</button>
<pre>{{form}}</pre>
</div>
we have controller which has ng-include to load an external html. now i want to access a control value in parent.
my template is MainMenuCreate
#{
Layout = null;
}
<div >
<h2>{{Headtitle}}</h2>
<p>
<div style="width:200px;">MainMenuId :</div>
<input type="text" name="MainMenuId" id="MainMenuId" data-ng-model="MainMenuId" />
</p>
<p>
<div style="width:200px;">MainMenu :</div>
<input type="text" name="MainMenu" id="MainMenu" data-ng-model="MainMenu" />
</p>
<p>
<div style="width:200px;">PageTitle :</div>
<input type="text" name="PageTitle" id="PageTitle" data-ng-model="PageTitle" />
</p>
<input type="button" name="btnSave" id="btnSave" value="Save" ng-click="Save()" />
and my main page is
<div data-ng-app="MainMenuModule">
<div data-ng-controller="MainMenuController">
<div data-ng-include="'MainMenuCreate'" >
</div>
{{MainMenuId}}
</div>
</div>
and controller is
app.controller('MainMenuController', function ($scope, MainMenuService) {
$scope.Save = function () {
var MainMenuRecord =
{
MainMenuId: $scope.MainMenuId,
MainMenu: $scope.MainMenu,
PageTitle: $scope.PageTitle
};
var promisePost = MainMenuService.post(MainMenuRecord);
promisePost.then(function (pl) {
$scope.MainMenu = pl.data.MainMenu;
loadRecords();
}, function (err) {
console.log("Err" + err);
});
}
});
when i call this save method then $scope.MainMenuId shows undefined
<div style="width:200px;">MainMenuId :</div>
<input type="text" name="MainMenuId" id="MainMenuId" data-ng-model="obj.MainMenuId" />
<div style="width:200px;">MainMenu :</div>
<input type="text" name="MainMenu" id="MainMenu" data-ng-model="obj.MainMenu" />
<div style="width:200px;">PageTitle :</div>
<input type="text" name="PageTitle" id="PageTitle" data-ng-model="obj.PageTitle" />
</div>
<input type="button" name="btnSave" id="btnSave" value="Save" ng-click="Save(obj)" />
app.controller('MainMenuController', function ($scope, MainMenuService) {
$scope.obj = {};
$scope.Save = function (obj) {
var MainMenuRecord =
{
MainMenuId: obj.MainMenuId,
MainMenu: obj.MainMenu,
PageTitle: obj.PageTitle
};
var promisePost = MainMenuService.post(MainMenuRecord);
promisePost.then(function (pl) {
$scope.MainMenu = pl.data.MainMenu;
loadRecords();
}, function (err) {
console.log("Err" + err);
});
}
});
I have the following controller:
function userControl($scope,$http) {
$scope.users = [
{"id":"0","name":"User1","roles":[{}]},
{"id":"1","name":"User2","roles":[{}]},
]
$scope.addUser = function() {
var nextid = $scope.getNextId();
$scope.users.push({id:nextid,name:$scope.userName});
$scope.userName = '';
//$apply();
};
$scope.getNextId = function() {
var count = 0;
angular.forEach($scope.users, function(data) {
count = data.id;
});
var count2 = parseInt(count)+1;
return count2;
};
}
And the following HTML:
<h2>Users</h2>
<div ng-controller="userControl">
<div ng-repeat="user in users">
{{user.id}} : {{user.name}}
</div>
<form ng-submit="addUser()">
<input type="text" ng-model="userName" placeholder="User Name" />
<input type="submit" value="add">
</form>
</div>
<h2>Add role to user</h2>
<div ng-controller="userControl">
<div ng-repeat="user in users">
<u>{{user.id}} : {{user.name}}</u><br />
<div ng-repeat="role in user.roles">
{{role.name}}
</div>
<br />
</div>
<form ng-submit="addRoleToUser()">
<select ng-model="selectedUser" name="userSelect" ng-options="user.id as user.name for user in users"></select>
<input type="submit" value="add">
</form>
</div>
When I add a user in the addUser() function I can see the user is added since it's listed under the ng-repeat, however the user name does not appear in the select box.
This is because you use the same controller twice. This creates two separate scopes. When you add a user in one scope it doesn't get added in the second scope. The fix is simple, join the code in one scope:
<div ng-controller="userControl">
<h2>Users</h2>
<div>
<div ng-repeat="user in users">
{{user.id}} : {{user.name}}
</div>
<form ng-submit="addUser()">
<input type="text" ng-model="userName" placeholder="User Name" />
<input type="submit" value="add">
</form>
</div>
<h2>Add role to user</h2>
<div>
<div ng-repeat="user in users">
<u>{{user.id}} : {{user.name}}</u><br />
<div ng-repeat="role in user.roles">
{{role.name}}
</div>
<br />
</div>
<form ng-submit="addRoleToUser()">
<select ng-model="selectedUser" name="userSelect" ng-options="user.id as user.name for user in users"></select>
<input type="submit" value="add">
</form>
</div>
</div>
An alternative approach is to create a Service since services are singletons:
module.factory('Users',function(){
var users = [
{"id":"0","name":"User1","roles":[{}]},
{"id":"1","name":"User2","roles":[{}]},
];
return {
users:users,
add:function(user){
users.push(user);
}
}
});
function userControl($scope, Users) {
$scope.users = Users.users;
$scope.addUser = function() {
var nextid = $scope.getNextId();
Users.add({id:nextid,name:$scope.userName});
$scope.userName = '';
};
$scope.getNextId = function() {
var count = 0;
angular.forEach($scope.users, function(data) {
count = data.id;
});
var count2 = parseInt(count)+1;
return count2;
};
}
This will work with your original markup.