mat checkbox not clearing when cancel form button clicked - angular-material

I have a list of cities in a form with check box. when trying cancel form , the list of checkboxes checked are not clearing . but when i uncheck each of the checkbox, it works
api-model.ts
export interface City{
city_Name: string;
}
class-model.ts
export class eModel {
cityList: Array<City>=[];
}
app.html
<div class="row">
<div class="column-3">
<div *ngFor="let data of cityData; let i=index">
<mat-checkbox color="primary" (change)="getCheckboxValues(data, i, $event)" >
{{data.city_Name}}
</mat-checkbox>
</div>
</div>
</div>
<button mat-raised-button class="cancel-button" (click)="Cancel()">Cancel</button>
app.ts
cityData: City[] = [];
ngOnInit(): void {
this.eModel.cityList = [];
loadCityList();
}
loadCityList() {
return this._getAPIservice.getCity().subscribe(data => {
this.cityData = data;
});
}
Cancel(): void {
this.eForm.resetForm({});
loadCityList();
this.eModel.cityList = [];
}

This can be achieved by using element reference variable.
Try this:
<div class="row">
<div class="column-3">
<div *ngFor="let data of cityData; let i=index">
<mat-checkbox #chkboxes color="primary" (change)="getCheckboxValues(data, i, $event)" >
{{data.city_Name}}
</mat-checkbox>
</div>
</div>
</div>
<button mat-raised-button class="cancel-button" (click)="Cancel()">Cancel</button>
In ts:
#ViewChildren('chkboxes') chkboxes: QueryList<any>; // Define this at the top
Cancel(){
this.chkboxes.forEach(x => x.checked = false);
}

Related

How to disable buttons based on data model values?

I am building a mini online shopping CMS project for collage.
I finished the project and now I want to add a feature where I have limited quantity of products.
When the quantity is equal to 0 then product is shown as 'out of stock' and my 'Add to cart' button becomes disabled.
I have added a 'quantity' property to my product class and now I need to change something in the Index view of the product.
I tried few options and it does not seem to work.
Here is the code for the Index.cshtml page.
#model IEnumerable
<Product>
#{ ViewData["Title"] = "Products"; }
<h1 class="display-4 pb-5">All Products</h1>
<div class="row">
#foreach (var item in Model)
{
<div class="col-4">
<div class="ajaxbg d-none">
<img src="~/Images/ajax_loader.gif" />
<p class="lead alert alert-success text-center d-none">
The product has been added!
</p>
</div>
<img src="~/Media/Products/#item.Image" class="img-fluid" alt="" />
<h4>#item.Name</h4>
<div>
#Html.Raw(item.Description)
</div>
<p>
#item.Price.ToString("C2")
</p>
<p>
<a asp-controller="Cart" asp-action="Add" asp-route-id="#item.Id" data-id="#item.Id" id="addToCartButton" class="btn btn-primary addToCart">Add to cart</a>
</p>
#if (item.Quantity == 0) { }
</div>
}
#if (ViewBag.TotalPages > 1) {
<div class="d-flex w-100 justify-content-center">
<pagination page-count="#ViewBag.TotalPages" page-target="/products" page-number="#ViewBag.PageNumber" page-range="ViewBag.PageRange"></pagination>
</div>
}
</div>
#section Scripts {
<script>
function DisableBtn() {
document.getElementById("addToCartBUtton").disabled = true;
}
$(function() {
$("a.addToCart").click(function(e) {
e.preventDefault();
let ajaxDiv = $(this).parent().parent().find("div.ajaxbg");
ajaxDiv.removeClass("d-none");
let id = $(this).data("id");
$.get('/cart/add/' + id, {}, function(data) {
$("div.smallcart").html(data);
ajaxDiv.find("img").addClass("d-none");
ajaxDiv.find("p").removeClass("d-none");
setTimeout(() => {
ajaxDiv.animate({
opacity: 0
}, function() {
$(this).addClass("d-none").fadeTo(.1, 1);
$(this).find("img").removeClass("d-none");
$(this).find("p").addClass("d-none");
});
});
});
});
});
</script>
}
Try this
#If(Model!=null)
{
#foreach (var item in Model)
{
..........
<p>
#if (item.Quantity == 0) {
<a disabled class="btn btn-primary addToCart">Add to cart</a>
}
else
{
<a asp-controller="Cart" asp-action="Add" asp-route-id="#item.Id" data-id="#item.Id" id="addToCartButton" class="btn btn-primary addToCart">Add to cart</a>
}
</p>
}
}

