Push $scope with ng-click AngularJS - javascript

I want the user to press the $scope.getJobList button to get the value of the $scope.getIdJobs variable. I am trying to solve this with the push functionality but it is not working.
Am I doing something wrong?
jsfidle
Example
$scope.getIdJobs = function(getIdJobs) {
$scope.getIdJobs = $filter('filter')( $scope.products, {id:getIdJobs})[0];
$scope.getJobList = function(currObj){
$scope.workflows[0].Steps.push($scope.getIdJobs); // It will add a new step ($scope.newStep) in first workflow's Steps
console.log($scope.workflows);
//$scope.workflows.push($scope.getIdJobs); // line that changed
$scope.workflows = job_detail.addJob(currObj)
console.log($scope.workflows);
};
//console.log("Estou dentro do getidJobs " + getIdJobs);
}
html
<article dir-paginate="product in filteredJobs | filter:searchTerm | orderBy: sorting.order:sorting.direction | itemsPerPage:5" id="{{product.id}}" class="productlist product col-sm-12">
<div class="inner-content">
<div class="clearfix">
<div class="col-md-8 col-sm-8 col-xs-8">
<h4 class="productname" name="{{product.Categoria}}"><a data-ng-href="#/job/{{product.id}}" ng-click="getIdJobs(product.id)">{{product.Title}}</a></h4>
<!--<h4 class="productname" name="{{product.Categoria}}"><a data-ng-href="#/job/{{filteredJobs.indexOf(product)}}">{{product.Title}}</a></h4>-->
<h4 style="color: gray;"><a data-ng-href="#/empresa">{{product.Empresa}}</a></h4>
</div>
</div>
</div>
</article>

Related

Getting abnormal result from angular model class function

