I am using Ekathuwa modals, I need to close it after a successfull Ajax PUT. I am trying to follow the examples they give. I am able to close the modal, but there is still a grey color on the screen. Like it is still open in the background? I still need to refresh the page for it to go away.
$scope.updateJob = function (job) {
console.log($scope.currentItem);
job.JobTypeId = $scope.currentItem.JobType.JobTypeId;
job.JobClassId = $scope.currentItem.JobClass.JobClassId;
job.GeoAreaId = $scope.currentItem.GeoArea.GeoAreaId;
jobFactory.updateJob(job).success(successCallback)
.error(errorCallback);
console.log(job);
var p = $ekathuwa.modal({
id: "EditJobModal", contentStyle: "width:800px;heigth:400px",
scope: $scope,
templateURL: "views/modals/EditJobModal.html"
});
$q.when(p).then(function (m) {
m.modal('hide');
});
};
var successCallback = function (data, status, headers, config) {
notificationFactory.success();
};
var errorCallback = function (job, status, headers, config) {
notificationFactory.error(job.ExceptionMessage);
};
Move hide modal logic to successCallback function.
I don't know your editable fields on "views/modals/EditJobModal.html" or other pages.
If it is on EditJobModal.html, Better to used two functions, one for create and open modal other for your update logic.
thanks,
Sarath
Update
//Edit Job Modal
$scope.EditJobModal = function (id) {
$.get('/api/apiJob/' + id, function (data) {
console.log(data);
$scope.currentItem = data;
$scope.openEditJobModal = $ekathuwa.modal({
id: "EditJobModal", contentStyle: "width:800px;heigth:400px",
scope: $scope,
templateURL: "views/modals/EditJobModal.html"
});
//show modal window
$scope.openEditJobModal.then(function (m) {
m.modal('show');
});
});
}
//Update Job
$scope.updateJob = function (job) {
console.log($scope.currentItem);
job.JobTypeId = $scope.currentItem.JobType.JobTypeId;
job.JobClassId = $scope.currentItem.JobClass.JobClassId;
job.GeoAreaId = $scope.currentItem.GeoArea.GeoAreaId;
jobFactory.updateJob(job).success(successCallback)
.error(errorCallback);
console.log(job);
};
var successCallback = function (data, status, headers, config) {
//hide modal window
$scope.openEditJobModal.then(function (m) {
m.modal('hide');
});
notificationFactory.success();
};
var errorCallback = function (job, status, headers, config) {
notificationFactory.error(job.ExceptionMessage);
};
Modal
<input type="submit" ng-click="updateJob(currentItem)" value="Submit" />
<input type="button" ng-if="true" data-dismiss="modal" value="Exit" />
Seems to be a bug in AngularUI. See this: https://github.com/angular-ui/bootstrap/issues/1643
The modal scope is not being destroyed correctly on either close or dismiss.
Related
So, earlier today I had a working form that could post and delete restaurants documents to a mongodb collection. Everything was working fine, but then I decided to try and load the form into a div instead of redirect to a new page. Doing so produced a different result when I tried to submit my restaurant form. Originally it would call $scope.add() in my restaurantsController, but now it is sending a GET request with form data to /restaurants instead of a POST to /api/restaurants. I'm looking for some insight as to what I did to change the behavior. Although it is loading the form when I click on my restaurant anchor tag, it is not loading the restaurants from the database.
Here is the jade and js for the menu anchors:
menu.js
app.controller("menu", ["$scope", "$http", function ($scope, $http) {
$scope.home = function () {
$("#content").html("");
};
$scope.restaurants = function () {
$http.get('/restaurants').
success(function(data, status, headers, config){
$("#main_content").html(data);
}).
error(function(data, status, headers, config){
});
};
}]);
nav.jade
mixin link(name, fn)
li
a.btn(ng-click=fn)= name
nav.navbar.navbar-inverse.navbar-fixed-top(role='navigation')
.container
.navbar-header
button.navbar-toggle.collapsed(type='button', data- toggle='collapse', data-target='#navbar', aria-expanded='false', aria- controls='navbar')
span.sr-only Toggle navigation
span.icon-bar
span.icon-bar
span.icon-bar
a.navbar-brand(href='/') Food App
#navbar.navbar-collapse.collapse
ul.nav.navbar-nav(ng-controller="menu")
+link("Home", "home()")
+link("Restaurants", "restaurants()")
And here is the form:
form(name="NewRestaurant" ng-submit="$event.preventDefault();add()")
.row
.form-group
input.form-control(type="text", name="name" placeholder="Name", ng-model="name" required)
.row
.form-group
input.form-control(type="text", name="address" placeholder="Address", ng-model="address" required)
.row
.form-group.col-md-6
-for(var i = 0; i <= 5; i++){
input(name="rating" type="radio", value=i, ng-model="rating" required)
=i
-}
.form-group.col-md-6
button.success(type="submit") Submit
and the controller...
app.controller("restaurants", ["$scope", "$resource", function ($scope, $resource) {
var Restaurant = $resource('/api/restaurants/:id');
var clearForm = function () {
$scope.name = '';
$scope.address = '';
$scope.rating = null;
}
clearForm();
var validRestaurant = function () {
if($scope.name !== '' && $scope.address !== '' && $scope.rating !== null)
return true;
else{
toastr.error("Please fill in all required form fields.");
return false;
}
}
$scope.query = function(){
Restaurant.query(function (results) {
$scope.restaurants = results;
});
};
$scope.add = function () {
alert("got here!");
if(validRestaurant()){
var restaurant = new Restaurant();
restaurant.name = $scope.name;
restaurant.address = $scope.address;
restaurant.rating = $scope.rating;
alert(restaurant);
Restaurant.save(restaurant, function (result) {
$scope.restaurants.push(result);
toastr.success("Saved " + $scope.name + ".")
clearForm();
});
}
};
$scope.update = function (id) {
};
$scope.remove = function (id) {
console.log(id);
Restaurant.delete({id: id}, function (err) {
console.log(err);
$scope.query();
});
};
$scope.query();
}]);
edit: Now that I am typing this up, I am wondering, maybe angular doesn't recognize the form and doesn't create a $scope for it because it gets loaded after the page loads...?
I have a user log into my AngularJS app and once they do a http.get retreives a dataset with some key values. One of those is a key that I need to post to a iframe to get it queued up for the right user (based on the key). Thus far I have this and it is not working.
HTML:
<form name="watchLiveForm" action="{{testingUrl}}" target="watch-live" method="post" ng-submit="controllsubmit()">
<label for="key">Company Software Key:</label>
<input type="text" name="key" id="key" ng-model="key">
<input type="submit">
</form>
<iframe name="watch-live" ng-src="{{testingUrl}}" width="100%" height="600"> </iframe>
Controller:
app = angular.module('angularWebApp.indexController', []);
app.controller('indexController', function($scope, $http, $rootScope, $sce) {
$scope.controllsubmit = function() {
console.log("I was called!");
};
if($scope.user !== undefined) {
if($scope.user.software_key.constructor === Array) {
$http.get('http://URL/api/' + $scope.user.software_key[1] + '/remotes').
success(function(data) {
if(data.id === 'error') {
console.log(data);
} else {
$scope.machineList = data;
$scope.key = $scope.user.software_key[1];
console.log($scope.user.software_key[1]);
console.log($scope.key);
$scope.testing = 'http://URL/settings';
$scope.testingUrl = $sce.trustAsResourceUrl($scope.testing);
}
}).
error(function(data) {
alert(data);
});
}
}
});
Directive:
angular.module('angularWebApp.indexDirectives', [])
.directive('form', function() {
return {
require: 'form',
restrict: 'A',
link: function(scope, element, attributes) {
var scopa = element.scope();
if (attributes.name && scopa[attributes.name]) {
scopa[attributes.name].$submit = function() {
// Parse the handler of submit & execute that.
var fn = $parse(attr.ngSubmit);
$scope.$apply(function() {
fn($scope, {$event: e});
});
};
}
}
};
});
After the user is logged in I call a http.get and obtain the software_key which I pass to the form (works). It just seems that getting the form to automatically submit is the issue as I want to made the inputs hidden eventually so they will not see the form as they do now. Any help is greatly appreciated!
I am trying to load Image icon(set time to load particular for 30 Second) while loading the data from the database but I am facing some problem as I want to set timer also for Loading Icon (i.e Loading Icon appear for 30 second) using angularjs. How I achieve this functionality as I was done this by ng-show and ng-hide but I am unable to attach time in Icon.
my Code is
editApp.controller('MyCtrl', ['$scope', '$http', 'ngDialog','$timeout' ,function ($scope,$http, ngDialog, $timeout) {
GetList();
$scope.dataloaded = false;
and after ajax call I set $scope.dataloaded to true
function GetList() {
debugger;
$http({
method: 'GET',
url: '/Home/GetProductList'
}).
success(function (data) {
if (data != null || data != 'undefined') {
$scope.productlist = data;
$scope.dataloaded = true;
}
})
.error(function (error) {
$scope.status = 'Unable to retrieve product' + error.message;
});
}
and my html code is
<div ng-hide="dataloaded" style="margin:auto" align="center"> </div>
and
<div ng-show="dataloaded" style="margin:auto" align="center"> </div>
Lets show div for 30 sec:
<button ng-click='show()'>Show</button>
<div ng-show='showDiv'/>
In controller:
$scope.show = function() {
$scope.showDiv = true;
$timeout(function() {
$scope.showDiv = false;
}, 30000);
}
In my projects at the moment, I use something along these lines for AJAX forms.
$scope.posting = false;
$scope.submitForm = function(form){
log(form);
log((!form.$invalid) ? 'Is valid' : 'Contains errors');
$scope.posting = true;
$http.post('/modules/ajax/addModule', $scope.module)
.success(function(data, status, headers, config){
data = data.data;
log(data);
$scope.posting = false;
if(data.error){
alert(data.message);
}
})
.error(function(data, status, headers, config){
data = data.data;
log(data);
$scope.posting = false;
});
}
and on the submit button, <input ng-disabled="form.$invalid || posting" ... />
Whilst it's not much to type code, manually switching the bool value seems a little non Angular to me. Is there anyway to tell if an $http.post is still active?
just write a directive which will disable and enable the button on http calls, like below
app.directive('onClick', function() {
return {
scope: {
onClick: '&'
},
link: function(scope, iElement, iAttrs) {
iElement.bind('click', function() {
iElement.prop('disabled',true);
scope.onClick().finally(function() {
iElement.prop('disabled',false);
})
});
}
};
});
note : onClick function should return a promise for this to work
Checkout this plunker to see it in action
I use angular-ladda for button with spinner while call is in progress
What I ended up doing was adding this code to my global JS file.
app.run(function($rootScope, $http) {
$http.defaults.transformRequest.push(function (data) {
$rootScope.$isPosting = true;
return data;
});
$http.defaults.transformResponse.push(function(data){
$rootScope.$isPosting = false;
return data;
})
});
Then I can just use
<a ng-disabled="isPosting" ...
Im working with AngularJS to display a table of app keys (app identifiers) and I would like to use an edit button to display a small form in that table row. Then the user can edit the fields and click "save" or "cancel"
Demo: http://jsfiddle.net/Thw8n/
I have the inline form working great. I click edit and a form appears. Cancel works great too.
My problem is
How do I connect the save button with a function that will make a $http call to an API
How do I get the data from that row to send to the $http call?
How do I disable editMode once the call comes back?
Here is the actual code Im using in my controller (in the JSFiddle Im not able to make the http call). The first $http fills out the form, the editAppKey function is what is called by the save button.
function AppKeysCtrl($scope, $http, $location) {
$http({
method: 'POST',
url: 'http://' + $location.host() + ':1111/sys/appkey/save',
data: {
// How do I get the data?
}
}).
success(function(data, status, headers, config) {
$scope.appkeys = data;
}).
error(function(data, status, headers, config) {
$scope.appkeys = [{ "appkey" : "ERROR", "name" : "ERROR", "created" : "ERROR" }];
});
$scope.editAppKey = function() {
$http({
method: 'POST',
url: 'http://' + $location.host() + ':1111/sys/appkeys'
}).
success(function(data, status, headers, config) {
alert("Success!");
$scope.editMode = false;
}).
error(function(data, status, headers, config) {
alert("There was an error.");
});
}
}
When we press on "Edit" button and change one of fields , we also change our main model appkeys. Its mean that on "Cancel" we need restore old model.
Its mean that we need at least:
So this is a snippets of HTML:
<td>
<button type="submit" data-ng-hide="editMode" data-ng-click="editMode = true; editAppKey(entry)" class="btn btn-default">Edit</button>
<button type="submit" data-ng-show="editMode" data-ng-click="editMode = false; saveField()" class="btn btn-default">Save</button>
<button type="submit" data-ng-show="editMode" data-ng-click="editMode = false; cancel()" class="btn btn-default">Cancel</button>
</td>
And our controller:
$scope.newField = {};
$scope.editing = false;
$scope.appkeys = [
{ "appkey" : "0123456789", "name" : "My new app key", "created" : tmpDate },
{ "appkey" : "abcdefghij", "name" : "Someone elses app key", "created" : tmpDate }
];
$scope.editAppKey = function(field) {
$scope.editing = $scope.appkeys.indexOf(field);
$scope.newField = angular.copy(field);
}
$scope.saveField = function() {
if ($scope.editing !== false) {
$scope.appkeys[$scope.editing] = $scope.newField;
$scope.editing = false;
}
};
$scope.cancel = function() {
if ($scope.editing !== false) {
$scope.appkeys[$scope.editing] = $scope.newField;
$scope.editing = false;
}
};
Demo Fiddle
[EDIT]
I you want to edit several rows at once, use array of newFields instead $scope.newField
You can pass e.g. current index as a parameter to the editAppKey() function:
... data-ng-click="editAppKey($index)"
and in the JS file:
$scope.editAppKey = function(index) {
window.console.log(appkeys[index]); // do what ever you want
}
as for the disabling once the request is back. If I undestand, you want to allow only one time edit and after editAppKey() is called once on some row, disable it, right? If so, maybe something like
<button type="submit" data-ng-hide="editMode" data-ng-click="editMode = true" class="btn btn-default"
data-ng-disabled="entry.isDisabled">Edit</button>
and in the editAppKey() function, something like
$scope.editAppKey = function(index){
$http.post(url, data).onsuccess(function(){
$scope.appkeys[index].isDisabled = true;
});
In case someone need multiple edit at once:
Just do the following:
on html cancel button, pass the index
data-ng-click="editMode = false; cancel($index)"
on JS side:
1) $scope.newField = {}; to $scope.newField = [];
2) inside editAppKey function, $scope.newField = angular.copy(field); to $scope.newField[$scope.editing] = angular.copy(field);
3) change the saveField function to:
$scope.saveField = function(index) {
$scope.appkeys[$scope.editing] = $scope.newField;
};
4) change the cancel function to:
$scope.cancel = function(index) {
$scope.appkeys[index] = $scope.newField[index];
$scope.editing = false;
};
Fiddle