How to Show 1 element and hide multiple elements in Angular 7

I am trying to click a details about an element and I just want the details of that particular details to show and hide other element details.
“This is Angular 7. I’ve tried on using *ngIf and failed in it. I am using parent and child component communication technique.
Parent HTML
<h4>2 Days Bangalore Mysore</h4>
</div>
<div class="ft-foot">
<h4 class="ft-title text-upper"><a routerLink="/details"
(click)="detailsbm2d()" class="btn btn-primary">DETAILS</a></h4>
</div>
<h4>2 Days Kodaikanal</h4><br>
</div>
<div class="ft-foot">
<h4 class="ft-title text-upper"><a routerLink="/details"
(click)="detailskod2d()" class="btn btn-primary">DETAILS</a></h4>
</div>
<h4>2 Days Ooty</h4><br>
</div>
<div class="ft-foot">
<h4 class="ft-title text-upper"><a routerLink="/details"
(click)="detailsoo2d()" class="btn btn-primary">DETAILS</a></h4>
</div>
Parent component
show: boolean= true;
show1:any = true;
show2: boolean = true;
detailsbm2d() {
this.show = !this.show;
}
detailskod2d() {
this.show1 = !this.show1;
}
}
detailsoo2d() {
this.show2 = !this.show2;
}
ngOnInit() {
}
}
Child HTML
<div class="container">
<div class="row">
<section class="col-sm-6">
<h1 class="text-upper">TOUR PLAN</h1>
</section>
</div>
</div>
<div class="container" *ngIf="!show">
<div id="page" class="col-md-8">
<P> Element1 </p>
</div>
</div>
<div class="container" *ngIf="!show1">
<div id="page" class="col-md-8">
<P> Element2 </p>
</div>
</div>
<div class="main-contents" *ngIf="!show2">
<div id="page" class="col-md-8">
<P> Element3 </p>
</div>
</div>
Child component
export class {
#Input() show1: boolean;
#Input() show2: boolean;
#Input() public text: string;
constructor() { }
ngOnInit() {
}
}
I expect only the Element1 to be displayed when I click the DETAILS button, but I get all the Element1,Element2 and Element3 are getting displayed.
show: boolean= false ;
show1:any = false ;
show2: boolean = false ;
// making show; show1; show2 initially to false hides it. when you click the DETAILS
// button the click event shows it.
and convert all *ngIf = show // (i.e., remove "!" from all *ngIf's)
correction of #muzzu47's answer
Parent component
show: boolean= true; //Default True for initially show first content
show1:any = false ;
show2: boolean = false ;
detailsbm2d() {
this.show = !this.show;
this.show2 = false;
this.show1 = false;
}
detailskod2d() {
this.show = false;
this.show2 = false;
this.show1 = !this.show1;
}
detailsoo2d() {
this.show = false;
this.show1 = false;
this.show2 = !this.show2;
}
In function other element should be false because you want to display at a time single element
convert all *ngIf = show // (i.e., remove "!" from all *ngIf's)

Page flickers when Angular JS is used in Bootstrap modal, but works fine after reload. (tried ngCloak too)

