Angular refresh list after post using Django-Rest-Framework - django

I've been looking on the forum how to update a list of items after the post using a server. The available examples show how to update the list but in memory.
This is my current code:
$http.get('job/').
success(function(data, status, headers, config) {
$scope.jobs = data;
}).
error(function(data, status, headers, config) {
console.log('Error', status);
});
$scope.save = function(job) {
$http.post('job/', job)
.success(function(data) {
$scope.jobs.push(data); // here i trying update the list in view
}).
error(function(data, status, headers, config) {
console.log('Error', status);
});
};
// HTML List
<tr ng-repeat="job in jobs">
{% verbatim %}
<td> {{ job.name }}</td>
<td>{{ job.description }}</td>
{% endverbatim %}
<td><a ng-click="edit(job.id)" class="btn btn-small btn-primary">edit</a></td>
<td><a ng-click="delete(job.id)" class="btn btn-small btn-danger">delete</a></td>
</tr>
// HTML form
<div class="span6" ng-controller="JobCtrl">
<h5>Create a New Job</h5>
<form class="form-inline">
<div class="form-group block-level">
<input type="text" class="form-control" name="name" ng-model="job.name" placeholder="Name">
</div>
<div class="form-group">
<input type="text" class="form-control" name="description" ng-model="job.description" placeholder="Description">
</div>
<div class="form-group">
<button class="btn btn-default" ng-click="save(job)">Add Job</button>
</div>
</form>
</div>
Thanks!

Solved using Observer.
myApp.service('JobService', function($http) {
var observerCallbacks = [];
// register the observer's callback in our callback list.
this.registerObserverCallback = function(callback){
observerCallbacks.push(callback);
};
// function to notify our observers and call the callback they registered with
var notifyObservers = function(){
angular.forEach(observerCallbacks, function(callback){
callback();
});
};
this.list = function() {
return $http.get('job/').
success(function(data) {
return data;
});
};
this.add = function(job) {
return $http.post('job/', job).success(function(data, status, headers, config) {
notifyObservers();
});
};
});
myApp.controller('JobCtrl', function ($scope, $http, $location, JobService) {
var getList = function() {
JobService.list().then(function(jobs){
$scope.jobs = jobs.data;
});
};
JobService.registerObserverCallback(getList);
getList();
$scope.save = function(job) {
JobService.add(job).success(function(data) {
$scope.job = '';
console.log('success!');
});
};
});

Here is the working solution (without BE communication). I think your code is fine, because it's working here, but I think you miss table tag around tr and td
http://jsfiddle.net/U3pVM/5031/
<table>
<tr ng-repeat="job in jobs">
<td> {{ job.name }}</td>
<td>{{ job.description }}</td>
<td><a ng-click="edit(job.id)" class="btn btn-small btn-primary">edit</a></td>
<td><a ng-click="delete(job.id)" class="btn btn-small btn-danger">delete</a></td>
</tr>
</table>
You don't have to do any $scope.$apply, because you are already working within angular scope (ng-click and $http backend request are that)

Related

Django template is rendering in Multi-step form, but context data is not visible

