Keep option selected on page refresh - javascript

So how my code works i'll give you a gist.
When there are no files in html_files, the default option is "---", but when there exists a file in html_files there are two options now,
1) "---"
2) file. But with default still as "---"
So what i want to do is, when there exists a file in html_files I want the default option change to the current file and not "---". I cant think of a way as to how to do it. Could someone help me?
<span title="list resources who's involved etc">About File:
<select class="experiment_file_selector" id="about_file" name="about_file">
<option value="None" {% if not exp.about_file %}selected="selected"{% endif %}>---</option>
{% for file in html_files %}
<option value="{{ file.id }}" {% if file == exp.about_file %}selected="selected"{% endif %} >{{ file.get_base_name }}</option>
{% endfor %}
</select></span>
I added a JS script as suggested below it does the work on getting the default file on the select input tag when the exp.about_file is present but for it to get displayed on the template it needs to be manually clicked.
To automate the process i tried using .click() which seems to fail somehow.
So basically how its working, of i select the first option from the select list "---" or listFile[0] and then select the second one exp.about_file or listFile[1] manually, it delivers the result some how but its not happening with the JS script.
So could someone suggest me a method to automate the mouse click event for
listFile[0] and listFile[1], somewhat like my JS code so that it works.
Thanks
$(document).ready(function(){
var listFile = document.getElementById('about_file');
if (listFile.length > 1)
{
listFile[1].setAttribute('selected', 'selected');
listFile[0].click();
listFile[1].click();
}
});

It will be easy if you use javascript. Just add attribute selected="selected" when your page loaded.
document.addEventListener('DOMContentLoaded', function(e) {
var listFile = document.getElementById('about_file');
if (listFile.length > 1) {
listFile[1].setAttribute('selected', 'selected');
}
});

Related

How to deal with dependable dropdowns in Django

