Angular post call with scala,play - angularjs

I want to call angular controller through scala.html file.and angular controller should redirect to scala controller to insert data.
I am getting the list from database through same approach .
but during insert it is not able to call function inside angular controller.
Scala html (interns.scala.html):
#import repository.Interns
#(dataList:play.api.libs.json.JsValue,internForm:Form[Interns])(implicit message:Messages)
#main("List Interns"){
<div ng-app="internApp">
<div ng-controller="InternCtrl">
<table class="table">
<tr>
<th >Id</th>
<th >Name</th>
<th >Email-Id</th>
<th >Mobile No.</th>
<th >Address</th>
<th >Emergency Contact No.</th>
<th></th>
<th><input type="submit" value="Add New Intern" class="btn btn-success" data-toggle="modal" data-target="#addIntern"> </th>
</tr>
<tr ng-repeat="intern in #dataList" class="danger">
<td>{{intern.id}}</td>
<td>{{intern.name}}</td>
<td>{{intern.email}}</td>
<td>{{intern.mobile}}</td>
<td>{{intern.address}}</td>
<td>{{intern.emergency}}</td>
<td> <input type="submit" value="Edit" class="btn btn-primary" data-toggle="modal" data-target="#addIntern"></td>
<td><input type="submit" value="Delete" class="btn btn-danger"> </td>
</tr>
</table>
</div>
</div>
<div ng-app="internApp">
<div ng-controller="AddCtrl">
<div class="modal fade" id="addIntern" role="dialog">
<div class="modal-dialog">
<div class="modal-content" style="height:700px;text-align:center;width:500px">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h1 class="modal-title">Add Intern</h1>
</div>
<form>
<input type="text" placeholder="Name" class="text" ng-model="name" size="30">
<br>
<br>
<input type="text" placeholder="Email" class="text" ng-model="email" size="30">
<br>
<br>
<input type="text" placeholder="Mobile Number" class="text" ng-model="mobile" size="30">
<br>
<br>
<input type="text" placeholder="Address" class="text" ng-model="address" size="30">
<br>
<br>
<input type="text" placeholder="Emergency Contact" class="text" ng-model="emergency" size="30">
<br>
<br>
<input type="submit" class="btn btn-primary" **ng-click="save()"** value="Add Intern" >
<br><br>
</form>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="#routes.Assets.versioned("javascripts/list.js")"></script>
}
Angular controller (list.js):
var internApp = angular.module('internApp', []);
internApp.controller('AddCtrl', function ($scope, $http){
alert("hello")
$scope.save = function(){
var data1 = {"id":8,"name":$scope.name,"email":$scope.email,"mobile":$scope.mobile,"address":$scope.address,"emergency":$scope.emergency};
$http({
method:'POST',
url:'/addNew',
data: JSON.stringify(data1),
contentType: 'application/json',
dataType:'json'
})
}})
internApp.controller('InternCtrl', function ($scope, $http){
$http.get('/list').success(function(data) {
$scope.dataList=data;
});
});

This one works for me without any problems:
https://jsfiddle.net/w3vyak05/2/
As you can see - you see the alert and I added a small part where after submission you see the data underneath the form. Of course in your application you would make the HTTP POST call there.
What is different from your approach:
I am using <form ng-submit="save()"> instead of ng-click. Please be careful when switching - you don't want to end up mixing the two:
Warning: Be careful not to cause "double-submission" by using both the ngClick and ngSubmit handlers together. See the form directive documentation for a detailed discussion of when ngSubmit may be triggered.
What else to keep in mind (sorry, off-topic but had to write it down):
In your code you have this: <input type="submit" class="btn btn-primary" **ng-click="save()"** value="Add Intern" > - I guess you just wanted to draw our attention to the ng-click but do not forget to remove the asterisks.
Your list is populated because this is the only "action" which is executed once the Angular controller has been loaded (just wanted to explain why the one controller is working and the other not).
You are using different syntax for making an HTTP POST and GET requests - try to stick to just one variant. Your future you will thank you :)