Application Description:
I am making a simple Ecommerce website(single page product listing) using AngularJS and Rails. It only handles Cash On Delivery Orders. The user adds products and checksout. All this process is done in Angular. The cart is stored in localstorage.When he checksout a modal pops up asking him to choose choose between two shipping methods. Depending on the shipping method he chooses the price which is displayed on the bootstrap modal has to be updated.
Problem Description:
The page flickers(the curly braces appear) when I try to do this. When I reload the whole thing it works properly.
After some research I found that I have to use $compile but I am not sure of how to use it. i read several tutorials but I am not able to figure it out.
Here is my angular code. The two functions I used in bootstrap modal are shippingCharges(), totalPrice(). They are at the end of the angular code.
<script>
var products = angular.module('products', []);
products.controller('ListController', ['$scope', function($scope) {
$scope.categories = JSON.parse('<%= j raw(#categories_hash.to_json) %>');
$scope.activeCategory = null;
$scope.cart = JSON.parse(localStorage.getItem('cart'));
if (!!$scope.cart) {
angular.forEach($scope.cart, function(item_quantity, item_id) {
$scope.categories.forEach(function(category, index1) {
category.products.forEach(function(product, index2) {
if (item_id == product.id) {
product.ordered_quantity = item_quantity;
}
});
});
});
};
$scope.formData = {
shipping: "scheduled"
};
$scope.addProductToCart = function(product_id) {
// event.preventDefault();
var cart = $scope.cart;
if (!cart) {
cart = {}
}
if (!cart[product_id]) {
cart[product_id] = 0;
}
cart[product_id] += 1;
localStorage.setItem('cart', JSON.stringify(cart));
$scope.cart = cart;
};
$scope.increaseQuantity = function(product) {
product.ordered_quantity += 1;
$scope.addProductToCart(product.id);
};
$scope.decreaseQuantity = function(product) {
product.ordered_quantity = product.ordered_quantity - 1;
var cart = $scope.cart;
if (!cart) {
cart = {}
}
cart[product.id] -= 1;
localStorage.setItem('cart', JSON.stringify(cart));
$scope.cart = cart;
};
$scope.removeProductFromCart = function(product_id) {
var cart = $scope.cart;
cart[product_id] = 0;
localStorage.setItem('cart', JSON.stringify(cart));
$scope.cart = cart;
}
$scope.totalPrice = function() {
total = 0;
$scope.categories.forEach(function(category, index) {
category.products.forEach(function(product, index1) {
total += product.price*product.ordered_quantity;
});
});
return total;
};
$scope.toggleCategory = function(category) {
if ($scope.activeCategory == category.category_id) {
$scope.activeCategory = null;
} else {
$scope.activeCategory = category.category_id;
}
};
$scope.shouldShowCategory = function(category) {
return($scope.activeCategory == category.category_id);
};
$scope.shippingCharges = function() {
var cart = $scope.cart;
var shippingcost;
if ($scope.formData.shipping == "scheduled"){
shippingcost = 35;
}else if ($scope.formData.shipping == "unscheduled"){
shippingcost = 75;
}
cart["shipping"]=shippingcost;
localStorage.setItem('cart', JSON.stringify(cart));
return shippingcost;
}
}]);
</script>
Boostrap Modal Code
<div class="modal fade" id="checkoutModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" ng-controller="ListController" ng-cloak >
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Information for delivery</h4>
</div>
<div class="modal-body checkout-details">
<form id="checkoutForm" class="form-horizontal">
<div id="checkoutLoading" class="progress progress-striped active hidden">
<div class="progress-bar progress-bar-success" style="width: 100%"></div>
</div>
<fieldset>
<legend>Choose a delivery method</legend>
<p>We are making a schedule delivery to <strong><%= delivery_timing[0] %></strong> on <strong><%= delivery_timing[1] %></strong>. If you are not located in the mentioned places please choose an unscheduled delivery</p>
<div class="radio">
<label><input type="radio" name="shipping" value="scheduled" ng-model="formData.shipping" ng-change="setShipping('scheduled')">Scheduled Delivery(Rs. 35)</label>
</div>
<div class="radio">
<label><input type="radio" name="shipping" value="unscheduled" ng-model="formData.shipping" ng-change="setShipping('unscheduled')">Unscheduled Delivery(Rs.75)</label>
</div>
<p class="ng-cloak">Total: {{shippingCharges() + totalPrice()}}</p>
</fieldset>
<fieldset>
<legend>Please provide delivery details:</legend>
<div class="errorMessage alert alert-dismissible alert-danger hidden">
<strong>Oh snap!</strong> Please provide phone number and address.
</div>
<div id="checkoutEmailFormGroup" class="form-group">
<label for="checkoutPhone">Email</label>
<input type="email" class="form-control" id="checkoutEmail" placeholder="me#example.com" >
</div>
<div id="checkoutPhoneFormGroup" class="form-group">
<label for="checkoutPhone">Phone</label>
<input type="phone" class="form-control" id="checkoutPhone" placeholder="+91-9999-999-999" >
</div>
<div id="checkoutAddressFormGroup" class="form-group">
<label for="checkoutAddress">Address</label>
<textarea class="form-control" id="checkoutAddress" placeholder="Plot No
Street Name
City" rows="5"></textarea>
</div>
</fieldset>
</form>
</div>
<div class="modal-footer">
<p class="ng-cloak" >Total cost: {{shippingCharges() + totalPrice()}}</p>
<button type="button" class="btn btn-default" data-dismiss="modal">Go Back</button>
<button id="checkout_trigger" type="button" class="btn btn-brown">Confirm</button>
</div>
</div>
</div>
</div>
Can you please let me know how to compile the code in the Bootstrap modal?

Can't seem to get AngularFire '$update' working

