addEventListener by select not workting - html

by running this code on flask, I am expecting to change tag "No name submitted" relating to the selected option, that I select out of the drop down menu. Instead of there are no changes, if I click on one option.
Thanks for your help!
<body>
<script>
document.addEventListener("change", function(){
document.querySelector("#selectoption").onchange(){
const channel = document.querySelector("#selectoption").value;
document.querySelector("#displaychannel").innerHTML=channel;
};
});
</script>
<h1> channels </h1>
<ul>
{% for channel in channels%}
<li>{{ channel }}</li>
{% endfor %}
</ul>
<form id="form2">
<select id="select">
{% for channel in channels%}
<option id="selectoption" value={{ channel }}>{{ channel }}</option>
{% endfor %}
</select>
</form>
<a1>You are:</a1>
<a1 id="displaychannel">No name submitted</a1>
</body>

You need to select the select to add an event listener to it. You can not add a onchange event listener to the document. You should never add an event listener inside an event listener as it will make the same function execute more and more times each times if the event is fired.
document.getElementById("selectoption").onchange = function(){...}
//or
document.getElementById("selectoption").addEventListener("change", function(event){...});
<select id="selectoption">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<script>
document.getElementById("selectoption").onchange = function(){
console.log(this.value);
}
</script>

Related

Django Prepopulate HTML MultieChoice Field

What's the best way to prepopulate a multiple choice select field. In my view, I'm adding the context the values for the field.
def get_context_data(self, *args, **kwargs):
context = super(UserProfileUpdateView, self).get_context_data(*args, **kwargs)
context['mystates']=user.states
output
Alaska, Arizona, Alabama,
Hmtl page
<div class="form-group">
<label for="id_states">Add State 2:</label> <select name="states" id="id_states" multiple="multiple">
{% include "accounts/snippets/states_drop_down_options.html" %}
</select>
</div>
state_drop_down_options.htmlm
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AZ">Arizona</option>
<option value="AR">Arkansas</option>
<option value="CA">California</option>
In each option you can check if that option is in the mystates variable:
<option value="AL" {% if 'Alabama' in mystates %}selected{% endif%}>Alabama</option>
<option value="AK" {% if 'Alaska' in mystates %}selected{% endif%}>Alaska</option>
<option value="AZ" {% if 'Arizona' in mystates %}selected{% endif%}>Arizona</option>
<option value="AR" {% if 'Arkansas' in mystates %}selected{% endif%}>Arkansas</option>
<option value="CA" {% if 'California' in mystates %}selected{% endif%}>California</option>
Depending on your project, you can have it the way that you think better for your purpose.
1st:
Django.forms.ModelMultipleChoiceField or Django.forms.MultipleChoiceField
2nd:The answer of #Nazkter is a good one,
3rd:
html
(I add a states attribute to select containing the value of {{ states }})
<select name="states" states="{{ states }}" id="id_states" multiple="multiple">
{% include "accounts/snippets/states_drop_down_options.html" %}
</select>
javascript
[].forEach.call(document.querySelectorAll('#id_states option') , function(elm){
var states = document.querySelector('#id_states').getAttribute("states").replace(/\s/g,'').split(",");
if(states.indexOf(elm.innerText) > -1){
elm.selected = true;
}
});

change form variable at onchange event

I got variable myvar in my wtf-form.
I would like to set it's value upon the user selects an option in the dropdown list, w/o the need to add a button/input for the user to confirm his selection.
So far, I am not able to have a POST event triggered in views.py whenever the user selects an option.
Moreover, setting form.myvar as I do below doesn't actually do anything, and the alert message won't fire either.
My flask template code:
<!-- extend base layout -->
{% extends "base.html" %}
<script>
$('#sel_id').change(function() {
window.alert(5 + 6);
});
</script>
{% block content %}
<div>
<form action="{{ url_for('compile') }}" method="POST">
<dl>
<select id="sel_id">
<option value="1">1</option>
<option value="2">2</option>
</select>
</dl>
</form>
</div>
<script type=text/javascript src="{{
url_for('static', filename='jquery.js') }}"></script>
{% endblock %}
I would write a piece of JavaScript or jQuery to handle this.
$('#sel_id').change(function() {
var = 4;
});
Also, you will want to name your variables something other than var, which is keyword. Name it something more descriptive.

Retain select option value after submit in Django