Related

Angular MaterialJS Dialog form with different save options

I'm trying to save form data in mdDialog but with options of (save and close) the dialog and (save) which will save the form data then open another dialog empty dialog without having to close and open the mdDialog again, the problem is how to call same SaveData function in same form for both save operations?
$scope.saveData = function (isValid) {
if (isValid) {
updateservice.postdata($scope.myformdata)
.then(function (data) {
$mdDialog.hide();
});
// error handling
}
};
and in the template:
<md-dialog>
<form name="form" ng-submit="saveData(form.$validform)" novalidate>
<md-dialog-content>
<div class="md-dialog-content">
<div>
</div>
<table class="table display" border="1" span="1" name="newForm" novalidate role="form" ng-style="{ width: th.width }">
</tr>
<tr>
<td><input type="text" class="form-control text-center" placeholder="required" ng-required="true"></td>
<td><input type="text" class="form-control text-center" placeholder="optional" ng-required="true"></td>
</tr>
</table>
</div>
</md-dialog-content>
<md-dialog-actions layout="row">
<md-progress-circular md-mode="indeterminate" md-diameter="20px" class="spinner"></md-progress-circular>
<button type="button" class="btn btn-primary" ng-click="save()" >Save</button>
<button type="submit" class="btn btn-primar">Save and close</button>
<button type="button" class="btn btn-default" ng-click="cancel()" ng-disabled="loading">Cancel</button>
</md-dialog-actions>
</form>
</md-dialog>
I changed Save button with type button is not posting the formdata, and changing type to submit like save and close saves data then opens and closes the dialog.
here's codePen with my code:
https://codepen.io/anon/pen/ZqoYRx
How about passing an argument like isSaveAndClose in the save function:
In HTML:
<button type="button" class="btn btn-primary" ng-click="save(false)" ng-show="!loading">Save</button>
<button type="button" class="btn btn-primar" ng-click="save(true)">Save and close</button>
In JS:
$scope.save = function (isSaveAndClose) {
saveData();
if (isSaveAndClose)
$mdDialog.hide().then(showCustomConfirm);
};

Atleast one field is mandatory in form: Form Validation in Angular

