i am a newbie of angularJS, i just want to ask how can i get value of on-success attribute which will have a JSON object on a successful upload request.
"on-success" attribute exists on post-creator.template.html page.
index.html
<body>
<div>
<post-creator post-id="0"></post-creator>
</div>
</body>
This a post-creator.template.html
<form role="form">
<div class="form-group float-label-control">
<label>Title</label>
<input type="text" placeholder="Name" class="form-control" ng-model="model.post.title">
</div>
<div upload-button
url="/user_uploads"
on-success="onSuccess(response)"
on-error="onError(response)"
ng-model="onSuccess(response)"
>Upload</div>
<div class="text-center">
<button type="button" class="btn btn-default" ng-click="model.save(model.post)">Save</button>
</div>
</form>
And this is post-creator.component.js:
(function () {
"use strict";
var module = angular.module(__appName);
function controller($http) {
var model = this;
model.post = null;
model.save = function (post) {
//get on-success value here
//console.log(model.onSuccess);
}
}
module.component("postCreator", {
templateUrl: "components/post-creator/post-creator.template.html",
bindings: {
category: "<",
postId: "<",
subCategory: "<"
},
controllerAs: "model",
controller: ["$http", controller]
});
}());
you can inject $element to your controller and get attributes binded to your directive by $element[0].attributes.
function controller($http, $element) {
var attrs = $element[0].attributes;
// you own logic
}
Related
My idea is to create a big form from separated components. So this is my main template:
<form novalidate>
<div class="row">
<user></user>
</div>
<button type="button" class="btn btn-default" ng-click="submit()"> Submit </button>
</form>
and its controller (the template is binded from ui route config to the controller)
(function () {
'use strict';
angular.module('app')
.controller('formCtrl', formCtrl);
function formCtrl ($scope) {
$scope.submit = function() {
console.log("read data");
}
}
})();
Now, the user component:
(function () {
'use strict';
var module = angular.module('app.user');
module.component("user", {
templateUrl: "app/user/user.html",
controllerAs: "model",
controller: function () {
var model = this;
model.user = {};
}
});
})();
and the user template:
<form novalidate>
<form-group>
<label for="inputUser"> Name <label>
<input ng-model="model.user.name" id="inputUser" type="text" placeholder="User"/>
</form-group>
<form-group>
<label for="inputUser"> Email <label>
<input ng-model="model.user.email" id="inputUser" type="email" placeholder="Email"/>
</form-group>
<div>
{{model.user | json}}
</div>
</form>
Now I want to be able to read user data when the user do the submit. How can I do it?
When using components, depending on the type of component (smart or dumb), you have to emit an output to the parent controller to handle such thing. But in this case, you can use ngModel to handle a model and change it on the parent from within the component. For example:
Working snippet:
angular.module('app', [])
.controller('formCtrl', function($scope) {
$scope.user = {};
$scope.submit = function() {
console.log($scope.user);
}
})
.component("user", {
bindings: {
user: '=ngModel'
},
templateUrl: "app/user/user.html",
controllerAs: "model",
controller: function() {}
});
angular.element(function() {
angular.bootstrap(document, ['app']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<form novalidate ng-controller="formCtrl">
<div class="row">
<user ng-model="user"></user>
</div>
<button type="button" class="btn btn-default" ng-click="submit()">Submit</button>
</form>
<script type="text/ng-template" id="app/user/user.html">
<form novalidate>
<div>
<label for="inputUser">Name
<label>
<input ng-model="model.user.name" id="inputUser" type="text" placeholder="User" />
</div>
<div>
<label for="inputUser">Email
<label>
<input ng-model="model.user.email" id="inputUser" type="email" placeholder="Email" />
</div>
<div>
{{ model.user | json }}
</div>
</form>
</script>
A possible solution would be $$childTail. So if I want to access to user:
$scope.$$childTail.model.user
so I have a form with an input and some other stuff and I'm trying to do some angular validation to make sure that the entered information is actually there (not blank). To do so, I'm using an if statement.
The error message I get is:
Cannot read property 'name' of undefined
It seems as if it can't read an <input> tag name if it's left blank. The function works when I fill in the , but not the others (which are a and . I'm just trying to use an if statement to see if they've been filled out. Here's the html and angular code below:
reviewModal.view.html (shortened form version)
<div class="modal-content">
<div role="alert" ng-show="vm.formError" class="alert alert-danger">{{ vm.formError }}</div>
<form id="addReview" name="addReview" role="form" ng-submit="vm.onSubmit()" class="form-horizontal">
<label for"name" class="col-xs-2 col-sm-2 control-label">Name</label>
<div class="col-xs-10 col-sm-10">
<input id="name" name="name" ng-model="vm.formData.name" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Submit review</button>
</form>
</div>
reviewModal.controller.js
(function() {
angular
.module('loc8rApp')
.controller('reviewModalCtrl', reviewModalCtrl);
reviewModalCtrl.$inject = ['$uibModalInstance', 'locationData'];
function reviewModalCtrl($uibModalInstance, locationData) {
var vm = this;
vm.locationData = locationData;
vm.onSubmit = function() {
vm.formError = "";
if(!vm.formData.name || !vm.formData.rating || !vm.formData.reviewText) {
vm.formError = "All fields required, please try again";
return false;
} else {
console.log(vm.formData);
return false;
}
};
vm.modal = {
cancel : function() {
$uibModalInstance.dismiss('cancel');
}
};
}
})();
locationDetail.controller.js
(function() {
angular
.module('loc8rApp')
.controller('locationDetailCtrl', locationDetailCtrl);
locationDetailCtrl.$inject = ['$routeParams', '$uibModal', 'loc8rData'];
function locationDetailCtrl($routeParams, $uibModal, loc8rData) {
var vm = this;
vm.locationid = $routeParams.locationid;
loc8rData.locationById(vm.locationid)
.success(function(data) {
vm.data = { location: data };
vm.pageHeader = {
title: vm.data.location.name
};
})
.error(function(e) {
console.log(e);
});
vm.popupReviewForm = function() {
var modalInstance = $uibModal.open({
templateUrl: '/reviewModal/reviewModal.view.html',
controller: 'reviewModalCtrl as vm',
resolve : {
locationData : function() {
return {
locationid : vm.locationid,
locationName : vm.data.location.name
};
}
}
});
};
}
})();
vm.formData must be defined before you can assigned/read name property in the html. Update code in reviewModalCtrl to init vm.formData:
vm.formData = {};
Use angular validation instated validating things in controller as follows.
<div class="modal-content">
<div role="alert" ng-show="addReview.$submitted && addReview.$invalid" class="alert alert-danger">All fields required, please try again</div>
<form id="addReview" name="addReview" role="form" ng-submit="vm.onSubmit()" class="form-horizontal">
<label for"name" class="col-xs-2 col-sm-2 control-label">Name</label>
<div class="col-xs-10 col-sm-10">
<input id="name" name="name" ng-model="vm.formData.name" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Submit review</button>
</form>
</div>
I have used required in text box and show the error message on top with
ng-show="addReview.$invalid"
You do not need any code on controller.
I wonder how can I send the id of the selected row from my table to the controller when I try to show the details of these row,this is my code:
app.js:
.controller("etudmodifCtrl", ["$scope", "$http", "filterFilter", "$rootScope", "logger", "$filter", "$modal", "$log", function ($scope, $http, filterFilter, $rootScope, logger, $filter, $modal, $log) {
$http({
method: 'GET',
url: 'http://localhost:50001/api/Students/' + $scope.store.id
}).success(function (data) {
$scope.firstname = data.FirstName;
$scope.lastname = data.LastName;
$scope.email = data.Email;
console.log("success");
}).error(function (data, status, headers, config) {
console.log("data error ...");
});
$scope.open = function () {
var modalInstance;
modalInstance = $modal.open({
templateUrl: "myModalContent1.html",
controller: "ModalInstanceCtrl",
resolve: {
items: function () {
return $scope.items
}
}
}), modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem
}, function () {
$log.info("Modal dismissed at: " + new Date)
})
}
}])
my html code:
<table class="table table-responsive table-hover" ng-controller="etudmodifCtrl">
<tr ng-repeat="store in currentPageStores">
<td align="center">{{store.LastName}}</td>
<td align="center">{{store.FirstName}}</td>
<td align="center">{{store.Email}}</td>
<td align="center">{{store.Class}}</td>
<td align="center">
<script type="text/ng-template" id="myModalContent.html">
< div class ="modal-header">Modify Informations</div><div class = "modal-body modal-dialog modal-lg3" data-ng-controller = "etudmodifCtrl">
<div class="panel-body" >
<div class="col-md-6">
<div class="form-group">
<label for="" class="col-sm-2">FirstName</label>< div class = "col-sm-10"><input type = "email" class ="form-control" ng-model = "firstname">
</div>
</div >< /div>
<div class="form-group">
<label for="" class="col-sm-2">LastName</label>< div class = "col-sm-10"><input type = "email" class ="form-control" ng-model = "lastname">
</div>
</div >< /div>
<div class="form-group">
<label for="" class="col-sm-2">Email</label>< div class = "col-sm-10"><input type = "email" class ="form-control" ng-model = "email">
</div>
</div >< /div>
</script>
</td>
</tr>
</table>
<button type="button" onclick="window.location = '" aria-label="Center Align" ng-click="open()" data-toggle="modal" data-target=".bs-example-modal-lg">Modify</button>
I try to send the id via the open function but I get a syntax error
thanks for help
In button bg-click pass the id by using ng-click="open(store.storeId)" complete code
<button type="button"
aria-label="Center Align"
ng-click="open(store.storeId)"
data-toggle="modal"
data-target=".bs-example-modal-lg">Modify</button>
And change your open function to accept a parameter like this
$scope.open = function (id) {
............
............
}
for more detail, who to pass value from controller to model controller see this Pass parameter to modal
I have a requirement where I need to open a dialog from a jsp page and while opening the dialog, I need to load it with some prepopulated data from the server (using an AJAX call). If I make the AJAX call before opening the dialog, I get the data but the dialog loads like a new page. If I try to get the data in the new controller, the dialog still does not reflect the data. What should I use to make sure the dialog reflects the data that I am getting from the server
<div class="container-fluid" ng-controller="EditUserController">
<div class="text-center container-fluid">
<label class="sub-header">Edit User: {{userEmail}}</label>
</div>
<form action="editUser" method="post" name="editForm">
<div>
<div class="pull-right">
<label>Delete User</label><br> <a href="#"
class="btn btn-block btn-sm btn-danger" ng-click="deleteUser(userEmail)">{{userEmail}}</a>
</div>
<div>
<label>Change Role</label>
</div>
<div>
<label>
<input type="checkbox" ng-model="superVisor" name="superVisorFlag"
ng-true-value="1" ng-false-value="0" value="${existingUser.superVisorFlag}">
Make a Supervisor</label>
</div>
<div>
<input type="text" class="form-control" ng-model="email"
name="emailAddress" ng-disabled = "true"
ng-options="email for email in userEmail"
value="${existingUser.emailAddress}"
placeholder="Enter New User Email Address" bs-typeahead>
</div>
<div>
<input type="text" class="form-control" ng-model="firstName"
name="firstName" value="${existingUser.firstName}"
placeholder="Enter First Name" bs-typeahead>
</div>
<div>
<input type="text" class="form-control" ng-model="lastName"
name="lastName" value="${existingUser.lastName}"
placeholder="Enter Last Name" bs-typeahead>
</div>
<div>
Save Changes
</div>
</div>
</form>
</div>
<script type="text/javascript"
src="<c:url value="/resources/scripts/admin.js"/>"></script>
The above is a jsp for the dialog. Below is my js file -
var app = angular.module('scc-admin', [ 'ngDialog', 'mgcrea.ngStrap' ]);
app.factory("UserList", function() {
var UserList = {};
UserList.data = [ {
userId : 111,
userFirstName : "xxx",
userLastName : "yyy",
userEmail : "xxx.yyy#zzz.com",
userRole : "Admin"
}, {
userId : 222,
userFirstName : "second",
userLastName : "last",
userEmail : "second.last#zzz.com",
userRole : "Manager"
}];
return UserList;
});
app.controller('UserSettingsController', function($scope, ngDialog, UserList,$http) {
// variable for the bashboard list
$scope.userList = UserList;
$scope.editUser = function(userEmail) {
$scope.userEmail = userEmail;
ngDialog.open({
template : 'editUser' ,
className : 'ngdialog-theme-default',
controller : 'EditUserController',
closeByEscape : true,
scope : $scope
});
};
$scope.addUser = function() {
ngDialog.open({
template : 'addUser',
className : 'ngdialog-theme-default',
controller : 'AddUserController',
closeByEscape : true,
scope : $scope
});
};
});
app.controller('EditUserController', function($scope, ngDialog, $http) {
ngDialog.template = $scope.output;
ngDialog.$modelValue = $scope.output;
var responsePromise = $http.get("initUser?email=" + $scope.userEmail);
responsePromise.success(function(data, status, headers, config) {
$scope.output = data;
console.log(data);
});
console.log($scope);
$scope.deleteUser = function(){
$scope.cfdump = "";
var str = {emailAddress : $scope.userForm.emailAddress.$modelValue};
str = JSON.stringify(str);
var request = $http({
method: 'post',
url: "deleteUser?formData=" + str,
data: ({formData:str})
});
request.success(function(html){
alert("success");
});
request.error(function(errmsg){
alert("Unable to delete user");
});
}
});
I am opening a dialog in usersettings controller and trying to load it with default data. I tried setting the new dialog's template to the output of the AJAX call, it did not work. What am I missing here?
After consulting the documentation, I learned following solution. It should work for you like it did for me.
To pass data (JSON Object) for ng-model inside the ngDialog, you can declare your ngDialog as following.
ngDialog.open({
template: 'my-template.html',
className: 'ngdialog-theme-plain',
data: $scope.myJSONObject
});
Now, with the above part done, you need to bind the data in your popup ngDialog, so go and put ngDialogData.myJSONObjectFieldName in your ng-model.
Consider following example for further elaboration. We assume that we have myJSONObject as following.
myJSONObject={
first_name: 'John',
last_name: 'Doe'
};
To use first_name inside your ngDialog's ng-model, simply put ng-model="ngDialogData.first_name".
To check whether the controller(VM) data is received in Modal Dialog use this
<pre>{{vm|json}}</pre>
Module and Controller:
var app = angular.module("DemoApp",['ngDialog']);
app.controller("DemoController",["$rootScope","ngDialog","productService",function($rootScope,ngDialog,productService){
var vm=this;
$rootScope.ngDialog = ngDialog; // to close Dialog using "ngDialog.close();" in ProductDialog.html
/* vm.products=[{brand:"Apple", price:60000, os:"iOS"},
{brand:"Samsung", price:35000, os:"Android"},
{brand:"Microsoft Lumia", price:30000, os:"Windows 10"}
];
*/
vm.getProductDetails=function() {
productService.getData().then(function (response) {
if (response.data) {
vm.products=response.data;
vm.ProdDialog();
}
});
};
vm.productPopup = function(x){
ngDialog.open({
template: 'ProductDialog.html',
className:'ProductDetailsDialog'
scope:$scope,
data:x,
closeByDocument:true
});
}
vm.getProductDetails();
}]);
Service:
app.factory("productService",["$http",function($http){
return {
getData: function() {
return $http.get("http://xxxxxxx/xxx/xxxxx");
}
};
}]);
DemoController.html
/* <table>
<tr>
<th>Brand</th>
<th>Price</th>
<th>OPerating System</th>
<th>Open ngDialog</th>
</tr>
<tr ng-repeat="x in vm.products">
<td ng-bind="x.brand"></td>
<td ng-bind="x.price| currency:"₹":2"></td>
<td ng-bind="x.os"></td>
<td><button ng-click="vm.productPopup(x)"></button></td>
</tr>
</table>
*/
ProductDialog.html:
<div class="ProductDetailsDialog">
<div class="ngdialog-content" role="document">
<div class="modal-header">
<button type="button" class="close" ng-click="ngDialog.close();">×</button>
<h4 class="modal-title">Product Detials</h4>
</div>
// <pre>{{vm|json}}</pre> //
<div class="modal-body">
<h4>Brand:<span ng-bind="ngDialogData.brand"></span></h4>
<h4>Price:<span ng-bind="ngDialogData.price | currency:"₹":2"></span></h4>
<p>Operating System:<span ng-bind="ngDialogData.os"></span></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default">OK</button>
</div>
</div>
</div>
I am using angular js directives for bootstrap. What i am trying for is to create an edit form on bootstrap modal when user clicks on edit button from list of items. Here is my code:
HTML:
<div class="modal-header">
<h3>Edit Template</h3>
</div>
<div class="modal-body">
<form name="form" class="form-horizontal" novalidate>
<fieldset>
<div class="span4" ng-class="smClass" ng-show="etemplate.status">{{etemplate.status}}</div>
<div class="control-group">
<label class="control-label" for="etemplateName">Name</label>
<div class="controls">
<input class="input-xlarge" id="etemplateName" ng-model="eTemplate.name" maxlength="150" type="text" required />
</div>
</div>
<div class="control-group">
<label class="control-label" for="etemplateDesc">Description</label>
<div class="controls">
<textarea id="templateDesc" id="etemplateDesc" ng-model="eTemplate.desc"></textarea>
</div>
</div>
<div class="center">
<input type="text" style="display:none;" ng-model="eTemplate.id" value="{{eTemplate.id}}" required />
<button type="button" ng-click="update(eTemplate)" class="btn btn-primary" ng-disabled="form.$invalid || isUnchanged(eTemplate)">Submit</button>
<button class="btn" ng-click="cancel()">Cancel</button>
</div>
</fieldset>
</form>
</div>
Controller:
controller('TemplateController', ['$scope', '$http', '$modal', function($scope, $http, $modal) {
var tmpId = '';
$scope.openEdit = function(id) {
tmpId = id;
var editTmpModalInstance = $modal.open({
templateUrl: 'editTemplateContent.html',
controller: 'ETModalInstance'
});
$http({
method: 'GET',
url: adminBaseUrl+'/get_template/',
params: {'id': tmpId}
}).
success(function(data, status, headers, config) {
$scope.$broadcast('EditTemplateDataReached', data);
}).
error(function(data, status, headers, config) {
});
}
}]).
controller('ETModalInstance', ['$scope', '$http', '$modalInstance', function($scope, $http, $modalInstance) {
$scope.emaster = {};
$scope.smClass = '';
$scope.eTemplate = {};
$scope.$on('EditTemplateDataReached', function(data) {
$scope.eTemplate = data;
$scope.$apply();
});
$scope.isUnchanged = function(eTemplate) {
return angular.equals(eTemplate, $scope.master);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
$scope.update = function(eTemplate) {
var strng = $.param(eTemplate);
};
}]).
My work around for achieving this is when user clicks on edit button id of selected item is passed in my controller which sends an ajax request to server and then fill the fields with respective values. However my fields are not populated when ajax data is returned.
Found the problem in my code i was using $scope for broadcasting and catching the data whereas i have to use $rootScope.
Wrong:
$scope.$broadcast('EditTemplateDataReached', data);
$scope.$on('EditTemplateDataReached', function(data) {
$scope.eTemplate = data;
$scope.$apply();
});
Correct:
$rootScope.$broadcast('EditTemplateDataReached', data);
$rootScope.$on('EditTemplateDataReached', function(e, data) {
$scope.eTemplate = data;
$scope.$apply();
});