Ajax post request don't work with flask route - ajax

I'm trying to build a 'like' button with ajax and flask,but when I try to get the string for the button to decide which button was clicked,my alert always return 'None'.
flask relevant part:
#bp.route('/<int:id>/post', methods=('GET', 'POST'))
#login_required
def show_post(id):
my_opinion=request.form.get("opinion")
my_post=get_post(id,False)
if request.method == 'POST':
opi = request.form.get("opinion")
if opi == 'Like':
update_like(id,my_post,g.user['id'])
my_opinion='like'
elif opi == 'Dislike':
update_dislike(id,my_post,g.user['id'])
my_opinion='dislike'
user_info=g.user['id']
user_new = get_db().execute(
'SELECT liked_posts,disliked_posts'
' FROM user u'
' WHERE id = ?',
(user_info,)
).fetchone()
return render_template('blog/show.html',post=my_post,user=user_new,my=my_opinion)
ajax part:
<script src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
crossorigin="anonymous"></script>
<script type="text/javascript">
$(document).on('submit','.opin',function(e)
{
e.preventDefault();
$.ajax({
type:'POST',
url:'/1/post?author=josh',
data:{
opinion:"check"
},
success:function()
{
const new_opinion = document.getElementsByClassName("opinion");
let special = "{{my}}";
alert(special);
const cssObj = window.getComputedStyle(new_opinion[0], null);
let bgColor = cssObj.getPropertyValue("background-color");
if (bgColor=='rgb(128, 128, 128)'){
bgColor="linear-gradient(144deg,#AF40FF, #5B42F3 50%,#00DDEB)";
}
else{
bgColor="gray"
}
new_opinion[0].style.background=bgColor;
}
})
});
</script>
This part alert 'None':
let special = "{{my}}";
alert(special);
I'm trying to get 'check' string into 'my' template parameter.

Related

Problem not displaying success message for each registration with Ajax

