How to reload Flask-based webpage after receiving data - javascript

I have a simple web project which gets data from, processes it and needs to output result on the page. After the spider works, the data is written to sqlite, but not displayed on the page. How to refresh page after writing data in sqlite?
button
<button id="scrape" class="btn btn-success mr-2">Scrape</button>
js
$.post('/wellness', {'specialty': specialty, 'state': state, 'city': city}, (res) => {
});
flask
#app.route('/<page_id>', methods=['GET', 'POST'])
def page(page_id):
file_html = f"{page_id}.html"
file_py = f"{page_id}.py"
file_db = f"{page_id}.db"
specialty = request.form.getlist('specialty[]')
state = request.form.getlist('state[]')
city = request.form.getlist('city[]')
settings = ''
with open('settings.json', 'r') as f:
for line in f.read():
settings += line
settings = json.loads(settings)
settings['specialty'] = specialty
settings['state'] = state
settings['city'] = city
with open('settings.json', 'w') as f:
f.write(json.dumps(settings, indent=4))
process = subprocess.Popen('python e:/Python/sqlite/spiders/' + file_py, shell=True)
process.wait()
try:
db = sqlite3.connect(file_db)
cursor = db.cursor()
cursor.execute('SELECT * FROM wellness ORDER BY id DESC')
cards = cursor.fetchall()
db.close()
return render_template(file_html, cards = cards)
except:
return render_template(file_html)

Write the appropriate append/fill HTML code to the div where you want to show
(res) => {
# Write append or fill here
});
Example
$.ajax({
url: "/update/",
type: "POST",
data: {"data": data},
success: function(resp){
$('div.stats').html(resp.data); # Filling the data in appropriate div
}
});
You would have to do similar thing for your use case.

solution:
$.post('/wellness', {'specialty': specialty, 'state': state, 'city': city}, (res) => {
$(location).attr('href', 'http://127.0.0.1:5000/wellness')
});

Related

Adding a 'show all' to django search with js/ajax if results > 5

I have a simple django search functionality using js/ajax. I want to add functionality so that when the queryset is greater than 5 a 'Show all' href will appear in the search results and it will redirect to a page with all the queryset.
This is for the case when a queryset returns a large number of results, rather than have them in one big box.
I thought I could just add a dictionary to my queryset, e.g. data.append({'pk': <add number to querset>, 'name': 'Show all results'}) but then I think this will mess around with the js logic with the forEach loop.
I'd want each search result up to 5 to link to the detail view, but then the last one should link to a completely different view.
I'm not sure what the best option is here.
My search in views.py:
def search_results(request):
"""
Handles search logic
"""
if request.is_ajax():
res = None
quote = request.POST.get('quote')
qs = Quote.objects.filter(name__icontains=quote)
if len(qs) > 0 and len(quote) > 0:
data = []
for pos in qs:
item = {
'pk': pos.pk,
'name': pos.name,
'image': str(pos.image.url)
}
data.append(item)
res = data
else:
res = 'No quotes found...'
return JsonResponse({'data': res})
return JsonResponse({})
and main.js that handles loading the search results:
const url = window.location.href
const searchForm = document.getElementById('search-form')
const searchInput = document.getElementById('search-input')
const resultsBox = document.getElementById('results-box')
const csrf = document.getElementsByName('csrfmiddlewaretoken')[0].value
const sendSearchData = (quote) => {
$.ajax({
type: 'POST',
url: 'search/',
data: {
'csrfmiddlewaretoken': csrf,
'quote': quote,
},
success: (res)=> {
console.log(res.data)
const data = res.data
let length = data.length
console.log(length)
if (Array.isArray(data)) {
resultsBox.innerHTML = ""
data.forEach(quote=> {
resultsBox.innerHTML += `
<a href="${url}${quote.pk}" class="item">
<div class="row mt-2 mb-2">
<div class="col-2">
<img src="${quote.image}" class="quote-img">
</div>
<div class="col-10">
<h5>${quote.name}</h5>
<p class="text-muted">${quote.seller}</p>
</div>
</div>
</a>
`
})
} else {
if (searchInput.value.length > 0) {
resultsBox.innerHTML = `<b>${data}</b>`
} else {
resultsBox.classList.add('not-visible')
}
}
error: (err)=> {
console.log(err)
}
}
})
}
searchInput.addEventListener('keyup', e=>{
console.log(e.target.value)
if (resultsBox.classList.contains('not-visible')){
resultsBox.classList.remove('not-visible')
}
sendSearchData(e.target.value)
})