I have got three input fields on a form.
I am looking for a way in which a form is valid if either or any combination of inputs is required, It means atleast one is necessary .Also user may enter inputs in any combination even then also form is valid.
I have read ng-required but that will make my expression too long.
<td>Name</td>
<td><input type="text" class="form-control input-xs" name="name"
ng-model="ctrl.orderSearch.name" minlength="4">
</td>
<td>Class</td>
<td><input type="text" class="form-control input-xs" name="class"
ng-model="ctrl.orderSearch.Class" minlength="6">
</td>
<td>Roll No:</td>
<td><input type="text" class="form-control input-xs" name="rollNo"
ng-model="ctrl.orderSearch.RollNo" minlength="6">
</td>
Update: I don't want to diable submit button. The form is valid in either of these scenarios:
1)field one or two or three is filled
2) 1,2 or 1,3 or 2,3 is filled
3) 1,2,3 is filled.
Also, I tried to use:
ng-required="!(ctrl.orderSearch.name.length || ctrl.orderSearch.rollNo.length )" on fields. But when I submit my form ,an in built pop up from angular is presented on my name field saying "Please fill this required field" because whenever form.$valid is called on an empty form , field one would be checked first and hence pop up will be displayed on that field. But to user, it may seem field one is mandatory which is not the case.
Also , I don't want to write a custom method for validation. Is is it possible using ng-required? Please help.
Check this link
HTML
<form name="myForm">
<input type="text" ng-model="fields.one" name="firstField" ng-required="!(fields.one.length || fields.two.length || fields.three.length)" />
<br/>
<input type="text" name="secondField" ng-required="!(fields.one.length || fields.two.length || fields.three.length)" ng-model="fields.two" />
<br/>
<input type="text" ng-model="fields.three" name="thirdField" ng-required="!(fields.one.length || fields.two.length || fields.three.length)" />
<br/>
<button type="submit" ng-disabled="!myForm.$valid">Submit</button>
<br/>
<div>
<p>Submitted ? <span ng-bind="fields.submitted"></span>
</p>
<p>Form $valid: <span ng-bind="myForm.$valid"></span>
</p>
</div>
</form>
Js
angular.module("myApp", [])
.controller('myCtrl', ['$scope', function ($scope) {
$scope.fields = {
one: '',
two: '',
three: '',
submitted: 'Not Yet'
};
$scope.submit = function () {
$scope.fields.submitted = "Yahooo";
}
}]);
You can create a $scope variable that will do the "either or all of fields required checking". That $scope variable will be your flag on when a form is valid or not.
example:
Controller
function SampleController(){
$scope.isValidForm = function(){
//do the checking here.
//return true or false
}
}
View:
<button ng-disabled="!isValidForm()">Submit</button>
I have edited your code check your code... check the fiddle link Fiddle
Hope this will help you to understand validation..
<div ng-app ng-controller="myCtrl">
<table ng-form="checkForm">
<tr>
<td>Name</td>
<td>
<input type="text" class="form-control input-xs" required name="name"
ng-model="ctrl.orderSearch.name" minlength="4" >
</td>
<td>
<div ng-show="checkForm.name.$invalid">
name error
</div>
</td>
</tr>
<tr>
<td>Class</td>
<td>
<input type="text" class="form-control input-xs" required name="class"
ng-model="ctrl.orderSearch.Class" minlength="6" >
</td>
<td>
<div ng-show="checkForm.class.$invalid">
class error
</div>
</td>
</tr>
<tr>
<td>Roll No:</td>
<td>
<input type="text" class="form-control input-xs" required name="rollNo"
ng-model="ctrl.orderSearch.RollNo" minlength="6" >
</td>
<td>
<div ng-show="checkForm.rollNo.$invalid">
Roll no error
</div>
</td>
</tr>
<tr>
<td colspan="3" style="font-weight:bold; color:green">
<span ng-show="checkForm.name.$valid || checkForm.class.$valid || checkForm.rollNo.$valid">Valid Form</span>
</td>
</tr>
</table>
</div>
Below is the code it will validate on form submitting event.It will restrict while you submit the form and your form contains all the fields empty.
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script>
angular.module('myApp', []).controller('myCtrl', function($scope) {
$scope.isOneFieldRequired = function (name,uclass,rollNo) {
return !(name|| uclass|| rollNo);
};
});
</script>
<div ng-app="myApp" ng-controller="myCtrl">
<form name="myForm">
<input type="text" ng-model="name" name="name" ng-required="isOneFieldRequired(name,uclass,rollNo)" />
<br/>
<input type="text" ng-model="uclass" name="uclass" ng-required="isOneFieldRequired(name,uclass,rollNo)" />
<br/>
<input type="text" ng-model="rollNo" name="rollNo" ng-required="isOneFieldRequired(name,uclass,rollNo)" />
<br/>
<button type="submit"> Submit</button>
</form>
</div>
</body>
</html>

Angular JS Forms submit not sending ID

