How to call view function via button from template in Django? - html

I've searched some of the related questions and I couldn't figure out how to do it. That is why I am posting a new question here.
I have a base.html file and there is a button which should run a function from views.py file. Here is the button code:
<form role="form" action="" method="POST">
{% csrf_token %}
<input type="submit" class="btn" value="Click" name="mybtn">
</form>
And here is my function from views.py file:
def create_new_product(request):
if request.method == 'POST':
'''Execute the code here'''
return render (request, 'products/base.html')
And in my Products' urls.py file:
app_name = 'products'
urlpatterns = [
path('create-new-product/', views.create_new_product),
path('', views.IndexView.as_view(), name='base'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]
Normally I have an IndexView class in views.py file which lists all the current products and what I expect from the above function is that it will generate new products and new products will also be listed in 'products' page.
The above function is not inside the IndexView class by the way.

You will stay on the same page with action="#"
Try instead action="" so you will stay on the same page but reloaded.
Update:
Read your comment.
The name argument is useful to call your url in Django template like :
path('create-new-product/', views.create_new_product, name='create_new_product')
The app_name = 'products' is very important. It tells Django where to check your path. So you can call your view everywhere in your project by:
...
<form action="{% url 'products:create_new_product' %}">...</form>

you can either use browser fetch api or jquery ajax to implement search functionality
include a js script to your template file
include this js snippet
$(elementSelector).on("click", async (e) => {
const fetchOptions = {}
const response = await fetch(YOUR_URL, {...fetchOptions});
const responseUrl = response.url // see fetch api docs
window.location = responseUrl // if you want to redirect
)

Related

django template form target with dynamic data

i'm new at django template. i have a search field in header and i want to send searched keyword in this format
search/q/{{keyword}}/
my html code is this
<form action="{% url 'content.search' q=searched_key %}" class="search-input">
<input type="text" name="searched_key">
<button type="submit"><i data-feather="search"></i></button>
</form>
i want to get input value and send but result url is this
http://127.0.0.1:8000/contents/search/q//?searched_key=test
how can i do it in right way?
you can POST your search value as form (don't need to use /search/q//?searched_key=test in url) and your view should be something like this:
def search_view(request):
if request.method == "POST":
search_key = form.save()
search_result = Content.objects.filter(key=search_key)
context = {
'results': search_result,
}
return render(request, 'content.html', context)
You're probably better off using javascript to accomplish this.
<form id="form-id">
<input type="text" id="searched_key" name="searched_key">
<button type="submit"><i data-feather="search"></i></button>
</form>
<script type="text/javascript">
function submitForm(e) {
// Prevent default form submit
e.preventDefault();
// Get the search query
let query = document.getElementById("searched_key").value;
// redirect to the url with the query appended
window.location.href = "/contents/search/" + query + "/";
return false;
}
// Add an event listener to the form when the page loads
window.addEventListener('load', function() {
document.getElementById("form-id").addEventListener('submit', submitForm);
});
</script>

Call Django on HTML button click

I'm trying to make a basic sort function for a Django project, but I don't know how to call the sort function when I click the 'sort' button
Django view:
def sort_btn(request):
if request.GET.get('sort-btn'):
cits = Citizen.objects.all().order_by('name')
return render_to_response(request, 'civil_reg/index.html', {'cits': cits})
HTML button:
<button name="sort-btn" id="sort-btn">sort</button>
you need to wrap your <button> with <form> tag, as following snippet:
<form action='actionUrl' method='GET'>
<button type='submit'> sort me</button>
</form>
and in your urls.py module you should point the actionUrl with specific view from the views.py module as follow:
from django.urls import path
from . import views
urlpatterns = [
path(actionUrl, views.yourSort),
]
you should more read about request lifecycle on Django:
user submit request
Django tries to get the first match between request's URL and routes defined in urls.py
the request is passed to the matched view
the view get executed, usually this some model processing
a response (template) is returned by the view as HttpResponse
I don't know about your program but my implementation is the full as it is that worked.
<button name="button" type="submit" onclick="location.href='{% url "actionUrl" %}'"> Send</button>
I am trying to call a function in views named "sendEmail"
path('actionUrl/', views.sendEmail,name='actionUrl')
And above one is the line which I included in urls file.

Laravel 5.4: Submit a HTML form and receive a JSON response

Question: how can I communicate JSON back from a controller to my html page, and embed the response in my page, instead of destroying the page?
The long story is like this:
Embedded in a quite large html page (created by a view when I open my base URL, say, http://.../home) I have a html form. It has some data fields, and the usual "Submit" button.
<form class="form-horizontal" method="POST" action="{{ route('form.user') }}">
{{ csrf_field() }}
... lots of input fields ...
<div class="form-group">
<button type="submit" class="btn btn-primary">
Submit
</button>
</div>
</form>
The receiving route ...
Route::post('form/user','ItemController#save')->name('form.user');
And the controller ...
public function save(Request $request) {
...
return response()->json(['status' => 'Saved successfully']);
}
The whole thing works like intended, if I fill the form and hit the "Submit" button, the controller receives all input fields via the $request properties.
The problem arises after the return from the controller, the html is cleared from the browser, and the JSON is displayed.
What I need is receive the JSON and display it in a div of my original html, not replace it.
Question: what do I need to do, how can I hook into the communication to intercept and handle the JSON response, so I can display the response text in my original web page (using JQuery), and not destroy the html?
Thx, Armin.
Capture the FORM submit event, and prevent the default.
Construct an AJAX request
Dictate the response type.
Convert the form data to a serialized object to be sent to the server
Capture the returned response and apply it to a DIV.
That would look something like this:
$('form').on('submit', function(e){
e.preventDefault(); //1
var $this = $(this); //alias form reference
$.ajax({ //2
url: $this.prop('action'),
method: $this.prop('method'),
dataType: 'json', //3
data: $this.serialize() //4
}).done( function (response) {
if (response.hasOwnProperty('status')) {
$('#target-div').html(response.status); //5
}
});
});

Post form data then render new template

So I have a form in my HTML that looks like this:
<form id="passer" method="POST" action="{% url 'Sizer:printView' %}">
{% csrf_token %}
<input type="hidden" id="vals">
<input type="submit" value="Print all selected items" id="printBut">
</form>
With this form what I wish to achieve is when the submit button is clicked my jQuery will calculate a value and put it into the vals field in the form, then I want it to post to the printView view (to get the calculated data into a view) then once the data has been post render a new template and pass in the data calculated by the jQuery.
My printView (where the data is being posted) looks like this:
def printView(request):
to_print = str(request.POST.get('vals'))
template = "Sizer/printview.html"
context = {'to_print':to_print}
return redirect('requested_print_data', to_print)
And my requested_print_data view (where I want to render my new template) looks like this:
def requested_print_data(request):
all_data['to_print'] = #Dont know how to get my variable
template = "Sizer/printdata.html"
context = {'all_data':all_data}
return render(request, template, context)
So at the moment what happens is when the form is submit, the value is calculated and stored into the form, the URL will gain the extra part from where it's being posted (www.example.com/printables ---On Submit---> www.example.com/printables/printview/) but the template will remain the same.
I have been stuck on this for a day or two now so any help would be greatly appreciated!
EDIT: jQuery as requested:
$('#passer').submit(function(){
console.log("Inside click");
var selected = [];
var $vals = "";
$('.datatable').find('input[type="checkbox"]:checked').each(function(){
selected.push($(this).attr('value'));
});
$.each(selected, function(index, val){
$vals+= val + ',';
});
console.log($vals)
$("#vals").val($vals)
You can render the out put in the printView itself. No need to write another view. Change your printView to
def printView(request):
to_print = str(request.POST.get('vals'))
template = "Sizer/printdata.html"
context = {'all_data':to_print}
return render(request, template, context)

How to display a date attribute of an object as the default value in HTML date input type

Hi I am trying to implement a editing page that accept the id of an object and load all its original value && enable editing/updateing.
e.g
for text type ,I use
<label>Field1:</label>
<input type="text" id="id_field1" value='{{ objectInstance.filed1}}' name="field1"/>
for Textares
<label>Field2:</label>
<textarea id="id_field2" name="field2">
{{ objectInstance.field2}}
They both worked fine in loading original data of the instance and allowing editing. But for the date field, I cannot find out how to load it..
I am trying something like
<label>Deadline:</label>
<input type="date" id="id_deadline" name="deadline" value={{objectInstance.deadline}}>
(the deadline is of date data type e.g 2013-6-4)
Can anyone help solving this problem? Thanks very much.
You can use the UpdateView generic class based view to simplify this process. A similar question was answered before.
The other way to fix this is to use a ModelForm, and pre-load it with an instance. This is actually what UpdateView does, but if you don't want to use class based views, here is the alternative:
In your forms.py:
from django import forms
from someapp.models import SomeModel
class SomeModelForm(forms.ModelForm):
class Meta:
model = SomeModel
In your views.py:
def someview(request):
obj = SomeModel.objects.get(pk=1) # Fetch the object to be edited
form = SomeModelForm(instance=obj) # Load the form with the object's data
return render(request, 'edit.html', {'form': form})
In edit.html:
<form method="POST">
{% csrf_token $}
{{ form }}
<input type="submit">
</form>
This will automatically create the form, fill it in with the data from the model. You would still have to write the logic to update the record in your view.