OctoberCms How to pass ajax response to javascript function - javascript

I created a form in my component html file, When i submit a form an ajax call triggers to my action defined in component. So far my code is working fine i'm getting response. But now i want the response to be passed to the javscript function that i created inside component htm file.
function markAddresses(addresses) {
geocoder = new google.maps.Geocoder();
addresses.forEach(address => {
geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({map: map,position: results[0].geometry.location});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
})
}
I want to pass my response like markAddresses(response)
<form method="post" data-request="onSend">
<div class="col-md-5">
<input type="text" name="location" class="form-control">
</div>
<div class="col-md-2">
<select name="service[]" id="services" class="form-control">
{% for client in records %}
<option value="{{ client.service }}">{{ client.service }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<select name="area[]" id="search" class="form-control" >
{% for client in records %}
<option value="{{ client.area }}">{{ client.area }} Miles</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<input type="submit" value="Looks for Shops" class="red-btn btn btn-default">
<a class="location-view" href="#">View all Shops</a>
</div>
This is how my Ajax is working. I think it is using octobercms Ajax framework

You can use data-attributes-api
<form method="post"
data-request="onSend"
data-request-success="markAddresses(data)"
<!-- ^-- this one -->
>
....
</form>
make sure markAddresses is global function you can access it globally. and data is return value from the handler.
If your handler looks like this
function onSend() {
return ['test' => 'data'];
}
It will pass object like below in markAddresses as variable data
console.log(data); // output : { "test": "data" }
If any doubt please comment.

Related

Django Form dropdown fill with values

I have a from with fields I created in Django models.py. One of the fields is:
res_person_1 = models.TextField(verbose_name="Odgovorna osoba 1")
HTML page is:
{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Prijavite nesukladnost</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Prijava</button>
</div>
</form>
</div>
When I inspect the HTML page, ID of object is 'id_res_person_1'. At the page load I run script to get from database all users, which should fill the 'res_person_1' field and that field should be dropdown.
Script is:
<script type="text/javascript">
var endpoint = '/call_jquery_korisnici/'
var korisnik_ime_prezime = []
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
korisnik_ime_prezime = data.korisnik_ime_prezime
console.log(korisnik_ime_prezime)
},
error: function(error_data){
console.log("error")
console.log(error_data)
}
})
</script>
I don't know how to fill that field and how to make it dropdown. It doesn't work with:
$("#id_res_person_1").html(korisnik_ime_prezime);
document.getElementById('id_res_person_1').value = korisnik_ime_prezime;
If I console output var korisnik_ime_prezime: (2) ["TestName1 TestLastname1", "TestName2 TestLastname1"]
You can use replaceWith to replace your textarea with select-box then use each loop to iterate through your return response from server and then append option inside your select-box.
Demo code :
$(document).ready(function() {
var korisnik_ime_prezime = []
/*$.ajax({
method: "GET",
url: endpoint,
success: function(data) {*/
//just for demo
korisnik_ime_prezime = ["TestName1 TestLastname1", "TestName2 TestLastname1"] // data.korisnik_ime_prezime
//replcae textarea with slect
$("#id_res_person_1").replaceWith("<select name='id_res_person_1' id='id_res_person_1' class='form-control'></select>")
//loop
$(korisnik_ime_prezime).each(function(i) {
$("#id_res_person_1").append("<option>" + korisnik_ime_prezime[i] + "</option>") //append options
})
/*},
error: function(error_data) {
console.log("error")
console.log(error_data)
}
})*/
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<form method="POST" enctype="multipart/form-data">
<textarea id="id_res_person_1"></textarea>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Prijava</button>
</div>
</form>

Ajax "on change" doesn't fire

I have a form, which I would like to pre-populate depending on selected item in a drop down list. The HTML code:
My Ajax.js looks like:
$("#domain_selected").on('change', function() {
$.ajax({
url: '/returndomaindetails',
data: {
domainselect: $("#domain_selected").val()
},
success: function(data, status, xhr) { // success callback function
if (data.length > 1) {
var js = JSON.parse(data)
var domainname = js['domainname']
var domainarchitect = js['domainarchitect'];
$('#domainname').empty().append(domainname)
$('#domainarchitect').empty().append(domainarchitect)
$("#domain_details").show()
} else {
$("#domain_details").hide()
}
},
error: function(jqXhr, textStatus, errorMessage) { // error callback
}
});
})
HTML
<div class="card">
<div class="card-body">
<h4 class="card-title">Change Domain</h4>
<form action="{{ url_for('changedomain') }}" method="post">
<div class="form-row">
<div class="form-group col-md-4">
<label for="domain_selected" class="col-form-label">Select domain</label>
<select id="domain_selected" name="domain_selected" class="form-control">
<option>Choose</option>
{% for x in domain %}
<option value="{{x}}">{{ x }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-row" name="domain_details" id="domain_details" style="display: none">
<div id="domain_name" class="form-group col-md-4">
<label class="col-form-label">Domain Name</label>
<input type="text" class="form-control" name="domainname" id="domainname" placeholder="">
</div>
<div class="form-group col-md-4">
<label class="col-form-label">Domain architect</label>
<input type="text" class="form-control" name="domainarchitect" id="domainarchitect" placeholder="">
</div>
</div>
<div>
<button type="submit" class="btn btn-primary">Change Domain</button>
</div>
{% block scripts %}
<script src="{{ url_for('static', filename='js/ajax.js') }}"></script>
{% endblock %}
Now, on the flask endpoint /returndomaindata , I have just a simple print statement to get indication that the GET request arrived, however it doesn't.
#app.route('/returndomaindetails', methods=["GET"])
def returndomaindetails():
if request.method=="GET":
print("got the GET request")
domainselect=request.args.get('domainselect')
data=Domains.returndomaindetails(domainselect)
print(data)
return json.dumps(data)
Seems like the "on change" event is not firing. There are absolutely no errors in the console. Similar functions work without problem in the same file.
It turned out to be indentation problem - a space before the function

How do you send an array to a modal for use in Laravel 5.5 blade with in_array for checkboxes to set the checked attribute?

I am trying to pass an array to a modal after I get a response from an ajax call on the eventClick() function in fullcalendar v3
// in my blade javascript section
This is getting good data but I need to send the tagcodes to the modal and an array like this..
$tagCodes
which should be an array like this..
'AM','FLEX'
A. I don't know how to make it a usable array.
B. I need to send it to the front-end as a variable called $tagCodes which is an array.
eventClick: function (event, jsEvent, view) {
let id = event.id;
let tag_codes = event.tag_codes;
console.log(tag_codes.split(" ").join(",").replace(/,\s*$/, ""));
( which is giving me this AM,FLEX )
$.ajax({
url: '/agenda/' + id,
type: 'GET',
data: {},
dataType: 'json',
success: function (data) {
$('#calendarModal input[name=id]').val(data.calendar.id);
$("#calendarModal .tagCodes").html(tag_codes.split(" ").join(",").replace(/,\s*$/, ""));
$('#calendarModal').modal();
}
});
}
// in my modal section
<div class="col-12">
<div class="row">
<div class="col-12 tagCodes"></div>
#foreach($tags as $tag)
<div class="col-3 text-center">
<label>
<input type="checkbox"
id="tag-{{ $tag->id }}" name="tags[]" value="{{ $tag->id }}"
#if( in_array($tag->code, [THIS IS WHERE IM TRYING TO SEND THE ARRAY]) ) checked #endif
> {{ $tag->code }}
</label>
</div>
#endforeach
</div>
</div>
Change this
<input type="checkbox"
id="tag-{{ $tag->id }}" name="tags[]" value="{{ $tag->id }}"
#if( in_array($tag->code, [THIS IS WHERE IM TRYING TO SEND THE ARRAY]) ) checked #endif
>
to
<input type="checkbox" id="tag-{{ $tag->code }}" name="tags[]" value="{{ $tag->id }}">
then in JavaScript do this.
var codes = tag_codes.split(" ");
for(var i=0;i<codes.length;i++)
$('#tag-'+codes[i]).prop('checked', true);

jquery .click() event issue (django)

I have created a view that generates posts and each post have a comments_set which produces all the comments made by user. When new comment is posted, below function is executed.
$("#comment-post-button").click(function(){
var event_id = document.getElementById('event-id').value;
var url= '/post-comments/'+event_id +'/';
var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
content:document.getElementsByName('comment-post-content')[0].value
}
$.post(url , data, function(){
$("#refresh-comments").load("/comments/" + event_id + '/', function(){
$("#comment-post-content").val("");
});
});
$("#comment-post-content").val("");
return false;
});
The problem is that the page contains multiple posts and each comment submission button has the same id "comment-post-button". So the above function works only for the top post and not for the rest. I can see what the problem is but don't know how to solve this. Please help.
Here is the html markup:
{% for event in events %}
<div class="post">
<div class="post-right">
<div class="post-author">{{ event.author.first_name }}</div>
<div class="post-content">{{ event.description }}</div>
<div class="post-bar">
<div class="post-likes">{{ event.up_votes }}<img src="/site-media/static/images/like.png" /></div>
<div class="post-dislikes">{{ event.down_votes }}<img src="/site-media/static/images/dislike.png" /></div>
<div class="post-timestamp">{{ event.pub_date }}</div>
Comment
</div>
<div class="post-comment">
<form method="post" action="/post-comments/{{ event.id }}/">
{% csrf_token %}
<input type="text" id="comment-post-content" name="comment-post-content" maxlength="200" placeholder="Add a comment..." />
<input type="hidden" id="event-id" value="{{ event.id }}">
<input type="submit" id="comment-post-button" class="comment-post-button" value="Post comment" />
</form>
</div>
<div id="refresh-comments" class="comments">
{% include "comments.html" %}
</div>
</div>
<div class="post-left">
<img src="../FestJanta/site-media/static/images/post.jpg" />
</div>
</div>
{% endfor %}
comments.html:
{% for comment in event.comment_set.all|slice:"3" %}
<div class="comments-right">
{{ comment.author.first_name }}
{{ comment.content }}<br>
<div class="comment-timestamp">{{ comment.pub_date }}</div>
</div>
<div class="comments-left"><img src="../FestJanta/site-media/static/images/comment.jpg" /></div>
{% endfor %}
Final working solution:
$(".comment-post-button").click(function(){
var btn = $(this);
var currentPost = btn.parents('.post');
var event_id = currentPost.find('.event-id').val();
var url= '/post-comments/'+event_id +'/';
var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
content:currentPost.find('input[name="comment-post-content"]').val()
}
$.post(url , data, function(){
$(currentPost.find('.refresh-comments')).load("/comments/" + event_id + '/', function(){
$(currentPost.find('.comment-post-content')).val("");
});
});
return false;
});
Remove id and add class:
<input type="hidden" class="event-id" value="{{ event.id }}">
Do something like this:
$('.comment-post-button').click(function(){
var $btn = $(this);
var $currentPost = $btn.parents('.post');
var event_id = $currentPost.find('.event-id').val();
//...
});
Find each element in $currentPost scope:
Instead of this:
content: document.getElementsByName('comment-post-content')[0].value
Do this:
content: $currentPost.find('input[name="comment-post-content"]').val()
You could do the following:
Identify all post buttons, e.g. by a class like .comment-button
Use the .on() notation of jQuery
Pass the event and use its target property to identify the DOM element that triggered the event
Use traversion to get the correct DOM element of the post
The result should look something like this (untested):
Markup (I basically just got rid of the IDs; not sure how/if django handles this automatically):
{% for event in events %}
<div class="post">
<div class="post-right">
<div class="post-author">{{ event.author.first_name }}</div>
<div class="post-content">{{ event.description }}</div>
<div class="post-bar">
<div class="post-likes">{{ event.up_votes }}<img src="/site-media/static/images/like.png" /></div>
<div class="post-dislikes">{{ event.down_votes }}<img src="/site-media/static/images/dislike.png" /></div>
<div class="post-timestamp">{{ event.pub_date }}</div>
Comment
</div>
<div class="post-comment">
<form method="post" action="/post-comments/{{ event.id }}/">
{% csrf_token %}
<input type="text" name="comment-post-content" maxlength="200" placeholder="Add a comment..." />
<input type="hidden" name="event-id" value="{{ event.id }}">
<input type="submit" class="comment-post-button" value="Post comment" />
</form>
</div>
<div class="comments">
{% include "comments.html" %}
</div>
</div>
<div class="post-left">
<img src="../FestJanta/site-media/static/images/post.jpg" />
</div>
</div>
{% endfor %}
Javascript:
$("body") // Could be any ancestor, body is not the best option
.on('click', '.comment-post-button' function(ev){
var clickTarget = ev.target, // The element clicked on
postElement = $(clickTarget).closest('.post'), // the div enclosing a post
commentSection = $(postElement).find(".comments"), // the div enclosing the comments
commentInputField = $(clickTarget).siblings("[name='comment-post-content']"),
event_id = $(clickTarget).siblings("[name='event-id']").val(),
url= '/post-comments/'+event_id +'/';
// Not sure what this token is, so I will not change that part
var data = {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
content: commentInputField.val()
}
$.post(url , data, function(){
$(commentSection).load("/comments/" + event_id + '/', function(){
$(commentInputField ).val("").prop('disabled', false); // In the callback, empty and reenable
});
});
$(commentInputField ).prop('disabled', true); // I guess disabling the field makes sense
return false;
});
An additional advantage is that you will end up with only one click handler. Note that the solution could be optimized (e.g. by improving the selectors). In addition, jslint will give some warnings.
to give each post & post_Comment_button a unique id, as suggested by someone, change the markup as follows:
{% for event in events %}
<div class="post" id="post_{{forloop.counter}}">
[...]
<input type="submit" id="comment-post-button_{{forloop.counter}}" class="comment-post-button" value="Post comment" />
then change the js function as follows:
$("#comment-post-button").click(function(event){
var buttonNr = event.target.id.replace('comment-post-button_', '');
var postId = 'post_' + buttonNr;
$("#" + postId)... --> and do whatever with it..

sending form information to server

I'm using select in a html form and once a user makes a selection from the select options I want that to be sent to the server by javascript. I can get text in a form sent to the server but nothing is sent to the server if I use select. This is my code:
{% extends "base.html" %}
{% import "forms.html" as forms %}
{% block header %}
<script>
$(document).ready(function() {
var ws;
$("#open").click(function(evt){
evt.preventDefault();
$.post("/", $("#eventForm.").serialize());
ws = new WebSocket("ws://" + "localhost" + ":" + "8888" + "/ws");
ws.onmessage = function(evt){
$("#display").append(evt.data + "<br />");
};
ws.onclose = function(evt) {alert("Server connection terminated");};
});
});
</script>
<div class="page-header">
<h1>Welcome</h1>
</div>
{% end %}
{% block body %}
<h2>Enter the Event you would like to follow</h2>
<form id ="eventForm" action="/" method="post">
<select name="aaaa" multiple="multiple">
<option value="" selected="selected"></option>
<option VALUE="abc"> ABC</option>
<option VALUE="def"> def</option>
<option VALUE="hij"> hij</option>
</select>
<!-- <input type="text" name="event" /> -->
<input type="submit" id="open" value="Submit Query" />
</form>
<h1>Coordinates</h1>
<div style="height:500px; width:700px; border:2px solid #ccc; overflow:auto; margin:0 auto;" id="display"></div>
{% end %}
I thought that $.post("/", $("#eventForm.").serialize()); would send the selected option as select is within the form tags.
I'm not really familiart with html and javascript.
Thanks
This may just be a simple typo.
change:
$.post("/", $("#eventForm.").serialize());
to:
$.post("/", $("#eventForm").serialize());

Categories

Resources