I am trying to send the course id to the controller in a form button, but it does not seem to work. The controller logs the vm.add.year correctly but vm.add.course gets undefined. Why?
index.html:
<form method="post" ng-submit="vm.addCourseToYear()">
<table class="table">
<tr ng-repeat="course in vm.courses | filter:search">
<td>{{course.courseName}}</td>
<td><select id="addCourse" name="addCourse" class="form-control" ng-model="vm.add.year" required>
<option value="year1"> Year1 </option>
</select></td>
<td><input style="display:none" ng-value="course._id" ng-model="vm.add.course">
<button type="submit" class="btn btn-primary" id="{{course._id}}">Add</button>
</td>
</tr>
</table>
</form>
index.controller.js
function addCourseToYear(){
console.log(vm.add.course);
console.log(vm.add.year);
};
I would do the following to fix this:
Add ng-click directive to button:
<button type="submit"
class="btn btn-primary"
ng-click="vm.addCourseToYear(vm.add)"
id="{{course._id}}">Add</button>
Remove the form action leaving just form:
<form>
Change the function to take a parameter:
function addCourseToYear(newItem){
console.log(newItem.course);
console.log(newItem.year);
};
Change this to initialize vm.add.course as course._id:
<td>
<input style="display:none" ng-init="vm.add.course = course._id" ng-model="vm.add.course">
<button type="submit" class="btn btn-primary" id="{{course._id}}">Add</button>
</td>
This follows the patterns found on Angular's site: https://docs.angularjs.org/guide/forms
try changing the code to this:
<form method="post" ng-submit="vm.addCourseToYear(vm.add.course._id)">
hope this solves your issue .. :)
display:none removes the object from the from,
change it to visibility: hidden;position:absolute
<input style="visibility:hidden;position:absolute;" ng-value="course._id" ng-model="vm.add.course">

AngularJS variable in scope - use variables of different scope

