Django - how to add conditional drop down in templates from database - html

I am new to django. I need to put conditional drop-down on my web app based on the radio button selected by user in form. The idea is that based on radio button selection by user another drop-down should be populated on the form. This drop down will be a from a list of values that will be retrieved from database. The final value selected from this drop-down will do the main operation by pressin separate buttons. Please suggest how to do that. An example or link will surely help. Thanks
My example code is
<script>
function my_radio_select() {
var1 = document.getElementById("radio1");
var2 = document.getElementById("radio2");
var3 = document.getElementById("radio3");
if (var1.checked === true) {
window.location.href = "A.html";
}
else if(var2.checked === true) {
window.location.href = "A.html";
document.myform.action = "A.html";
}
else if(var3.checked === true) {
window.location.href = "A.html";
}
}
</script>
<br>
<br>
<br>
<input type="radio" id="radio1" name="project_type" value=0 checked onclick="my_radio_select();">
<label>Projects I own</label>
<br>
<input type="radio" id="radio2" name="project_type" value=1 onclick="my_radio_select();">
<label>Projects I manage</label>
<br>
<input type="radio" id="radio3" name="project_type" value=1 onclick="my_radio_select();">
<label>Projects I can edit</label>
{% endblock %}
class MyProjForm(ModelForm):
existing_projs = CSProj.objects.all()
choices_int = tuple((p.name, p.name) for p in existing_projs)
#tech = forms.ChoiceField(label='Existing Projects' ,widget=forms.Select(attrs={'class':'form-control'}),choices=choices_int,required=True)
tech = forms.ChoiceField(label='Existing Projects' ,widget=forms.Select(attrs={'class':'form-control'}),choices=choices_int,required=False)
class Meta:
model = CSProj
fields = ['name','user_workspace', 'compiler_path','ccs_path','tdk_path']
exclude = ('name','user_workspace', 'compiler_path','ccs_path','tdk_path')
def __init__(self, *args, **kwargs):
if 'user' in kwargs:
user = kwargs.pop('user')
super(MyProjForm, self).__init__(*args, **kwargs)
### Done to refresh choices as soon as it is added
existing_projs = CSProj.objects.filter(owner_id=user)
choices_int = tuple((p.name, p.name) for p in existing_projs)
self.fields['tech'].choices=choices_int

If you want to do all the stuff without reloading the page you need to use ajax. Django will only render the form for you.
1) Render all the required fields in a form (or two forms).
2) Hide those fields (or form) that should appear only if the radio button is checked (Using JS, jQuery).
3) Show the hidden stuff and get the necessary values from db using ajax as the radio button is checked.

Related

Get the radio button value in a form [duplicate]