I want to do this after the user registers, shows a successful message and the text boxes are empty again and ready for the next registration, but the registration success message is only displayed for the first registration, but I want to Display each registration
public IActionResult submitSingelControlItem(int Projectid,String calender, String ProjectName,String ProjectManagementName, String ajaxControlItem,String ajaxFraindName,int SingelControlState)
{
Hesabrsee hesabrsee = new Hesabrsee();
hesabrsee.ControlDate = ConvertDateTime.ConvertShamsiToMiladi(calender);
hesabrsee.SabtDate = DateTime.Now;
hesabrsee.Projectid = Projectid;
hesabrsee.ProjectName = ProjectName;
hesabrsee.ProjectManagementName = ProjectManagementName;
hesabrsee.FaraindName = ajaxFraindName;
hesabrsee.Deiscreption = ajaxControlItem;
hesabrsee.ControlState = SingelControlState;
_context.Add(hesabrsee);
_context.SaveChanges();
return Json(new { status = "ok" });
}
<script>
$("#btn").on('click', function () {
var ajaxFraindName = $("#ajaxFraindName").val();
var ajaxControlItem = $("#ajaxControlItem").val();
var calender = $("#calender").val();
var SingelControlState = $("#SingelControlState").val();
if (ajaxFraindName == '' || ajaxControlItem == '' || calender == '' || SingelControlState == '') {
alert("لطفا ورودی ها را پر کنید");
}
else {
$.ajax({
type: "Post",
url: '#Url.Action("submitSingelControlItem", "Hasabrsee")',
data: {
'ajaxControlItem': $("#ajaxControlItem").val(),
'ajaxFraindName': $("#ajaxFraindName").val(),
'Projectid': $("#Projectid").val(),
'ProjectName': $("#ProjectName").val(),
'ProjectManagementName': $("#ProjectManagementName").val(),
'calender': $("#calender").val(),
'SingelControlState': $("#SingelControlState").val(),
}
}).done(function (res) {
if (res.status == 'ok') {
$("#ohsnap").removeClass('d-none').removeClass('alert-danger').addClass('alert-success').html('مورد کنترلی با موفقیت ثبت شد');
$("#ajaxControlItem").val("");
$("#ajaxFraindName").val("");
}
setTimeout(function () {
$('#ohsnap').fadeOut('fast');
}, 2000)
});
}
});
</script>
<div id="ohsnap" class="col-md-4 col-xs-12 alert d-none" style="text-align:center;"></div>
Of course, it displays the message only once because you are removing the class from the $("#ohsnap") div and then you are not restoring it.
Try using Toastr to display the popup alert. It is easier to do.
From the Toastr documentation:
Download the CSS and JS files and add them to your project.
Reference the css <link href="toastr.css" rel="stylesheet"/>
Reference the script <script src="toastr.js"></script>
in your .done() function call toastr;
.done(function (res) {
if (res.status == 'ok') {
toastr.success('title-here', 'مورد کنترلی با موفقیت ثبت شد', {
timeOut: 2000,
closeButton: true,
});
$("#ajaxControlItem").val("");
$("#ajaxFraindName").val("");
});

Using Select2 autocomplete with Django project does not work while fetching the data

In my Django project, I have a Search field. I used Select2 autocomplete with it. I needed to fetch the product_list from my Product model. So I created a rest API that returns the product in json formats.
Here is my rest API code:
serializer.py:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = ProductList
fields = ('product_id', 'product_name', 'product_image', 'product_available',
'product_description')
views.py:
class JSONResponse(HttpResponse):
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
def list(request):
if request.method == 'GET':
products = ProductList.objects.filter(product_name__icontains=request.GET.get('q'))
serializer = ProductSerializer(products, many=True)
serializer_data = serializer.data
customData = {'results': serializer_data}
return JSONResponse(customData)
Now in my html, in the javascript portion I used this code mentioned in this Select2 doc. The code I used, looks like this:
base.html:
<script type="text/javascript">
$(document).ready(function() {
$('.js-data-example-ajax').select2({
ajax: {
url: "/api.alif-marine.com/search/products",
dataType: 'json',
delay: 250,
type: 'GET',
data: function (params) {
return{
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data.results,
};
},
cache: true
},
placeholder: 'Search for a product',
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
function formatRepo (repo) {
if (repo.loading) {
return repo.text;
}
var markup = "<div class='select2-result-repository clearfix'>" +
{# "<div class='select2-result-repository__avatar'><img src='" + repo.owner.avatar_url + "' /></div>" +#}
"<div class='select2-result-repository__meta'>" +
"<div class='select2-result-repository__title'>" + repo.product_name + "</div>";
if (repo.product_description) {
markup += "<div class='select2-result-repository__description'>" + repo.product_description + "</div>";
}
return markup;
}
function formatRepoSelection (repo) {
return repo.product_name || repo.text;
}
});
</script>
When I used Postman to check if the rest API works or not, it worked perfectly. For my query in the Postman like these:
localhost:8000/api.alif-marine.com/search/products?q=t
or
localhost:8000/api.alif-marine.com/search/products?q=tho
or
localhost:8000/api.alif-marine.com/search/products?q=thomas
The retrieved json data is given below for query localhost:8000/api.alif-marine.com/search/products?q=t :
{
"results":[
{
"product_id":9,
"product_name":"thomas",
"product_image":"/media/media/tom_dushtu.jpg",
"product_available":"available",
"product_description":"jah dushtu"
},
{
"product_id":8,
"product_name":"ami dissapointed",
"product_image":"/media/media/dissapointment.jpg",
"product_available":"available",
"product_description":"I ma kinda dissapointed, you know.................."
}
]
}
Now with all those, I couldn't make it work. The autocomplete is not working. Nothing is shown when I press one key or write the name of the whole product.
. It always has shown Searching.... I tried reading the issues on the Github repo and some other things but couldn't solve it.
What am I doing wrong?
This is how the select2 library is handled:
views.py:
class BurdenTypeAutocomplete(autocomplete.Select2QuerySetView):
def get_result_label(self, obj):
return format_html(" {} / {}", obj.arabic_name,obj.englsh_name)
def get_queryset(self):
qs = BurdenTypeSales.objects.filter(effect_type="2")
if self.q:
qs = qs.filter(
Q(arabic_name__icontains=self.q)
| Q(account__number__icontains=self.q)
| Q(englsh_name__icontains=self.q)
)
return qs[:10]
Url.py:
url(r'^burden_type_autocomplete/$',views.BurdenTypeAutocomplete.as_view(),name='burden_type_autocomplete'),
form.py:
burden_type_sales = forms.ModelChoiceField(queryset=BurdenTypeSales.objects.filter(effect_type='2'),
widget=autocomplete.ModelSelect2(url='burden_type_autocomplete',attrs={'required':'required'}))

Django GET request in AJAX

I need to get some HTML using AJAX.
My view work fine as long as I use jQuery:
view.py
def my_ajax(request):
if request.is_ajax():
my_form = MyForm()
context = {
'form': my_form
}
return render(request, 'myapp/form.html', context)
main.js (jQuery load)
$(document).ready(function() {
$('#foo').click(function() {
$('#bar').load('{% url "myapp:form" %}');
});
});
If I use the JavaScript XMLHttpRequest I have to remove if request.is_ajax(): from the view otherwise I got the error The view myapp.views.my_ajax didn't return an HttpResponse object. It returned None instead.
main.js (XMLHttpRequest)
(function() {
document.getElementById('foo').addEventListener("click", function() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("bar").innerHTML = xhttp.responseText;
}
};
xhttp.open("GET", '{% url "myapp:form" %}', true);
xhttp.send();
}, false);
})();
What I'm doing wrong in the XMLHttpRequest?
I am surely missing something but I would like to use Vanilla JavaScript this time.
Thanks!
Try to add xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); after var xhttp = new XMLHttpRequest();.