How to display the values of the attributes of the data queried and retrieved by Ajax call in django

I am trying to query the database based on what the user has clicked on the page and display the data retrieved by it without refreshing the page. I am using Ajax for this. Let me show you the codes
html
<label for="landacq" class="civil-label">Land Acquisation Cases</label>
<input class="civil-category" type="radio" name="civil-cat" id="landacq" value="land acquisation" hidden>
<label for="sc" class="civil-label">Supreme Court</label>
<input class="civil-court" type="radio" name="civil-court" id="sc" value="supreme court" hidden>
<label for="limitation" class="civil-label">Limitation</label>
<input class="civil-law-type" type="radio" name="civil-law-type" id="limitation" value="limitation" hidden>
js
for (i = 0; i < lawTypeInput.length; i++) {
lawTypeInput[i].addEventListener("click", (e) => {
e.preventDefault();
cat = civilCatval;
court = civilCourtval;
lawT = civillawTypeval;
console.log("this is from ajax : ", cat, court, lawT);
$.ajax({
type: "POST",
headers: { "X-CSRFToken": csrftoken },
mode: "same-origin", // Do not send CSRF token to another domain.
url: "civil",
data: {
"cat[]": civilCatval,
"court[]": civilCourtval,
"lawT[]": civillawTypeval,
},
success: function (query) {
showCivilQ(query);
// console.log(data);
},
error: function (error) {
console.log(error);
},
});
});
}
function showCivilQ(query) {
q.textContent = query;
console.log(query);
}
So here for example, if the user the click the radio button in the html, the values are grabbed by in js file and then sent to the url mentioned as a POST request. There these values are use to filter the database and return the objects like this
views.py
def civil_home(request):
if request.is_ajax():
get_cat = request.POST.get('cat[]')
get_court = request.POST.get('court[]')
get_lawT = request.POST.get('lawT[]')
query = Citation.objects.filter(law_type__contains ='civil' ,sub_law_type__contains= get_cat, court_name__contains = get_court, law_category__contains = get_lawT)
return HttpResponse(query)
else:
subuser = request.user
subscription = UserSubscription.objects.filter(user = subuser, is_active = True)
context = {
'usersub': subscription,
}
return render(request, 'civil/civil_home.html', context)
This is the result I am getting which is correct.
My Question is these objects contain attributes having some values in for eg, title, headnote etc. How can I display these attributes in the html rather than displaying the object names returned as shown in the Image like title of the citation, headnote of the citation etc
A solution could be to return a json object instead of the query resultset; because Ajax works well with json
You need a function that translates a Citation object into a dictionary (change it based on your real attributes). All elements must be translated into strings (see date example)
def citation_as_dict(item):
return {
"attribute1": item.attribute1,
"attribute2": item.attribute2,
"date1": item.date.strftime('%d/%m/%Y')
}
This dictionary must be translated into a json through import json package
def civil_home(request):
if request.is_ajax():
get_cat = request.POST.get('cat[]')
get_court = request.POST.get('court[]')
get_lawT = request.POST.get('lawT[]')
query = Citation.objects.filter(law_type__contains ='civil' ,sub_law_type__contains= get_cat, court_name__contains = get_court, law_category__contains = get_lawT)
response_dict = [citation_as_dict(obj) for obj in query]
response_json = json.dumps({"data": response_dict})
return HttpResponse(response_json, content_type='application/json')
else:
subuser = request.user
subscription = UserSubscription.objects.filter(user = subuser, is_active = True)
context = {
'usersub': subscription,
}
return render(request, 'civil/civil_home.html', context)
In your HTML page you should be able to parse the response as a normal JSON object
I figured out another way to do it, which is giving me the required results too.
Here I am filtering the values of the query, and then converting it to a list and passing it as a JsonResponse
views.py
def civil_home(request):
if request.method == "POST" and request.is_ajax():
get_cat = request.POST.get('cat[]')
get_court = request.POST.get('court[]')
get_lawT = request.POST.get('lawT[]')
query = Citation.objects.values().filter(law_type__contains ='civil' ,sub_law_type__contains= get_cat, court_name__contains = get_court, law_category__contains = get_lawT)
result = list(query)
return JsonResponse({"status": "success", "result": result})
else:
subuser = request.user
subscription = UserSubscription.objects.filter(user = subuser, is_active = True)
context = {
'usersub': subscription,
}
return render(request, 'civil/civil_home.html', context)
And then I am recieving the reponse here and iterrating over it to print the attributes in the html
js
for (i = 0; i < lawTypeInput.length; i++) {
lawTypeInput[i].addEventListener("click", (e) => {
e.preventDefault();
cat = civilCatval;
court = civilCourtval;
lawT = civillawTypeval;
console.log("this is from ajax : ", cat, court, lawT);
$.ajax({
type: "POST",
headers: { "X-CSRFToken": csrftoken },
mode: "same-origin", // Do not send CSRF token to another domain.
url: "civil",
data: {
"cat[]": civilCatval,
"court[]": civilCourtval,
"lawT[]": civillawTypeval,
},
success: function (response) {
console.log(response.result);
civilData = response.result;
if ((response.status = "success")) {
$("#queryResult").empty();
for (i = 0; i < civilData.length; i++) {
$("#queryResult").append(
`
${civilData[i].title}
<p>${civilData[i].headnote}</p>
`
);
}
} else {
$("#queryResult").empty();
$("#queryResult").append(
`
<p>No Citations Found</p>
`
);
}
},
error: function (error) {
console.log(error);
},
});
});
}
A csrf_token can be mentioned at the top of the html page and then it can be passed in the header to avoid any conflict.

