Handle multiple buttons using one form using AngularJS - javascript

I have a form with different text fields and some buttons. I want for every press of a button to execute a different operations, but using the the same function of ng-submit(). For example I want to implement CRUD operations on a database, and based on the data I get from the form to execute another operations. Based on the information from another post from the site I managed to do this:
<form name="formUser" ng-submit="cruduser()" role="form">
// I didn't put the text fields because are irrelevant for this problem
<div class="form-actions">
<button type="submit" ng-click="addButton=true" ng-disabled="form.$invalid || dataLoading" class="btn btn-danger">Add</button>
</div>
<br/>
<div class="form-actions">
<button type="submit" ng-click="readButton=true" ng-disabled="form.$invalid || dataLoading" class="btn btn-danger">Read</button>
</div>
<br/>
<div class="form-actions">
<button type="submit" ng-click="updateButton=true" ng-disabled="form.$invalid || dataLoading" class="btn btn-danger">Update</button>
</div>
<br/>
<div class="form-actions">
<button type="submit" ng-click="deleteButton=true" ng-disabled="form.$invalid || dataLoading" class="btn btn-danger">Delete</button>
</div>
</div>
This is my .js file:
'use strict';
angular.module('admin')
.controller('AdminController',
['$scope', '$rootScope', '$location', 'AdminService',
function ($scope, $rootScope, $location, AdminService) {
$scope.cruduser = function() {
this.addButton = false;
this.readButton = false;
this.updateButton = false;
this.deleteButton = false;
if(this.addButton) {
console.log('Add');
}
if(this.readButton) {
console.log('Read');
}
if(this.updateButton) {
console.log('Update');
}
if(this.deleteButton) {
console.log('Delete');
}
};
$scope.redirect = function() {
session.sessionValue = ' ';
window.location = "/#/login";
}
}]);
The problem is that after I initialize the buttons with "false", they remain stuck with that value.

You can pass the type of operation that you want in your cruduserfunction on click of the buttons like this:
<button ng-click = "cruduser('add')"></button>
Then in the cruduser function in the controller you can check for the passed operation like this:
$scope.cruduser = function(crudOp) {
if (crudOp === 'add') {
//do something
}
}

Related

Getting a 405 (Method Not Allowed) in AngularJS

So, I am creating a web app, where one page I have a user list and on the second page, I have the users details page. On the second page, I have a confirm button where I want to remove that user when the "Confirm" button is clicked with a 200 Status code. However, I am getting a DELETE : 405 (Method Not Allowed). So, here is my code down below. Please tell me or help me fix this problem. Thank you in advance.
Here is my code.
<div ng-controller="MyCtrl">
<div ng-repeat="person in userInfo.lawyers | filter : {id: lawyerId}">
<a class="back" href="#/lawyer">Back</a>
<button type="button" class="edit" ng-show="inactive" ng-click="inactive = !inactive">
Edit
</button>
<button type="submit" class="submit" ng-show="!inactive" ng-click="inactive = !inactive">Save</button>
<button class="btn btn-primary" ng-click="doDelete(id)">Confirm</button>
<div class="people-view">
<h2 class="name">{{person.firstName}}</h2>
<h2 class="name">{{person.lastName}}</h2>
<span class="title">{{person.email}}</span>
<span class="date">{{person.website}} </span>
</div>
<div class="list-view">
<form>
<fieldset ng-disabled="inactive">
<legend>Basic Info</legend>
<b>First Name:</b>
<input type="text" ng-model="person.firstName">
<br>
<b>Last Name:</b>
<input type="text" ng-model="person.lastName">
<br>
<b>Email:</b>
<input type="email" ng-model="person.email">
</fieldset>
</form>
</div>
</div>
</div>
Services
app.factory('people', function ($http) {
var service = {};
service.getUserInfo = function () {
return $http.get('https://api-dev.mysite.io/admin/v1/unconfirmed_lawyers');
};
service.confirmUser = function (lawyerId) {
return $http.put('https://api-dev.mysite.io/admin/v1/lawyers/{lawyerId}/confirm');
};
return service;
});
LawyerController
app.controller('LawyerController', ['$scope', 'people', '$routeParams',
function ($scope, people, $routeParams) {
$scope.lawyerId = $routeParams.id;
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
});
}]);
HomeController
var isConfirmed = false;
app.controller('HomeController', function($scope, people, $http) {
if (!isConfirmed) {
people.getUserInfo().then(function (response) {
$scope.userInfo = response.data;
}, function (error) {
console.log(error)
});
}
});
App.js
$scope.doDelete = function(lawyer) {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
$scope.userInfo.lawyers.splice(index, 1);
location.href = '#/lawyer';
};
If you changed your HTML, so you passed the person instead.
<button class="btn btn-primary" ng-click="doDelete(person)">Confirm</button>
You can use this to find the index within the lawyers, then remove it.
$scope.doDelete = function(lawyer) {
var index = $scope.userInfo.lawyers.indexOf(lawyer);
$scope.userInfo.lawyers.splice(index, 1)
};
The issue is your are using $http.delete which performs an HTTP Delete request. This doesn't sound like something you intended.