Django AJAX form, no POST data in view

I have some contact form and JS/Angular code sending it to view for some validation and mailing.
contact_form.js
(function() {
var app = angular.module('contactForm', []);
app.config(function ($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});
app.controller('contactFormController', ['$http', '$scope', function($http, $scope){
$scope.contact_form = {};
this.send = function(form){
if (form.$valid){
$http.post('/contact_form_submit/', {'form': $scope.contact_form}).
success(function(data, status, headers, config) {
if (data.status == 1) {
$scope.msg = 'Twoja wiadomość została wysłana.';
$scope.contact_form = {};
$scope.contactForm.$setPristine();
}
else if (data.status == 'delay')
$scope.msg = 'Odczekaj.';
}).
error(function(data, status, headers, config) {
$scope.msg = 'Wystąpił błąd.';
if (status == '403')
$scope.msg += ' Włącz cookie!';
});
}
else
this.msg = 'invalid!';
};
}]);
})();
view.py
def contact_form_submit(request):
return return_json(request)
if not request.is_ajax() or (request.method != 'POST'):
raise SuspiciousOperation
response_data = {}
# dealing with existing (or not) delay entry
try:
if request.session['mailer_delay'] > str(timezone.now()):
response_data['status'] = 'delay'
return return_json(response_data)
except KeyError:
pass
# validation
form_data = {}
for field in ['name', 'email', 'phone', 'subject', 'text']:
form_data[field] = request.POST.items()
# mailing
mailer = send_mail('Subject here', 'Here is the message.', 'from#example.com',
['to#example.com'], fail_silently=False)
request.session['mailer_delay'] = str(timezone.now()+timedelta(seconds=60))
response_data['status'] = mailer
return return_json(response_data)
and the return_json()
def return_json(data):
from django.http import HttpResponse
import json
return HttpResponse(json.dumps(data), content_type="application/json")
The problem is i get no items at all in request.POST in view. Firebugs tells me that data was sent correctly, but there's no in view.
Someone knows the answer what's wrong?
Ok, i got it. All data was in request.body, not request.POST.
Could anyone explain why? I've read the docs, but still it's not clear for me.