I am trying to create a dependable dropdown on Django but since my JavaScript/ajax knowledge is not great, I have hit rock bottom. Note: I have read previous questions on this matter but none of them fully solved my problem.
Problem Description:
Due to my database size, I am retrieving partial data from the server whenever a view is requested. This makes my job of using forms harder since I am using the username of the user to filter my server. Here is a simplified version of my code.
urls.py
urlpatterns = [
url(r'^SpecificVessel', views.SpecificVessel, name="goSpecificVessel"),
]
views.py
#login_required
def SpecificVessel(request):
#Get the username to filter the tables from SQL Server:
username = None
if request.user.is_authenticated:
username = request.user.username
#Get the shipnames.
cursor.execute("select distinct SHIPNAME from Table where [GROUP]=" + "'" + username + "'")
row = cursor.fetchall()
df_listofships = pd.DataFrame(data=row, columns=['SHIPNAME'])
shipnames = list(df_listofships['SHIPNAME'].tolist()) # LIST FOR SHIP SELECTION
#Get All the data from database.
cursor.execute("select * from Table2 where [GROUP]=" + "'" + username + "'")
row = cursor.fetchall()
df = pd.DataFrame(data=row)
colnames = list(dftrans.columns.values.tolist()) #LIST FOR YEAR DROPDOWN SELECTION
#getting the dropdown selections:
Dropdown_shipname = request.POST.get('Dropdown_shipname')
Dropdown = request.POST.getlist('Dropdown')
return render(request, 'SpecificVessel.html',
{'colnames': colnames, 'Dropdown': Dropdown, 'shipnames': shipnames, 'Dropdown_shipname': Dropdown_shipname,})
SpecificVessel.html
<form method="post">
{% csrf_token %}
<div class="form-group col-md-4">
<label for="Dropdown_shipname"><b>Select Vessel</b></label>
<select name="Dropdown_shipname" id="Dropdown_shipname" data-style="btn-default" class="selectpicker form-control" >
{% for i in shipnames %}
<option value="{{ i }}" {% if Dropdown_shipname == i %} selected {% endif %}>{{ i }} </option>
{% endfor %}
</select>
</div>
<div class="form-group col-md-4">
<label for="Dropdown"><b> Select Month </b></label>
<select name="Dropdown" id="Dropdown" data-style="btn-default" class="selectpicker form-control" multiple>
{% for i in colnames %}
<option value="{{ i }}" {% if Dropdown == i %} selected {% endif %} >{{ i }} </option>
{% endfor %}
</select>
</div>
<div class="form-group col-md-1 margin_top_25">
<input type="submit" value="Submit" />
</div>
</form>
What is the problem?
The solution I have in the code above provides me with independent dropdowns. That is, whenever there is a mismatch, it throws me an error. I have been trying to approach this in different way, however, after long research online, I found out that javascript or ajax may be the way to go about this. My question is this: Is there any way in which I could get what the user has selected in Dropdown_shipname before he submits the results? If yes, how would you solve this problem?
I hope I was clear enough. Please let me know if I should explain the problem any better.
There's a lot I feel I need to address before answering your main question.
The if request.user.is_authenticated bit is unnecessary; you already decorate the view with #login_required, so there's no way the user isn't authenticated.
Where does cursor come from? It doesn't look like you're using Django's database stuff (the ORM, or even raw cursors), but something else? Why is that?
Having a global cursor may lead to trouble down the line in production, when it's being shared between requests in a multithreaded situation. (Using Django's database functionality the database connections are correctly reset between requests, and each thread gets its own connection.)
Your SQL queries are vulnerable to SQL injection attacks, since you're just concatenating strings together. You need to use placeholders (parametrized queries) instead. How that's done depends on the database and database driver you're using.
You definitely don't need Pandas and a Pandas dataframe to extract the data from your database result! (My pet peeve: useless use of Pandas.)
The first retrieval would be shipnames = [row[0] for row in cursor].
The second retrieval would be colnames = [d[0] for d in cursor.description] (or similar; depends on your database). (However, you really don't want to fetch a number of rows just to get the column names; one row, e.g. LIMIT 1 in standard SQL, would do.)
You should be using Django forms to manage, well, forms. That way you don't need to manage rendering the <select>s and <option>s and selecteds manually.
This view would likely become a FormView subclass.
You say "This makes my job of using forms harder since I am using the username of the user to filter my server.", but that's a non-issue. You can well pass in your Django request, or just the User, or an username, to a custom form class, and have it modify or even add fields dynamically to the form based on it.
That said, the most minimal solution here is a tiny bit of JavaScript, to refresh the page with an added query string argument for the first selection. That is, when the user changes the shipname field, you'd refresh the page with e.g. ?shipname=selection-here, and deal with figuring out the correct choices for the other field in your view code.
The most minimal way I can think of is
<script>
document.getElementById("Dropdown_shipname").addEventListener("change", (event) => {
location.href = `?shipname=${event.target.value}`;
}, false);
</script>
Beyond that, you could use an AJAX request to selectively refresh only part of the page, and beyond that, maybe refactor the form into, say, a React.js or Vue.js component that deals with the form.
But either way, no, you're not going to be able to dynamically change the other field without JavaScript.

Trigger different events in JQuery based on if condition in html in Flask

I have developed a Flask website, which I need to trigger different alert messages depending on customers' salary after clicking on a button. I am doing the if statement inside the HTML using the Jinja2 template and according to condition triggers the id and then use this id to trigger an event using JQuery. I believe I am doing something wrong since nothing is happening after I click on the button.
Following is part of my code:
<div>
{% if ((current_user.salary)>=2000 and (current_user.salary) <=5000) %}
<div id="msg0"></div>
{% endif %}
{% if ((current_user.salary)>=1000 and (current_user.GPA) <2000) %}
<div id="msg1"></div>
{% endif %}
</div>
JQuery Code:
$( document ).ready(function(){
$("#second").unbind('click').bind( 'click', function() {
$('#msg0').alert("Your salary is above 2000");
$('#msg1').alert("You salary is less than 2000");
});
});
I did not include the code for designing the button since it is irrelevant I can click on the button. However, I do not think what I am doing with ` is correct. Maybe my JQuery code is not correct.
I would appreciate it if anyone can help me.`
Consider the following code.
$(function(){
$("#second").off('click').click(function() {
if($("#msg0").length){
alert("Your salary is above 2000");
}
if($("#msg1").length){
alert("You salary is less than 2000");
}
}
});
You need to check which of these elements exist in the DOM. To do this, we can check if the jQuery Object has length of 1 or higher.

Django: AJAX code needed for dependent dropdowns

Since I'm new to Django and have absolutely no knowledge of JS/AJAX, I'm trying to code in the most simple possible way dependent dropdowns. I managed to get my dropdowns populated with values from my database (data_immo). Now I need to have the second dropdown updated after user selection in the first one.
Here is my home.html file with the two dropdowns (regions and departements):
<select name="regions" id="regions">
{% for item in query_results_dict %}
<option value={{ item.nom_reg }}>{{ item.nom_reg }}</option>
{% endfor %}
</select>
<select name="departements" id="departements">
{% for item in departements %}
<option val="{{ item.insee_dep }}"> {{ item.insee_dep }} </option>
{% endfor %}
</select>
views.py:
def MyView(request):
query_results = data_immo.objects.all()
regions = data_immo.objects.values_list("nom_reg", flat=True).distinct()
departements = data_immo.objects.values_list("insee_dep", flat=True).distinct()
query_results_dict = {
'query_results': query_results,
'regions': regions,
'departements': departements,
}
return render(request,'home.html', query_results_dict)
models.py:
class data_immo(models.Model):
id = models.AutoField(primary_key=True)
insee_dep = models.IntegerField(db_column='INSEE_DEP', blank=True, null=True)
nom_reg = models.TextField(db_column='NOM_REG', blank=True, null=True)
class Meta:
managed = True
db_table = 'immo'
My understanding is that I need to retrieve the selected value from the "regions" dropdown and use an onChange function to trigger an action that will use that variable and inspect the db so only matching depatements are selected. Unfortunately I don't know how to proceed. I know there are a few examples out there, but none of them were really satisfying, and those I tried failed due to my lack of JS/AJAX knowledge.
Let me know if need more details.
EDIT 1: added models.py; also, the website that has been recommended in the comments has values stored in different tables whereas mine are all in the same one. Surely this must have an impact on my code and cannot be replicated per se.

Is there an alternative for onload on <select>?

I am using jinja templates to compile a form of multiple select blocks based on a template variable dictionary, like this:
{% for key, value in some_template_variable_dict.items %}
<select id="{{ key }}_selector" name="key">
{% for item in values %}
<option value="{{ item }}">{{ item }}</option>
{% endfor %}
</select>
{% endfor %}
I would like to fire the following wrapper function for selectize on all of the select blocks on loading the document:
function selectizeSingleChoice(selector) {
$('#'+selector).selectize({
sortField: 'text',
maxItems: 1,
create: false,
highlight: true,
openOnFocus: true
});
}
The select block does not have an onload event handler, and I cannot put it in a general $(document).ready(); section either, as the exact list of select blocks and their id-s is dependent on user choice. There is also an option that a slightly different version of the selectize wrapper is needed for some of them (e.g. not only one selected option allowed etc), so I cannot fire it on each and every select item either.
A working solution is to insert a script tag inside the for loop, but I dislike it for being messy.
Since your data is generated dynamically you could mark each select option with a class that specifies it's type like class="type1" and class="type2" so later you can do separate actions on them from the JS side. Or you could use the HTML data-* attribute to differentiate them.

Using javascript variable in python(flask/Django) dictionary html

I am trying to use a javascript variable in a python dictionary in html, is this possible? Any help would be great.
e.g if I had a dictionary - current_data
var num_key = "4";
alert( {{ current_data[num_key] }} );
If I do the following it works perfectly,
alert( {{ current_data["4"] }} );
But with the javascript variable, it won't work.
Thanks again.
No, while you can use Jinja to create JavaScript embedded in <script> tags, you cannot use it the other way around. When Flask renders this page it's static. The page does not still have blocks of code inside {{ }} or {% %}, it holds the result of those operations. However, there are other options. You could put the contents of current_data into hidden input with the keys as the id attributes.
View
{% for key in current_data %}
<input id="{{ key }}" type="hidden" value="{{ current_data[key] }}"/>
{% endfor %}
JavaScript
var num_key = "4";
alert(document.getElementById(num_key).value);
One extra piece of advice, it's not good practice to embed JavaScript into your html. You should have a separate .js file containing this and then include it in your html.

Categories

Resources