I’m having some strange problem with my JS program. I had this working properly but for some reason it’s no longer working. I just want to find the value of the radio button (which one is selected) and return it to a variable. For some reason it keeps returning undefined.
Here is my code:
function findSelection(field) {
var test = 'document.theForm.' + field;
var sizes = test;
alert(sizes);
for (i=0; i < sizes.length; i++) {
if (sizes[i].checked==true) {
alert(sizes[i].value + ' you got a value');
return sizes[i].value;
}
}
}
submitForm:
function submitForm() {
var genderS = findSelection("genderS");
alert(genderS);
}
HTML:
<form action="#n" name="theForm">
<label for="gender">Gender: </label>
<input type="radio" name="genderS" value="1" checked> Male
<input type="radio" name="genderS" value="0" > Female<br><br>
Search
</form>
This works with any explorer.
document.querySelector('input[name="genderS"]:checked').value;
This is a simple way to get the value of any input type.
You also do not need to include jQuery path.
You can do something like this:
var radios = document.getElementsByName('genderS');
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
// do whatever you want with the checked radio
alert(radios[i].value);
// only one radio can be logically checked, don't check the rest
break;
}
}
<label for="gender">Gender: </label>
<input type="radio" name="genderS" value="1" checked="checked">Male</input>
<input type="radio" name="genderS" value="0">Female</input>
jsfiddle
Edit: Thanks HATCHA and jpsetung for your edit suggestions.
document.forms.your-form-name.elements.radio-button-name.value
Since jQuery 1.8, the correct syntax for the query is
$('input[name="genderS"]:checked').val();
Not $('input[#name="genderS"]:checked').val(); anymore, which was working in jQuery 1.7 (with the #).
ECMAScript 6 version
let genderS = Array.from(document.getElementsByName("genderS")).find(r => r.checked).value;
Here's a nice way to get the checked radio button's value with plain JavaScript:
const form = document.forms.demo;
const checked = form.querySelector('input[name=characters]:checked');
// log out the value from the :checked radio
console.log(checked.value);
Source: https://ultimatecourses.com/blog/get-value-checked-radio-buttons
Using this HTML:
<form name="demo">
<label>
Mario
<input type="radio" value="mario" name="characters" checked>
</label>
<label>
Luigi
<input type="radio" value="luigi" name="characters">
</label>
<label>
Toad
<input type="radio" value="toad" name="characters">
</label>
</form>
You could also use Array Find the checked property to find the checked item:
Array.from(form.elements.characters).find(radio => radio.checked);
In case someone was looking for an answer and landed here like me, from Chrome 34 and Firefox 33 you can do the following:
var form = document.theForm;
var radios = form.elements['genderS'];
alert(radios.value);
or simpler:
alert(document.theForm.genderS.value);
refrence: https://developer.mozilla.org/en-US/docs/Web/API/RadioNodeList/value
Edit:
As said by Chips_100 you should use :
var sizes = document.theForm[field];
directly without using the test variable.
Old answer:
Shouldn't you eval like this ?
var sizes = eval(test);
I don't know how that works, but to me you're only copying a string.
Try this
function findSelection(field) {
var test = document.getElementsByName(field);
var sizes = test.length;
alert(sizes);
for (i=0; i < sizes; i++) {
if (test[i].checked==true) {
alert(test[i].value + ' you got a value');
return test[i].value;
}
}
}
function submitForm() {
var genderS = findSelection("genderS");
alert(genderS);
return false;
}
A fiddle here.
This is pure JavaScript, based on the answer by #Fontas but with safety code to return an empty string (and avoid a TypeError) if there isn't a selected radio button:
var genderSRadio = document.querySelector("input[name=genderS]:checked");
var genderSValue = genderSRadio ? genderSRadio.value : "";
The code breaks down like this:
Line 1: get a reference to the control that (a) is an <input> type, (b) has a name attribute of genderS, and (c) is checked.
Line 2: If there is such a control, return its value. If there isn't, return an empty string. The genderSRadio variable is truthy if Line 1 finds the control and null/falsey if it doesn't.
For JQuery, use #jbabey's answer, and note that if there isn't a selected radio button it will return undefined.
First, shoutout to ashraf aaref, who's answer I would like to expand a little.
As MDN Web Docs suggest, using RadioNodeList is the preferred way to go:
// Get the form
const form = document.forms[0];
// Get the form's radio buttons
const radios = form.elements['color'];
// You can also easily get the selected value
console.log(radios.value);
// Set the "red" option as the value, i.e. select it
radios.value = 'red';
One might however also select the form via querySelector, which works fine too:
const form = document.querySelector('form[name="somename"]')
However, selecting the radios directly will not work, because it returns a simple NodeList.
document.querySelectorAll('input[name="color"]')
// Returns: NodeList [ input, input ]
While selecting the form first returns a RadioNodeList
document.forms[0].elements['color']
// document.forms[0].color # Shortcut variant
// document.forms[0].elements['complex[naming]'] # Note: shortcuts do not work well with complex field names, thus `elements` for a more programmatic aproach
// Returns: RadioNodeList { 0: input, 1: input, value: "red", length: 2 }
This is why you have to select the form first and then call the elements Method. Aside from all the input Nodes, the RadioNodeList also includes a property value, which enables this simple manipulation.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/RadioNodeList/value
Here is an Example for Radios where no Checked="checked" attribute is used
function test() {
var radios = document.getElementsByName("radiotest");
var found = 1;
for (var i = 0; i < radios.length; i++) {
if (radios[i].checked) {
alert(radios[i].value);
found = 0;
break;
}
}
if(found == 1)
{
alert("Please Select Radio");
}
}
DEMO : http://jsfiddle.net/ipsjolly/hgdWp/2/ [Click Find without selecting any Radio]
Source (from my blog): http://bloggerplugnplay.blogspot.in/2013/01/validateget-checked-radio-value-in.html
Putting Ed Gibbs' answer into a general function:
function findSelection(rad_name) {
const rad_val = document.querySelector('input[name=' + rad_name + ']:checked');
return (rad_val ? rad_val.value : "");
}
Then you can do findSelection("genderS");
lets suppose you need to place different rows of radio buttons in a form, each with separate attribute names ('option1','option2' etc) but the same class name. Perhaps you need them in multiple rows where they will each submit a value based on a scale of 1 to 5 pertaining to a question. you can write your javascript like so:
<script type="text/javascript">
var ratings = document.getElementsByClassName('ratings'); // we access all our radio buttons elements by class name
var radios="";
var i;
for(i=0;i<ratings.length;i++){
ratings[i].onclick=function(){
var result = 0;
radios = document.querySelectorAll("input[class=ratings]:checked");
for(j=0;j<radios.length;j++){
result = result + + radios[j].value;
}
console.log(result);
document.getElementById('overall-average-rating').innerHTML = result; // this row displays your total rating
}
}
</script>
I would also insert the final output into a hidden form element to be submitted together with the form.
I realize this is extremely old, but it can now be done in a single line
function findSelection(name) {
return document.querySelector(`[name="${name}"]:checked`).value
}
I prefer to use a formdata object as it represents the value that should be send if the form was submitted.
Note that it shows a snapshot of the form values. If you change the value, you need to recreate the FormData object. If you want to see the state change of the radio, you need to subscribe to the change event change event demo
Demo:
let formData = new FormData(document.querySelector("form"));
console.log(`The value is: ${formData.get("choice")}`);
<form>
<p>Pizza crust:</p>
<p>
<input type="radio" name="choice" value="regular" >
<label for="choice1id">Regular crust</label>
</p>
<p>
<input type="radio" name="choice" value="deep" checked >
<label for="choice2id">Deep dish</label>
</p>
</form>
If it is possible for you to assign a Id for your form element(), this way can be considered as a safe alternative way (specially when radio group element name is not unique in document):
function findSelection(field) {
var formInputElements = document.getElementById("yourFormId").getElementsByTagName("input");
alert(formInputElements);
for (i=0; i < formInputElements.length; i++) {
if ((formInputElements[i].type == "radio") && (formInputElements[i].name == field) && (formInputElements[i].checked)) {
alert(formInputElements[i].value + ' you got a value');
return formInputElements[i].value;
}
}
}
HTML:
<form action="#n" name="theForm" id="yourFormId">
I like to use brackets to get value from input, its way more clear than using dots.
document.forms['form_name']['input_name'].value;
var value = $('input:radio[name="radiogroupname"]:checked').val();

Post form data then render new template

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)