I am working on this problem and somehow resolved it to a very great extent and almost everything is done. But the Django is rendering my template but not the Context.
I don't know why I have checked it by debugging and my context is rendering but not showing in frontend.
On this template, there is a form with 4 fieldset , I am submitting data in 1st fieldset and the dynamically show o/p accordingly on the second fieldset.
I am attaching screenshot to show what is rendering in template(2nd fieldset)
edit:
I have debugged this and in code all is working fine but it is not showing up in fornt-end, I dont know why
#views.py
def createQuotePage(request):
if request.method == "POST":
# Getting all the value
# saving in Table
saveInUnitsTable(-------some code, removed to shorten question ------)
saveInCustomerTable(-------some code, removed to shorten question ------)
saveInInquiryTable(-------some code, removed to shorten question ------)
flight_suggestions =Flight.objects.filter(sourceairportid=1,destinationairportid=51)
context = {'flight_suggestions':flight_suggestions,"test":"99999999999999999999999999999999999999"}
return render(request,"Freight/create_quote.html",context=context) # <-- here is the PROBLEM
if request.method == "GET":
print("========================GET=======================")
context = {'airport_data' : list(Airport.objects.all()),
'commodity_data':list(Commodity.objects.all()),
'customerType_data':list(Entity.objects.all()),
}
return render(request,"Freight/create_quote.html",context=context)
#scripts.js
(function($) {
"use strict";
$.backstretch;
$('#top-navbar-1').on('shown.bs.collapse', function(){
$.backstretch("resize");
});
$('#top-navbar-1').on('hidden.bs.collapse', function(){
$.backstretch("resize");
});
$('.f1 fieldset:first').fadeIn('slow');
$('.f1 .btn-next').on('click', function() {
//
var parent_fieldset = $(this).parents('fieldset');
var next_step = true;
var current_active_step = $(this).parents('.f1').find('.f1-step.active');
var progress_line = $(this).parents('.f1').find('.f1-progress-line');
//
var formData1 = $("#total-shipment-form").serialize();
var formData2 = $("#units-form").serialize();
var formData3 = $("#customerDetailForm").serialize();
var formData4 = $("#firstFieldset").serialize();
var formData = formData1 + '&' +
formData2 + '&' +
formData3 + '&' +
formData4
$.post("",formData)
.done(function(){
//
console.log('Success : ');
// var parent_fieldset = $(this).parents('fieldset');
// var next_step = true;
// var current_active_step = $(this).parents('.f1').find('.f1-step.active');
// var progress_line = $(this).parents('.f1').find('.f1-progress-line');
if( next_step ) {
parent_fieldset.fadeOut(400, function() {
current_active_step.removeClass('active').addClass('activated').next().addClass('active');
bar_progress(progress_line, 'right');
$(this).next().fadeIn();
scroll_to_class( $('.f1'), 20 );
});
}
//
})
.fail(function(){
console.log('Error : ');
});
});
Edited:-
Html template
<fieldset id="secondFieldset">
<div class="form-group select_all_style">
<input class="form-check-input" type="checkbox" value=""
id="select_all">
<label for="select_all" class="font-bold lh-26 fs-14">Select All</label>
</div>
{{test}}
<div class="airline_wrapper check_box_wrapper">
{{test}}
{% for flight in flight_suggestions %}
<div class="col_2 text-center dhl_text ">
<div class="aviation_wrapper">
<div class="aviation_checkbox">
<input class="form-check-input" type="checkbox" value=""
id="flexCheckDefault">
</div>
<div class="d-inline pl_10">
<!-- <p>Expiry Date <span><b>6 Sep 2022</b></span></p> -->
<h4 class="fw-400 fs-28">{{flight.flightcompany}}</h4>
<p>Air Freight</p>
</div>
</div>
</div>
<div class="col_6">
<div class="flight_container text-center">
<i class="fa-solid fa-plane plane_style"></i>
<div class="flight_details"></div>
<div class="flight_content">
<div>
<h4>{{flight.sourceairportid.airportname}}</h4>
<p>{{flight.sourceairportid.cityid.cityname}}</p>
</div>
<div>
<h4>{{flight.destinationairportid.airportname}}</h4>
<p>{{flight.destinationairportid.cityid.cityname}}</p>
</div>
</div>
<hr>
<div class="d-flex">
<div class="flight_sub_text text-left">
<label for="">Transit Time</label>
<h5>-- Hrs</h5>
<h5>{{flight.trasittime}} Hrs</h5>
</div>
</div>
</div>
</div>
<div class="col_3">
<h4 class="text-center reference_text">Past Reference</h4>
<div class="buy_text_wrapper">
<p>Buy Rate</p>
<p>Sell Rate</p>
</div>
<div class="buy_text_wrapper">
<p>USD 5,500.00</p>
<p>USD 7,000.00</p>
</div>
<h5 class="probabilty_text text-center pt-4"><span><i
class="fa-solid fa-arrow-trend-up"></i> 70%</span>
Winnning Probabilty</h5>
</div>
{% endfor %}
</div>
<div class="f1-buttons">
<button class="btn btn-primary btn-next" type="button">Request Better
Rates</button>
</div>
</fieldset>

PayPal API PopUp closes immediately after clicking PayPal button (Sandbox)

I am trying to implement the PayPal API into my Django / Vue checkout system, but everytime i try to access checkout via the paypal checkout buttons, thepopup closes immediately and i get these errors:
Error messages in developer tools
Obviously it has something to do with the cart's items' attributes and i tried to adjust them accordingly, but i can't figure out how to fix it. My Code:
<template>
<div class="page-checkout">
<div class="columns is-multiline">
<div class="column is-12">
<h1 class="title">Kasse</h1>
</div>
<div class="column is-12 box">
<table class="table is-fullwidth">
<thead>
<tr>
<th>Artikel</th>
<th>Preis</th>
<th>Anzahl</th>
<th>Gesamt</th>
</tr>
</thead>
<!-- vue for loop for looping through items in cart and displaying them in a table -->
<tbody>
<tr
v-for="item in cart.items"
v-bind:key="item.product.id"
>
<td>{{ item.product.name }}</td>
<td>{{ item.product.price }}€</td>
<td>{{ item.quantity }}</td>
<td>{{ getItemTotal(item).toFixed(2) }}€</td>
</tr>
</tbody>
<tfoot>
<tr style="font-weight: bolder; font-size: larger;">
<td colspan="2">Insgesamt</td>
<td>{{ cartTotalLength }}</td>
<td>{{ cartTotalPrice.toFixed(2) }}€</td>
</tr>
</tfoot>
</table>
</div>
<!-- Fields for user information -->
<div class="column is-12 box">
<h2 class="subtitle">Versanddetails</h2>
<p class="has-text-grey mb-4">*Felder müssen ausgefüllt sein</p>
<div class="columns is-multline">
<div class="column is-6">
<div class="field">
<label>*Vorname</label>
<div class="control">
<input type="text" class="input" v-model="first_name">
</div>
</div>
<div class="field">
<label>*Nachname</label>
<div class="control">
<input type="text" class="input" v-model="last_name">
</div>
</div>
<div class="field">
<label>*E-Mail</label>
<div class="control">
<input type="email" class="input" v-model="email">
</div>
</div>
<div class="field">
<label>*Telefonnummer</label>
<div class="control">
<input type="text" class="input" v-model="phone">
</div>
</div>
<div class="column is-6">
<div class="field">
<label>*Adresse</label>
<div class="control">
<input type="text" class="input" v-model="address">
</div>
</div>
<div class="field">
<label>*Postleitzahl</label>
<div class="control">
<input type="text" class="input" v-model="zipcode">
</div>
</div>
<div class="field">
<label>*Ort</label>
<div class="control">
<input type="text" class="input" v-model="place">
</div>
</div>
</div>
<!-- looping through errors for authorization -->
<div class="notification is-danger mt-4" v-if="errors.length">
<p v-for="error in errors" v-bind:key="error">{{ error }}</p>
</div>
<hr>
<div id="card-element" class="mb-5"></div>
<!-- Part for PayPal implementation -->
<template v-if="cartTotalLength">
<hr>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<!-- Include the PayPal JavaScript SDK -->
<div ref="paypal"></div>
<!-- <button class="button is-dark" #click="submitForm">Weiter mit PayPal</button> -->
</template>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Checkout',
data() {
return {
loaded: false,
paidFor: false,
cart: {
items: []
},
stripe: {},
card: {},
first_name: '',
last_name: '',
email: '',
phone: '',
address: '',
zipcode: '',
place: '',
errors: []
}
},
mounted() {
document.title = 'Kasse | RELOAD'
this.cart = this.$store.state.cart
// Imported PayPal functionality from https://fireship.io/lessons/paypal-checkout-frontend/
const script = document.createElement("script");
script.src = "https://www.paypal.com/sdk/js?client-id=AeAKmRDX7HTesdUvfqYqCQz3fZHIkjAoQ5-BG6K-7xnL5GBMVvwQba53v-I8Fx1p9wurUtoBuk7D6bV1"; // Replace YOUR-CLIENT-ID with paypal credentials
script.addEventListener("load", this.setLoaded);
document.body.appendChild(script); // Adds script to the document's body
},
watch: {
$route(to, from,) {
if (to.name === 'Category') {
this.getCategory()
}
}
},
methods: {
getItemTotal(item) {
return item.quantity * item.product.price
},
// Authorization methods
submitForm() {
this.errors = []
if (this.first_name === '') {
this.errors.push('Bitte Vornamen angeben')
}
if (this.last_name === '') {
this.errors.push('Bitte Nachnamen angeben')
}
if (this.email === '') {
this.errors.push('Bitte E-Mail angeben')
}
if (this.phone === '') {
this.errors.push('Bitte Telefonnummer angeben')
}
if (this.adress === '') {
this.errors.push('Bitte Adresse angeben')
}
if (this.zipcode === '') {
this.errors.push('Bitte Postleitzahl angeben')
}
if (this.place === '') {
this.errors.push('Bitte Ort angeben')
}
},
// Imported PayPal functionality from https://fireship.io/lessons/paypal-checkout-frontend/
setLoaded() {
this.loaded = true;
window.paypal
.Buttons({
// createOrder: (data, actions) => {
// return actions.order.create({
// purchase_units: [
// {
// description: this.product.description,
// amount: {
// currency_code: "EUR",
// value: this.product.price
// }
// }
// ]
createOrder: (data, actions) => {
return actions.order.create({
"purchase_units": [{
"amount": {
"currency_code": "EUR",
"value": item.product.price,
"breakdown": {
"item_total": { /* Required when including the items array */
"currency_code": "EUR",
"value": item.quantity * product.price
}
}
},
"items": [
{
"name": item.product.name, /* Shows within upper-right dropdown during payment approval */
"description": item.product.description, /* Item details will also be in the completed paypal.com transaction view */
"unit_amount": {
"currency_code": "EUR",
"value": item.product.price
},
"quantity": item.product.quantity
},
]
}]
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
this.paidFor = true;
console.log(order);
},
onError: err => {
console.log(err);
}
})
.render(this.$refs.paypal);
}
},
computed: {
// Computing total price and total amount of all items
cartTotalPrice() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.product.price * curVal.quantity
}, 0)
},
cartTotalLength() {
return this.cart.items.reduce((acc, curVal) => {
return acc += curVal.quantity
}, 0)
}
}
}
</script>
The createOrder function inside setLoaded() is assigning properties using item although it's not clear where item comes from as it's not being passed in from anywhere:
setLoaded() {
this.loaded = true;
window.paypal.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
currency_code: "EUR",
value: item.product.price, // <--- item is not defined here
breakdown: {
item_total: {
currency_code: "EUR",
value: item.quantity * product.price, // <--- or here
},
},
},
...
If you mean to reference the items in the cart data property you need to use this.cart.items and possibly loop through it if you're trying to send individual item details.