I have a simple Invoicing & Inventory management application where we display the list of invoices under a particular customer which you can see in the img below. Also, when we click on View/Edit button the bootstrap modal pop-up is displayed with the selected invoice details. The problem I notice here is, the result of Grand Total function is wrong which I being a novice in angular unable to figure out.
I also read about the impact of function calls in angular template here https://medium.com/showpad-engineering/why-you-should-never-use-function-calls-in-angular-template-expressions-e1a50f9c0496 because I'm calling the functions in my template code below. I tired the pipe soultion shown in the article but that didn't help me.
Looking for someone who can help me figure out the Grand Total issue. Any help is really appreciated. Kindly look at the images & code below for the reference.
1. Invoice lists under customer(Raj Kapoor)
2. Invoice Bootstrap Modal Pop-up (On click of View/Edit Button)
Note: Here, assume that we've edited invoice no 4
3. Template code(admin-invoices.component.html)
Note: I'm providing only the absolute essentials part of code to keep it simple to understand. Focus only on 2 things: 1. View/Edit button function call 2. Invoice amount calculations section
<div class="container">
<div class="row g-0 mb-4">
<!-- Customer Name & Total Balance code goes here -->
</div>
<table class="table table-hover border" datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger">
<thead class="thead-dark">
<tr>
<!-- Table heading goes here like Date, Invoice No.,
Amount, Balance Due, Operation, Action etc.
-->
</tr>
</thead>
<tbody>
<tr *ngFor="let invoice of customerInvoices">
<td class="text-center">{{invoice.invoiceDate | date:'dd/MM/yyyy'}}</td>
<td class="text-center">{{invoice.invoiceNumber}} </td>
<td class="text-center">{{invoice.invoiceTotal | currency:'INR':true}}</td>
<td class="text-center">{{invoice.invoiceTotal - invoice.paymentTotal | currency:'INR':true}}</td>
<td class="text-center">
<button type="button" class="btn btn-success" (click)="setInvoice(invoice)" data-bs-toggle="modal" data-bs-target="#invoiceDetailsModal">
View/Edit Details
</button>
</td>
</tr>
</tbody>
</table>
<!-- View/Edit Details: Bootstrap Modal Starts -->
<div class="modal fade" id="invoiceDetailsModal" tabindex="-1" aria-labelledby="invoiceDetailsLabel" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<!-- Shop Details header goes here. -->
</div>
<div class="modal-body pt-0">
<div class="row">
<!-- To Customer, Date and Invoice No goes here-->
</div>
<!-- Items List Section -->
<div class="row">
<div class="items-table">
<div class="row header">
<!-- Table Heading: Sr. No, Item Details,
Qty, Rate, Amt goes here.. -->
</div>
<ng-container *ngFor="let invItem of invoice.invoiceItem; let i=index;">
<!-- Table data(list of all items) goes here-->
</ng-container>
<!-- Invoice amount calculations section -->
<div class="row">
<div class="col-4">
<!-- sub total row -->
<div class="row" style="border: 1px solid green;">
<div class="col-6 text-end">Sub Total:</div>
<div class="col text-center">{{invoiceSubTotal() | currency:'INR':true}}</div>
</div>
<!-- discount row -->
<div class="row">
<div class="col-6 ps-0 pe-0 text-end">
Discount:
<select class="form-select p-0" style="display: inline; width:60px;" [(ngModel)]="invoice.discountLabel" name="discountLabel" id="discountLabel" aria-label="Select discount option">
<option value="%">%</option>
<option value="Rs">Rs</option>
</select>
</div>
<div class="col text-center">
<input [(ngModel)]="invoice.discountTotal" name="discountTotal" type="number" style="border: 1px solid #ddd; width:100px">
</div>
</div>
<!-- freight row -->
<div class="row">
<div class="col-6 text-end">Freight(Rs.):</div>
<div class="col text-center"><input [(ngModel)]="invoice.freight" name="freight" type="number" style="border: 1px solid #ddd; width:100px"></div>
</div>
<!-- grand total row -->
<div class="row">
<div class="col-6 text-end">Grand Total:</div>
<div class="col text-center">{{calculateGrandTotal() | currency: 'INR':true}}</div>
</div>
<!-- Received row -->
<div class="row">
<div class="col-6 text-end">Received:</div>
<div class="col text-center">
<input [(ngModel)]="invoice.paymentTotal" name="paymentTotal" type="number" style="border: 1px solid #ddd; width:100px">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal" (click)="clearData()">Close</button>
<button type="button" class="btn btn-outline-secondary" (click)="updateInvoice()">
Update & Print
</button>
</div>
</div>
</div>
</div>
<!-- View/Edit Details: Bootstrap Modal Ends -->
4. Component Class(admin-invoices.component.ts)
#Component({
selector: 'app-admin-invoices',
templateUrl: './admin-invoices.component.html',
styleUrls: ['./admin-invoices.component.css']
})
export class AdminInvoicesComponent {
customerInvoices: Invoice[] = []; // to get list of all invoices under this customer
invoice: Invoice = new Invoice();
customerId: number;
customer: Customer = new Customer(); // To avoid initial undefined value of customer field
totalBalance: number = 0.0; // total balace of all invoices under this customer
itemsList: Item[] = [];
constructor(private route: ActivatedRoute,
private customerService: CustomerService,
private invoiceService: InvoiceService,
private itemService: ItemService) {
this.customerId = +(this.route.snapshot.paramMap.get('customerId')); // converting string to number using '+'
this.setCustomer();
this.setItems();
this.invoiceService.getCustomerInvoices(this.customerId)
.subscribe((invoices: Invoice[]) => {
this.customerInvoices = invoices.map(invoice => new Invoice(invoice));
this.calculateTotalBalance(); // get the total balace of all invoices under this customer
});
}
setCustomer() {
this.customerService.get(this.customerId)
.subscribe((customer: Customer) => this.customer = customer);
}
setItems() {
this.itemService.getAll()
.subscribe((items: Item[]) => this.itemsList = items);
}
calculateTotalBalance() {
this.customerInvoices.forEach(invoice => {
this.totalBalance = this.totalBalance + (invoice.invoiceTotal - invoice.paymentTotal);
});
}
setInvoice(invoice: Invoice) {
this.invoice = invoice;
}
addItem() {
this.invoice.addItem();
}
removeItem(item) {
this.invoice.removeItem(item);
}
invoiceSubTotal() {
return this.invoice.invoiceSubTotal();
}
calculateGrandTotal() {
return this.invoice._invoiceTotal;
}
updateInvoice() {
// update code goes here
}
}
5. Invoice Model class(invoice.ts)
export class Invoice {
invoiceId?: number;
invoiceNumber: number;
discountLabel: string = '';
discountTotal: number = 0.0;
freight: number = 0.0;
invoiceTotal: number = 0.0;
paymentTotal: number = 0.0;
invoiceDate: string;
narration: string = '';
customer: Customer;
invoiceItem: InvoiceItem[] = [];
description: string;
constructor(customer?: Customer, invoiceNumber?: number);
constructor(invoice: Invoice);
constructor(customerOrInvoice?: Customer | Invoice, invoiceNumber?: number){
if(!invoiceNumber) {
// Existing invoices
Object.assign(this, customerOrInvoice); // copy everything in current invoice object
} else {
// New invoice creation
this.invoiceDate = new Date().toISOString().substring(0,10);
this.customer = customerOrInvoice as Customer;
this.invoiceNumber = invoiceNumber;
this.invoiceItem.push({itemId: 0, quantity: 0, rate: 0}); // default invoice_item
}
}
addItem() {
this.invoiceItem.push({itemId: 0, quantity: 0, rate: 0}); // default invoice_item
}
invoiceSubTotal(): number {
let subTotal = 0.00;
this.invoiceItem.forEach(item => {
subTotal += (item.quantity * item.rate);
});
return subTotal;
}
get totalDiscount(): number {
if(this.discountLabel === '%') return ((this.discountTotal * this.invoiceSubTotal())/100);
return this.discountTotal; // Considering discountLable to either 'Rs' or not selected
}
get _invoiceTotal(): number {
this.invoiceTotal = (this.invoiceSubTotal() - this.totalDiscount) + this.freight;
return this.invoiceTotal;
}
}
First of all, I would like to thank #GRD or grdtechlab#gmail.com for collaborating with me over an email to help me with this problem. This was basically two way efforts to find out the root cause. But again credit goes to GRD.
Root Cause: So, the backend response object was the main issue and not the UI code. Because, when we query sequelize database to get the Decimal type data, then it converts the decimal values to string values. And, in the resultant object, we end up with the string type values instead of 'number' type(in javascript). This leads to abnormal results in our computation functions like _invoiceTotal( ) getter function above.
Read more here https://github.com/sequelize/sequelize/issues/8019
Solution: As mentioned in the above github issue, I changed the sequelize configuration to dialectOptions : {decimalNumbers: true} and this converted all the decimal values to number in the response object.
See the response object images below to understand this better.
1. Incorrect Response object (string values instead of number type)
2. Correct Response object (after changing sequelize configuration)

