AngularJS :- Calling a function query - html

Building a Shpping Cart using AngularJS .
I had code the code from a user on JSFiddle.
JS:-
function CartForm($scope) {
$scope.invoice = {
items: [{
qty: 10,
description: 'item',
cost: 9.95}]
};
$scope.addItem = function() {
$scope.invoice.items.push({
qty: 1,
description: '',
cost: 0
});
},
$scope.removeItem = function(index) {
$scope.invoice.items.splice(index, 1);
},
$scope.total = function() {
var total = 0;
angular.forEach($scope.invoice.items, function(item) {
total += item.qty * item.cost;
})
return total;
}
}
HTML
<h2>Shopping Card Example</h2>
<div ng:controller="CartForm">
<table class="table">
<tr>
<th>Description</th>
<th>Qty</th>
<th>Cost</th>
<th>Total</th>
<th></th>
</tr>
<tr ng:repeat="item in invoice.items">
<td><input type="text" ng:model="item.description"class="input-small" readonly="readonly"></td>
<td><input type="number" ng:model="item.qty" ng:required class="input-mini"> </td>
<td><input type="number" ng:model="item.cost" ng:required class="input-mini" readonly="readonly"></td>
<td>{{item.qty * item.cost | currency}}</td>
<td>
[<a href ng:click="removeItem($index)">X</a>]
</td>
</tr>
<tr>
<td><a href ng:click="addItem()" class="btn btn-small">add item</a></td>
<td></td>
<td>Total:</td>
<td>{{total() | currency}}</td>
</tr>
</table>
</div>
I want to have the add item outside the table . How do I access the addItem function outside the outside the above snippet of HTML code.
JS Fiddle http://jsfiddle.net/slav123/75m7e/

Your problem is related to scope visibility: you define your cart login in the CartForm scope and you want to access that logic from outside that scope.
There are several ways of doing that:
You could always do it the nasty way: pin any global funcionalities to the $rootScope to make them visible throughout the whole app:
function CartForm($scope, $rootScope) {
// ...
$rootScope.addItem = $scope.addItem;
}
Or you could try a cleaner way: you should pack your cart functionalities into a shared service that you can inject wherever you need it:
app.factory('CartService', function() {
// some cart logic here
// return your cart api
return {
addItem: function() {/*...*/}
}
});
After you defined yor cart logic as a factory, you can use it anywhere you want by simply injecting it as a dependency:
app.controller('MyPageCtrl', function($scope, CartService) {
$scope.cart = CartService;
});
and use the functionality into the view:
<a href ng:click="cart.addItem()" class="btn btn-small">add item</a>

Related

Problems in the group with a list of products for cart

we are making an angular online shop and I have a question, since I am pretty new to it. We have a List of products, but for the cart i need one specific product of the list after pressed the button "add to cart" atm I am trying to figure this out in the product.component.ts
Which looks like this:
#Input()
productItem!: Product;//is from model but I think ptoducts(the list) is actually directly from the database
products: any;
private msg!: MessengerService;
private cartService!: cartService;
cartService!: cartService;
constructor(private http: HttpClient) {
}
ngOnInit(): void {
this.getProducts();
}
deleteProducts(){
this.deleteProduct();
}
addToCart(){
console.log(this.productItem) //does not work. this.products returns the whole list of products
// this.cartService.productToCart(this.productItem).subscribe(() => {
// this.msg.sendMsg(this.productItem)
// })
}
getProducts()
{
return this.http.get("products").subscribe(x => {
this.products = x;
console.log(this.products);
});
}
deleteProduct()
{
//return this.http.delete(this.url).subscribe(data => {
//console.log(data);
return this.http.delete("products").subscribe(x => {
this.products = x;
console.log(this.products);
});
}
//produstDelete(prod: Product){
//console.log(prod)
// let conf = confirm("sind Sie sicher ?");
//if(conf)
// this.serviceproduct.produktDelete(prod);
}
Btw just to say, my only part was the addToCart in this code. They dont comment anything out so I have no idea what they even do here...anyways, atm I just want to get ONE product.
When I do this.productItem, then the {} is completely empty. When i do this.products, i get the whole list of all the items.
This is the html part btw:
<tbody>
<tr *ngFor ="let product of products ">
<td> {{product.Name}}</td>
<td> {{product.Category}}</td>
<td> {{product.Price}}</td>
<td> <img src = "../assets/ProductPic/{{product.Pic}}"></td>
<td><button class="btn-danger" (click)="deleteProduct()"> Löschen </button></td>
<td><button class="btn-change" routerLink="/updateProduct/:id" routerLinkActive="active"> Change </button></td>
<td><button class="btn-cart" (click)="addToCart()"> In cart </button></td>
</tr>
</tbody>
I would really really appreciate if somebody could help, i add anything more that is needed and please no roast, I did watch Tutorials on it, but sometimes it do is hard to udnerstand things
If you simply need the product available in the function, then edit the function signature in the componen:
addToCart(product: Product){
this.productItem = product;
console.log(this.productItem) //does not work. this.products returns the whole list of products
}
and include it in the HTML:
<tbody>
<tr *ngFor ="let product of products ">
<td> {{product.Name}}</td>
<td> {{product.Category}}</td>
<td> {{product.Price}}</td>
<td> <img src = "../assets/ProductPic/{{product.Pic}}"></td>
<td><button class="btn-danger" (click)="deleteProduct()"> Löschen </button></td>
<td><button class="btn-change" routerLink="/updateProduct/:id" routerLinkActive="active"> Change </button></td>
<td><button class="btn-cart" (click)="addToCart(product)"> In cart </button></td>
</tr>
</tbody>