I am not using Ajax or django forms. I have plain HTML select tag inside the form tag and sending the selected option value in my view. I want to retain the select option value after the submission. Currently, it comes to default value of 1 irrespective of my selection. Help would be appreciated.
Here is my template code:
<form method = "post" action = "{% url 'index' %}">
{% csrf_token %}
<label class="mainlbl">Vega</label>
<select name = "drop1" >
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
<input class="btn btn-ocean btn-side-bar" type = "submit" value="Submit">
</form>
Here is my view for that:
def index(request):
if request.method == "POST":
vega = request.POST['drop1']
vega = int(vega)
gvo = GVOptimize('NSE', 'Nifty')
data = gvo.get_optimal_strategies(vega)
str1 = None
for i in range(0, len(data)):
if i == 0:
str1 = data[i]
elif i == 1:
str2 = data[i]
elif i == 2:
str3 = data[i]
elif i == 3:
str4 = data[i]
else:
break
context_dict = {'str1': str1, 'str2': str2, 'str3': str3, 'str4': str4 'vega': vega}
return render(request, 'demo/dashboard.html', context_dict)
else:
context_dict = {}
return render(request, 'demo/dashboard.html', context_dict)
If you really insist on having a hacky way of maintaining the selected option you can change your form to check every option to see if it equals the number you pass back in your context
<form method = "post" action = "{% url 'index' %}">
{% csrf_token %}
<label class="mainlbl">Vega</label>
<select name = "drop1" >
{% for idx in "useaformpls!" %}
<option value="{{ forloop.counter }}" {% if context_val == forloop.counter %}selected {% endif %}>
{{ forloop.counter }}
</option>
{% endfor %}
</select>
<input class="btn btn-ocean btn-side-bar" type = "submit" value="Submit">
</form>
Where context_val equals the index you pass back in the context data of your view.
this answer is here only, because this is not how it should be resolved!
you are using Django, so use Forms that are dedicated for such a use, there are many reasons why to use them, but there are few that matters:
simple code
straight-forward use of forms with generic views
data validation (yes, you do not need to check if this is an integer, or if somebody is hacking your page and posting value outside of range that is in your select)
data escape - yes, no more stupid security holes
validation tied to form elements, allowing to resubmit data and display to the user where is exactly an error
and don't tell me that this is more work...
forms.py
class MyForm(forms.Form):
drop1 = forms.IntegerField('Vega', choices=[(x,x) for x in range(1, 13)])
views.py
def index(request):
context_dict = {}
if request.method == "POST":
form = MyForm(data=request.POST)
if form.is_valid():
vega = form.cleaned_data['drop1']
gvo = GVOptimize('NSE', 'Nifty')
data = gvo.get_optimal_strategies(vega)
(str1, str2, str3, str4) = data[:4]
context_dict = {'str1': str1, 'str2': str2,
'str3': str3, 'str4': str4 'vega': vega}
else:
form = MyForm()
context_dict['form'] = form
return render(request, 'demo/dashboard.html', context_dict)
dashboard.html
{% if form.is_valid %}
<p>Vega: {{ vega }}</p>
{% else %}
<form method="post" action="{% url 'index' %}">{% csrf_token %}
{{ form }}
<input class="btn btn-ocean btn-side-bar" type="submit" value="Submit">
</form>
{% endif %}
I am not sure if this is a good practice but you may try creating a function in your view.
def send_selected_combo(self):
value_from_select = self.request.GET.get('select_html')
return value_from_select
Then in your template you can call the function.
<select name="select_html" selected="id_selector">
<option value="combo_value" {%if.view.send_selected_combo=="combo_value"%} selected {%endif%}></option>
</select>
<select name = "drop1" >
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
When you submit the form in views.py you can use
selected_value = request.POST.get("drop1"); // If incase you are using get method which you shouldn't then use request.GET.get("drop1")

Error retrieving multiple select option in Django

I have a drop down with multiple select option in my html page. On form submission, I am trying to capture all of the selected options by user in that drop down. but it throws me an error instead "TypeError:'instancemethod' object is not subscriptable". Following is my template.html and views.py
Template.html:
Select packages:
<form name=automationForm action="/vsawebauto/automation/results/" method="post">
//some form elements
<select id="package" name="package[]" multiple="multiple" size="5">
{% for i in ida.package_set.all %}
<option value="{{ i.pkg_id }}">{{ i.display_name }}</option>
{% endfor %}
</select>
//some form elements
<input type="submit" id="submit" value="Submit Job" />
Views.py:
def results(request):
//some code
selected_packages = request.POST.getlist['package[]']
//some code
return HttpResponse("Selected Packages:"+selected_packages)
Note: I debugged the code as well. The request.POST object has multiple selected values. For eg. when 1 and 701 packages are selected by user, request.POST has 'package[]': ['1','701']. But the code fails when I do request.POST.getlist['package[]']
request.POST.getlist['package[]']
Should be
request.POST.getlist('package[]')
Replace [] with () which was the cause of the error.
Here is the documentation and usage of getlist.
Also, change
return HttpResponse("Selected Packages:"+selected_packages)
to
return HttpResponse("Selected Packages: %s" % selected_packages)

How to loop use jinja2 for loop to create a select element?

Say I have a python list called seq and I want to render it in a select element how do I do that?
I tried:
<select name="Exercise1">
{% for item in seq %}
<option value="{{item}}">{{item}}</option>
{% endfor %}
</select>
it didn't work.
UPDATE:
here is the template code:
<!DOCTYPE html>
<html>
<head>
<title>Unit 2 Rot 13</title>
</head>
<body>
<h2>Enter some text to ROT13:</h2>
<form method="post">
<select name="Exercise1">
{% for item in seq %}
<option value="{{item}}">{{item}}</option>
{% endfor %}
</select>
<br>
<input type="submit">
</form>
</body>
</html>
and here is the rendered html source code:
<!DOCTYPE html>
<html>
<head>
<title>Unit 2 Rot 13</title>
</head>
<body>
<h2>Enter some text to ROT13:</h2>
<form method="post">
<select name="Exercise1">
</select>
<br>
<input type="submit">
</form>
</body>
</html>
I'm not sure why the element just disappears and there is no errors raised.
You are very close my friend you just missed a few spaces:
You wrote this:
<option value="{{item}}">{{item}}</option>
Which needs to look like this:
<option value="{{ item }}">{{ item }}</option>
Let me know if that fixes it. Good luck!
Without those spaces it just looks like garbage to python and to the browser :)
Check the function where you render template, it must contain:
def generate_template_for_exercize1():
seq = [1, 2, 3] #here you probably will have more complex statement
return render_template('your_template.html', seq=seq)