Post form data then render new template - html

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)

Related

Getting selected value from dropdown menu to remain when page refreshes

I am trying to figure out a way in Django to maintain the selected value in a dropdown menu, after the page refreshes. Here is the current code I have. Whenever I make a selection the page refreshes, showing the correct data associated with the selection, but defaults to the name of the top selection in the dropdown menu. Thanks for the help.
<html>
<form method="GET" action=".">
<select name="option-menu" id="option-menu">
<option value="" disabled selected>Choose a Name</option>
{% for d in database %}
<option value="{{d.name}}">{{d.name}}</option>
{% endfor %}
</select>
<button type="submit" class="btn-filter">Filter</button>
</form>
</html>
--views.py--
option_menu = request.GET.get("option-menu")
qs = Database.objects.filter(database_id=id)
if option_menu != '' and option_menu is not None:
qs = qs.filter(name__icontains=option_menu)
return render(request,
template_name='main/database.html',
context={"queryset": qs
})
You could create a function in your template that activates periodically, or on the click of a specific element that sends the selection to the view which saves it to a cache file.
Function to check the selection:
<script>
function saveSelection() {
var selection
selection = $('#option-menu').val()
dict = {}
dict[selection] = selection
$.ajax({
url: '//' + '' + '/' + '' + "/",
type: 'POST',
headers: {'X-CSRFtoken': '{{ csrf_token }}'},
data: dict,
dataType: 'json'
})
}
</script>
You'll need to populate your own url in here, I couldn't glean it from your code above
In your view, you have a if statement to handle POST requests to save the selection, and you pass the selection into your context with a try block
try:
savedInfo = {}
csv_reader=csv.DictReader(saveFile)
for row in csv_reader:
if row['Selection'] == "Your selection text index 0":
selection = 0
elif row['Selection'] == "Your selection text index 1":
selection = 1
savedInfor[row['Selection']] == row['Selection']
context['saveInfo'] = savedInfo
except:
pass
if request.method == "POST":
data = request.POST
#save data
Then, on page load, you need a function to change the selection from the default value to the saved one
{% for info, value in saveInfo.items %}
<script>
$('document').ready(function(){
$('#option-menu').prop('selectedIndex', '{{value.1}}'
</script>
This probably isn't a perfect method for this, but it may push you in the right direction

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>

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

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
)

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
}
});
});

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.