I have a question about the program below. In controller, the saveContact function: if I change line ContactService.save($scope.newcontact); to $scope.contacts.push($scope.newcontact);
It seems that the program works the same. I would like to know if the reason is that when this line ($scope.contacts = ContactService.list(); get executed, the reference of contact list in the service is assigned to $scope.contacts so that push new contact to $scope.contacts is same as push new contact to the contact list in the service?
<div ng-app="app" ng-controller="ContactController">
<form class="well">
<label>Name</label>
<input type="text" name="name" ng-model="newcontact.name" />
<label>Email</label>
<input type="text" name="email" ng-model="newcontact.email" />
<label>Phone</label>
<input type="text" name="phone" ng-model="newcontact.phone" />
<br/>
<input type="hidden" ng-model="newcontact.id" />
<input type="button" value="Save" ng-click="saveContact()" class="btn btn-primary" />
</form>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="contact in contacts">
<td>{{ contact.name }}</td>
<td>{{ contact.email }}</td>
<td>{{ contact.phone }}</td>
<td> edit | delete
</td>
</tr>
</tbody>
</table>
</div>
var module = angular.module('app', []);
module.service('ContactService', function () {
//to create unique contact id
var uid = 1;
//contacts array to hold list of all contacts
var contacts = [{
id: 0,
'name': 'Viral',
'email': 'hello#gmail.com',
'phone': '123-2343-44'
}];
//save method create a new contact if not already exists
//else update the existing object
this.save = function (contact) {
if (contact.id == null) {
//if this is new contact, add it in contacts array
contact.id = uid++;
contacts.push(contact);
} else {
//for existing contact, find this contact using id
//and update it.
for (i in contacts) {
if (contacts[i].id == contact.id) {
contacts[i] = contact;
}
}
}
}
//simply search contacts list for given id
//and returns the contact object if found
this.get = function (id) {
for (i in contacts) {
if (contacts[i].id == id) {
return contacts[i];
}
}
}
//iterate through contacts list and delete
//contact if found
this.delete = function (id) {
for (i in contacts) {
if (contacts[i].id == id) {
contacts.splice(i, 1);
}
}
}
//simply returns the contacts list
this.list = function () {
return contacts;
}
});
module.controller('ContactController', function ($scope, ContactService) {
$scope.contacts = ContactService.list();
$scope.saveContact = function () {
//ContactService.save($scope.newcontact);
$scope.contacts.push($scope.newcontact); ----change here
$scope.newcontact = {};
}
$scope.delete = function (id) {
ContactService.delete(id);
if ($scope.newcontact.id == id) $scope.newcontact = {};
}
$scope.edit = function (id) {
$scope.newcontact = angular.copy(ContactService.get(id));
}
})
Link to the original program.
It's not quite the same. The array pointed to by $scope.contacts and the array used internally by ContactsService are the same array, but ContactsService is doing work in save that you are not doing by pushing directly on to $scope.contacts.
Specifically, if the contact you are adding is a new contact (one that doesn't have an id) then it adds an id for it. Additionally, save will update an existing contact.
Your change will appear to work because you are adding the contact to the ContactsService internal array, but you are bypassing the API the ContactsService has specified.
Your method could end up duplicating contacts in the list as well by indiscriminately adding them.
Related
When I change the quantity, the quantity focus is lost..
click here to see image
AngularJS Code: ng-change code
$scope.txtqty = function (item) {
var id = item.Id;
$http.put("/api/Products/txtqty/" + id, item).then(function (response) {
$scope.gridproducts = response.data;
})
}
HTML table code
<table>
<tbody>
<tr ng-repeat="item in gridproducts">
<td ng-click="griddelete(item.Id)"><a class="delete"><i class="fa fa-times-circle-o"></i></a></td>
<td class="name">{{item.ProductName}}</td>
<td>{{item.ProductRate}}</td>
<td><input class="form-control qty" type="text" style="width:50px" ng-change="txtqty(item)" ng-model="item.ProductQty" value="{{item.ProductQty}}"></td>
<td>{{item.TotalAmount}}</td>
</tr>
<tr></tr>
<tfoot>
<tr>
<th colspan="2"></th>
<th colspan="2"><b>Total</b></th>
<th><b>{{gridproducts[0].TotalBill}}</b></th>
</tr><tr>
<th colspan="2"><b></b></th>
<th colspan="2"><b>Total Items</b></th>
<th><b>25</b></th>
</tr>
</tfoot>
</table>
Webapi Controller code this is webapi controller here you can see the
[System.Web.Http.Route("api/Products/txtqty/{id}")]
[ResponseType(typeof(void))]
public IHttpActionResult PuttxtQTY(int id, Product Pro)
{
var q = gridlist.Where(x => x.Id == id).FirstOrDefault();
if (q != null)
{
q.ProductQty = Pro.ProductQty;
q.TotalAmount = q.ProductQty * q.ProductRate;
q.TotalBill = gridlist.Sum(x => x.TotalAmount);
foreach (var item in gridlist)
{
item.TotalBill = q.TotalBill;
}
}
return Ok(gridlist);
}
You could give each input a unique ID and manually re-focus it as such:
HTML with ID on input
<td><input class="form-control qty" type="text" id="productQty_{{item.id}}" style="width:50px" ng-change="txtqty(item)" ng-model="item.ProductQty" value="{{item.ProductQty}}"></td>
Function adjusted with re-focus logic
$scope.txtqty = function (item) {
var id = item.Id;
$http.put("/api/Products/txtqty/" + id, item).then(function (response) {
$scope.gridproducts = response.data;
document.getElementById("productQty_" + id).focus();
})
}
Hope this does the job :)
I want to get json array Data from service and then display this data inside table (with checkboxes)
after that i want to get data ( which was checked by user , i mean checkbox was clicked) and put it another json Array and then wrap this variable as camVariable in order to export it for second user form,
i have tried this in several ways but can’t accomplish my goal, what should i change to make it possible?
here is my code:
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('jsonData');
});
camForm.on('variables-fetched', function() {
$scope.jsonData = camForm.variableManager.variableValue('jsonData');
});
var selectedDocuments=$scope.selectedDocuments=[];
$scope.content = '';
$scope.isChecked = function(id){
var match = false;
for(var i=0 ; i < $scope.selectedDocuments.length; i++) {
if($scope.selectedDocuments[i].id == id){
match = true;
}
}
return match;
};
$scope.sync = function(bool, item){
if(bool){
// add item
$scope.selectedDocuments.push(item);
} else {
// remove item
for(var i=0 ; i < $scope.selectedDocuments.length; i++) {
if($scope.selectedDocuments[i].id == item.id){
$scope.selectedDocuments.splice(i,1);
}
}
}
};
camForm.on('submit', function() {
camForm.variableManager.createVariable({
name: 'selectedDocuments',
type: 'json',
value:$scope.selectedDocuments
});
});
function toJsonValue(arr) {
var myJSON = "";
var FinalResult = JSON.stringify(arr);
myJSON = JSON.stringify({FinalResult});
var json=$scope.json={};
json=JSON.parse(myJSON);
return json;
}
$scope.toggle = function (index){
if($scope.jsonData[index].hidethis == undefined){
$scope.jsonData[index].hidethis = true;
}else{
$scope.jsonData[index].hidethis = !$scope.jsonData[index].hidethis;
}
}
</script>
<h2>My job List</h2>
<div class="container">
<table name ="table" class="table table-hover" style="width:100%;" cellspacing="0">
<thead>
<tr>
<th style="width:80px; height:25px;"><input style="width:25px; height:25px;" type="checkbox" onclick="checkAll(this)"></th>
<th style="width:140px;">id</th>
<th style="width:305px;">organizationNameEN</th>
<th style="width:305px;">organizationNameGE</th>
<th> </th>
</tr>
</thead>
<tbody ng-repeat="item in jsonData" >
<tr>
<td><input type="checkbox" ng-change="sync(bool, item)" ng-model="bool" ng-checked="isChecked(item.id)" ></td>
<td><input style="width:305px;" type="number" id="id" ng-model="item.id" readonly /></td>
<td><input style="width:305px;" type="text" id="organizationNameEN" ng-model="item.organizationNameEN" required /></td>
<td><input style="width:305px;" type="text" id="organizationNameGE" ng-model="item.organizationNameGE" required/></td>
<td><button class="btn btn-default btn-xs" ng-click="toggle($index)"><span class="glyphicon glyphicon-eye-open"></span></button></td>
</tr>
<tr id="{{hideid + $index}}" ng-show="item.hidethis">
<td>
<label for="startDate" class="control-label">startDate</label>
<div class="controls">
<input style="width:105px;" id="strtDate" class="form-control" type="text" ng-model="item.startDate" required readonly/>
</div>
<br>
<label for="endDate" class="control-label">endDate</label>
<div class="controls">
<input style="width:105px;" id="endDate" class="form-control" type="text" ng-model="item.endDate" required readonly/>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<script>
function checkAll(bx) {
var cbs = document.getElementsByTagName('input');
for(var i=0; i < cbs.length; i++) {
if(cbs[i].type == 'checkbox') {
cbs[i].checked = bx.checked;
}
}
}
</script>
</form>
I do something similar. In my first form, the user captures some transactions. Form 2 they double-capture (new transactions which must match the first capture) and form 3 they view they successful transactions and authorise them.
I have handled this by creating a JSON array of transactions in the first form. I save this to a process variable in the on-submit event using code like this:
camForm.on('submit', function() {
// this callback is executed when the form is submitted, *before* the submit request to
// the server is executed
// creating a new variable will add it to the form submit
variableManager.createVariable({
name: 'customVariable',
type: 'String',
value: 'Some Value...',
isDirty: true
});
I retrieve it in the subsequent forms like you do in the form-loaded/variables-fetched events.
If the JSON array data is updated in subsequent forms, I save it back to the same variable using code like this:
camForm.on('submit', function(evt) {
var fieldValue = customField.val();
var backendValue = variableManager.variable('customVariable').value;
if(fieldValue === backendValue) {
// prevent submit if value of form field was not changed
evt.submitPrevented = true;
} else {
// set value in variable manager so that it can be sent to backend
variableManager.variableValue('customVariable', fieldValue);
}
});
These code snippets are from the Camunda documentation.
Hopefully someone can help.
I am developing an application using HTML AngularJs which uses ng-repeat,ng-options and ng-model and populates multiple rows based on the data in the database for a user. Each row has static data coming from DB (returned as object via restAPI) and dynamic select option for user selection. Select option is hardcoded in app.js and linked to model on HTML for DB update upon selection using update button. Each row has its own button and i can see update function is working at row level.
I want to set the default value of the drop down list dynamically as value of an element coming from database. Object is same as one being used to populate rows with static data .
Code is in the fiddle at https://jsfiddle.net/6j88L61y/4/
HTML below
<body>
<h1 align="center">User Tracker</h1>
<div ng-controller="MainController as main">
<div>
<p>Please Enter ID </p>
<p>
<input type="text" ng-model="main.model.userName"></input>
<button ng-click="main.model.getOrgList()">List State List</button>
</p>
</div>
<hr ng-show="main.model.formSubmitted"></hr>
<div>
<table class="table table-bordered" border="1">
<thead>
<tr>
<th>ID</th>
<th>User Name</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="org in main.model.orgList" id="{{org.id}}">
<td>{{org.id}}</td>
<td align="center">{{org.user}}</td>
<td align="center">
<select ng-model="main.model.selectedRecord.appCurrentStateSelected[$index]" ng-options="option.value as option.value for option in main.model.appCurrentStateList" ></select>
</td>
<td>
<button ng-click="main.model.updateAppDetailsList({id:org.id,userName:org.name,appCrntState:main.model.selectedRecord.appCurrentStateSelected})">Update</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
JS
"use strict";
angular.module('myApp',[]);
angular.module('myApp').service('AppModel', function( $http) {
this.userId='';
this.userName ="";
this.formSubmitted="";
this. selectedRecord ={appCurrentStateSelected:''};
this.appCurrentStateList =[{name: 'New',value:'New',id:1}, {name: 'InUse',value:'InUse',id:2},{name: 'Inactive',value:'Inactive',id:3},{name: 'Deleted',value:'Deleted',id:4}];
this.submittedAppDetailsList=[];
console.log(' json sample:'+this.submittedAppDetailsList);
var path = 'home';
var currentProtocol = location.protocol;
var host =location.host;
var apiHost = currentProtocol+'//'+host+'/api/';
console.log('API url is : ' +apiHost);
// Get method
this.getOrgList = function() {
var path = 'home/userid';
console.log(this.userName);
console.log(this.selectedRecord);
$http.get(apiHost+path+'/'+this.userName+'/')
.then(function(response) {
this.orgList =response.data;
this.formSubmitted = true;
console.log(response.data);
}.bind(this),
function(response) {
console.log(response.data);
});
}
// Post method
this.updateAppDetailsList = function(appdetailsList) {
var path = 'home/update';
console.log(this.selectedRecord);
$http.post(apiHost+'home/update/',appdetailsList)
.then(function(response) {
this.submittedAppDetailsList.push(response.data);
this.formSubmitted = false;
console.log(response.data);
}.bind(this),
function(response) {
console.log('Error : '+response.data);
});
}
});
angular.module('myApp').controller('MainController', ['AppModel', function (AppModel) {
this.model = AppModel;
}]);
I am attempting to remove an item (round) from my DB. I can console.log the $id but when I try to roundsList.$remove(round.id) it does not do anything. I am, once again, thoroughly confused...
JS:
.controller('RoundsCtrl', ['$scope', '$firebase', 'FBURL', function ($scope, $firebase, FBURL, url) {
var roundsRef = new Firebase(FBURL + 'rounds');
var roundsList = $firebase(roundsRef).$asArray();
var usersRef = new Firebase(FBURL + 'users');
var usersRef = usersRef.child($scope.loggedInUserID).child('rounds');
var usersRounds = $firebase(usersRef).$asArray();
$scope.removeItem = function (index, round, event) {
// Avoid wrong removing
if (round.$id == undefined) return;
// Firebase: Remove item from the list
$scope.roundsList.$remove(round.$id);
};
/* SET DEFAULT FOR TOGGLE TO COLLAPSED*/
$scope.isCollapsed = true;
/* ONCE ROUNDS ARE LOADED RETURNS ROUNDS BY ID FOR INDIVIDUAL USER*/
usersRounds.$loaded()
.then(function (data) {
$scope.rounds = data.map(function (item) {
console.log(item);
console.log(item.$id);
return roundsList.$getRecord(item.roundID);
});
});}])
HTML:
<tbody ng-repeat="round in rounds | orderBy:orderBy">
<tr>
<td>
{{round.date}}
</td>
<td>
{{round.courseName}}
</td>
<td>
{{round.courseID}}
</td>
<td>
{{round.user}}
</td>
<td>
{{round.userID}}
</td>
<td>
{{round.tags}}
</td>
<td>
View
Edit
<button class="btn btn-danger" ng-click="isCollapsed = !isCollapsed">Delete</button>
</td>
</tr>
<tr collapse="isCollapsed">
<td colspan="7">
<div>
<div class="well well-lg">
<p>Are you sure? This cannot be undone!</p>
<button ng-click="removeItem($index, round, $event)" class="btn btn-danger">Delete Round</button>
<button ng-click="isCollapsed = !isCollapsed" class="btn btn-info">Cancel</button>
</div>
</div>
</td>
</tr>
</tbody>
EDIT:
I was finally able to delete from both DBs using the following code. hope it helps someone else down the line.
/* DELETES ROUND FROM MAIN ROUND DATABASE AND FROM USER SPECIFIC DB*/
var roundsListSync = $firebase(roundsRef);
var usersRoundsListSync = $firebase(usersRefRounds);
$scope.removeItem = function (index, round, event) {
roundsListSync.$remove(round.$id);
//console.log(usersRounds);
var i = 0;
var len = usersRounds.length;
for (; i < len;) {
console.log(usersRounds[i].roundID);
if (usersRounds[i].roundID === round.$id) {
var usersRoundsID = usersRounds[i].$id;
//console.log(usersRoundsID);
usersRoundsListSync.$remove(usersRoundsID);
i++;
} else {
i++;
}
}
};
You are calling $scope.roundsList.$remove(round.$id), however you have not declared roundsList in the scope: var roundsList = $firebase(roundsRef).$asArray(); Try var roundsList = $firebase(roundsRef).$asArray() instead.
If that doesn't work, try to make a firebase reference that is not an array:
var roundsListSync = $firebase(roundsRef);
roundsListSync.$remove(round.$id);
I'm trying to upload an image via an input field, tie the base64 of the image to a variable, then add that variable to the attribute of an object so I can store it in my Firebase db.
Input form & field for object:
<div class="row modalDetail">
<h3>New Episode</h3>
<table class="">
<tbody>
<tr>
<td class="labelField">Name</td>
<td><input type='text' ng-model='episode.name'></td>
</tr>
<tr>
<td class="labelField">Title</td>
<td><input type='text' ng-model='episode.title'></td>
</tr>
<tr>
<td class="labelField">Description</td>
<td><input type='text' ng-model='episode.shortDescription'></td>
</tr>
<tr>
<td class="labelField">Time</td>
<td><input type='text' ng-model='episode.time'></td>
</tr>
</tbody>
</table>
<img src="../images/placeholder.png" id="pano">
<!-- START Image File Upload -->
<td class="labelField">Image</td>
<span class="btn btn-default btn-file">
<input type="file" accept="image/*" capture="camera" id="file-upload">
</span>
<div id="spin"></div>
<div class='btn btn-warning' ng-click='createEpisode()'> Create an Episode</div>
</div>
The service for uploading to Firebase:
'use strict';
app.service('Uploader', ['$firebase', 'FIREBASE_TEST_URL', function($firebase, FIREBASE_TEST_URL) {
var ref = new Firebase(FIREBASE_TEST_URL);
var episodes = $firebase(ref);
return {
all: episodes,
create: function(episode) {
location.reload();
//Add to firebase db
return episodes.$add(episode);
},
delete: function(episodeId) {
location.reload();
return episodes.$remove(episodeId);
},
update: function(episode) {
location.reload();
return episodes.$save(episode);
}
};
}]);
Controller that has the file handling for the image, etc.:
'use strict';
app.controller('UploadCtrl', ['$scope', 'Uploader', function ($scope, Uploader) {
$scope.episodes = Uploader.all;
$scope.createEpisode = function(){
Uploader.create($scope.episode).then(function(data){
$scope.episode.name = '';
$scope.episode.title = '';
$scope.episode.description = '';
$scope.episode.time = '';
$scope.episode.img1 = $scope.episodeImgData;
});
};
$scope.deleteEpisode = function(episodeId){
bootbox.confirm('Are you sure you want to delete this episode?', function(result) {
if (result === true) {
Uploader.delete(episodeId).then(function(data){
console.log('Episode successfully deleted!');
});
}
});
};
$scope.updateEpisode = function(episode) {
Uploader.update($scope.episode).then(function(data) {
console.log(episode);
console.log('Episode successfully updated.');
});
};
$scope.selectEpisode = function(object) {
$scope.selectedEpisode = object;
setTimeout(function(){ $scope.$apply($scope.selectedEpisode = object); });
};
// ********************************************************************************** //
// START Image Upload: https://github.com/firebase/firepano/blob/gh-pages/firepano.js //
// REQUIRED: app/scripts/js/crypto.js in index.js
var spinner = new Spinner({color: '#ddd'});
$scope.episodeImgData = '../images/defaultplaceholder.png';
function handleFileSelectAdd(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));
$scope.episodeImgData = e.target.result;
document.getElementById('pano').src = $scope.episodeImgData;
console.log($scope.episodeImgData);
};
})(f);
reader.readAsDataURL(f);
}
function handleFileSelectEdit(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
var hash = CryptoJS.SHA256(Math.random() + CryptoJS.SHA256(filePayload));
$scpope.episodeImgData = e.target.result;
document.getElementById('pano2').src = $scope.episodeImgData;
$scope.selectedEpisode.img1 = $scope.episodeImgData;
console.log($scope.episodeImgData);
};
})(f);
reader.readAsDataURL(f);
}
$(function() {
$('#spin').append(spinner);
document.getElementById('file-upload').addEventListener('change', handleFileSelectAdd, false);
document.getElementById('file-upload2').addEventListener('change', handleFileSelectEdit, false);
});
// END Image Upload: https://github.com/firebase/firepano/blob/gh-pages/firepano.js //
// ******************************************************************************** //
}]);
All the attributes in the form save to the DB except img1. When the update button is clicked, I thought I could just pass in episodeImgData to the object (img1 variable) to save, but it doesn't save anything at all (just the form variables tied to episode.name, etc.). What's the best way to do this? I'm using parts of the FirePano example (https://github.com/firebase/firepano/blob/gh-pages/firepano.js) for the image handling.
Update (20160519): Firebase just released a new feature called Firebase Storage. This allows you to upload images and other non-JSON data to a dedicated storage service. We highly recommend that you use this for storing images, instead of storing them as base64 encoded data in the JSON database.
There were a lot of small problems with that code.
Since your episodes are an array, you can to create is with $asArray, otherwise it won't have a $add method: var episodes = $firebase(ref).$asArray();
You were calling location.reload() before sending the data to the server
Your file-upload handler wasn't triggering for me
There were dangling references to the spinner from firepano
I think that first two were the biggest. But it is hard to find that type of problem if you don't provide a minimal example that reproduces the problem. I did that for you now.
In the end, the code is not too big so I'll share it here:
var app = angular.module('myapp', ['firebase'])
.service('Uploader', function($firebase) {
var ref = new Firebase('http://<yourfirebase>.firebaseio.com/');
var episodes = $firebase(ref).$asArray();
return {
all: episodes,
create: function(episode) {
//Add to firebase db
return episodes.$add(episode);
}
};
})
.controller('UploadCtrl', function ($scope, Uploader) {
$scope.episodes = Uploader.all;
$scope.createEpisode = function() {
if ($scope.episodeImgData) {
$scope.episode.img1 = $scope.episodeImgData;
}
Uploader.create($scope.episode);
};
$scope.handleFileSelectAdd = function(evt) {
var f = evt.target.files[0];
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var filePayload = e.target.result;
$scope.episodeImgData = e.target.result;
document.getElementById('pano').src = $scope.episodeImgData;
};
})(f);
reader.readAsDataURL(f);
};
document.getElementById('file-upload').addEventListener('change', $scope.handleFileSelectAdd, false);
});
The corresponding (body) HTML:
<body ng-app='myapp'>
<div class="row modalDetail" ng-controller='UploadCtrl'>
<h3>New Episode</h3>
<table class="" ng-model='episode'>
<tbody>
<tr>
<td class="labelField">Name</td>
<td><input type='text' ng-model='episode.name'></td>
</tr>
<tr>
<td class="labelField">Title</td>
<td><input type='text' ng-model='episode.title'></td>
</tr>
<tr>
<td class="labelField">Description</td>
<td><input type='text' ng-model='episode.shortDescription'></td>
</tr>
<tr>
<td class="labelField">Time</td>
<td><input type='text' ng-model='episode.time'></td>
</tr>
</tbody>
</table>
<td class="labelField">Image</td>
<span class="btn btn-default btn-file">
<input type="file" accept="image/*" capture="camera" id="file-upload">
</span>
<div class='btn btn-warning' ng-click='createEpisode()'>Create an Episode</div>
<br/>
<img id="pano">
</div>
</body>
This is a working demo if creating an episode with optional image data: http://jsbin.com/roriwu/7.