How to add a control to a input file using angularjs?

I want to require an input of type file using angularjs without using the attribute required in the HTML code.
My interface is : enter image description here
I want to get an alert after hitting the button submit.
This is what I have done : enter image description here
function DatabaseCtrl($scope, $http, predefineds, locationSearch, queries, database, $window) {
var credentials = {
fileName: ""
};
$scope.credentials = credentials;
$scope.uploadToFolder = function() {
if( $scope.credentials.fileName.length<1 ) {
$window.alert("Please select a file!");
return false;
}
database.uploadToFolder($scope.credentials.fileName, true);
};
The HTML code :
<form role="form" name="frmUploadFolder" ng-submit="uploadToFolder()">
<div class="box">
<h2>
<span ng-show="isUserFile">File directory browser :</span>
<button type="button" ng-show="isUserFile" class="btn btn-default">See file(s)</button>
<button type="button" ng-show="!isUserFile" class="btn btn-default">Upload file(s)</button>
</h2>
<div class="content">
<p>
<label ng-show="isUserFile" >Please specify a file, or a set of files:</label><br>
<input type="file" ng-show="isUserFile" name="datafile" id="fileName" ng-model="credentials.fileName" size="20" required multiple>
<button type="submit" ng-show="isUserFile" class="btn btn-default" >Upload</button><br>
</p>
<div ui-if="!tree.length" class="message">
<p ui-if="!tree.loading">
<span ng-show="!isUserFile">Empty directory</span>
</p>
</div>
</div>
</div>
</form>
The service js :
angular.module('referl.services').factory('database', function($http, channel, $rootScope) {
var database = {
uploadToFolder: function(fileName, navigateOnSuccess) {
var parameters = {
fileName: fileName
};
$http.get("api/database/uploadToFolder", {params: parameters})
.success(function(response) {
if(response.error) {
alert(response.error);
} else {
if (navigateOnSuccess) {
alert("Navigation On Success !");
}
}
});
}
};
Any help please?
For some reason angular does not fully support binding a model element to a file input. The directive approach is generally the accepted work around, but within your controller you can also use document.getElementById("filename") to get a reference to the filename input and grab its value.

adding array to other form controller in angular

I have an event.controller.js and event.view.html
In the controller I have event and guests,
event is the form of multiple models and guests is 1 model with an array that I can pass more values too.
I have localStorage for events to save the form but guests array doesn't get passed into the form because they are seperated even though they're part of the same controller.
function EventController($location, UserService, EventService, $rootScope, $http, FlashService) {
var vm = this;
vm.guests = [];
vm.addGuest = function () {
vm.guests.push(vm.newGuest);
}
vm.removeGuest = function (guest) {
var index = vm.guests.indexOf(guest);
vm.guests.splice(index, 1);
}
vm.event = event;
function event() {
vm.dataLoading = true;
EventService.Create(vm.events)
.then(function (response) {
if (response.success) {
FlashService.Success('Event created successful', true);
$location.path('/events');
} else {
FlashService.Error(response.message);
vm.dataLoading = false;
}
});
}
my event.view.html looks like
<form name="form" ng-submit="vm.event()" role="form">
<!--All my event input fields-->
<div class="form-actions">
<button type="submit" ng-disabled="form.$invalid || vm.dataLoading" class="btn btn-primary">Create</button>
Cancel
</div>
</form>
<form name="form" ng-submit="vm.guest()" role="form">
<div class="form-actions">
<button type="submit" ng-disabled="guestform.$invalid || vm.dataLoading" ng-click="vm.addGuest()" class="btn btn-primary">Add Guest</button>
</div>
<div ng-repeat="guest in vm.guests track by $index" class="col-sm-6">
{{guest}} - <a class="btn" ng-click="vm.removeGuest(guest)">Delete</a>
</div>
</form>
different forms submit to the same eventcontroller but are different model namespaces, how would I get a vm.events.guest array that is equal to the vm.guests after I add to it from the vm.addGuest() method?

Disable required attribute on one radio button

I have 3 radio buttons in a bootstrap modal and I want only 2 of them to be required in order to submit the form. I created a requiredCheck() function that's using a jQuery implementation so I'd rather not use this. What is the best way to disable the required attribute for one radio button, when using AngularJS?
HTML
<form name="jawn">
<div class="modal-header">
<h3 class="modal-title">Jawn</h3>
</div><!-- /modal-header -->
<div class="modal-body">
<ul>
<li ng-repeat="item in items">
<label for="optionsRadios">
<input type="radio" ng-model="$parent.data.status" name="optionsRadios" ng-value="item.id" required/ ng-click="requiredCheck()"> {{item.name}}
</label>
</li>
</ul>
<h4>Comment</h4>
<textarea ng-class="{error: thing.comment.$dirty && thing.comment.$invalid}" type="text" rows="3" cols="64" ng-model="data.comment" ng-minlength="4" ng-required></textarea>
<span class="error" ng-show="thing.comment.$error.required">required</span>
</div><!-- /modal-body-->
<div class="modal-footer">
<button type="submit" class="btn btn-warning" ng-click="ok()" ng-disabled="thing.$invalid">Part Jawn</button>
<button type="button" ng-click="cancel()" class="btn btn-default">Cancel</button>
</div>
</form>
JavaScript
angular.module('app')
.controller('ModalController', function($scope, $modalInstance, $timeout) {
'use strict';
$scope.item = 0;
$scope.items = [
"Zero": 0,
"Uno": 1,
"Dos": 2
];
$scope.requiredCheck = function () {
var $btnWarning = $('.btn-warning');
var $textarea = $('textarea');
$timeout(function() {
if($scope.data.status === item.Dos) {
$btnWarning.removeAttr('disabled');
$textarea.removeAttr('required');
} else if ($scope.data.status === 3) {
$btnWarning.prop('disabled',true);
$textarea.prop('required', true);
} else if ($scope.data.status === 3) {
$btnWarning.prop('disabled',true);
$textarea.prop('required', true);
}
},100);
};
$scope.ok = function () {
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$modalInstance.close();
};
});
You should use angualrjs approach. As you have already specified ngRequired set true/false from controller.
From DOCs
ngRequired: Sets required attribute if set to true
HTML
<textarea ng-model="data.comment" ng-required="textRequired"></textarea>
Script
$scope.requiredCheck = function () {
if(condition){
$scope.textRequired = false;
}else{
$scope.textRequired = true;
}
};
Note: I have simplified the answer

AngularJS can't pass $index from bootstrap modal window

I'm banging my head against the wall here. I'm using ng-repeat to populate a table. Inside each row i have 2 buttons, one for updating the row content and for uploading files. The upload button opens a bootstrap modal window, where the user selects the files and clicks on submit.
The submit button uses ng-click to run a function which uses $index as parameter. But the $index value is always the same no matter which row is selected.
The thing I don't understand is that I use the exact same syntax (although outside of a modal window) on my update button, which works just fine.
HTML:
<tr ng-repeat="item in items | filter:search " ng-class="{'selected':$index == selectedRow}" ng-click="setClickedRow($index)">
<td>{{$index}}</td>
<td ng-hide="idHidden" ng-bind="item.Id"></td>
<td ng-hide="titleHidden">
<span data-ng-hide="editMode">{{item.Title}}</span>
<input type="text" data-ng-show="editMode" data-ng-model="item.Title" data-ng-required />
<td>
<button type="button" class="btn btn-primary uploadBtn" data-ng-show="editMode" data-toggle="modal" data-target="#uploadModal">Upload file <i class="fa fa-cloud-upload"></i></button>
<!-- Upload Modal -->
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="uploadModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="uploadModalLabel">Options</h3>
</div>
<div class="modal-body">
<h4>Upload Documents</h4>
<form>
<div class="form-group">
<select data-ng-model="type" class="form-control" id="fileTypeSelect">
<option value="Policy">Policy</option>
<option value="SOP">SOP</option>
</select>
<br>
<div class="input-group"> <span class="input-group-btn">
<input type="file" id="file">
</span>
</div>
<br>
<button type="button" class="btn btn-default" data-ng-click="uploadAttachment($index, type)">Upload</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<button type="button" data-ng-hide="editMode" data-ng-click="editMode = true;" class="btn btn-default pull-right">Edit <i class="fa fa-pencil-square-o"></i></button>
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; updateItem($index)" class="btn btn-default">Save</button>
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; cancel()" class="btn btn-default">Cancel</button>
</td>`
JS:
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
So the function uploadAttachment($index, type) which is triggered by ng-click doesn't pass the right index number. It always passes the same, no matter what row it is clicked in.
I have omitted some of the code that is irrelevant. If needed i can provide the whole thing.
Any suggestions to what I am missing?
Edit:
I have tried to implement DonJuwe suggestions.
I have added this inside my controller:
$scope.openModal = function(index) {
var modalInstance = $modal.open({
templateUrl: 'www.test.xxx/App/uploadModal.html',
controller: 'riskListCtrl',
resolve: {
index: function() {
return index;
}
}
});
};
This is my modal template:
<div class="modal-header">
<h3 class="modal-title" id="uploadModalLabel">Options</h3>
</div>
<div class="modal-body">
<h4>Upload Documents</h4>
<form>
<div class="form-group">
<select data-ng-model="type" class="form-control" id="fileTypeSelect">
<option value="Policy">Policy</option>
<option value="SOP">SOP</option>
</select>
<br>
<div class="input-group"> <span class="input-group-btn">
<input type="file" id="file">
</span>
</div>
<br>
<button type="button" class="btn btn-default" data-ng-click="uploadAttachment($index, type)">Upload</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
And finally my function which resides inside RiskListCtrl (the only controller i use):
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
It seems that $scope.items[index].Id is empty. Error: Cannot read property 'Id' of undefined
The modal window has its own scope. That means you need to resolve data you want to pass into the modal's scope. To do so, use resolve within the modals open(options) method.
Before I will give you an example, I want to suggest having only one modal for all your table items. This will let you keep a single template where you can easily use id (now, you create a template for each of your table items which is not valid). Just call a controller function and pass your $index:
<button type="button" class="btn btn-primary uploadBtn" data-ng-show="editMode" ng-click="openModal($index)">Upload file <i class="fa fa-cloud-upload"></i></button>
In your controller, create the modal instance and refer to the template:
$scope.openModal = function(index) {
var modalInstance = $modal.open({
templateUrl: 'myPath/myTemplate.html',
controller: 'MyModalCtrl',
resolve: {
index: function() {
return index;
}
}
});
};
Now you can access index in your MyModalCtrl's scope by injecting index:
angular.module('myModule', []).controller('MyModalCtrl', function($scope, index) {
$scope.index = index;
});
Since, you are getting the index value outside model then you can also use ng-click and then call a function in your controller and store the index value in a temporary variable and then when you are using submit button then just take make another variable and assign the value of temporary variable to your variable. for example:
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; updateItem($index)" class="btn btn-default">Save</button>
and then make a function in your controller
$scope.updateItem = functon(index)
{
$scope.tempVar = index;
}
now use the value of tempVar in you function
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var index = tempVar; //assign the value of tempvar to index
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}

Categories