knockout form to django-rest-framework - django

I am trying to implement a knockoutjs form to my django site. Im new to knockout so followed an example but for some reason when I submit the page refreshes with no errors but nothing gets committed to the api.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<form data-bind="submit: mySubmit">
<input data-bind="value: firstname" />
<input data-bind="value: lastname" />
<button type="submit">Go</button>
</form>
<script type="text/javascript">
var viewModel = {
mySubmit : function(formElement) {
var formData = {
'firstname' : $('#firstname').val(),
'lastname' : $('#lastname').val()
};
$.ajax({
url: "127.0.0.1:8000/api/test",
type: "POST",
data: formData,
datatype: "json",
processData:false,
contentType: "application/json; charset=utf-8",
success: function (result){
alert(result);
}
});
}
};
ko.applyBindings(viewModel);
</script>

you haven't declared observable's in viewModel . so consider declaring to make things go smooth .
viewModel:
var viewModel = {
firstname:ko.observable(),lastname:ko.observable(),
mySubmit : function(formElement) {
var formData = {
'firstname' : viewModel.firstname() ,
'lastname' : viewModel.lastname()
};
$.ajax({
url: '/echo/json/', //mocking ajax request
type: "POST",
data: formData,
contentType: "application/json; charset=utf-8",
success: function (result){
alert("success");
}
});
}
};
ko.applyBindings(viewModel);
Working sample here

Related

Django/Ajax sending 'none' value to view

When i send data from ajax to view in Django I am getting none in data. What seems to be the problem. Here is mycode. Where as if i remove processData: false, contentType: false, then data is printed successfully but on file it gives error.
Ajax code
<script>
function submit_data()
{
var type = $('#type').val();
var subtype = $('#subtype').val();
var name = $('#name').val();
var price = $('#price').val();
var weight = $('#weight').val();
var details = $('#details').val();
var picture1 = $('#image1')[0].files[0];
var picture2 = $('#image2')[0].files[0];
var picture3 = $('#image3')[0].files[0];
var vedio_url = $('#vedio_link').val();
alert(picture1)
$.ajax({
url: '/add_record/',
type: 'POST',
headers: { "X-CSRFToken": '{{csrf_token}}' },
processData: false,
contentType: false,
data: {
type,
subtype,
name,
price,
weight,
details,
picture1,
picture2,
picture3,
vedio_url,
},
success: function (response) {
alert("datauploaded successfully!")
},
error: function(){
alert('error')
}
});
}
</script>
View code
def add_record(request):
print("Yes i am here")
type = request.POST.get('type')
subtype = request.POST.get('subtype')
name = request.POST.get('name')
price = request.POST.get('price')
weight = request.POST.get('weight')
details = request.POST.get('details')
picture1 = request.FILES.get('picture1')
picture2 = request.FILES.get('picture2')
picture3 = request.FILES.get('picture3')
vedi_url = request.POST.get('vedio_url')
print (picture1)
print(type)
print(request.POST)
return JsonResponse({'message':'success'},status=200)
Error:
Yes i am here
None
None
<QueryDict: {}>
its returning none, Why is that?
Ajax without files:
Your JS data element should be a dictionary, also remove processData and contentType parameters.
<!doctype html>
<html lang="en">
<head>
</head>
<body>
<input type="text" id="name"/>
<button type="button" id="send" onclick="submit_data()">Send<button/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js" integrity="sha512-n/4gHW3atM3QqRcbCn6ewmpxcLAHGaDjpEBu4xZd47N0W2oQ+6q7oc3PXstrJYXcbNU1OHdQ1T7pAP+gi5Yu8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
function submit_data()
{
var name = $('#name').val();
$.ajax({
url: '/add_record/',
type: 'POST',
headers: { "X-CSRFToken": '{{csrf_token}}' },
data: {
'name': name,
},
success: function (response) {
alert(response.data)
},
error: function(){
alert('error')
}
});
}
</script>
</body>
</html>
views:
from django.shortcuts import render
from django.http import JsonResponse
def form_record(request):
return render(request, "mytemplate.html", {})
def add_record(request):
print("Yes i am here")
name = request.POST.get('name')
print(f"Post: {request.POST}")
return JsonResponse({'data': name},status=200)
Ajax with files:
Because you are sending binary data you should to use FormData:
function submit_data()
{
var name = $('#name').val();
var formData = new FormData() // changes here
formData.append('name', name) // and here
$.ajax({
url: '/add_record/',
type: 'POST',
headers: { "X-CSRFToken": '{{csrf_token}}' },
contentType: false, // and here
enctype: 'multipart/form-data', // and here
processData: false, // and here
cache: false,
data: formData, // <-- carefully here
success: function (response) {
alert(response.data)
},
error: function(){
alert('error')
}
});
}
Result:
you can do with a lot of entries please because I have a more complex problem.
in my case I have 6 entries when I enter an entry I have an output in the form of a table and at the end I have to make a final request which will take into account the rows that I have selected.
Excuse my English.
my js :
function submit_data(){
list_fournisseurs = selectcheck();
list_entrepot = selectcheck1();
var numdoc = $('#numdoc').val();
var reference = $('#reference').val();
var reference_doc = $('#reference_doc').val();
var date_debut = $('#date_debut').val();
var date_fin = $('#date_fin').val();
var format_fournisseur = new FormData();
var format_entrepot = new FormData();
var format_numdoc = new FormData();
var format_reference = new FormData();
var format_reference_doc = new FormData();
var format_date_debut = new FormData();
var format_date_fin = new FormData();
const format = [
format_fournisseur.append('list_fournisseurs', list_fournisseurs),
format_entrepot.append('list_entrepot', list_entrepot),
format_numdoc .append('numdoc', numdoc),
format_reference.append('reference', reference),
format_reference_doc.append('reference_doc', reference_doc),
format_date_debut.append('date_debut', date_debut),
format_date_fin.append('date_fin', date_fin),
]
$.ajax({
type : 'POST',
url : 'fournisseur_ajax',
data : {
'csrfmiddlewaretoken': csrf,
'format' : format,
},
//processData: false,
success : (res) =>{
console.log('res.data',res.data)
},
error : (err) =>{
console.log(err)
},
})
}
my view
if request.method == "POST" :
check_list_fournisseurs = request.POST.getlist("format_fournisseur[]")
print("########## voici la liste ###########",check_list_fournisseurs)
check_list_entrepot = request.POST.getlist("format_entrepot[]")
print("########## voici la liste ###########",check_list_entrepot)
print("numdoc ",num_doc)
print("item_ref",item_ref)
print("item_doc",item_doc)
print("date_depart", date_debut)
print("date_fin",date_fin)
context ={'check_list_entrepot':check_list_entrepot,"check_list_fournisseurs":check_list_fournisseurs, 'num_doc':num_doc, 'item_ref':item_ref, 'item_doc':item_doc, 'date_debut':date_debut, 'date_fin':date_fin}
return render(request,"final.html",context)