Showing changes without refreshing in VueJS

I'm so new in VueJS and still don't control much of its funcionalities,
I'm trying when I update or delete something in my window not need to refresh to see the changes...how can I do it, please?
My functions work perfectly in my controller, just need to solve the question of seeing changes.
Here I post my code if it helps...thank you very much!!
UpdateProfile.vue:
<div class="field">
<label class="label">Schedules</label>
<!--Edit and Delete Schedules-->
<div v-for="schedule in sortedDays(data.schedulesDisplayed)" class="control">
<div class="container">
<div class="field">
<label class="label">Week Day: {{schedule.week_day}}</label>
</div>
<div class="row">
<div class="col">
<div class="row">
Opening Time: <input class="input" type="text" placeholder="Pub schedules" v-model="schedule.opening_time">
</div>
</div>
<div class="col">
<div class="row">
Closing Time: <input class="input" type="text" placeholder="Pub schedules" v-model="schedule.closing_time">
</div>
</div>
</div>
<div class="field">
<div class="buttons is-left">
<div class="button is-info" #click="updatePubSchedule(schedule)">
<span class="icon"><i class="fas fa-save fa-lg"></i></span>
<span>Save</span>
</div>
<div class="button is-danger" #click="deletePubSchedule(schedule)">
<span class="icon"><i class="far fa-trash-alt"></i></span>
<span>Delete Schedule</span>
</div>
</div>
</div>
</div>
</div>
</div>
updatePubSchedule(schedule){
var instance = this;
this.api.put('/pubschedules/update/' + this.data.id, schedule).then(response => {
console.log(schedule);
//data = response.data;
instance = response.data;
});
},
deletePubSchedule(schedule){
var instance = this;
this.api.delete('/pubschedules/delete/' + this.data.id, schedule).then(response => {
//data = response.data;
instance = response.data;
});
},
And in my controller:
/**
* #param Pub $pub
*/
public function updatePubSchedule(Pub $pub)
{
//json_die(request()->all());
Schedule::where([
['pub_id','=', $pub->id],
['week_day' ,'=', request()->get('week_day')]
])->update(request()->all());
}
/**
* #param Pub $pub
*/
public function deletePubSchedule(Pub $pub)
{
Schedule::where([
['pub_id','=', $pub->id],
['week_day' ,'=', request()->get('week_day')]
])->delete();
}
I don't know how you get your initial data but you can have a GET request that gets fresh data from the laravel after you update/delete initial data.
With the response from that request you can update your data.schedulesDisplayed prop.
Important! You need to set the :key attribute in the div that uses v-for rendering like this
<div v-for="(schedule, index) in sortedDays(data.schedulesDisplayed)" :key="index" class="control">
I used the index for the sake of this example but you should use a unique property of sortedDays return.

