Retain select option value after submit in Django - html

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")

Related

laravel retrive old() wherein query values

I have 2 multiple value select lists that I pass users between them using jquery.
<select multiple="multiple" id="ListAllUsers" class="form-control">
#foreach ($users as $user)
<option class="content" value="{{ $user->id }}">{{ $user->name }}</option>
#endforeach
</select>
<select name="user_id[]" required multiple="multiple" id="SelectedUsers" class="form-control">
#if (!empty(old('user_id')) && $create_form)
#foreach ($old_value_users as $old_user)
<option class="content" value="{{ $old_user->id }}">{{ $old_user->name }}</option>
#endforeach
#endif
</select>
Now, my issue is that when I go and pass the old('user_id') value in the whereIn query, I only get the first result of the array instead of all of the results that are passed in.
$old_users_id = [old('user_id')];
$old_value_users = User::whereIn('id', $old_users_id)->get();
If I replace $old_users_id = [old('user_id')] with $old_users_id = [1,2,3], it works like a charm. I have dd(old('user_id')) and it is indeed an array, so I do not understand what is the hick-up!
Since old('user_id') is an array, you should not put it in an array. Try this;
You shold provide an empty array if old('user_id') is null.
$old_users_id = old('user_id')?old('user_id'):[];
$old_value_users = User::whereIn('id', $old_users_id)->get();
+ point
Instead of whereIn try with whereIntegerInRaw if you are adding a large array of integer bindings to your query.For more check documentation
Something like this one
<select class="custom-select chosen-select {{ $errors -> has('add_project_owner') ? 'is-invalid' : '' }}" name="add_project_owner[]" id="add_project_owner" multiple>
<option value="">choose</option>
#foreach ($owners as $owner)
<option value="{{ $owner -> emp_name }}" {{ (collect(old('add_project_owner'))->contains($owner -> emp_name)) ? 'selected' : '' }}>{{ $owner -> emp_name }}</option>
#endforeach
</select>

change value form after press button (django)

I have a form where when I select my option and press the "Select" button I need to update the form with the data of my selected object. My problem is that when I do my static object the {% for%} already marks me an error because it is not a list. I do not know if this is the correct way to do it.
This is running Mysql, django 1.11 and python 2.7.15
views.py
def administrador(request):
alumno = Alumnos.objects.all()
mapa = mapas.objects.all()
competencias = Competencias.objects.all()
context = {
'alumno': alumno,
'mapa': mapa,
'competencias': competencias
}
return render(request, 'competencias_app/competencias.html', context)
def seleccion(request):
alumno = Alumnos.objects.get(pk=request.POST['Nombre'])
context = {'alumno': alumno}
return render(request, 'competencias_app/competencias.html', context)
competencias.html
<form action="/seleccion" method="POST">
{% csrf_token %}
<div>
<select id="carrera" name="Carrera">
<option value="1">TICS</option>
<option value="2">Carrera</option>
<option value="3">Carrera</option>
<option value="4">Carrera</option>
<option value="5">Carrera</option>
</select>
</div>
<div>
<select id="Alumno" name="Nombre">
{% for alumno in alumno %}
<option value="{{alumno.idAlumnos}}">{{alumno.nombre}}</option>
{% endfor %}
<input type="submit" name="Seleccionar">
</select>
</div>
<label for="ID">ID</label>
<input type="input" name="id" disabled value="{{alumno.idAlumnos}}"><br>
<label for="apellidos">Apellidos</label>
<input type="input" name="apellidos" disabled value="{{alumno.apellidos}}"><br>
<label for="Correo">Correo</label>
<input type="input" name="Correo" disabled value="{{alumno.correo}}"><br>
</form>
the output when press "seleccionar" is
Request Method: POST
Request URL: http://localhost:8000/seleccion
Django Version: 1.11.21
Exception Type: TypeError
Exception Value:
'Alumnos' object is not iterable
Images for more details
I solve my problem with one if, i don't know if is the correct solution but works!
competencias.html
<form action="/seleccion" method="POST">
{% csrf_token %}
<div>
<select id="carrera" name="Carrera">
<option value="1">TICS</option>
<option value="2">Carrera</option>
<option value="3">Carrera</option>
<option value="4">Carrera</option>
<option value="5">Carrera</option>
</select>
</div>
<div>
<select id="Alumno" name="Nombre">
{% if alumno|length > 1 %}
{% for alumno in alumno %}
<option value="{{alumno.idAlumnos}}">{{alumno.nombre}}</option>
{% endfor %}
{% else %}
<option value="{{alumno.idAlumnos}}">{{alumno.nombre}}</option>
{%endif%}
<input type="submit" name="Seleccionar">
</select>
</div>
<label for="ID">ID</label>
<input type="input" name="id" disabled value="{{alumno.idAlumnos}}"><br>
<label for="apellidos">Apellidos</label>
<input type="input" name="apellidos" disabled value="{{alumno.apellidos}}"><br>
<label for="Correo">Correo</label>
<input type="input" name="Correo" disabled value="{{alumno.correo}}"><br>
</form>
views.py
def administrador(request):
alumno = Alumnos.objects.all()
mapa = mapas.objects.all()
context = {
'alumno': alumno
}
return render(request, 'competencias_app/competencias.html', context)
def seleccion(request):
lstCompetencias = []
alumno = Alumnos.objects.get(pk=request.POST['Nombre'])
for p in Competencias.objects.raw('Select * from test_app_competencias where idmapasfk_id = %s', [request.POST['Nombre']]):
lstCompetencias.append(p)
context = {
'alumno' : alumno,
'competencias' : lstCompetencias
}
return render(request, 'competencias_app/competencias.html', context)

addEventListener by select not workting

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>

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

default select box by a passed parameter to django template?

I'm passing a dictionary to a django template and trying to set a default value for a select box. This template is an 'edit product' template for a previous 'add product' template, thus the user selected one of the following options from a select box when he added a new product and what I am trying to do now is in the 'edit product' template so he can change it while the default will be as the one he selected at first.
Is there a way to do something like this:
<td><select name="gender_limit" deafault="{{django_context.gender}}">
<option value="Male">Male</option>
<option value="Female">Female</option>
<option value="Both">Both</option>
</select>
</td>
Rather than:
<td><select name="gender_limit" >
<option value="Male" selected >Male</option>
<option value="Female">Female</option>
<option value="Both">Both</option>
</select>
</td>
I have tried to look a solution for this but haven't found. Any help is appreciated. Thanks
I found a solution to my problem, here is an example (a different one from the question example):
<select name="units">
<option ng-selected="'{{ med.units }}' == 'mg' " value="mg">mg</option>
<option ng-selected="'{{ med.units }}' == 'gr' " value="gr">gr</option>
<option ng-selected="'{{ med.units }}' == 'mcg' " value="mcg">mcg</option>
<option ng-selected="'{{ med.units }}' == 'ng' " value="ng">ng</option>
</select>
Or even as so:
<select name="units" ng-model="'{{ med.units }}'">
<option value="mg">mg</option>
<option value="gr">gr</option>
<option value="mcg">mcg</option>
<option value="ng">ng</option>
</select>
med.units is django context passed from a view.