I’m pretty new to Angular, Firebase and AngularFire, so it's probable I'm going about this the wrong way.
Basically I have a form in a modal(UI Bootstrap) and I want to update some previously stored values, but AngularFire ‘$update’ doesn’t update them in Firebase. Creating and deleting items outside the modal is working fine.
This is within my service:
updateItem: function (id, item) {
var item_ref = new Firebase(FIREBASE_URL + ‘/items/‘ + user_id + '/' + id);
var item = $firebase(item_ref);
item.$update({
name: item.name,
notes: item.notes
});
}
This is within my controller:
$scope.edit = function(id) {
$modal.open({
templateUrl: 'views/item.html',
backdrop: 'static',
keyboard: false,
resolve: {
data: function() {
return {
title: 'Edit item',
item: Items.getItem(id)
};
}
},
controller: 'EditItemCtrl'
})
.result.then(function(item) {
Items.updateItem(item.$id, item);
});
};
This is my modal controller:
app.controller('EditItemCtrl', function ($scope, $modalInstance, data) {
$scope.data = data;
$scope.ok = function(item) {
$modalInstance.close(item);
};
$scope.cancel = function() {
$modalInstance.dismiss();
};
});
This is my modal template:
<div class="modal-content">
<div class="modal-header">
<button class="close" style="margin-top: -10px;" type="button" ng-click="cancel()">×</button>
<h3>{{data.title}}</h3>
</div>
<div class="modal-body">
<form name="editItem" role="form" novalidate>
<div class="form-group">
<label class="sr-only" for="itemName">Item name</label>
<input name="name" type="text" class="form-control" placeholder="Item name" value="{{data.item.name}}" ng-model="data.item.name">
</div>
<div class="form-group">
<label class="sr-only" for="itemNotes">Item notes</label>
<textarea name="notes" class="form-control" rows="2" id="itemNotes" placeholder="Notes" ng-model="data.item.notes" ng-maxlength="500">{{data.item.notes}}</textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-default" type="button" ng-click="cancel()">Cancel</button>
<button class="btn btn-primary" type="button" ng-click="ok(editItem.data.item)">OK</button>
</div>
</div>
Stepping through everything shows that the item to be updated and new values are being passed through to the service, but they're not making their way into Firebase.
I'm guessing that I'm probably going about this the wrong way though - any guidance would be much appreciated.

Adding active class to dynamic Twitter Bootstrap carousel in ASP.NET MVC

I'm using the Boostrap 2.x slider to display a series of testimonials on a webpage which I retrieve from a database.
My code is as follows:
<div id="testimonials" class="carousel slide">
<div class="carousel-inner">
#foreach (var item in Model.Testimonials)
{
<div class="item" style="max-height:70px; overflow:hidden">
<h4>#item.Title</h4>
#item.Quote
</div>
}
</div>
</div>
For the slider to work, the first item needs to be set to 'active', otherwise the first item shown is blank. How do I add the 'active' class to the first item in MVC?
So the first item should display as
<div class="item active" style="max-height:70px; overflow:hidden">
instead of
<div class="item" style="max-height:70px; overflow:hidden">
In my script file I have:
$(document).ready(function () {
$('#testimonials').carousel({
interval: 6000
});
$('#testimonials').carousel('cycle');
}
(there are 2 sliders on this page)
Thanks.
You can check for the first item in the loop:
<div id="testimonials" class="carousel slide">
<div class="carousel-inner">
#{
var i = 0;
foreach (var item in Model.Testimonials)
{
var itemClass = i++ == 0 ? "item active" : "item";
<div class="#itemClass" style="max-height:70px; overflow:hidden">
<h4>#item.Title</h4>
#item.Quote
</div>
}
}
</div>
</div>
or replace foreach with for loop if your Model.Testimonials property is a type of IList<T> or any collection, which items can be individually accessed by index:
<div id="testimonials" class="carousel slide">
<div class="carousel-inner">
#for (int i = 0; i < Model.Testimonials.Count; i++)
{
var item = Model.Testimonials[i];
var itemClass = i == 0 ? "item active" : "item";
<div class="#itemClass" style="max-height:70px; overflow:hidden">
<h4>#item.Title</h4>
#item.Quote
</div>
}
</div>
</div>
If you want to do this with JavaScript, so:
$(document).ready(function () {
$('.carousel-inner .item:first').addClass('active');
$('#testimonials').carousel({
interval: 6000
});
$('#testimonials').carousel('cycle');
}
Also I would suggest you to move the style="max-height:70px; overflow:hidden" line to css class:
.carousel-inner .item {
max-height: 70px;
overflow: "hidden";
}

Resources