Unable to get the parameter from URL in angular js and pass it to PHP

I have a product page where products from database is showing. Code for that product page.
<!-- language: lang-html -->
<div class="tab-content vertical col-md-10 col-lg-10 col-sm-9 col-xs-9 left-aligned">
<div class="tab-pane fade in active">
<perfect-scrollbar wheel-propagation="true" suppress-scroll-x="true" min-scrollbar-length="8" class='ps-scrollbar'>
<div class="ecommerce_product col-lg-3 col-md-4 col-sm-4 col-xs-6" ng-repeat="products in data | filter:search | startSearchFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
<div class="thumb">
<img class="img-responsive" ng-src="../upload/{{products.image}}">
<div class="overlay"><a ng-href="#/app/ecommerce/product-edit?id={{products.id}}" data-ng-click="editUser(products)" ><i class="material-icons">shopping_cart</i></a></div>
</div>
<div class="product-info">
<h4><a ui-sref="app.mus-song-view"><b>{{ products.pname | limitTo: 8 }}{{products.pname > 8 ? '...' : ''}}</b></a></h4>
<p class="price"> <b>Price:</b> {{products.price}}</p>
<p class="price"><b>Sale Price:</b>{{products.price - products.discount | number:2}}</p>
</div>
</div>
</perfect-scrollbar>
</div>
</div>
<!-- end snippet -->
Now the problem is i want to edit a particular product in a different page when clicked on the product. I passed the id in the url. But i am not being able to call the url parameter from the controller and at the same time pass the parameter to a php file so that i can call the data from the database.
Is there anyone who can help me from this. Please.
To get a url param you can use: $routeParams
For example you can get the id of a product from that route:
www.yoursite.com/product/id
by doing:
var id = $routeParams.id
In you HTML/PHP page after you pass param to the URL
Suppose your URL will be example.com/edit?id=1
and in the page when you visit above URL.
<?php
$id = $_GET['id'];
?>
<div ng-controller="my_ctrl">
<input type="hidden" ng-model="myID" value="<?php echo $id; ?>" />
{{myID}}
</div>
Now in your angular controller my_ctrl you can access your value (id) by using
myID
In your controller (my_ctrl):
//.............
$scope.myID = ""; //Initial Value
//.............
Remember Angular is both way data binding framework, so if you change the value of a model in you HTML will reflect on JS and if you change value in JS will reflect on View.

Assign value to dynamically created scope variables

I'm trying to create a means to toggle dynamically created rows of information. I've tried using ng-init, and then passing it to a function, but I'm screwing up somewhere and I can't seem to wrap my head around how or if this is possible. The gap, I believe, is in getting the concatenated scope variable to be referenced elsewhere. I'm using Bootstrap 3 and AngularJS 1.5.
The HTML:
<div class="row" data-ng-repeat="equipment in task.equipment">
<div class="col-md-12">
<h4 class="green-text">
{{ equipment.equipId }}
<small class="green-text">
<i class="glyphicon"
data-ng-class="{'glyphicon-triangle-bottom': field{{ $index }}, 'glyphicon-triangle-right': !field{{ $index }}}"
data-ng-init="equipment['field' + $index] = true"
data-ng-click="toggleTaskEquip('field{{ $index }}')">
field{{ $index }}: I WANT THIS TO WORK</i>
</small>
</h4>
</div>
<div data-ng-show="field{{ $index }}">
...stuff here...
</div>
</div>
The JS:
$scope.toggleTaskEquip = function(toggleBool)
{
if (toggleBool === true)
$scope.isTaskEquipOpen = false;
else if (toggleBool === false)
$scope.isTaskEquipOpen = true;
};
If I understand the problem correctly, you want to be able to toggle the boolean created in the ng-init with a click.
I think you need this:
<div class="container-fluid">
<div ng-controller="MyCtrl">
<div class="row" data-ng-repeat="equipment in task.equipment">
<div class="col-md-12">
<h4 class="green-text">
{{equipment.equipId}}
<small class="green-text">
<i class="glyphicon"
data-ng-class="{'glyphicon-triangle-bottom': isVisible, 'glyphicon-triangle-right': !isVisible}"
data-ng-init="isVisible = true"
data-ng-click="isVisible = !isVisible">I WANT THIS TO WORK</i>
</small>
</h4>
</div>
<div data-ng-show="isVisible">
...stuff here...
</div>
</div>
</div>
</div>
You don't even need the function toggleTaskEquip on the $scope.
JSFiddle here.
ng-repeat creates a new scope for each template instance, so you can just create a separate isVisible for each equipment with isVisible = true in the ng-init.