jQuery change event being fired twice

I have a form with input fields including a date.
Below is my code;
<form action="/test/" method="get" class="form-horizontal">
<!-- truncated codes -->
<label class="col-sm-1 control-label">Date:</label>
<div class="col-sm-2">
<div class="input-group m-b-none">
<span class="input-group-addon btn btn-success btn-sm btn-outline"><i class="fa fa-calendar"></i></span>
<input type="text" name="date" value="{{ $date }}" class="form-control start_date" id="date" autocomplete="off" required>
</div>
</div>
</form>
and it is my jQuery code
$('.start_date').change(function () {
var timestamp = Date.parse($("input[name='date']").val());
if (isNaN(timestamp) == false) {
date = $('.start_date').val();
// call function
} else {
var prev = $(this).data('val');
alert('Invalid Date');
$('#date').val(prev);
}
});
$('#date').datepicker({
todayBtn: "linked",
keyboardNavigation: false,
forceParse: false,
calendarWeeks: true,
autoclose: true,
format: 'yyyy-mm-dd'
});
I don't understand why after each change in date, this function runs twice.
What am I doing wrong and how can I fix it?
I'm using jQuery version 3.1.1 and already tried this.
Also, I don't have .start_date anywhere else in the page.
You might have '.start_date' somewhere else in the page as well.
I suggest you use off()
$('.start_date').off().change(function (){
var timestamp = Date.parse($("input[name='date']").val());
if (isNaN(timestamp) == false) {
date = $('.start_date').val();
/*call function*/
}
else{
var prev = $(this).data('val');
alert('Invalid Date');
$('#date').val(prev);
}
});
Problem is my bootstrap datepicker change event fire two times. The trick is to use changeDate instead of change.
$('.start_date').on("changeDate", function() {
});