How to post table data without refreshing my view after removing a record?

I am writing a movie app that allows you to rent movies (similar to Redbox). I have a CheckOut cart view containing a table. Each table row has a remove button which uses AJAX to delete element in the view and also update the SQL database that the app works with. After removing any items from the cart, the user should be able to click 'purchase' and process the items that were left in the cart, all without needing to refresh the page.
I have an Order model containing a list of OrderDetails. Each OrderDetails item has information about a movie. It is data from OrderDetails list that the table is populated with.
The issue comes in when I remove items from cart and try to post the form with the values in the table. My CheckOut HttpPost controller method receives the model, but the OrderDetail list still has the item count it originally had before I removed items from cart. Logically, there is no data bound to the properties since I deleted the hidden tags I had in each record.
Because the list contains elements I don't need, processing the list results in garbage data going into the database.
I tried to simply remove the garbage elements within my CheckOut HttpPost method before it begins processing the list. This worked great but I don't want to have to remove anything in the CheckOut method after posting the form. I'm expecting the list to not contain the elements.
CheckOut POST method:
[HttpPost]
public IActionResult CheckOut(Order order)
{
if (ModelState.IsValid == false)
{
return View("CheckOut", order);
}
foreach (var orderDetailObj in order.OrderDetailsList)
{
_checkOutService.StoreMoviesInOrder(GetConnectionString(), order.OrderId, orderDetailObj);
}
return RedirectToAction("PurchaseSummary", new { Id = order.OrderId });
}
CheckOut.cshtml view:
#model MovieContract.Order
...
#for (int i = 0; i < Model.OrderDetailsList.Count; i++)
{
<tr>
<td>
<input type="button" name="btnRemove" class="removeButton" value="Remove" onclick="Remove(this, '#Model.CartId', #Model.OrderDetailsList[i].Movie.FilmId)" />
</td>
<td hidden>
<input asp-for="#Model.OrderDetailsList[i].Movie.AddedToCart" value="#Model.OrderDetailsList[i].Movie.AddedToCart" hidden />
</td>
<td hidden>
<input asp-for="#Model.OrderDetailsList[i].Movie.FilmId" value="#Model.OrderDetailsList[i].Movie.FilmId" hidden />
</td>
<td>
<input asp-for="#Model.OrderDetailsList[i].Movie.FilmName" value="#Model.OrderDetailsList[i].Movie.FilmName" hidden />
#Model.OrderDetailsList[i].Movie.FilmName
</td>
<td>
<input asp-for="#Model.OrderDetailsList[i].Movie.GenreName" value="#Model.OrderDetailsList[i].Movie.GenreName" hidden />
#Model.OrderDetailsList[i].Movie.GenreName
</td>
<td>
<input asp-for="#Model.OrderDetailsList[i].Movie.PricePerDay" value="#Model.OrderDetailsList[i].Movie.PricePerDay" class="pricePerDay" hidden />
#Html.DisplayFor(modelItem => #Model.OrderDetailsList[i].Movie.PricePerDay)
</td>
<td hidden>
<input asp-for="#Model.OrderDetailsList[i].Movie.AmountOnHand" value="#Model.OrderDetailsList[i].Movie.AmountOnHand" hidden />
</td>
</tr>
}
As for AJAX, I simply have an AJAX function that calls a post controller method. The method deletes the appropriate item from the database and returns NoContent();. Upon success, AJAX deletes the desired row from the view.
I expect that by the time I reach the CheckOut HttpPost method, the parameter object's list property will contain less elements if I had decided to remove any from the cart. I don't want to have to refresh the whole page to rebuild my model each time I remove an item from the cart.
Here is a working demo :
View
#model AjaxDeleteItem.Models.Order
<div>
<form method="post" asp-action="CheckOut">
<table class="table" id="table">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.OrderDetailsList.Count; i++)
{
<tr class="count">
<td>
<input type="button" name="btnRemove" class="removeButton" value="Remove" onclick="Remove(this, #Model.OrderDetailsList[i].Id)" />
</td>
<td >
<input class="FilmId" asp-for="#Model.OrderDetailsList[i].Movie.FilmId" value="#Model.OrderDetailsList[i].Movie.FilmId" />
</td>
<td >
<input class="FilmName" asp-for="#Model.OrderDetailsList[i].Movie.FilmName" value="#Model.OrderDetailsList[i].Movie.FilmName" />
</td >
<td>
<input class="GenreName" asp-for="#Model.OrderDetailsList[i].Movie.GenreName" value="#Model.OrderDetailsList[i].Movie.GenreName" />
</td>
<td>
<input class="PricePerDay" asp-for="#Model.OrderDetailsList[i].Movie.PricePerDay" value="#Model.OrderDetailsList[i].Movie.PricePerDay" />
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit"/>
</form>
</div>
#section Scripts
{
<script>
function Remove(obj,id) {
$.ajax({
type: "post",
url: "/orders/deleteorderitem?id="+id,
success: function () {
$(obj).closest('tr').remove();
var count = $(" tbody tr").length;
var i = 0;
$("tbody tr").each(function () {
var row = $(this);
if (i < count)
{
row.find("input[class=FilmId]").attr("name", "OrderDetailsList[" + i + "].Movie.FilmId");
row.find("input[class=FilmName]").attr("name", "OrderDetailsList[" + i + "].Movie.FilmName");
row.find("input[class=GenreName]").attr("name", "OrderDetailsList[" + i + "].Movie.GenreName");
row.find("input[class=PricePerDay]").attr("name", "OrderDetailsList[" + i + "].Movie.PricePerDay");
i++;
}
});
},
error: function () {
alert("Fail to delete");
}
});
}
</script>
}
2.Controller:
[HttpPost]
public async Task<IActionResult> DeleteOrderItem(int id)
{
var orderdetail = await _context.OrderDetails.FindAsync(id);
_context.OrderDetails.Remove(orderdetail);
await _context.SaveChangesAsync();
return NoContent();
}
[HttpPost]
public IActionResult CheckOut(Order order)
{
if (ModelState.IsValid == false)
{
return View("Details", order.CartId);
}
//the stuff you want
}
3. Result :

HTML problem: cannot find variables in a function

So I'm trying to make a simple CRUD system but running into a problem. More specifically, I'm making a webpage that can add and delete entries but when I try to run the webpage it shows some errors notifying that some variables can't be accessed or not defined. I know this is due to the variable being in a local function. Any tips on how to fix this? Here's the HTML and TypeScript code:
import * as ko from "knockout";
class People {
id: KnockoutObservable < number > ;
name: KnockoutObservable < string > ;
age: KnockoutObservable < number > ;
constructor(name: string, age: number, id: number) {
this.name = ko.observable(name);
this.age = ko.observable(age);
this.id = ko.observable(id);
}
addEntry = function() {
let self = this;
this.entryInfo = ko.observableArray([
new People("Long", 23, 36457547),
new People("TD", 23, 43635736)
]);
this.removeEntry = function(entry: People) {
this.entryInfo.remove(entry);
}
}
}
ko.applyBindings(new People("Long", 23, 3234234));
<!DOCTYPE html>
<html>
<script src="./externals/require.js"></script>
<script src="./built/require-config.js"></script>
<script>
require(["built/hello"]);
</script>
<h2>Employee Information (<span data-bind="text: entryInfo().length"></span>)</h2>
<body>
<table>
<thead>
<th>ID Number</th>
<th>Name</th>
<th>Age</th>
</thead>
<tbody data-bind="foreach: entryInfo">
<tr>
<td><input data-bind="value: id" /></td>
<td><input data-bind="value: name" /></td>
<td><input data-bind="value: age" /></td>
<td>Remove Entry</td>
</tr>
</tbody>
</table>
<button data-bind="click: addEntry">Add Entry</button>
</body>
</html>
Screenshot of the error:
enter image description here

How to list values using ng-repeat using AngularJS and JsonResult ASP.NET MVC

I'm trying to render a list from my JsonResult Controller. It's ok, I receive data in my Angular service, but a in trouble to render it in a list using ng-repeat. It´s renders a big empty list.
When the data is not a list, it´s works.
Angular.
Debug
var app = angular.module('FileApp', []);
app.service('ngFileService', function ($http) {
this.getFileByFileCode = function (fileCodigo) {
var response = $http.get("/Files/GetFile?fileCodigo=" + fileCodigo);
return response;
};
});
app.controller('ngFileController', function ($scope, ngFileService) {
$scope.filterFileCode = "";
$scope.getFilteredFile = function () {
var promise = ngFileService.getFileByFileCode($scope.filterFileCode);
promise.then(function (resp) {
$scope.File = resp.data;
$scope.Message = "Call is Completed Successfully";
}, function (err) {
$scope.Message = "Call Failed " + err.status;
});
};
});
HTML
<tr>
<td>Enter Search Value:</td>
<td><input type="text" ng-model="filterFileCode" class="form-
control" ng-change="getFilteredFile()" /></td>
</tr>
<table class="table table-bordered table-condensed table-striped">
<thead>
<tr>
<th>Documentos Gerais File</th>
<th></th>
<th>CTB</th>
<th>COM</th>
<th>Site</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="f in File">
<td>Documentos</td>
<td>{{f.FileCTB}}</td>
<td>{{f.FileCOM}}</td>
<td>{{f.FileSite}}</td>
</tr>
</tbody>
</table>
Erro
I expect to render a list of boolens values.
**DataCriacao: "/Date(-62135596800000)/"
DataFim: "06/07/2018"
DataInicio: "26/06/2018"
DescricaoServico: null
FileCOM: (2) [true, false]
FileCTB: (2) [false, false]
FileCodigo: 190562
FileCodigoId: 0
FileCodigoNv: null
FileMimeType: null
FileSite: (2) [false, false]**
[SOLVED]
I find de solution making the above solution:
<tbody>
<tr>
<td>Documentos</td>
<td>Comandos</td>
<td><span ng-repeat="(key, value) in File.FileCTB track by $index">
{{value}}</span></td>
<td><span ng-repeat="(key, value) in File.FileCOM track by $index">
{{value}}</span></td>
<td><span ng-repeat="(key, value) in File.FileSite track by $index">
{{value}}</span></td>
</tr>
</tbody>
I solved this problem storing in a viewModel object all date below:
DataCriacao: "/Date(-62135596800000)/"
DataFim: "06/07/2018"
DataInicio: "26/06/2018"
DescricaoServico: null
FileCOM: (2) [true, false]
FileCTB: (2) [false, false]
FileCodigo: 190562
FileCodigoId: 0
FileCodigoNv: null
FileMimeType: null
FileSite: (2) [false, false]
So, I can iterate only in the attribute that is collections ou array.

AngularJS Hide rows from table on given condition when a button is clicked

I'm trying to hide some rows from a table when a button is clicked. I want to hide just the rows where the number of exams is equals to zero.
HTML code:
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-class="{'showNot' : item.examsNum === 0}" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
AngularJS:
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.hide = function () {
angular.element('.showNot').css("display", "none");
};
}]);
Here is the jsfiddle: link
I'm pretty new to AngularJS, and I can't see what I'm doing wrong.
Thanks!
Try using a show/hide flag, and use it in ng-show along with the zero check:
Here's a fiddle.
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-hide="(item.examsNum == 0) && hideZero" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
and
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.hide = function () {
$scope.hideZero = !$scope.hideZero;
};
}]);
You can give an id to your table <table id="table"> then change your selector to
var elem = document.querySelector('#table');
angular.element(elem.querySelector('.showNot')).css('display', 'none')
We cant use class selectors easily in jQlite - Limited to lookups by tag name but this should work your you
JSFiddle Link
you need to use the ng-show or ng-hide directive insted of display none
html
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide()"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-show="Display" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
script
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.Display = true;
$scope.hide = function () {
$scope.Display = !$scope.Display ;
};
}]);
Perhaps using a filter is more correct.
https://docs.angularjs.org/api/ng/service/$filter
Filters may be used to hide items in a list based on some criteria - which sounds like what you are doing
Okay. So you got something wrong over here. the 'item' is only available inside the scope of ng-repeat. You cannot access it at the same level as ng-repeat.
Here is a working version of your code. And please use ng-hide/ng-show for such things. Its more efficient.
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br />
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data.records">
<td ng-hide='item.examsNum === 0'>{{item.name}}</td>
<td ng-hide='item.examsNum === 0'>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>