show records on same details page by clicking next button in asp.net mvc getting error

I want to display the records on details page when user click on next button then he should be able to display the next record of table. Suppose user select the details of a particular record id 1 he get the details of that id 1 at the same time on the same page by clicking the next button user should be able to get the record of id 2 and vice versa. I have done it but getting some error when table has no such id named id 3 after id 1 and id 2 its showing me the error. Please help me to find out where i am wrong.
View
#model WebApp.ViewModels.ViewTeamList
<script type="text/javascript">
var dataid = '#Html.Raw(Json.Encode(Model.TeamDetails.TeamId))';
for( var item in dataid)
console.log(dataid[item]);}();
</script>
<script type="text/javascript">
$("#btnNext").click(function () {
var $buttonClicked = $(this);
var nid = $buttonClicked.attr('data-id');
console.log(nid);
$.ajax({
url: 'Team/Next',
data: { dataid: nid },
//data: JSON.stringify(data.TeamId),
success: function (response) {
divDetail.html(data);
}
});
});
</script>
<div class="row">
<div class="col-md-11 col-sm-11 pull-left" style=" font-size:large; font-weight:600">
#Model.TeamDetails.TeamName
</div>
#* <div class="col-md-1 col-sm-1 pull-right">*#
<div class="navi-but">
<a href="#" id="btnPrevious" data-id="#Model.TeamDetails.TeamId" class="details">
<span class="previous">Previous</span>
</a>
<a href="#" class="details" data-id="#Model.TeamDetails.TeamId" id="btnNext">
<span style="padding-right:7px">Next</span><span class="next"></span>
</a>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<img src="~/Images/settings.png" />
</a>
<ul class="dropdown-menu" role="menu">
<li>Edit</li>
</ul>
</li>
</div>
#* </div>*#
</div>
<div class="row">
<div class="col-md-4 col-sm-4">
#Html.CustomLabel("lblTeam","CT Team Name:")
</div>
<div class="col-md-8 col-sm-8">
#Model.TeamDetails.TeamName
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4">
#Html.CustomLabel("lblDescription","Description:")
</div>
<div class="col-md-8 col-sm-8">
#Model.TeamDetails.Description
</div>
</div>
<div class="row">
<div class="col-md-4 col-sm-4">
#Html.CustomLabel("lblCTUserCount","User Count")
</div>
<div class="col-md-8 col-sm-8 pull-left">
#Model.TeamDetails.UserCount
</div>
</div>
Controller
public ActionResult Next(int dataid)
{
dataid++;
ViewTeamList viewTeamList = new ViewTeamList();
viewTeamList.ViewTeamDetails(dataid);
return PartialView("_ViewTeamDetails", viewTeamList);
}
View model
public class ViewTeamList
{
public TeamDetails TeamDetails;
private ITeamService teamService;
public ViewTeamList()
{
}
public void ViewTeamDetails(int Id)
{
teamService = new TeamService(pDbContext);
TeamDetails = teamService.GetTeamDetails(Id);
//return (TeamDetails.First());
}
}
Please help where i am doing wrong.
I didn't look your code in detail but it seems to me that you have a logical problem. Since you are always incrementing id by one ( dataid++; ) that won't work if some record is deleted in the meantime. For example let's say that you have Record1 with id 1, Record2 with id 2 and Record 3 with id 3 and you delete Record2. Now when you are trying to get next record after Record1 you are incrementing id by 1 so you have 2 and there is no record with id 2 in the db anymore.
Instead of dataid++; you should find next id that really exists in db. As I said I didn't read code in detail so there may be more possible problems.
To Display from WebMethod You Should follow these steps:
create
[webmethod]
to retrieve all the data
List items then make a javascript method in client side use:
ajax({ type:'post', url:'exaple.aspx/showMethod', data:{}, datatype:'json', contentType:'application/json; charset=utf-8',
scuccess:function(data) --display from here in table or any other
data ), error:function(){ alert('Error'); } })

Categories

Resources