Django AJAX: Access data from Dynamic multiple forms

Each form's input is associated with a unique data-comment-pk. I'm trying to access the value of data-comment-pk of the input which is submitted. Currently, the AJAX success function's alert(comment_pk) is only fetching me the comment_pk of the first form. How can I access the comment_pk of the form which is submitted instead of getting the comment_pk of the first form?
html template
{% for comment in object_list %}
<h3>{{comment.comment}} by {{comment.username}}</h3>
<form class="score-form">
<input type="submit" value="Up" name="up" class="Up" data-comment-pk="{{comment.pk}}" />
<input type="submit" value="Down" name="down" />
</form>
{% endfor %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script>
$(".score-form").submit(function (e) {
e.preventDefault();
var comment_pk = $(".Up").attr("data-comment-pk");
var url = comment_pk + "/vote";
console.log(url)
$.ajax({
type: 'GET',
url: url,
data: { "up": 'UP' },
success: function (response) {
if (response["valid"]) {
alert(comment_pk);
}
},
error: function (response) {
console.log(response)
}
})
})
</script>
models.py
class CommentModel(VoteModel, models.Model):
comment = models.TextField()
username = models.ForeignKey(User, on_delete=models.CASCADE)
views.py
class CommentView(ListView):
model = CommentModel
def comment_vote(request, comment_id):
if request.is_ajax and request.method == "GET":
# do some stuff
return JsonResponse({"valid": True}, status=200)
Here is the solution to this problem :
var comment_pk = $(".Up", this ).attr("data-comment-pk");
Using this will return the current HTML element.
try: add "this" to before .Up in the comment_pk.
let me know if it works.
this- will get the currect form that have been submit and get the .Up Class
<script>
$(".score-form").submit(function (e) {
e.preventDefault();
var comment_pk = $("this .Up").attr("data-comment-pk");
var url = comment_pk + "/vote";
console.log(url)
$.ajax({
type: 'GET',
url: url,
data: { "up": 'UP' },
success: function (response) {
if (response["valid"]) {
alert(comment_pk);
}
},
error: function (response) {
console.log(response)
}
})
})
</script>

Getting list of Sharepoint Site Collections - OnPrem 2016. Console.log is empty

I'm tyring to get a list of all the site collections that users have permissions to access. My plan is to display these on the home page, to make it easy for them to navigate to each of their sites. I've tried the following code, but nothing form my API call is writing the the console. It's just blank. What am I missing with writing to the console? Is the name siteURL wrong?
'''
$.ajax({
url: "/_api/search/query?querytext='contentclass:sts_site'",
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
var results = data.d.results;
var itemhtml = "";
$.each(results, function (index, dataRec) {
console.log(siteUrl);
});
},
error: function (data) {
(data);
}
})
'''
Here is a code snippet to get all site collection and print using Console.log:
<script src="https://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$( document ).ready(function() {
//print sites info
searchSites(_spPageContextInfo.webAbsoluteUrl,
function(query){
var resultsCount = query.PrimaryQueryResult.RelevantResults.RowCount;
for(var i = 0; i < resultsCount;i++) {
var row = query.PrimaryQueryResult.RelevantResults.Table.Rows.results[i];
var siteUrl = row.Cells.results[6].Value;
console.log(JSON.stringify(siteUrl));
}
},
function(error){
console.log(JSON.stringify(error));
}
);
});
function searchSites(webUrl,success, failure) {
var url = webUrl + "/_api/search/query?querytext='contentclass:sts_site'";
$.ajax({
url: url,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data) {
success(data.d.query);
},
error: function (data) {
failure(data);
}
});
}
</script>
Reference:
What is the REST endpoint URL to get list of site collections?

