Issue with dropdown submitting selected value - Django/Python - python

I am trying to get the selected value in the dropdown to add to the cart. The way I have it prints out different dropdowns but submits the data into the cart. I just want one dropdown that submits the selected value. Thank you.
{% for product in products %}
<form class = 'pull-right' method ='GET' action='{% url "update_cart" product.slug 1 %}'>
<select id="menulist">
<option>{{ product.name }}: ${{ product.price }}</option>
{% endfor %}
</select>
<button type = 'submit' class ="btn btn-info btn-md" class ='pull-right'>Add To Order</button>
</form>

Simply two things need.
First, You should setup option's value. second, forloop should target only option, not whole form.
<form class = 'pull-right' method ='GET' action='{% url "update_cart" product.slug 1 %}'>
<select id="menulist" name="{# your select's name here #}">
{% for product in products %}
<option value="{{ product.id|slugify }}">{{ product.name }}: ${{ product.price }}</option>
{% endfor %}
</select>
<button type = 'submit' class ="btn btn-info btn-md" class ='pull-right'>Add To Order</button>
</form>
This code snippet show two different point. 1. option have value, select has name. 2. forloop should in select tags.

Related

get name attr value for formset with appropriate prefix and formset form index

I am manually displaying modelformset_factory values in a Django template using the snippet below. One of the inputs is using the select type and I'm populating the options using another context value passed from the view after making external API calls, so there is no model relationship between the data and the form I'm trying to display.
view
my_form = modelformset_factory(MyModel, MyModelForm, fields=("col1", "col2"), extra=0, min_num=1, can_delete=True,)
template
{{ my_form.management_form }}
{% for form in my_form %}
<label for="{{ form.col1.id_for_label }}">{{ form.col1.label }}</label>
{{ form.col1 }}
<label for="{{ form.col2.id_for_label }}">{{ form.col2.label }}</label>
<select id="{{ form.col2.id_for_label }}" name="{{ form.col2.name }}">
<option disabled selected value> ---- </option>
{% for ctx in other_ctx %}
<option value="{{ ctx.1 }}">{{ ctx.2 }}</option>
{% endfor %}
</select>
{% endfor %}
The other_ctx populating the select option is a List[Tuple]
I am trying to get the name value for the col2 input using {{ form.col2.name }} but only col2 is getting returned instead of form-0-col2. I could prepend the form-0- value to the {{ form.col2.name }} but wondering if:
I could do the above automatically? I'm assuming the formset should be aware of the initial formset names with appropriate formset index coming from the view.
Is there a way to include the select options in the initial formset that is sent to the template so that I can simply use {{ form.col2 }}?
Just saw that I could use form-{{ forloop.counter0 }}-{{ form.col2.name }} as an alternative as well, if getting it automatically does not work.
I think what you are after is form.col2.html_name - docs
This is the name that will be used in the widget’s HTML name attribute. It takes the form prefix into account.

Dynamically change <textarea> depending on <select> in jinja2 / flask