I would have a question concerning variables in scope and visibility.
Currently I have two controller variables:
vm.selectedUser
vm.selectedUserRole
The problem is, that I generate the tables in a ng-repeat loop and all inputs and selects in the different tables share this two mentioned variables above.
My question now would be how can I use this two parameters above in my method:
vm.addInstitutionUserConnection(institutionUserConnectionContent.institution, institutionUserConnectionContent, selectedUser, selectedUserRole)
Is there any chance to do this because the input, select elements and the span-button element (add user) have different scopes (this is my guess - I don't know exactly)
Thanks a lot for help!
<div ng-repeat="institutionUserConnectionsOfInstitution in vm.institutionUserConnectionsOfInstitutions">
<div ng-repeat="institutionUserConnectionContent in institutionUserConnectionsOfInstitution.institutionUserConnectionContents">
<div ng-show="addUser" class="row">
<table>
<tr>
<td class="adduserinput">
<input
type="text"
class="form-control"
placeholder="Benutzer durchsuchen"
ng-model="vm.selectedUser"
typeahead="user as vm.userLabelFormatter(user) for user in vm.getUsersByTerm($viewValue) | limitTo:5"
typeahead-min-length="3"
typeahead-wait-ms="100"
typeahead-editable="false" />
</td>
<td class="adduserroles">
<select class="form-control" ng-model="vm.selectedUserRole" ng-options="role as role for role in vm.roles">
</select>
</td>
<td>
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="vm.addInstitutionUserConnection(institutionUserConnectionContent.institution, institutionUserConnectionContent)">add user</button>
</span>
</td>
</tr>
</table>
</div>
</div>
Do it like this -
<div ng-repeat="institutionUserConnectionsOfInstitution in vm.institutionUserConnectionsOfInstitutions">
<div ng-repeat="institutionUserConnectionContent in institutionUserConnectionsOfInstitution.institutionUserConnectionContents">
<div ng-show="addUser" class="row">
<table>
<tr>
<td class="adduserinput">
<input
type="text"
class="form-control"
placeholder="Benutzer durchsuchen"
ng-model="institutionUserConnectionContent.selectedUser"
typeahead="user as vm.userLabelFormatter(user) for user in vm.getUsersByTerm($viewValue) | limitTo:5"
typeahead-min-length="3"
typeahead-wait-ms="100"
typeahead-editable="false" />
</td>
<td class="adduserroles">
<select class="form-control" ng-model="institutionUserConnectionContent.selectedUserRole" ng-options="role as role for role in vm.roles">
</select>
</td>
<td>
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="vm.addInstitutionUserConnection(institutionUserConnectionContent.institution, institutionUserConnectionContent, institutionUserConnectionContent.selectedUser, institutionUserConnectionContent.selectedUserRole)">add user</button>
</span>
</td>
</tr>
</table>
</div>
</div>
Explanation -
I just changed the vm to institutionUserConnectionContent.
reason - since you'll have multiple rows in the table (ng-repeat), if you use vm, you would end up with overwriting the same selectedUser and selectedUser of one row with other.
Hope this helps.

How to populate data in a twitter-bootstrap modal using angularjs

Using:
-Twitter-Bootstrap
-AngularJs
Here's the story
Created table: rows are dynamically created using "ng-repeat". The data item inside the first cell (in a row) has an on-click event triggering a Twitter-Bootstrap modal to appear. The input fields in the modal match the columns in the [table] row. The user edits the necessary data in that row. This should update database and changes reflect immediately in the table.
However, I cannot get the data from the table to populate inside the modal fields.
Here's the weird thing... If I use a Twitter-Bootstrap (TBS) popup instead of a TBS modal, everything works. EVERYTHING. All the data populates inside the popup fields, it's editable, it actually saves to the database, AND updates the table row! But popups suck and I am restricted from using them.
Using the EXACT SAME code, why won't the data populate inside a modal?
Obviously, this leads me to believe using syntactically identical code, a popup and modal do not function the same way. But why?
The research I've done, and documentation I've perused on here as well as both TBS and AngularJS, has been either too overwhelming or altogether unhelpful.
In Summary, this is the functionality I'm looking to achieve:
User clicks the data inside the first cell of a table row
(on-click) Modal appears populated with the data in the row (particularly this).
User can edit the fields
Save/Update. The trigger event can be "enter" or button "on-click" I don't care, I just want it to work.
Here's the gist of the code (with the popup which works, and the modal which doesn't).
Disclaimer: I couldn't get it to work in here (SO or jfiddle) I'm probably missing a reference. But I know you all are smarter than me, and with what I've given, I have the utmost confidence in this community to be able to figure out what it is I'm doing wrong.
I thank you all in advance for your help.
<!DOCTYPE html>
<html ng-app="person">
<head>
<title>HELP ME WITH MODALS</title>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="PersonCtrl">
<table style="border:1px solid black; padding:3px;">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Favorit Color</th>
<th>Favorit Food</th>
<th>Favorite Season</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in persons" ng-click="updatePerson(person)">
<td data-toggle="modal" data-target="#editModal">{{person.firstName}}</td>
<td>{{person.lastName}}</td>
<td>{{person.favoriteColor}}</td>
<td>{{person.favoriteFood}}</td>
<td>{{person.favoriteSeason}}</td>
<td>
<button popover-template="dynamicPopover.templateUrl" popover-placement="left" popover-title="Edit" ng-click="current.person=person">Edit</button>
</td>
</tr>
</tbody>
</table>
<!-- Modal -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" style="color:#513011;">×</span>
</button>
<h4 class="modal-title" id="editModalLabel">Edit Person</h4>
</div>
<!--/HEADER-->
<div class="modal-body">
<form ng-submit="update(current.person)">
<div class="form-group">
<label for="firstname">First Name:</label>
<input name="firstname" type="text" ng-model=current.person.firstName class="form-control" required>
</div>
<div class="form-group">
<label for="lastname">Last Name:</label>
<input name="lastname" type="text" ng-model=current.person.lastName class="form-control" required>
</div>
<div class="form-group">
<label for="favoritecolor">Favorite Color:</label>
<input name="favoritecolor" type="text" ng-model=current.perosn.favoriteColor class="form-control">
</div>
<div class="form-group">
<label for="favoritefood">Favorite Food:</label>
<input name="favoritefood" type="text" ng-model=current.perosn.favoriteFood class="form-control">
</div>
<div class="form-group">
<label for="favoriteseason">Favorite Season:</label>
<input name="favoriteseason" type="text" ng-model=current.perosn.favoriteSeason class="form-control">
</div>
</form>
</div>
<!--/MODAL-BODY-->
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" ng-click="update(current.person)" class="btn btn-primary" value="Save" />
</div>
<!--/MODAL-FOOTER-->
</div>
<!--/MODAL-CONTENT-->
</div>
<!--/MODAL-DIALOG-->
</div>
<!--/MODAL-->
</div>
<!--/CONTROLLER-->
</body>
</html>
<!-- script for edit popover-->
<script type="text/ng-template" id="popoverTemplate.html">
<div>
<form ng-submit="update(current.person)">
<div class="form-group">
<label for="firstname">First Name:</label>
<input name="firstname" type="text" ng-model=current.person.firstName class="form-control">
</div>
<div class="form-group">
<label for="lastname">LastName:</label>
<input name="lastname" type="text" ng-model=current.person.lastName class="form-control">
</div>
<div class="form-group">
<label for="favoritecolor">Favorite Color:</label>
<input name="favoritecolor" type="text" ng-model=current.person.favoritecolor class="form-control">
</div>
<div class="form-group">
<label for="favoritefood">Favorite Food:</label>
<input name="favoritefood" type="text" ng-model=current.person.favoritecolor class="form-control">
</div>
<div class="form-group">
<label for="favoriteseason">Favorite Season:</label>
<input name="favoriteseason" type="text" ng-model=current.person.favoritecolor class="form-control">
</div>
<input type="submit" class="btn btn-default" value="Submit">
<input type="button" class="btn btn-default pull-right" ng-click="delete(current.schoolTerm)" value="Delete">
</form>
</div>
</script>
<script>
var person = angular.module('person', []);
personApp.controller('PersonCtrl', [
function ($scope) {
var person = [
{
'firstName': 'Christine',
'lastName': 'Smith',
'favoriteColor': 'Pink',
'favoriteFood': 'Sushi',
'favoriteSeason': 'Summer'
},
{
'firstName': 'Dana',
'lastName': 'Carvey',
'favoriteColor': 'Yellow',
'favoriteFood': 'Tomatoes',
'favoriteSeason': 'Summer'
},
{
'firstName': 'Terry',
'lastName': 'Gross',
'favoriteColor': 'Chartreuse',
'favoriteFood': 'Lasagna',
'favoriteSeason': 'Spring'
}
];
}]);
</script>
If you want to use the modal in the twitter bootstrap and pass data back and forth, you have to extend/wrap it around with your own directives, and I don't recommend doing that since there are already directives that do just that.
If you are new to Angular, and Have to use bootstrap consider using Angular Ui Bootstrap , which is a set of custom directives written using the twitter bootstrap.
If you are not supporting IE8 and haven't committed to twitter bootstrap, I strongly encourage you checkout lumx.
Note: These two are both still in beta, so use with caution.
Okay, now lets get back to your question. If you decide to stay with twitter bootstrap and once you have the angular ui bootstrap installed - it's easy, just follow this steps https://github.com/angular-ui/bootstrap#installation - , the only thing that probably will be a little confusing at first would be how to pass your scope properties from the caller controller up to the modal.
In a nutshell you have to do something like this in the caller controller:
var modalInstance = $modal.open({
templateUrl: 'yourModalTemplate.html',
controller: 'yourModalController',
resolve: {
itemsFromCallerController: function () {
return [{ i: 1, i: 2 }];
}
}
and your modal's controller should look something like this:
angular.module("app").controller('yourModalInstanceController', function ($scope, $modalInstance, itemsFromCallerController, action) {
$scope.modalHeader = "your modal header";
$scope.items = itemsFromCallerController;
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Take a look at this Plunker

Resources