model does not change angularjs - angularjs

I have client list in a table.
When I click on editClient, the name of the client will be displayed in an input text. This work perfectly.
<body ng-app="myClientApp" ng-controller="myClientController">
<a class="btn btn-success" ng-click="chargerClients()">
Charger Clients
</a>
<div ng-if="clients">
<table>
<tr ng-repeat="cl in clients >
<td>{{cl.idClient}} </td>
<td>{{cl.nomClient}} </td>
<td> <a class="btn btn-success" ng-click="editClient(cl.idClient,cl.nomClient)"></td>
</table>
<div>
<input type="text" ng-model="id">
<input type="text" ng-model="nom">
<button ng-click="modifyClient()"> validate</button>
</div>
</div>
</body>
The problem is when I click on modifyClient, it keeps the same values and nothing happens. How can I fix this problem?
<script>
var app=angular.module("myClientApp", []);
app.controller("myClientController", function($scope,$http,$window) {
$scope.chargerClients=function(){
$http.get("/clients")
.success(function(data){
$scope.clients=data;
});
};
//load id and name
$scope.editClient=function(idClient, nomClient){
$scope.id=idClient;
$scope.nom=nomClient;}
//modifyClient
$scope.modifyClient=function(){
var params="";
var params = ({
idClient:$scope.id,
nomClient: $scope.nom});
$http({
method: 'PUT',
url: "clients",
data: params,
headers: {'Content-type': 'application/json'}
})
.success(function(data) {
$window.alert($scope.id+$scope.nom);
$scope.chargerClients();
$window.location.href = '/index.html'
})
};
}
</script>

Try using POST method in your modifyClient

Thank you i solve it; i have to add link in ng-model:
`<ng-model="client.id">`
and in the script also:
$scope.client={}
$scope.editClient=function(idClient, nomClient){
$scope.client.id=idClient;
}
$scope.modifyClient=function(){
var params="";
var params = ({
idClient:$scope.client.id
});

Related

How can I access $scope asynchronous data from another method in same controller

When my scope has two properties that each contain an array retrieved asynchronously from the database, I cannot elegantly access the one from the other. I'm sure I must be missing something because my current solution feels like a hack.
I have an Angular CRUD page that contains a table and a form which contains a dropdown select control. When I click on a row in the table and want to update it, I need to populate the dropdown with the current value. In order to get this right, I'm currently declaring a global variable and assign the array used to populate the dropdown to that variable once it is retrieved from the database.
var columnHeaderArray;
var app = angular.module('myApp', []);
app.controller('ColumnHeadingController',
function ($scope, $http) {
$scope.GetAllData = function () {
$http({
method: "get",
url: "/api/Staat8Maintenance/GetAllColumnHeadings"
}).then(function (response) {
$scope.columnheaders = response.data;
$scope.GetGroupHeaderData();
},
function () { alert("Error Occured"); });
};
$scope.GetGroupHeaderData = function () {
$http({
method: "get",
url: "/api/Staat8Maintenance/GetGroupHeadingsForCombo"
}).then(function (response) {
$scope.groupheaders = response.data;
columnHeaderArray = response.data;
},
function () { alert("Error Occured"); });
};
$scope.UpdateColumnHeading = function (cho) {
document.getElementById("OriginalOrder").innerHTML = cho.ColumnOrder;
document.getElementById("OriginalColumnHeading").innerHTML = cho.ColumnHeading;
$scope.ColumnHeading = cho.ColumnHeading;
$scope.ColumnOrder = cho.ColumnOrder;
$scope.SelectedOption = columnHeaderArray[columnHeaderArray.findIndex(x => x.GroupingHeaderId == cho.GroupingHeaderId)];
document.getElementById("btnSave").setAttribute("value", "Update");
document.getElementById("btnSave").style.backgroundColor = "Yellow";
document.getElementById("formColumnHeading").style.display = "block";
};
}
);
<div id="SubAccountGrouping" class="tabcontent"
ng-controller="ColumnHeadingController"
ng-init="GetAllData()">
<h2>Column Headings</h2>
<h5>This is where the column headings will be maintained.</h5>
<div id="formColumnHeading" class="form" role="form">
<div class="container">
<div class="row">
<div class="form-horizontal">
<div class="form-group">
<label class="col-sm-1 edittextwide">Heading:</label>
<div class="col-sm-6">
<input type="text" class="form-control edittextwide"
id="inputColumnHeading"
placeholder="Column Heading"
ng-model="ColumnHeading" />
</div>
</div>
<div class="form-group">
<label class="col-sm-1">Order:</label>
<div class="col-sm-6">
<input type="number" class="form-control"
id="inputColumnOrder"
placeholder="Order"
ng-model="ColumnOrder" />
</div>
</div>
<div class="form-group">
<label class="col-sm-1 edittextwide">Group Heading:</label>
<div class="col-sm-6">
<select class="form-control edittextwide"
name="groupHeadings"
id="selectGroupHeadings"
ng-model="SelectedOption"
ng-options="gh as gh.HeadingName for gh in groupheaders track by gh.GroupingHeaderId">
</select>
</div>
</div>
</div>
</div>
<div class="row">
<div>
<input type="button" id="btnSave" class="form-control btn-default"
value="Submit" ng-click="InsertData()" />
</div>
</div>
</div>
<div class="hiddenlabel">
<label id="OriginalOrder">0</label>
<label id="OriginalColumnHeading">ABC</label>
</div>
</div>
<div class="scrolldiv">
<table class="table">
<thead>
<tr>
<th>Heading</th>
<th>No of Sub-Accounts</th>
<th>Column Order</th>
<th>Group Heading</th>
<th>Parent Group Heading</th>
<th>Include in Staat 8</th>
<th>Actions</th>
</tr>
</thead>
<tr ng-repeat="cho in columnheaders">
<td>{{cho.ColumnHeading}}
</td>
<td>{{cho.NumberOfEntries}}
</td>
<td>{{cho.ColumnOrder}}
</td>
<td>{{cho.GroupHeading}}
</td>
<td>{{cho.ParentGroupHeading}}
</td>
<td>{{cho.IncludeInStaat8?'Yes':'No'}}
</td>
<td>
<input type="button" class="btn btn-warning"
value="Update"
ng-click="UpdateColumnHeading(cho)" />
</td>
</tr>
</table>
</div>
</div>
When I try to set $scope.SelectedOption using $scope.groupheaders directly, it bombs out. I realise this is because of the asynchronous nature, but I suspect there must be a more elegant way to achieve this?
// include $q to use promises
function ($scope, $http, $q) {
// create a deferred promise
var q = q.defer();
// call the first $http method and store the promise
var promise1 = $http(config1);
// call the second $http method and store the promise
var promise2 = $http(config2);
// handle when the first promise resolves
promise1
.then( (data) => {
$scope.columnheaders = response.data;
})
.catch( (errors) => q.reject(errors));
// handle when the second promise resolves
promise2
.then( (data) => {
$scope.groupheaders = response.data;
})
.catch( (errors) => q.reject(errors));
// wait for both promises to resolve then do final actions
$q.all([promise1, promise2])
.then( () => {
columnHeaderArray = response.data;
q.resolve();
});
// return the promise for calling methods to wait until this resolves
return q.promise;
}
Reference for using $q
Reference for using $http
You can streamline the above code to make it more condensed, but I've broken it out some to be a little easier to follow.

Pass text box value to services in angular

I have two pages-one is to create data and when I click save button text box values will be send to backend method.In another page am displaying those entered datas in table.So am using two controller methods here.
I dont know how to send text box values to backend using angular.I did it using jquery simply but I dont know angular thats why am struggling.
This is my first page to save text box details:
<div class="row ">
<label>Name<span id="required">*</span></label>
<input type="text" ng-model="item.name" class = "col-lg-5 col-md-5 col-sm-5 col-xs-10"/>
</div>
<div class="row ">
<label class="col-lg-2 col-md-2 col-sm-3 col-xs-12 ">Description</label>
<textarea ng-model="item.description"></textarea>
</div>
<div class="row marTop">
<span class="pull-right">
<button class="btn save btn-primary" ng-click="addItem(item)"><i class="fa fa-floppy-o"></i>Save</button>
<button class="btn cancel btn-default" onclick="window.location.href = '/Admin/RoleList'"><i class="fa fa-ban"></i>Cancel</button>
</span>
</div>
Script: In this method only I need to pass name and description values
<script>
var app=angular
.module("intranet_App", [])
.controller('myCtrl', function ($scope, $http) {
$scope.items = [];
$scope.addItem = function (item) {
$scope.items.push(item);
$scope.item = {};
}
//$scope.item = aaa;
console.log(item)
//$scope.values = {
// name: 'newroleName',
// description: 'roledescription'
//};
$http.post("/Admin/RolesInsert"){
alert("success")
}
})
</script>
This is my second page to get table data( that saved name should be display in this table)
<table class="table table-hover table-bordered" id="mydata" ng-controller="myCtrl">
<thead class="colorBlue">
<tr>
<th>S.No</th>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody id="">
<tr ng-repeat="x in roleList | filter:searchText">
<td>{{x.Id}}</td>
<td>{{x.name}}</td>
<td>
<i class="edit fa fa-pencil-square-o" id="edit{{x.Id}}" ng-click="edit{{x.Id}}"></i>
<i class="update fa fa-floppy-o" id="update{{x.Id}}" ng-click="update{{x.Id}}"></i>
<i class="editCancel fa fa-times" id="editCancel{{x.Id}}" ng-click="cancel{{x.Id}}"></i>
</td>
</tr>
</tbody>
</table>
script for second table
<script>
var app=angular
.module("intranet_App", [])
.controller('myCtrl', function ($scope, $http) {
$scope.values = {
};
$http.post("/Admin/getRolesList")
.then(function (response) {
$scope.roleList = response.data;
});
})
</script>
One of the ways of doing this is:
angular.module("intranet_App", [])
.controller('myCtrl', function ($scope, $http, myFactory) {
...
function sendDataToBackend() {
var requestHeaders = {
"Content-Type": 'application/json'
}
var httpRequest = {
method: 'POST',
url: 'your url',
headers: requestHeaders
};
httpRequest.data = $scope.items;
$http(httpRequest).then(function (response) {
//Handle the response from the server
})
}
}
Finally got an answer:
<script>
var app=angular
.module("intranet_App", [])
.controller('myCtrl', ["$scope","$http", function ($scope, $http ,myFactory) {
$scope.items = [];
$scope.addItem = function (item) {
$scope.items.push(item);
//$scope.oRoles = $scope.item
$scope.json = angular.toJson($scope.item);
console.log($scope.json)
}
$scope.myFunc = function (item) {debugger
$scope.addItem(item);
var requestHeaders = {
"Content-Type": 'application/json'
}
var httpRequest = {
method: 'POST',
url: '/Admin/RolesInsert',
headers: requestHeaders
};
httpRequest.data = $scope.json;
$http(httpRequest).then(function (response) {
alert(response)
//$window.location.href = '/Admin/RoleList';
})
}
}])
</script>

Can't access the specified url using rest and angularjs

I am trying to get data using REST api from html form using angularjs and do some db operation on it. I am getting 404 error for the rest link specifid.
Here's my js code
var app=angular.module("myApp",[]);
app.controller("mycon",function($scope,$http){
console.log("entered here");
$scope.test={};
$scope.add = function() {
console.log("entered here");
var json=JSON.stringify($scope.test);
console.log($scope.test);
console.log(json);
$http({
url: "rest/xyz/role",
method: "GET",
data: json,
headers: {'Content-Type': 'application/json'}
})
.success(function(data, status,header,config) {
$scope.data = data;
}).error(function(data, status,header,config) {
alert("error");
});
}});
<body ng-app="myApp" ng-controller="mycon">
<center>
<h2> Login Here! </h2>
<hr/>
<form >
<table>
<tr>
<td>Signum Id:</td>
<td><input type="text" ng-model="test.sig"/></td>
</tr>
<tr>
<button class="btn waves-effect waves-light" type="submit" ng-click="add()" name="action"> Submit <i class="material-icons right">send</i>
</tr>
</table>
</form>
</center>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"></script>
</body>
and my REST code goes here.
#Path("/xyz")
public class RestServices {
#GET
#Path("/role")
#Produces({ "application/json" })
public String list() {
//do db operation
}
}
After deploying and running the project on server, I am getting following error:
http://localhost:8080/LoginEmployee/rest/xyz/role "404 NOT FOUND".
Add servlet mapping in web.xml as "rest/*". and also check the project name which should be "LoginEmployee"
Try removing rest/ from $http param.
url: "xyz/role",

AngularJS access $http return json array

i have older post which i deleted i solved it there.
I have other issue:
I have this data array came from PHP with $http(i use console.log):
I can't access that data with ng-repeat:
ibids.controller("auctions",function($http){
var req = {
method: 'POST',
url: 'includes/bids.php',
headers: {
'Content-Type': 'json'
},
data: 'q=getAuctions'
}
$http(req).then(function(req){
console.log(req);
var auctionslist = req.data;
}, function(){
});
});
html:
<body ng-controller="auctions as auction">
<input type="text" value="test" ng-model="man">
{{man}}
<hr>
<div class="search" >
<input type="text">
<div class="res" ng-repeat="x in auction.auctionslist">
{{x}}
</div>
</div>
</body>
What is wrong here ? i recive json data from php and perfect assign to data array in $http .when i use console.log(req) this is what you see in the pictures and its recive the json array perfect.
i don't know how to use ng-repeat on that data .
You have to use $scope and add a property on it for this data and use it in template
ibids.controller("auctions",function($http, $scope){
var req = {
method: 'POST',
url: 'includes/bids.php',
headers: {
'Content-Type': 'json'
},
data: 'q=getAuctions'
}
$http(req).then(function(req){
console.log(req);
$scope.auctions = req.data;
}, function(){
});
});
and in html
<body ng-controller="auctions">
<input type="text" value="test" ng-model="man">
{{man}}
<hr>
<div class="search" >
<input type="text">
<div class="res" ng-repeat="auction in auctions">
{{auction}}
</div>
</div>

AngularJS - Upload Image to SharePoint Library/Corrupted File

I am using the following Angular Module to attempt to upload images to SharePoint through a Web browser: https://github.com/nervgh/angular-file-upload
I am getting successful 200 POST messages and a file is being uploaded... However, it is not showing the image itself in the preview or opening of the image, but rather an [X]. I am guessing this is related to how the content is encoded, but unsure of what to do next. Here is my controller:
appControllers.controller('appUploadImageCtrl', ['$scope', '$location', 'FileUploader', function ($scope, $location, FileUploader) {
var uploader = $scope.uploader = new FileUploader({
url: "/sites/_api/web/lists/getByTitle('Images')/RootFolder/Files/add(url='test.jpg',overwrite='true')",
processData: false,
transformRequest: angular.identity,
headers: {
'Accept': 'application/json;odata=verbose', 'content-type': undefined, 'X-RequestDigest': $("#__REQUESTDIGEST").val() }
});
// FILTERS
uploader.filters.push({
name: 'imageFilter',
fn: function (item /*{File|FileLikeObject}*/, options) {
var type = '|' + item.type.slice(item.type.lastIndexOf('/') + 1) + '|';
return '|jpg|png|jpeg|bmp|gif|'.indexOf(type) !== -1;
}
});
// CALLBACKS
uploader.onWhenAddingFileFailed = function (item /*{File|FileLikeObject}*/, filter,
options) {
console.info('onWhenAddingFileFailed', item, filter, options);
};
uploader.onAfterAddingFile = function (fileItem) {
console.info('onAfterAddingFile', fileItem);
};
uploader.onAfterAddingAll = function (addedFileItems) {
console.info('onAfterAddingAll', addedFileItems);
};
uploader.onBeforeUploadItem = function (item) {
console.info('onBeforeUploadItem', item);
};
uploader.onProgressItem = function (fileItem, progress) {
console.info('onProgressItem', fileItem, progress);
};
uploader.onProgressAll = function (progress) {
console.info('onProgressAll', progress);
};
uploader.onSuccessItem = function (fileItem, response, status, headers) {
console.info('onSuccessItem', fileItem, response, status, headers);
};
uploader.onErrorItem = function (fileItem, response, status, headers) {
console.info('onErrorItem', fileItem, response, status, headers);
};
uploader.onCancelItem = function (fileItem, response, status, headers) {
console.info('onCancelItem', fileItem, response, status, headers);
};
uploader.onCompleteItem = function (fileItem, response, status, headers) {
console.info('onCompleteItem', fileItem, response, status, headers);
};
uploader.onCompleteAll = function () {
console.info('onCompleteAll');
};
console.info('uploader', uploader);
$scope.cancel = function () {
$location.path('/');
}
}]);
HTML:
<div class="col-md-3">
<h3>Select files</h3>
<div ng-show="uploader.isHTML5">
<!-- 3. nv-file-over uploader="link" over-class="className" -->
<div class="well my-drop-zone" nv-file-over="" uploader="uploader">
Base drop zone
</div>
<!-- Example: nv-file-drop="" uploader="{Object}" options="{Object}" filters="{String}" -->
<div nv-file-drop="" uploader="uploader" options="{ url: '/foo' }">
<div nv-file-over="" uploader="uploader" over-class="another-file-over-class" class="well my-drop-zone">
Another drop zone with its own settings
</div>
</div>
</div>
<!-- Example: nv-file-select="" uploader="{Object}" options="{Object}" filters="{String}" -->
Multiple
<input type="file" nv-file-select="" uploader="uploader" multiple /><br />
Single
<input type="file" nv-file-select="" uploader="uploader" />
</div>
<div class="col-md-9" style="margin-bottom: 40px">
<h3>Upload queue</h3>
<p>Queue length: {{ uploader.queue.length }}</p>
<table class="table">
<thead>
<tr>
<th width="50%">Name</th>
<th ng-show="uploader.isHTML5">Size</th>
<th ng-show="uploader.isHTML5">Progress</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in uploader.queue">
<td><strong>{{ item.file.name }}</strong></td>
<td ng-show="uploader.isHTML5" nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
<td ng-show="uploader.isHTML5">
<div class="progress" style="margin-bottom: 0;">
<div class="progress-bar" role="progressbar" ng-style="{ 'width': item.progress + '%' }"></div>
</div>
</td>
<td class="text-center">
<span ng-show="item.isSuccess"><i class="glyphicon glyphicon-ok"></i></span>
<span ng-show="item.isCancel"><i class="glyphicon glyphicon-ban-circle"></i></span>
<span ng-show="item.isError"><i class="glyphicon glyphicon-remove"></i></span>
</td>
<td nowrap>
<button type="button" class="btn btn-success btn-xs" ng-click="item.upload()" ng-disabled="item.isReady || item.isUploading || item.isSuccess">
<span class="glyphicon glyphicon-upload"></span> Upload
</button>
<button type="button" class="btn btn-warning btn-xs" ng-click="item.cancel()" ng-disabled="!item.isUploading">
<span class="glyphicon glyphicon-ban-circle"></span> Cancel
</button>
<button type="button" class="btn btn-danger btn-xs" ng-click="item.remove()">
<span class="glyphicon glyphicon-trash"></span> Remove
</button>
</td>
</tr>
</tbody>
</table>
<div>
<div>
Queue progress:
<div class="progress" style="">
<div class="progress-bar" role="progressbar" ng-style="{ 'width': uploader.progress + '%' }"></div>
</div>
</div>
<button type="button" class="btn btn-success btn-s" ng-click="uploader.uploadAll()" ng-disabled="!uploader.getNotUploadedItems().length">
<span class="glyphicon glyphicon-upload"></span> Upload all
</button>
<button type="button" class="btn btn-warning btn-s" ng-click="uploader.cancelAll()" ng-disabled="!uploader.isUploading">
<span class="glyphicon glyphicon-ban-circle"></span> Cancel all
</button>
<button type="button" class="btn btn-danger btn-s" ng-click="uploader.clearQueue()" ng-disabled="!uploader.queue.length">
<span class="glyphicon glyphicon-trash"></span> Remove all
</button>
</div>
</div>
The problem with your code is that you are trying to upload your image as a normal byte array, which isn't possible when you are uploading to libraries through the SharePoint REST API.
To be able to upload non-text files to SharePoint, they have to be uploaded as a base64 encoded byte array.
Your options are to either use another Angular module such as Angular-Base64-Upload, or to encode the image file before you upload it using your first choice of file upload module.
In case you go for option two, you can encode the image using the following technique, though how it will work with your selected file uploader, I cannot say. It appears you can modify the file attribute of the FileItem in the file uploader, so it should not be that hard.
Encoding the image file to a base64 binary arraybuffer
//Create a new FileReader object
var reader = new FileReader();
reader.onload = processImage;
//Read the file as a base64 encoded string
reader.readAsDataURL(input.files[0]);
function processImage () {
//The image file has been read by the filereader
//and can be converted to an arraybuffer
var arrayBuffer = base64ToBinary(this.result);
//Upload the image to the SharePoint images library
uploadImage(arrayBuffer);
}
function base64ToBinary (base64EncodedFile) {
var BASE64_MARKER = ';base64,';
var base64Index = base64EncodedFile.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
var base64 = base64EncodedFile.substring(base64Index);
var raw = atob(base64);
var rawLength = raw.length;
var array = new Uint8Array(rawLength);
for (i = 0; i < rawLength; i++)
{
array[i] = raw.charCodeAt(i);
}
return array.buffer;
}
When I wrote a similar piece of code for a project, I noticed that SharePoint (or just IE) had trouble getting the MIME types correct. I ended up stripping it from the image to make it work, as below.
var raw = atob(base64.replace(/^data:image\/(png|jpg);base64,/, ""));
Uploading to SharePoint image library using the REST API and Ajax
If you decide to not go for an Angular module to upload your file, you can instead upload files directly to a SharePoint library through the REST API using normal ajax calls with jQUery. This might have to be modified for the Angular syntax, but the concept is the same.
var requestUrl = String.format("{0}/_api/web/lists/getByTitle('Images')/rootfolder/files/Add(url='{1}', overwrite=true)", _spPageContextInfo.siteAbsoluteUrl, fileName);
$.ajax({
url: requestUrl,
type: "POST",
data: buffer, //This is the base64 encoded buffer from the above step
processData: false,
headers: {
Accept: "application/json;odata=verbose",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
success: function(result) {
console.log("Upload complete!");
},
error: function(error) {
console.log("Something went wrong!");
}
});

Resources