Flask + Heroku: H12 Request Timeout Error

I have a Heroku app to run Scrapy Spider. After starting, I get error H12. How to fix it?
JQuery:
$.post('/wellness', {'specialty': specialty, 'state': state, 'city': city}, (res) => {
$(location).attr('href', 'http://127.0.0.1:5000/wellness')
});
flask:
if request.method == 'POST':
specialty = request.form.getlist('specialty[]')
state = request.form.getlist('state[]')
city = request.form.getlist('city[]')
settings = ''
with open(file_json, 'r') as f:
for line in f.read():
settings += line
settings = json.loads(settings)
settings['specialty'] = specialty
settings['state'] = state
settings['city'] = city
with open(file_json, 'w') as f:
f.write(json.dumps(settings, indent=4))
process = subprocess.Popen('python spiders/' + file_py, shell=True)
process.wait()
return render_template(file_html)

Ajax Call Returns HTML page as response instead of rendering page (Rails)

Hey having a issue with the rendering of a .erb file, in my AJAX call I make a call to my create action on rails where I validate and process the form data and sent back the completed order data as render: json which works fine.
I have a conditional that checks to see if parameter exists, it if does then the completed order data is passed back as a response via render: json
It if doesn't exists it will render a receipt page.
The problem is when I render the receipt page, the full HTML receipt page comes back as a response instead of rendering the page. Please Help!
$scope.placeOrder = function() {
var body = composeOrderBody();
var isValid = validateForm(body.order);
if(isValid) {
var orderComplete = '<%= #orderComplete %>';
var baseUrl = '<%= request.base_url %>';
console.log('Passing order object: ', body.order);
$http({
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
url: checkout_url,
data: {
order: body.order,
xhr_request: true
},
}).then((function(_this) {
return function(response) {
if(typeof response.data == 'undefined' || response.data == null || !response.data) {
console.log('Error: missing Order Number from Order Confirmation data.', response.data);
}
console.log('Order Confirmation response data object:' , response.data);
if(orderComplete) {
var redirectUrl = 'http://' + orderComplete
var order_params = `?oid=${response.data.oid}?cart=${response.data.cart}?total=${response.data.total}`
window.location.href = redirectUrl + order_params;
} else {
console.log('Base Url: ', baseUrl);
// window.location.href = `${baseUrl}/receipt`;
}
};
})(this));
} else {
console.log('Form Validation or Stripe Validation Failed');
}
} // end placeOrder
Rails Code
# Redirect to orderComplete URL if it's set
if !#orderComplete.blank?
puts 'orderComplete parameter is not blank'
# Sum up all the line item quantities
qty = #order.line_items.inject(0) {|sum, line_item| sum + line_item.quantity}
# Get all of the coupons (and values) into a string
coupons = #order.applied_coupons.map { |coupon| coupon.coupon }.join(',')
coupon_values = #order.applied_coupons.map { |coupon| '%.2f' % coupon.applied_value.to_f }.join(',')
order_params = {
"oid" => URI::escape(#order.number),
"cart" => URI::escape(#cart),
"total" => URI::escape('%.2f' % #order.total),
}
#redirectUrl = URI.parse(URI.escape(#orderComplete))
#redirectUrl.query = [#redirectUrl.query, order_params.to_query].compact.join('&')
#redirectUrl = #redirectUrl.to_s
if params[:xhr_request]
render json: order_params.to_json
return
end
render 'receipt_redirect', :layout => 'receipt_redirect'
else
puts 'OrderComplete Parameter is blank'
render 'receipt', :layout => 'receipt', :campaign => #campaign
end

Laravel Ajax not updating

I have Laravel project for fire department and I have competitions with results of each team. I made a page where I can edit competition. In result controller
public function update (Request $request){
$item = new Items();
$item->item = $request->item;
$item->data = $request->data;
$item->miejscowosc = $request->miejscowosc;
$item->gmina = $request->gmina;
$item->wojewodztwo = $request->wojewodztwo;
$item->poziom = $request->poziom;
$item->komisja1 = $request->komisja1;
$item->komisja2 = $request->komisja2;
$item->komisja3 = $request->komisja3;
$item->komisja4 = $request->komisja4;
$item->komisja5 = $request->komisja5;
$item->sedzia_glowny = $request->sedzia_glowny;
$item->komisje_powolal = $request->komisje_powolal;
$item->protesty = $request->protesty;
$item->kontuzje = $request->kontuzje;
$item->uwagi = $request->uwagi;
$item->update();
return 'Done';
}
When I change :
$item->update();
To :
$item->save();
It perfectly adds new competition. But when I have
$item->update();
It doesn't update.
Here is my ajax code :
$(document).ready(function() {
$('#updateComp').click(function (event){
$.ajax({
type: 'post',
url: '',
data: {
'_token': $('input[name=_token]').val(),
'item': $("#item").val(),
'data': $('#data').val(),
'miejscowosc': $('#miejscowosc').val(),
'gmina': $('#gmina').val(),
'wojewodztwo': $('#wojewodztwo').val(),
'poziom': $('#poziom :selected').text(),
'komisja1': $('#komisja1').val(),
'komisja2': $('#komisja2').val(),
'komisja3': $('#komisja3').val(),
'komisja4': $('#komisja4').val(),
'komisja5': $('#komisja5').val(),
'sedzia_glowny': $('#sedzia_glowny').val(),
'komisje_powolal': $('#komisje_powolal').val(),
'protesty': $('#protesty').val(),
'kontuzje': $('#kontuzje').val(),
'uwagi': $('#uwagi').val()
},
success: function(data){$('#alert').append('<div class="alert alert-success">Dodano do bazy</div>')},
error: function(){$('#alert').html('<div class="alert alert-danger">Błąd, nie udało się dodać do bazy. Wprowadź dane ponownie</div>')}
});
});
Do I have to change something in ajax code to make it work? Or is it another reason?
(really sorry for other language in project)
For eloquent update, change your code like below code:
Items::find($id)->update(['column' => 'value']);
Here $id is id which you want to update the record. See document
UPDATE
$id = $request->id;//Item id to update...
$arrItem = array(
'item' => $request->item,
'data' => $request->data,
.
.
.
'uwagi' => $request->uwagi,
);
//Update item data...
Items::find($id)->update($arrItem);
you have to send the item id to, so it can point which item need to update
$.ajax({
type: 'post',
url: 'your_url',
data: {
'id':$('#your_id_field'),
'your other field':$('#your_other_field),
.
.
},
success: function(data){$('#alert').append('<div class="alert alert-success">Dodano do bazy</div>')},
error: function(){$('#alert').html('<div class="alert alert-danger">Błąd, nie udało się dodać do bazy. Wprowadź dane ponownie</div>')}
});
//controller, find the data using items model by searching the item's id
public function update (Request $request){
$item = Items::find($request->get('id'));
$item->item = $request->get('item');
.....
.....
....
$item->update();
return 'Done';
}

Categories

Resources