Not working json data in Template with vue js

I can not pass the json data in the template correctly. I try in any way I can not find. If you want everything in a snippet I can put it. Thank you in advance.
My HTML:
<div id="app">
<cols :pops="pops"></cols>
</div>
My App:
var main = new Vue({
el: '#app',
data:{
pops: [],
},
mounted: function () {
var self = this;
$.ajax({
url: '../assets/data/pop.json',
method: 'GET',
success: function (data) {
self.pops = data;
},
error: function (error) {
console.log(error);
}
});
},
In same file (app)
Vue.component('cols', {
template:
`<li v-for="pop in pops"> <b>{{ pop.Commune }}</b><span>{{ pop.Population }}</span><div :style="{width: ( pop.Population/520504 * 100) + '%'}"></div></li>`,
});
ERROR
Property or method "pops" is not defined on the instance but referenced during render.
The "data" option should be a function that returns a per-instance value in component definitions.
You're not actually passing the data properties to the component (and the others).
In your HTML try to do this:
<div id="app">
<headermain></headermain>
<search></search>
<cols :pops="pops"></cols>
</div>
Injecting the data.pops in the pops property of the cols component.

Access the element that fired an action

I have two buttons in the application template that fire different actions in my controller. I want to set up ladda.js to add a spinner to the buttons while the ajax function in the corresponding action is waiting to resolve. But to start ladda I have to do something like this...
$('#form-submit').click(function(e){
e.preventDefault();
var l = Ladda.create(this);
l.start();
});
So in my controller I have the typical action setup starting an ajax function. But what would be the best way to get the button that fired the action so I can start ladda like it shows above?
For reference here are the buttons in the template
// templates/application.hbs
<li class="navbar-right"><button {{action 'startBot'}} class="btn btn-success ladda-button" data-style="slide-down"><span class="ladda-label">Start Bot</span></button><button {{action 'stopBot'}} class="btn btn-danger ladda-button" data-style="slide-down"><span class="ladda-label">Stop Bot</span></button></li>
And these are the actions in the controller
// controllers/application.js
isConnected: false,
actions: {
startBot: function(){
var self = this;
console.log('starting bot');
Ember.$.ajax({
method: 'post',
dataType: 'json',
url: 'http://localhost:3000/api/v1/bot',
success: function(data) {
console.log(data);
self.toggleProperty('isConnected');
self.get('notify').success('Bot started');
},
error: function(err) {
console.log(err);
self.get('notify').error('There was a problem');
}
});
},
stopBot: function(){
var self = this;
console.log('stoping bot');
Ember.$.ajax({
method: 'delete',
dataType: 'json',
url: 'http://localhost:3000/api/v1/bot',
success: function(data) {
console.log(data);
self.toggleProperty('isConnected');
self.get('notify').success('Bot stopped');
},
error: function(err) {
console.log(err);
self.get('notify').error('There was a problem');
}
});
},
}