How is a radio button unchecked, if there's only one button?

I have these two radio buttons inside an Input Form:
<input type="radio" name="info_only_on" value="yes"> Info-only
<input type="radio" name="info_only_on" value="off"> (Clear Button)
It creates two buttons, so the user can check info-only and then turn off info-only if they made a mistake. I created the 2nd button because once the radio button is checked, clicking it again, doesn't deselect it.
I've switched to type="checkbox", which does let the user deselect.
<input type="checkbox" name="info_only_on" value="yes">
Looking at specs for the radio type button, I'm not seeing anything for the user unchecking it. What am I missing?
I'm using html, php and avoiding javascript.
The php used to check the box value is:
// When info_only_on is set to clear, it's value should be passed here as "no"
if($_POST["info_only_on"] == "yes")
{ $info_only = "Added Member info online but not paying online. "; }
else
{ $info_only = " "; }
// BUILD UP MESSAGE to email to our membership chair
$MsgToWrite = "\r\n" . $BasicInfo . $PhoneInfo . $EmailInfo;
If ($info_only <> " ")
{ $MsgToWrite = $MsgToWrite . "\r\n" . $info_only; }
I don't think that you can do it without javascript, here is a simple example :
HTML Code :
<input type="radio" name="name" id="radioBtn" onclick="test(this)" /> Radio
Javascript Code :
var radioState = false;
function test(element){
if(radioState == false) {
check();
radioState = true;
}else{
uncheck();
radioState = false;
}
}
function check() {
document.getElementById("radioBtn").checked = true;
}
function uncheck() {
document.getElementById("radioBtn").checked = false;
}
Take a look here : https://jsfiddle.net/eloufirhatim/ypwhugxz/
Unfortunately, there is no way to deselect a single radio button using HTML. In HTML, exactly one radio button needs to be selected. If you want the ability to deselect all radio buttons after one was selected, then you will have to use javascript for this.
From Wikipedia: "It is possible that initially none of the radio buttons in a group are selected. This unselected state cannot be restored by interacting with the radio button widget, though it may be possible through other user interface elements." https://en.wikipedia.org/wiki/Radio_button

retrieving value of dynamically built set of checkboxes