iOnic list not refreshing after adding a new item to the list using web service

We have a iOnic based project and during check out users can add new address to their account.
This is what my controller file look like
$scope.addAddress = function() {
$scope.showLoading();
addressService.addUserAddress($scope.userDetails.userID, $scope.addAddressdata.houseNo, $scope.addAddressdata.street, $scope.addAddressdata.AddDesc, $scope.addAddressdata.LID)
.success(function(response) {
console.log(response);
$scope.hideLoading();
$scope.closeModal();
$scope.getAllAddress();
});
};
$scope.getAllAddress = function() {
addressService.getAllLocations()
.success(function(response) {
$scope.locations = response;
$scope.hideLoading();
});
};
And this is what my services file look like
function() {
"use strict";
var myApp = angular.module('jobolo');
myApp.service('addressService', ['$http', 'appVariableService', function($http, appVariableService) {
var addressService = this;
addressService.getAllLocations = function() {
var data = {
appid: appVariableService.get('appId')
};
return $http.post(appVariableService.get('baseURL') + 'useraddress/getMyLocation', data);
};
addressService.getUserAddress = function(userId) {
return $http.get(appVariableService.get('baseURL') + 'useraddress/myaddress/' + userId, {cache:false});
};
addressService.addUserAddress = function(userId, houseNo, street, adddesc, lid) {
var data = {
appid: appVariableService.get('appId'),
userid: userId,
houseno: houseNo,
street: street,
adddesc: adddesc,
lid: lid,
};
return $http.post(appVariableService.get('baseURL') + 'useraddress/adAdd' , data);
};
}]);
})();
When I add a new address it does add to the database but isn't showing in list. I tried adding $scope.refreshList(); to the code too. When I log out and come back it does show up. Thank you for your help in advance
View Codes are
<ion-view class="main-content">
<ion-nav-buttons side="secondary">
<button menu-toggle="right" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<div class="bar bar-subheader">
<h2 class="title">Select Address</h2>
</div>
<ion-content class="has-subheader" scroll="true" overflow-scroll="true" style="bottom:57px">
<div class="list">
<ion-radio
ng-model="data.selectedAddress"
ng-value="address"
ng-repeat="address in userAddresses"
class="radio-nowrap"
>
House No. {{address.HouseNo}}, {{address.Street}}, {{address.AddDesc}}, {{address.AreaName}}, {{address.City}}
</ion-radio>
</div>
<!-- <div class="row">
<div class="col location-form">
<button class="button" type="button" ng-click="openModal()">Add New Address</button>
</div>
</div> -->
</ion-content>
<div class="row" style="position: absolute;bottom: 0;padding:0">
<div class="col location-form">
<button class="button" type="button" ng-click="openModal()">Add New Address</button>
</div>
<div class="col location-form">
<button class="button" type="button" ng-disabled="!data.selectedAddress" ng-click="selectAddress(data.selectedAddress)">Select Address</button>
</div>
</div>