checking if the success data is empty in ajax method of jquery

I have two select boxes in my form.when a user select an option of first select box the options of second select box will be shown by jquery ajax.My problem is that some options of first select box has no record in database and when they selected the second select box should not be shown.I need to check if the data is empty .I treid this code but nothing happens
view:
<script type='text/javascript'>
$(document).ready(function(){
$('#subsec').hide();
$('section').change(){
var sec_id=$(this).val();
var url='article_controler/get_options/'+sec_id;
$.ajax({
url:url,
type:'post',
success:function(resp){
if(!resp)
$('#subsec').hide();
else
$('#subsec').show();
$('$subsec').html(resp)
})
}
});
</script>
you can try this
$.ajax({
url:url,
type:'post',
success:function(resp){
if(resp == "" || resp == null){
$('#subsec').hide();
}
else {
$('#subsec').show();
$('#subsec').html(resp);
}
})
}
});
I have added inline comments to help you out
class Article_Controller extends CI_Controller
{
public function get_options()
{
$option = $this->input->post('option'); // validate this
//Get a list of Sub options from your model
$model = ''; //your own implementation here
//If no model data returned, send a 404 status header
//and bail
if(!$model){
return $this->output->set_status_header(404);
}
$responce = array(
'suboptions' => $model // array of suboptions the model returned
);
// Ideally Abstract all the Ajax stuff to
// its own controller to keep things Dry
return $this->output
->set_status_header(200)
->set_content_type('application/json')
->set_output(json_encode($responce));
}
}
-
//Global URL variable or put it in <base href>
var URL = "<?php echo site_url();?>";
(function($){
var myForm = {
init : function(){
//initialize myForm object properties here
this.Form = $("form#myFormID");
this.selectChange = this.Form.find("select#mySelectBoxI");
this.newSelect = this.Form.find("select#secondaryselectboxId");
//hide second select with CSS by default
//Bind the Change event to our object(myForm) method
this.selectChange.on('change', $.proxy(this.ChangedEvent, this));
},
ChangedEvent : function(event){ // gets the change event
//Grab the currentTarget(option[i]) value from the event received
//You may also need to pass the CSRF Token
this.buildAjaxRequest({'option' : event.currentTarget.value});
},
buildAjaxRequest : function( data ){
var config = {
cache : false,
url : URL + 'article_controller/get_options',
method : 'POST',
data : data, //'option' : event.currentTarget.value
dataType : 'json'
};
this.makeAjaxRequest(config).then(
$.proxy(this.ResponceHandler, this),
$.proxy(this.ErrorHandler, this)
);
},
makeAjaxRequest : function( config ){
return $.ajax( config ).promise();
},
ResponceHandler : function( data ){
$.each(data.suboptions, function(i, v){
this.newSelect.append('<option value="'.data[i].'">'.data[v].'</option>');');
});
this.newSelect.show();
},
ErrorHandler : function(xhr, statusText, exception){
switch(xhr.status)
{
case 404: //remember the 404 from the controller
alert(xhr.statusText); //handle your own way here
break;
}
},
}
myForm.init();
}(jQuery));
Hi pls try this,
<script type='text/javascript'>
$(document).ready(function(){
$('#subsec').hide();
$('#firstSelectBoxId').change("selectboxMethod");
});
function selectboxMethod(){
var sec_id=$("#firstSelectBoxId").val();
alert("Selected from first select"+sec_id);
if(sec_id != null){
var url='article_controler/get_options/'+sec_id;
$.ajax({
url:url,
type:'post',
success:function(resp){
$('#subsec').show();
$('#subsec').html(resp);
}
});
}else{
$("#subsec").hide();
}
}
</script>

Resources