I have a set of dynamically built checkboxes (sub-categories of main-category).
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18001700">first</input>
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18001800">second</input>
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18001900">third</input>
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18002000">forth</input>
Now when I submit the form, when I return back to the form from Server (if didn't pass validation, for example) I would like to be able to reconstruct that list of checkboxes with their values. Assume that the first two checkboxes were checked by the user I would like to have something like this:
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18001700" checked>first</input>
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18001800" checked>second</input>
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18001900">third</input>
<input type="checkbox" name="SubCats" class="subcat-checkbox" value="18002000">forth</input>
I assume that I do that as one of the first things here:
(document).ready(function () {
loadSubCategories();
}
I am using ASP.NET MVC and I can't figure out how do I deliver that information into the View (the HTML). I assume this is a common task in web development. How is it done in general?
You can use the localStorage provided by the web browser to store javascript variables to save the states of the checkbox and restore the states when teh webpage is loaded again.
This is how I did it:
function save() {
var elems = document.getElementsByName("SubCats");
var states = [];
for (i = 0; i < elems.length; i++) {
states.push(elems[i].checked);
}
localStorage.setItem("checkboxStates", JSON.stringify(states));
}
function restore() {
if (localStorage.getItem("checkboxStates") !== null) {
var states = JSON.parse(localStorage.getItem("checkboxStates"));
var elems = document.getElementsByName("SubCats");
for (i = 0; i < elems.length; i++) {
elems[i].checked = states[i];
}
}
}
restore();
Here is the JSFiddle demo
In the demo, you can check any checkbox you like and click the Save states button. When you re run the code, you will see that it keeps the previous settings.
The flow:
When you click the Save states button, the save() function is called and it builds an array of the checkbox states sequentially and serializes them before storing them in the localStorage.
When the page is loaded again, the restore() function is triggered by default. This checks if there are states saved before. And if there are, it deserializes then and then loops through the available checkboxes, setting the states back as previously saved.
Also note that the info stored in the localStorage can be accessed on any page and therefore the data is always available.
You can also read about sessionStorage.
Thank you all for all the help. These are all interesting suggestions, especially the one using localStorage which I have never used and perhaps I should give it a look.
Anyway, I decided to go for the naive way. I am keeping the checked Sub-Categories in a hidden text field separated by commas and then when building the tag again I am checking for every Sub-Category whether it has been checked before.
Here is my code:
function loadSubCategories() {
if ($("#ddlCategory").val() != "-1") {
var SubCatsCheckboxes = {};
SubCatsCheckboxes.url = "/BLHelpers/GetSubCats";
SubCatsCheckboxes.type = "POST";
SubCatsCheckboxes.data = JSON.stringify({ CategoryId: $("#ddlCategory").val() });
SubCatsCheckboxes.datatype = "json";
SubCatsCheckboxes.contentType = "application/json";
SubCatsCheckboxes.success = function (SubCatsList) {
var sub_cats = $("#SubCatsStr").val().split(",");
$("#SubCatsDiv").empty();
$.each(SubCatsList, function (index, value) {
var option_to_append = "<input type=\"checkbox\" name=\"SubCats\" class=\"subcat-checkbox\" value=\"" + value.SubCategoryId + "\"";
if ($.inArray(value.SubCategoryId.toString(), sub_cats) != -1) {
option_to_append += " checked "
}
option_to_append += ">" + value.Caption + "</option><br/>";
$("#SubCatsDiv").append(option_to_append);
});
};
$.ajax(SubCatsCheckboxes);
}
else {
$("#SubCatsDiv").empty();
}
}
Where :
<input id="SubCatsStr" name="SubCatsStr" type="hidden" value="#Model.SubCatsStr" />
is my hidden field that keeps the checked Sub Categories ids.

HTML nav menu/form list that redirects on button click

Here is what I'm trying to do, and I feel as though maybe I'm overthinking it. I can easily make a dropdown nav list, but what I need is to combine two different dropdown lists to give a user options, then when they click the button it will send them to a page that corresponds with their choices.
For example, dropdown list one: What type of advice do you need?
-Career
-Relationships
-Health
droplist two: What layout do you want?
-Quick and Dirty
-Standard
-In-depth
Then I just need to program in the link to every combination of these pages. How do program in the correct redirects depending on the selections?
Assuming you have a pair of drop-down menus like this:
<form method="post">
<p>What type of advice do you need?
<br><select id="s1">
<option>Career</option>
<option>Relationships</option>
<option>Health</option>
</select>
<p>What layout do you want?
<br><select id="s2">
<option>Quick and Dirty</option>
<option>Standard</option>
<option>In-depth</option>
</select>
<input type="button" onclick="send(this.form)" value="Send"/>
</form>
The button at the end of the form, when clicked calls a function that will redirect to the page you want comparing the items selected in each menu. The function should receive a reference to the form (passed in this.form), get the selected indexes and text (or values, if you use them in each option) and test them in a condicional branch:
function send(form) {
var s1 = document.getElementById("s1");
var s2 = document.getElementById("s2");
var choice1 = s1.options[s1.selectedIndex].text;
var choice2 = s2.options[s2.selectedIndex].text;
if (choice1 == "Career" && choice2 == "Quick and Dirty") {
location.href = "http://quickdirtycareers.com";
} else if (choice1 == "Career" && choice2 == "Standard") {
location.href = "http://standardcareers.com";
} else {
location.href = "http://careers.stackoverflow.com";
}
}
Here's a Fiddle with a working sample: http://jsfiddle.net/helderdarocha/TNZ9A/
(There are many other ways to do it, adding CSS, dynamic selection, focus, etc. It's easier to add these enhancements using JQuery.)