Knockoutjs list in a list select binding

I have seen so many example of this problem but not as a list. Here's my code:
<div>
<form>
<p>You have asked for <span data-bind='text: gifts().length'> </span> gift(s)</p>
<input id='giftname' type='text'/><button data-bind='click: createGift'>Add Gift</button>
<table>
<thead>
<tr>
<th>Gift name</th>
<th>Pack</th>
<th>Price</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: gifts'>
<tr>
<td><input data-bind='value: name' readonly='readonly'/></td>
<td><select data-bind="options: packs,
optionsText: 'pack',
value: price" /></td>
<td><input data-bind="value: price ? price.packprice : 'unknown'" readonly="readonly"/></td>
<td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td>
</tr>
</tbody>
</table>
<button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>
</form>
</div>
<script type="text/javascript">
var GiftModel = function(gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);
self.addGift = function(gift) {
var newGift = {
name: gift.name,
packs: gift.packs,
price: gift.price
};
self.gifts.push(newGift);
};
self.removeGift = function(gift) {
self.gifts.remove(gift);
};
self.createGift = function() {
var gname = $('#giftname').val();
//should be getting gift options from webservice
var newGift = {name: gname,
packs: [{pack:'Each', packprice: '2'}, {pack:'Dozen', packprice: '12'}], price: {pack:'', packprice: ''}};
self.addGift(newGift);
$('#giftname').val('');
};
};
var viewModel = new GiftModel([]);
ko.applyBindings(viewModel);
</script>
When I add gifts, it creates options of packs. Each pack has a certain price. My problem is just simple. How will I show the price on the next column for the selected pack of the gift line? Sorry im just new to knockoutjs. Thanks!
System will automatically update price after selecting package if you make it observable. I made a little refactoring to you code, now it works:
<div>
<form>
<p>You have asked for <span data-bind='text: gifts().length'> </span> gift(s)</p>
<input
id='giftname' type='text' data-bind='value: giftName' />
<button data-bind='click: createGift'>Add Gift</button>
<table>
<thead>
<tr>
<th>Gift name</th>
<th>Pack</th>
<th>Price</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: gifts'>
<tr>
<td>
<input data-bind='value: name' readonly='readonly' />
</td>
<td>
<select data-bind="options: packs,
optionsText: 'pack',
optionsValue: 'packprice',
value: price" />
</td>
<td>
<input data-bind="value: price() || 'unknown'" readonly="readonly"
/>
</td>
<td><a href='#' data-bind='click: $root.removeGift'>Delete</a>
</td>
</tr>
</tbody>
</table>
<button data-bind='enable: gifts().length > 0' type='submit'>Submit</button>
</form>
</div>
function GiftModel(name) {
var self = this;
self.name = ko.observable(name);
self.price = ko.observable();
self.packs = ko.observable([{
pack: 'Each',
packprice: '2'
}, {
pack: 'Dozen',
packprice: '12'
}]);
}
var ViewModel = function (gifts) {
var self = this;
self.gifts = ko.observableArray(gifts);
self.giftName = ko.observable();
self.removeGift = function (gift) {
self.gifts.remove(gift);
};
self.createGift = function () {
self.gifts.push(new GiftModel(self.giftName()));
};
};
var viewModel = new ViewModel([]);
ko.applyBindings(viewModel);
Here is working fiddle: http://jsfiddle.net/vyshniakov/pzJaH/
P.S. Don't use jQuery to get field value if you using knockout. It is much easier to do this with knockout.