In my python file I have a dictionary
results = {'Key1':'Value1', 'Key2':'Value2'}. I passed it in return render_template('pages/queries.html', results=results)
Now in html I have
<select name="results">
{% for key, value in results.items() %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</select>
{% for value in results.values() %}
<textarea rows="10" cols="40" name="results"> {{value}} </textarea>
{% endfor %}
This is unfortunately displaying three textareas for some reason. The desired result I want is someone selects a value from the dropdown (select html) and if they choose 'key2' then I want 'value2' to appear inside of textarea. If they choose 'key1' then dynamically I want textarea to update to 'value1'. But this isn't happening and I've tried changing the locations of all the jinja codes and variations and haven't figured it out, please help.
You need to add onChange event handler and update text area accordingly.
<select name="results" onchange="changeText(this);">
{% for key, value in results.items() %}
<option value="{{ value }}">{{ key }}</option>
{% endfor %}
</select>
<textarea rows="10" cols="40" name="results" id="myTextArea"> {{results.values()[0]}} </textarea>
JS code for updating text area on onChange event.
function changeText(el) {
document.getElementById('myTextArea').value = el.value;
}

Django getting right return value for post.request

I am trying to get the product id using request.post in Django. I am currently testing using the console, but the only product_id value I am returned is 1.
This is the particular function in the view:
def test_view(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
my_carts_current_entries = Entry.objects.filter(cart=cart_obj)
products = Product.objects.all()
if request.POST:
product_id = request.POST.get('product_id')
entry_quantity = request.POST.get('entry_quantity')
product_obj = Product.objects.get(id=product_id)
print(product_id)
# print(entry_quantity)
# Entry.objects.create(cart=cart_obj, product=product_obj, quantity=product_quantity)
return render(request, 'carts/test.html', {'cart_obj': cart_obj, 'my_carts_current_entries': my_carts_current_entries,
'products': products})
This is the html on the template.
<form method="POST">
<br>
{% csrf_token %}
{% for product in products %}
{{ product.name }} <br>
<button>Add to Basket</button>
{{ product.id }}
<input type="hidden" name='product_id' value='{{ product.id }}'>
<br>
{% endfor %}
</form>
Your problem is that you have as many <input> tags within 1 <form> as many products you have displayed. They all have the same name, so you always get the value of the first one.
I'd recommend getting rid of <input> and attaching the value of product.id to the button itself (or <input type="submit"> to be exact). Here's the more descriptive explanation:
How can I build multiple submit buttons django form?
An alternative would be to change your code to have multiple forms, like that:
{% for product in products %}
<form method="POST">
{% csrf_token %}
{{ product.name }}
<br/>
<button>Add to Basket</button>
{{ product.id }}
<input type="hidden" name='product_id' value='{{ product.id }}'>
</form>
<br/>
{% endfor %}

getting data from dynamically generated html form

I am dynamically generating a html page from data in the database(mainly labels retrieved since I'm in the stage of CREATING data to store in the db). I retrieve labels and id's from the database, then store it in a class which I return to jinja2 so that I can then dynamically generate all the labels and input boxes. Here is a snippet:
<div class="dataDiv">
<label class="inputBoxLabels">Device<span style="padding-left: 85px;font-size: 12px;">New</label>
<select id="devices" class="inputBoxes" style="height: 25px;">
{% for key, value in devices.iteritems() %}
{% if deviceID == key %}
<option value="{{ key }}" selected="selected">{{ value }}</option>
{% else %}
<option value="{{ key }}">{{ value }}</option>
{% endif %}
{% endfor %}
</select>
</div>
another example, this time an input box:
{% if inspection.statusDict|length > 0 %}
<select class="inputBoxes" id="ins_' + {{ inspection.insID }} + '" style="height: 25px;">
{% for key, value in inspection.statusDict.iteritems() %}
<option value="{{key}}">{{value}}</option>
{% endfor %}
</select>
{% else %}
<input type="text" class="inputBoxes" id="ins_' + {{ inspection.insID }} + '">
{% endif %}
This is what the select list looks like after is has been populated for visual reference:
Now the problem. I have everything inside a form and I have no idea how to retrieve the data from each input and select when I receive the post since it's all dynamically generated.
I originally thought of using jquery instead and ajax but if possible I'd like to stick to forms
Off the top of my head I think if you're submitting to a Pyramid view via POST you should be able to iterate over request.POST to get whatever was submitted.
Something like and inspect each item
for item in request.POST.keys():
print item + ' - ' + request.POST[item]
I'd have to try it when I get home to a console to confirm.

How to get value from dropdown list

I'm trying to get value from dropdown box into variable and then store it. I'm new to Flask and cant find anything in the documents about it.
But I dont know how to get the value from dropdown list with request.form or any other why in that matter.
My flask code in app.py
#app.route('/add', methods=['POST'])
def add_entry():
if not session.get('logged_in'):
abort(401)
title = request.form['title']
link = request.form['link']
shown = request.form['shown']
#I hardcoded the id here too see basic function.
kate = Category.query.filter_by(id = 2).first()
add_into = Entries(title, link, shown, kate)
db.session.add(add_into)
db.session.commit()
And here is the html for it.
<form action="{{ url_for('add_entry') }}" method=post class="add-entry custom">
<dl>
<dt>Title:
<dd><input type=text size=120 name=title>
<dt>Link:
<dd><input type=text size=120 name=link>
<dt>Shown:
<dd><input type=text size=120 name=shown>
<label for="customDropdown">Category</label>
<select style="display:none;" id="customDropdown">
{% for c in cate %}
{% if c.id == 1 %}
<option id="{{ c.name }}" name="{{ c.name }}" SELECTED>{{ c.name }}</option>
{% else %}
<option>{{ c.name }}</option>
{% endif %}
{% endfor %}
</select>
<dd><input class="success button" type=submit value=Post it!>
</dl>
</form>
A select tag, like an input tag, needs a "name" attribute on it if you wish to have the value passed as form data.
<select name="name" style="display:none;" id="customDropdown">
Now, you should be able to access it through request.form['name'] as you have been your input elements.

Categories