Push extenal data with data from server to array - arrays

I am currently working on a project in which, I am fetching the data from server and adding(pushing) in the array for further process. And its working great.
I face problem when I add an external data to the array with the data coming from server.
var quantity= ItemsValue[1];
$scope.product = [];
$http.get(___).success(function(data) {
$scope.greeting = data ;
$scope.product.push($scope.greeting);
}
I want to push "quantity" with the "$scope.greeting". I already tried different thing such as concatenation but failed.
I want data of array to be like this. For Example
$scope.product=[{ "greeting.name": "abc", "greeting.price": "50",
"quantity":"1" }]
Name and Price came from server and quantity in added as an extra data to Array.
<tbody >
<tr ng-repeat="greeting in product" ><!-- -->
<td class="cart_product">
<img src={{greeting.Image}} alt="book image" ></td>
<td class="cart_description">
<h4>{{greeting.Name}}</h4></td>
<td class="cart_price">
<p>Rs. {{greeting.Cost}}</p>
</td>
<td class="cart_quantity">
<div class="cart_quantity_button">
<a class="cart_quantity_up" href=""> + </a>
<input class="cart_quantity_input" type="text" name="quantity" value="Itemsquantity" autocomplete="off" size="2">
<a class="cart_quantity_down" href=""> - </a>
</div>
</td>
<td class="cart_total">
<p class="cart_total_price">Rs. {{greeting.Cost}}</p>
</td>
<td class="cart_delete">
<a class="cart_quantity_delete" ng-click="removeItem($index)"><i class="fa fa-times"></i></a>
</td>
</tr>
</tbody>
This is the code of client end.
Any way to push these things together...

You can just add it into the object by creating a new property
var quantity = ItemsValue[1];
$scope.product = [];
$http.get(___).success(function(data) {
$scope.greeting = data;
$scope.greeting.quantity = quantity;
$scope.product.push($scope.greeting);
}

Related

AngularJS table stop sorting when in edit mode

I have AngularJS table with CRUD operations and sortable header. When I add the new row to table the lines are jumping and the table is getting sorted while in edit mode.
I want to stop sorting while in the edit mode and should sort only after saving the new row. I searched online for fixing this issue but nothing helped yet.
Here is the HTML file:
<thead>
<tr>
<td><input type="text" ng-model="main.search.Data1" id="myInput" placeholder="search for Data1..."/></td>
<td><input type="text" ng-model="main.search.Data2" id="myInput" placeholder="search for Data2..."/></td>
</tr>
<tr class="table_header" style="background-color: blue;">
<th><a href="#" ng-click="orderByField='data1'; reverseSort = !reverseSort"> Data1 <span ng-show ="!reverseSort">^</span><span ng-show="reverseSort">v</span></th>
<th><a href="#" ng-click="orderByField='data2'; reverseSort = !reverseSort"> Data2</th>
</tr>
</thead>
<tbody>
<tr ng-repeat=" code in main.Table | orderBy: Predicate | orderByField:reverseSort | filter:main.search"></tr>
<script type="text/ng-template" id="dispay">
<td>{{code.data1}}</td>
<td>{{code.data2}}</td>
</script>
<script type="text/ng-template" id="edit">
<td><input type="text" ng-model="code.data1" class"form-control input-sm"/></td>
<td><input type="text" ng-model="code.data2" class"form-control input-sm"/></td>
</script>
</tbody>
Here is the JS code:
//add new row
$scope.addNew = function(data) {
$scope.Table.unshift({
data1: "",
data2: ""
});
console.log($scope.table);
};
//Edit the row
$scope.edit = function(data){
$scope.selected = angular.copy(data);
$scope.backuplist = angular.copy($scope.table);
};
The behaviour is correct because on addNew you add 1 empty record in apply cycle which then will reorder again the list.
You have 2 ways to go :
1) When Adding new Item, create sperate object and upon submit add it in the list:
$scope.addNew = function(data) {
$scope.newItem ={
data1: "",
data2: ""
};
};
$scope.save = function() {
$scope.table.push($scope.newItem);
};
Like this there is speration of concerns and not to mingle the main list.
Or if you still want to add it in main list directly which i dont recommend you can implement your custom filter which keeps always the empty data at the top - In your predicate Method.
<tr class="table_header" style="background-color: blue;">
<th><a href="#" ng-click="orderByField='data1'; reverseSort = !reverseSort" ng-disabled="setTrueFalse"> Data1 <span ng-show ="!reverseSort">^</span><span ng-show="reverseSort">v</span></th>
<th><a href="#" ng-click="orderByField='data2'; reverseSort = !reverseSort" ng-disabled="setTrueFalse"> Data2</th>
</tr>
$scope.setTrueFalse = true/false
MAke use of ng-disabled.. Set it to true when you do not want to sort the values and vice versa

how can I keep some values in a ngshow and ng hide variable so that $digest does not initialize them again and again in angularjs?

I am displaying some data in a web app that I am getting from a SQL database using a http service. I want to be able to modify the information of that data on the same table where the data is shown. I am using angularjs and I am using the directives ng-show and ng-hide on the table. Here I show the part of the code I am talking about.
<table>
<tr>
<td><font size = 4>Servicio: </font> </td>
<td> </td>
<td>
<select class="col-sm-12" name="repeatSelect" id="repeatSelect" ng-model="currentItem.ServicioId">
<option ng-repeat="option in items.Servicio" value="{{option.Id}}"> {{option.Nombre}}</option>
</select>
</td>
</tr>
</table>
<h4>Cliente: {{getNameC(currentItem.ServicioId)}}</h4>
<br />
<button class="btn btn-primary" ng-click="editOrCreate()">Nuevo</button>
<button class="btn btn-primary" ng-click="list()">Actualizar</button>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Cantidad</th>
<th>Tipo Concepto</th>
<th>Descripción</th>
<th>Precio Unitario</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in itemsSC">
<td>
<div ng-hide="editingData[item.Id]">{{item.Cantidad}}</div>
<div ng-show="editingData[item.Id]"><input ng-model="currentItem.Cantidad" /></div>
</td>
<td>
<div ng-hide="editingData[item.Id]">{{getName(item.ServicioConceptoTipoId)}}</div>
<div ng-show="editingData[item.Id]">
<select name="repeatSelect" id="repeatSelect" ng-model="currentItem.ServicioConceptoTipoId">
<option ng-repeat="option in items.ServicioConceptoTipo" value="{{option.Id}}"> {{option.Nombre}}</option>
</select>
</div>
</td>
<td>
<div ng-hide="editingData[item.Id]">{{item.Descripcion}}</div>
<div ng-show="editingData[item.Id]"><input type="text" ng-model="currentItem.Descripcion" /></div>
</td>
<td>
<div ng-hide="editingData[item.Id]">{{item.PrecioUnitario}}</div>
<div ng-show="editingData[item.Id]"><input ng-model="currentItem.PrecioUnitario" /></div>
</td>
<td>
<button class="btn btn-xs btn-primary" ng-hide="editingData[item.Id]" ng-click="editOrCreate(item)">Modificar</button>
<button class="btn btn-xs btn-primary" ng-show="editingData[item.Id]" ng-click="saveEdit(currentItem,0)">Actualizar</button>
<button class="btn btn-xs btn-primary" ng-hide="viewField" ng-click="delete(item)">Eliminar</button>
</td>
</tr>
</tbody>
<tfoot id="total">
<tr>
<td colspan="3" class="text-right">Total:</td>
<td class="text-right">
{{total(currentItem.ServicioId) | currency}}
</td>
</tr>
</tfoot>
</table>
On my controller I am using object arrays to get the information from the databases and I am using a mirror array to keep the boolean values of the data shown on the table, so depending on the boolean value the tables shows the data or get an input for the user to modify the data.
I get the mirror array once I know the service and client related to the data I want to show and which is possible to be modified.
However, when I click on the button to modify the status of the ng-hide or ng-show object named editingData, the controllers modifies it, but the $digest run all the other functions related to the bindings of the view and returns the bool object array to its inital values.
I haven´t been able to find away to go around this normal working way of the $digest and $watches so my $editingData object is not modified to its initial values. Here I show the code of the controller related to this.
angular.module("App")
.controller("ConceptoCtrl", function ($scope, $http, $resource, serviciosConceptoFactory, serviciosConceptoTipoFactory, serviciosFactory, clientesFactory) {
$scope.list = function () {
$scope.items = serviciosConceptoFactory.query();
$scope.itemsT = serviciosConceptoTipoFactory.query();
$scope.items.ServicioConceptoTipo = $scope.itemsT;
$scope.itemsS = serviciosFactory.query();
$scope.items.Servicio = $scope.itemsS;
$scope.itemsC = clientesFactory.query();
$scope.itemsS.Cliente = $scope.itemsC;
}
//some other functions
$scope.editingData = {};
$scope.getitemsSC = function (item) {
$scope.itemsSC = [];
for (var j = 0; j < $scope.items.length; j++) {
if ($scope.items[j].ServicioId == item) {
newitem = $scope.items[j];
$scope.itemsSC.push(newitem);
}
}
for (var i = 0; i < $scope.itemsSC.length; i++) {
$scope.editingData[$scope.itemsSC[i].Id] = false;
}
}
$scope.editOrCreate = function (item) {
$scope.currentItem = item;
$scope.editingData[item.Id] = true;
}
$scope.list();
});
The {{getNameC(currentItem.ServicioId}} function shown on the html file is the one that calls the $scope.getItemsSC(item) function once it knows the services and client related to the data that will be shown and it is this function the one that initializes the boolean values for the $scope.editingData mirror array depending on the Id of the item.
The $scope.editOrCreate(item) function is the one that changes the boolean object of the specified item so that the view shows the input element for the user instead of the data. However, $digest re-runs the $scope.getItemsSC(item) function because the $watches were modified, and that´s what I want to avoid, because in this case the input elements are never shown.
I thank in advance any help provided
Instead of using the HTML to call functions when data is a available, use the $promise property attached to the resources.
$scope.list = function () {
$scope.items = serviciosConceptoFactory.query();
$scope.itemsT = serviciosConceptoTipoFactory.query();
$scope.items.ServicioConceptoTipo = $scope.itemsT;
$scope.itemsS = serviciosFactory.query();
$scope.items.Servicio = $scope.itemsS;
$scope.itemsC = clientesFactory.query();
$scope.itemsS.Cliente = $scope.itemsC;
var promiseArray = [$scope.items.$promise,
$scope.itemsT.$promise,
$scope.itemsS.$promise,
$scope.itemsC.$promise
];
$q.all(promiseArray).then(function(resultsArray) {
var items = resultsArray[0];
var itemsT = resultsArray[1];
var itemsS = resultsArray[2];
var itemsC = resultsAttay[3];
//create mirror array here
//create editingData array here
});
};
By using the .then method of the promises, the processing of the data can be delayed until it arrives from the server. This way there is no need for the HTML to call functions.

AngularJS orderBy a column containing a list

is it possible to use orderBy with something other than strings and numbers?
I have a list of customers and one of the columns contains an array of values (list of urls). I want to order by the url list, i.e. the first url in the list.
I thought the array would maybe be automatically converted to a string. I also tried using providerUrls[0] as orderBy criteria.
I know I could write my own sorting function but if there is a simple solution for this I would like to learn how to use it.
This is a reduced example of my code:
<table>
<thead>
<tr>
<td>
<p data-ng-click="sortBy = providerUrls; sortReverse = !sortReverse;">
URLs
<span data-ng-show="sortBy === providerUrls && !sortReverse">
<img src="arrow-down.svg"/>
</span>
<span data-ng-show="sortBy === providerUrls && sortReverse">
<img src="arrow-up.svg"/>
</span>
</p>
</td>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="provider in providerFilter = (providers | orderBy:sortBy:sortReverse) track by $index">
<td>
<p data-ng-repeat="url in provider.urls track by $index">
{{url}}
</p>
</td>
</tr>
</tbody>
</table>
My data structure:
var a = {
providerId: "a",
providerUrls: ["abc", "def", "ghi"]
// more properties
};
// b and c similar
$scope.providers = [a, b, c];

knockout js showing related objects(selected id) on click

I'm new to Knockout js and need some advice. What I am trying to do (the correct way) is have orders listed in a grid and a "production" button that when it is click, will show only the production objects that have matching id's to the order id. I'm trying to wrap my head around Knockouts binding, but I think I am over thinking things.
right now I have 2 objects Order and Production with are observable arrays filled with observables. Order has value of orderId and Production have value of prodId that I am checking for a match. I'm now wondering if I should not make this on object with mutli-dimensional array. Would it be easier to show selected data that way?
here is an example of the initial arrays
var initProduction = [
new Production({
proId:"183175",
pType:"Art TIme",
startTime:"11:20",
stopTime:"11:50",
totalTime:"",
by :"MJ"
})
var initData = [
new Order({
date:"06-09-2014",
orderId:"183175",
name:"Columbus Africentric",
dateRec:"05-23-2014",
rushDate:"",
totalQty:55,
parts:"1",
auto:"No",
type:"Local",
})
]
so should I combine into a multidimensional array? And if so, how would I do that? And how would I create a click event to show related data in another table showing only the production info.
I hope this makes sense and someone can help me. I apologize for my ignorance.
here is a stripped down version of my html bindings
<table>
<tbody data-bind="foreach:filteredOrders">
<tr>
<td>
<label class="read" data-bind="text:orderId, visible:true" />
</td>
<!-- controls -->
<td class="tools">
<button class="button toolButton" data-bind="click: $root.showSummary">Show Production</button>
</td>
</tr>
</tbody>
</table>
<h3>Production Summary</h3>
<table class="ko-grid" id="menu" >
<tbody data-bind="foreach:filteredProds">
<tr>
<td>
<div>
<label class="read" data-bind="text:proId, visible:true" />
</div>
</td>
</tr>
</tbody>
</table>
I would just have an orders array and then link the production object to the order.
var model = {
orders: [
{
date:"06-09-2014",
orderId:"183175",
name:"Columbus Africentric",
dateRec:"05-23-2014",
rushDate:"",
totalQty:55,
parts:"1",
auto:"No",
type:"Local",
production: {
proId:"183175",
pType:"Art TIme",
startTime:"11:20",
stopTime:"11:50",
totalTime:"",
by :"MJ"
}
},
{
date:"06-09-2014",
orderId:"183176",
name:"Angle Africentric",
dateRec:"05-23-2014",
rushDate:"",
totalQty:55,
parts:"1",
auto:"No",
type:"Local"
}
]
};
In the above json the second order doesn't have a production object.
Then in the viewModel I would use a computed which will return the orders depending on if all orders or only production orders should be shown. I've created a toggle here which is linked to the button.
var ViewModel = function (model) {
var self = this;
self.orders = $.map(model.orders, function (order) { return new Order (order); });
self.toggleProductionMode = function (order) {
order.showProductionOrder(!order.showProductionOrder());
};
};
var Order = function (order) {
var self = this;
ko.utils.extend(self, order);
self.showProductionOrder = ko.observable(false);
};
View:
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody data-bind="foreach: orders">
<tr>
<td data-bind="text: orderId"></td>
<td data-bind="text: name"></td>
<td data-bind="if: production"><button data-bind="click: $root.toggleProductionMode">Toggle Production Orders</button>
</td>
</tr>
<tr data-bind="visible: showProductionOrder, with: production">
<td colspan="3">
<table>
<tr>
<th>proId</th>
<th>pType</th>
</tr>
<tr>
<td data-bind="text:proId"></td>
<td data-bind="text:pType"></td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
Demo here: http://jsfiddle.net/X3LR6/2/

How do I check my database every once in a while in a jsp page?

Ok, so I have a jsp web page that shows me what are the courses that I am registered to.
the jsp code that is performed in the begining of the page:
<div>
<%
String username = request.getUserPrincipal().getName();
Iterable<Course> avCourses = ORM.getAvailableCourses(username);
%>
</div>
<form id="avCoursesForm">
<fieldset>
<legend>Available courses: </legend>
<table class="coursesTable">
<tr id="firstTr" style="display: none;">
<td class="blueBorder" style="width:5%;"></td>
<td class="blueBorder" style="width:20%;"><b>Course name</b></td>
<td class="blueBorder" style="width:15%;"><b>Course id</b></td>
<td class="blueBorder" style="width:5%;"><b>Credit points</b></td>
<td class="blueBorder" style="width:10%;"><b>Group number</b></td>
</tr>
<%
Iterator<Course> iter = avCourses.iterator();
int size = 0;
while(iter.hasNext())
{
Course course = iter.next();
%>
<tr id="trOfTable<%=size%>" style="display: none;">
<td class="blueBorder" style="width:5px;">
<input type="checkbox" name="option" value="<%=course.courseName%>" />
</td>
<td class="blueBorder">
<a href=# onclick="getPage('<%=request.getContextPath() %>', '<%=course.courseName %>');">
<%=course.courseName%> </a>
</td>
<td class="blueBorder">
<%=course.courseId%>
</td>
<td class="blueBorder">
<%=course.creditPoints%>
</td>
<td class="blueBorder">
<%=course.groupNum%>
</td>
</tr>
<%
size++;
}
%>
</table>
</fieldset>
</form>
the function getAvailableCourses() is at ORM.java file (this file queries the DB).
My goal is to check the database every X seconds to see if a certain course is still available for registration. I don't know how to do that. Can you help me?
In other words, I want to asynchronously check the database and accordingly refresh parts of the page (unavailable course will disappear and new available courses will appear).
tnx, Itamar.
You can use javascript setTimeout. This method call a target javascript function after every x times. Here is the pseudo code
<script type="text/javascript">
function checkCourse(){
var courseId = 5; //for example
// call servlet using ajax to check course is available or not.
callServlet(); // you have to implement the callServlet
}
var x = 2000;
setTimeout("checkCourse()",x);
</script>

Resources