I have 2 radio buttons in a ChoiceField and I would like to display some parts of the template, depending of witch radio button is selected.
Following :
form.py
class CtdForm(forms.Form):
protocol_name = forms.CharField(max_length=100)
rb = forms.BooleanField(required=False, label='RB')
mr = forms.BooleanField(required=False, label='MR')
CHOICES = [('rb' ,'RB'), ('mr', 'MR')]
analyse_type = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect)
template html
...
{{ form.analyse_type }}
Here I would like to test which button is selected and display the template depending of the selection
something like : {% if form.analyse_type.? == true %}
...
I test a lot of syntaxe with form.analyse_type.? like form.analyse_type.field.widget.choices to have each choices in a loop ect. , but I do not found the right one returning the selected radiobutton...
Maybe this way is not the right one to do what I want.
If you have any idea, solution thank you ;)
Edit for user2497126
Thanks for all tips :) !
I have an error Uncaught Error: GET_ELEMENTS: -> form[data-sb-form-api-token] seems to be in link with the object analyse_type
As requested, following a print screen with the html element.I tired different synthaxe like
let radioValue =$("input[name='analyse_type']:checked").value();
I also put my HTML code in case
{% extends "index.html" %}
{% load static %}
{% block content %}
<div style="padding-left: 30%;" class="col-lg-6 col-xl-6"
<h2 class="h4 fw-bolder">
Analyse Type
</h2>
<br>
{{ form.analyse_type }}
<br> </div>
<div id="template-one" style="display:none;">
<div style="padding-right: 30%;" class="col-lg-6 col-xl-6">
<h2 class="h4 fw-bolder">
TEST
</h2>
</div>
</div>
{% endblock %}
{% block javascript %}
<script type="text/javascript">
$(document).ready(function () {
$(".custom-control-input").change(function () {
let radioValue = $("input[name='analyse_type']:checked").value();
let templateOne = document.getElementById('template-one')
if (radioValue == "rb") {
$("#template-one").show();
} else {
$("#template-one").hide();
}
});
});
</script>
{% endblock javascript %}
EDIT
if I do a
console.log($("input[name='analyse_type']:checked").val())
in the debugger of chrome I have a return of rb.
But the error is still there with no result.
I also change the html, include the template-one in the same div of the form like your example
The problem seems here
$(".custom-control-input").change(function () {
I replace .custom by select or select#id_analyse_type, based on some forum answers, but I have no result
Thanks for your time and your help :)
EDIT
Here the solution :
{% block javascript %}
<script type="text/javascript">
$(document).ready(function () {
let radioValue = $("input[name='analyse_type']:checked").val();
if (radioValue == "rb") {
$("#template-one").show();
} else {
$("#template-one").hide();
}
$('#id_analyse_type').change(function () {
let radioValue = $("input[name='analyse_type']:checked").val();
if (radioValue == "rb") {
$("#template-one").show();
} else {
$("#template-one").hide();
}
});
});
</script>
{% endblock javascript %}
Thank you for your help !
Here is an edited answer which I have tried to adapt to your question
For the change function (i.e when selecting the radio) inspect and replace the class value with the one in your radio input. Also ensure you supply the correct name when instantiating the variable radioValue, I have used 'analyze_type' for the sake of the example but inspect and confirm the correct name value of the radio input.
You can achieve it using JS like this in your template
{% extends "base.html" %}
{% block title %}Form title{% endblock title %}
{% block content %}
<!-- page content -->
<div class="x_content">
{{ form.analyse_type}}
<div id="template-one" style="display:none;">
Template one
</div>
<div id="template-two" style="display:none;">
Template two
</div>
</div>
<!-- /page content -->
{% endblock %}
{% block javascript %}
<script>
$(document).ready(function(){
$(".custom-control-input").change(function(){
let radioValue = $("input[name='analyse_type']:checked").val();
let templateOne = document.getElementById('template-one')
if(radioValue == "RB"){
$("#template-one").show();
$("#template-two").hide();
}
else {
$("#template-two").show();
$("#template-one").hide();
}
});
});
</script>
{% endblock javascript %}
I'm using AMP and Jinja to fetch some data and its not working. I have this example
<div>
<amp-render src="amp-script:dataFunctions.fetchData" layout="fixed-height" height="52">
<template type="amp-mustache">
{% for user in users %}
<div>
<h3>
{{user.name}}
</h3>
</div>
{% endfor %}
</template>
</amp-render>
<amp-script id="dataFunctions" script="fetch-data-script" width="52" height="52" data-ampdevmode>
</amp-script>
<script id="fetch-data-script" type="text/plain" target="amp-script">
function fetchData(index) {
return fetch('https://jsonplaceholder.typicode.com/users')
.then(response => response.json())
.then(findContinentsData)
}
function findContinentsData(json) {
console.log(json)
return json
}
exportFunction('fetchData', fetchData);
</script>
</div>
This is what my console returns
I cannot make it work even with different data samples. What can be the error here?
I want to iterate over an object I return from django view to create dynamically columns in a table (each column is a field in a model and I want to be able to switch the model without changing the template)
In the html body part of the template the same exact code worked fine, in the script section it's not.
My guess is the zip object pass as iterator that can consumed only once? if so how do I make django send a normal list object?
This is my view:
def HelperColumnesFieldsAndNames(data):
columns = { '<ManyToOneRel: client.paymentdata>':["unimp_pay","unimplemented"],
'<ManyToOneRel: client.subscribtiondata>':["subscribtiondata","unimplemented"],
'<ManyToOneRel: client.calldata>':["calldata","unimplemented"],
'<ManyToOneRel: client.extracommunicationdata>':["extracommunicationdata","unimplemented"],
'client.Client.creation_date':["creation_date","Creation Date"],
'client.Client.first_name':["first_name","First Name"],
'client.Client.last_name':["last_name","Last Name"],
'client.Client.address':["address","Address"],
'client.Client.city':["city","City"],
'client.Client.phone_number':["phone_number","Main Phone"],
'client.Client.creator_of_user':["creator_of_user","Client Creator"],
'client.Client.status':["status","Status"],
'client.Client.status_change_time':["status_change_time","Last Time Status Changed"],
'client.Client.allocated':["allocated","Currently Allocated To Talpan"],
'client.Client.group':["group","Owner Group"],
'client.Client.tags':["tags","Tags"],
'client.Client.tagged_items':["tagged_items","Tagged Item"],
}
column_name = []
column_field = []
for field in data:
field = str(field)
if field in columns.keys():
column_field.append(columns[field][0])
column_name.append(columns[field][1])
return zip(column_name, column_field)
# view function
def AllClientts(request):
user_groups = []
for groups in request.user.groups.all():
if groups.name != MANGER_GROUP_NAME:
user_groups.append(groups)
# get all object that belongs to the requested user groups
tableData = Client.objects.filter(group__in=user_groups)
return render(request, "client/clients.html", {"objects": tableData, "columns_name":HelperColumnesFieldsAndNames(Client._meta.get_fields()) })
Working example non in the script section
{% block content %}
<div class="d-flex pt-5 pb-2">
<!-- Need to be set to colums initials names using django -->
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Show
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton" id="swichable_column">
<!--reate fileds name and Showable names -->
{% for name in columns_name %}
<div class="checkbox">
<label>
<input type="checkbox" checked="checked" class="chackable_name" value="{{ name.1 }}">{{ name.0 }}</label>
</div>
{% endfor %}
</div>
</div>
</div>
<div id="example-table"></div>
{% endblock content %}
Script section in my tamplet - not working even do it's the same code
<script>
//define some sample data
var tabledata = [
{id:1, first_name:"Oli Bob", age:"12", col:"red", dob:""},
{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
{id:3, name:"Christine Lobowski the gratest and latest", age:"42", col:"green", dob:"22/05/1982"},
{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
];
$(function() {
var table = new Tabulator("#example-table", {
height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
data:tabledata, //assign data to table
layout:"fitColumns",
pagination:"local",
paginationSize:6,
paginationSizeSelector:[3, 6, 8, 10],
columns:[ //Define Table Columns
{% for name in columns_name %}
{title:"{{ name.0 }}", field:"{{ name.1 }}", align:"center", cellClick:function(e, cell){alert("cell clicked - " + cell.getValue())}},
{% endfor %}
]});
</script>
Apparently if I return zip object directly it's itearable and can be consume once only.
I replace zip() with list(zip()) and it's solved that issue
I'm trying to create a drag and drop function in my project that when ever i drop an item it automatically saves in the backend side.
<script style="text/javascript">
$(function() {
$( "#roles li" ).draggable({
appendTo: "body",
helper: "clone",
});
$( "#item-roles li" ).droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
accept: ":not(.ui-sortable-helper)",
drop: function( event, ui ) {
alert('you drop this')
$( "<li></li>" ).text( ui.draggable.text() ).appendTo( this );
}
})
});
In my Html code goes here.
<div id="item-roles">
<h3>Role in {{item.name|title}} Item</h3>
<ul>
<h3>Drag role here!</h3>
{% for item_role in item_roles %}
<li class="placeholder" style="list-style-type: none;">
{{item_role.show_role}} Remove
</li>
{% empty%}
<li>No items found</li>
{% endfor %}
</ul>
</div>
<div id="roles">
<h3>Roles in this Show</h3>
<ul>
{% for role in roles %}
<li>
<a class="role-detail">{{ role.role_name }}</a>
</li>
{% empty %}
<p>No show roles </p>
{% endfor %}
</ul>
You can use dajaxice (and dajax) for calling your django functions "from" javascript. Now you need to write down your python code which is missing from your question...
I have this code I'm using to generate a list of records categorized into year, make, series, body style, and color for vehicles. I'd like to customize this further this way:
for the year, I want to have only up to 2004 being individual...the rest will fall under other i.e. 2009, 2008, 2007, 2006, 2005, 2004, Other.
for the make, I want to display the six makes with the highest popularity...there's a field in the model I'm using to assign the popularity of a make with a value of primary (highest), secondary or tertiary. The rest will fall under Other.
For the body style and color, I want to have the items having less than 3 records falling under Other.
My code is as below:
year_count = vehicle_query.order_by(
'-common_vehicle__year__year').values('common_vehicle__year__year').
annotate(count=Count('id'))
make_count = vehicle_query.order_by(
'common_vehicle__series__model__manufacturer__manufacturer').
values('common_vehicle__series__model__manufacturer__manufacturer').
annotate(count=Count('id'))
style_count = vehicle_query.order_by(
'common_vehicle__body_style__style').values
('common_vehicle__body_style__style').annotate(count=Count('id'))
colour_count = vehicle_query.order_by(
'exterior_colour__exterior_colour').values(
'exterior_colour__exterior_colour').annotate(count=Count('id'))
The bulk of what you're asking would probably better be handled outside of Django and instead by client-side javascript. To be clear, you could have portions handled by Django, but it would be cleaner not doing so. There are benefits to doing it this way:
Your Django template code stays cleaner
It will degrade nicely
You can later update the interface (change the javascript) and not have to worry about breaking the Django template
To handle this you could simply make a script that when given a <ul> tag (and maybe some arguments) will render that list in the format you're asking about.
Here's a simple example using jQuery. For this example, I'm going to wrap the functionality in a using a jQuery plugin pattern.
Say your django template outputs the following...
<ul>
<li>Chevy</li>
<li>Mazda</li>
<li>Honda</li>
<li>Ford</li>
<li>BMW</li>
</ul>
jquery.showmorelist.js
(function($) {
$.fn.ShowMoreList = function(visibleItemCount) {
// Wrap parent element
var parent = $(this).wrap('<div class="show-more-list"></div>').parent();
var ul = $(this);
// Enumerate children and hide extras
var counter = 0;
$(this).children().filter('li').each(function(){
counter += 1;
if (counter > visibleItemCount) {
$(this).hide();
$(this).addClass('hidden');
}
});
// Add link and bind click
var link = $('> Show More').click(function(){
$(ul).children().filter('.hidden').show();
});
$(parent).append(link);
}
})(jQuery);
page.html
<script type="text/javascript" src="jquery.showmorelist.js"></script>
<script type="text/javascript">
// On page load...
$(function() {
$('ul').ShowMoreList(4); // Shows only the first 4 items
});
</script>
This is a rather simple example, and it won't switch the "Show More" to "Hide More" but you should be able to figure that out from the context.
I managed to get a solution, so I thought it'd be good to update the answer here:
In the head section I have this:
<script type="text/javascript" src="{{ MEDIA_URL }}share/jquery/jquery.min.js"></SCRIPT>
<script type="text/javascript">
(function($) {
$(document).ready(function() {
//hide the additional content under "Display More"
$("div.additional_content").hide();
$("a.more").click(function () {
//show or hide the additional content
$(this).siblings("div.additional_content").toggle();
//change the attributes and text value of the link toggle
if($(this).text() == "Display Less"){
$(this).removeClass("less");
$(this).addClass("more");
$(this).html("Display More");
}else{
$(this).removeClass("more");
$(this).addClass("less");
$(this).html("Display Less");
}
return false;
});
});
})(jQuery);
Then wherever I want to reduce the number of available options I have this:
<div class="module_wrap">
<div class="module"> {% if year_count %} <strong>{% trans "Year" %}</strong> <br />
{% for item in year_count|slice:":6" %}
<ul>
<li> {{ item.common_vehicle__year__year }} ({{ item.count }}) {% if request.session.chosen_year %} <img src="{{ MEDIA_URL }}img/undo.gif" border="0" alt="Remove Year Filter" title="Remove Year Filter" /> {% endif %} </li>
</ul>
{% endfor %}
<div class="additional_content"> {% for item in year_count|slice:"6:" %}
<ul>
<li> {{ item.common_vehicle__year__year }} ({{ item.count }})</li>
</ul>
{% endfor %} </div>
{% if year_count|slice:"6:" %}Display More<br />
{% endif %} <br />
</div>
</div>
{% endif %}