I'm creating a sport app with django. I would like to display a list of matches with a countdown for each match.
For now, I only have one countdown. I use this Jquery countdown: http://keith-wood.name/countdown.html (that goes to the new year). I have a loop to display my matches. So the question is how can I insert the countdown into the loop and make it go to the DateTime of my objects "match"?
Here is my template:
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<style type="text/css">#import "/Users/marc-a antoine.lacroix/Desktop/Jquery/jquery.countdown.package-1.6.0/jquery.countdown.css";</style>
<script type="text/javascript" src="http://keith-wood.name/js/jquery.countdown.js"> </script>
<script language="javascript">
$(document).ready(function(){
var newYear = new Date();
newYear = new Date(newYear.getFullYear() + 1, 1 - 1, 1);
$('#defaultCountdown').countdown({until: newYear});
});
</script>
</head>
<body>
<div style="float:left">
{% for match in matches %}
<div>
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
Go
</div>
{% endfor %}
</div>
<div id="defaultCountdown"> </div>
</body>
"matches" is the list containing every matches. "real_start" is the DateTime of my objects "match"
My views.py is simply:
def page(request):
matches = Match.live_matches.all()
return render_to_response('myhtml.html', {'matches': matches}, context_instance=RequestContext(request))
So I don't know how to import my "real_start" DateTime into the countdown and how to insert this countdown into the loop.
Here is my current code:
<script language="javascript">
$(function(){
$('.match_wrap').each(function(){
var match_start=$(this).data('match_start');
$(this).find('.matchTimer').countdown({until: match_start});
});
})
</script>
</head>
<body>
<div style="float:left">
{% for match in matches %}
</br></br>
<div class="match_wrap" data-match_start="{{ match.real_start|date:"M j, Y" }}">
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
<div>
<ul>
{% for team in match.teams %}
<li>
<img src="{{ team.logo.url }}">
</li>
{% endfor %}
</ul>
</div>
Go
<div class="matchTimer"> </div>
</div>
{% endfor %}
</div>
</br></br>
I also tried:
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="http://keith-wood.name/js/jquery.countdown.js"></script>
<script language="javascript">
$('.match_countdown').each(function() {
var self = $(this),
date_string = self.attr('data-date'),
date = new Date.parse(date_string);
self.countdown({until: date});
});
</script>
</head>
<body>
<div style="float:left">
{% for match in matches %}
</br></br>
<div class="match_countdown" data-date="{{ match.real_start|date:'M j, Y' }}"></div>
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
<div>
<ul>
{% for team in match.teams %}
<li>
<img src="{{ team.logo.url }}">
</li>
{% endfor %}
</ul>
</div>
Go
</div>
{% endfor %}
</div>
Similar to charlietfl's answer but js parses the correct date.
{# template #}
{% for match in matches %}
<div>
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
Go
<div class="match_countdown" data-date="{{ match.real_start|date:'M j, Y' }}"></div>
</div>
{% endfor %}
and then the js:
$('.match_countdown').each(function() {
var self = $(this),
date_string = self.attr('data-date'),
date = new Date(date_string);
self.countdown({until: date});
});
Here (http://jsfiddle.net/miki725/MQcYw/1/) js jsfiddle which illustrates the solution.
WHenever you need to invoke a plugin on many elements that requires different data for each instance is often easiest to loop over the elements involved and call each instance from within the loop.
Something like this should be easy to implement:
HTML
{% for match in matches %}
<div class="match_wrap" data-match_start="{{match.startFormattedToCountDownPlugin}}">
<p>{{ match }}</p>
<p> {{match.real_start}} <p>
Go
</div>
<div class="matchTimer"> </div>
</div>
{% endfor %}
JS
$(function(){
$('.match_wrap').each(function(){
var match_start=new Date.parse($(this).data('match_start'));
$(this).find('.matchTimer').countdown({until: match_start});
});
})
Related
I have created a _layout.twig file which acts as my base to hold content on the page -> _layout.twig:
<!DOCTYPE html>
<html lang="{{ craft.app.language }}">
<head>
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<meta charset="utf-8" />
<title>
{{ siteName }}
</title>
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
name="viewport" />
<link rel="stylesheet"
href="https://unpkg.com/leaflet#1.4.0/dist/leaflet.css"
integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
crossorigin="" />
{% includeCssFile siteUrl ~ 'assets/css/style.css' %}
</head>
<body>
{% include '_includes/nav' %}
<div>
{% block content %}
{% endblock %}
</div>
<footer class="main-footer">
<div class="footer-wrapper">
{{ exampleInformation.exampleDescription|markdown }}
<p>
© {{ now|date('Y') }}, Lorem Ipsum
</p>
</div>
</footer>
<script src="https://unpkg.com/leaflet#1.4.0/dist/leaflet.js" integrity="sha512QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg==" crossorigin=""></script>
{% includeJsFile siteUrl ~ 'assets/js/scripts.js' %}
</body>
</html>
Through the control panel in craft CMS I created an entry that contains a table that has a series of coordinates (longitude and latitude values) and a lightswitch to toggle it on or off, along with some other general information for each entry that is created e.g. title, date, image, etc. on a separate tab.
The _entry.twig page extends _layout.twig -> _entry.twig:
{% extends '_layout' %}
{% set featureImage = {
mode: 'crop',
width: 600,
height: 600,
quality: 90
} %}
{% block content %}
<div class="entry__container">
<div class="entry__wrapper">
<div class="entry__title">
<h1>
{{ entry.title }}
</h1>
</div>
<div class="entry__image">
{% if entry.featureImage|length %}
{% for image in entry.featureImage.all() %}
<img src="{{ image.getUrl(featureImage) }}"
alt="{{ image.title }}" />
{% endfor %}
{% endif %}
</div>
<div>
{% for block in entry.exampleContent.all() %}
<div class="entry__description">
{% if block.type == 'text' %}
{{ block.text }}
{% elseif block.type == 'image' %}
{% for image in block.image.all() %}
<img src="{{ image.url }}" alt="{{ image.title }}" />
{% endfor %}
{% endif %}
</div>
{% endfor %}
</div>
{# display post categories #}
{% if entry.exampleCategories|length %}
<div class="entry__category">
<p>
Categories
</p>
{% for category in entry.exampleCategories.all() %}
{{- category.title -}}
{% endfor %}
</div>
{% endif %}
{# display table info #}
{% if entry.lotInfo|length %}
<div class="entry__coordinate">
<ul>
{% for row in entry.lotInfo %}
{% if row.createNewEntry == '1' %}
<li>
<div data-latCoordinate="{{ row.latitude }}"
id="latCoordinate">
{{ row.latitude }}
</div>,<div data-lngCoordinate="{{ row.longitude }}"
id="lngCoordinate">
{{ row.longitude }}
</div>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{# end table info #}
</div>
</div>
{% endblock %}
I was able to put together this small section in _entry.twig which looks at the table and if the lightswitch is set to 1, it outputs the corresponding latitude and longitude values in the row:
{# display table info #}
{% if entry.lotInfo|length %}
<div class="entry__coordinate">
<ul>
{% for row in entry.lotInfo %}
{% if row.createNewEntry == '1' %}
<li>
<div data-latCoordinate="{{ row.latitude }}"
id="latCoordinate">
{{ row.latitude }}
</div>,<div data-lngCoordinate="{{ row.longitude }}"
id="lngCoordinate">
{{ row.longitude }}
</div>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{# end table info #}
These values are currently displaying on the front end entry page which will show the coordinates depending on which lightswitch toggle is active- which has allowed me to ensure that it is pulling the correct coordinates corresponding to the correct information.
Now, I have an external js file linked which lives in local/craft/assets/js/*.js and contains this script -> scripts.js:
//Set initial map view
var map = L.map('map', { scrollWheelZoom: false }).setView(
[50.4205, -104.52],
15,
)
//Initialize the tilemap
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
minZoom: 14.5,
attribution:
'© OpenStreetMap contributors',
}).addTo(map)
// Set location array
var locations = [{ lat: 'SOME LATITUDE COORDINATE', lng: 'SOME LONGITUDE COORDINATE' }]
function addToMap(locationArray) {
//Iterate through array object
;[].forEach.call(locationArray, function (location) {
var marker = L.marker([location.lat, location.lng]).addTo(map)
})
}
//Show markers
addToMap(locations)
Currently, this script will create a leaflet/osm map and then based on:
// Set location array
var locations = [{ lat: '(SOME LATITUDE VALUE)', lng: '-(SOME LONGITUDE VALUE') }];
will output a marker to the map (currently only works if I manually insert lat and long coordinates) which lives in my index.twig template file -> index.twig:
{% extends '_layout' %}
{% set posts = craft.entries.section('example').all() %}
{% block content %}
<div class="background-test">
<div id="map"></div>
</div>
<div class="main-container">
<div class="main-wrapper">
<h1 class="example-title">
Some Title
</h1>
<div class="category-list">
{% set entries = craft.entries.limit(null) %}
{% for category in craft.categories.relatedTo(entries).order(
'title asc'
) %}
{% set entryCount = entries.relatedTo(category).total() %}
<a href="{{ category.url }}">
{{- category.title -}}<span class="count-number">({{ entryCount }})</span>
</a>
{% endfor %}
</div>
{% include '_includes/listing' with {
posts: posts
} only %}
</div>
</div>
{% endblock %}
What would be the best way to somehow use the
{{ row.latitude }}, {{ row.longitude }}
variables from my _entry.twig file in my existing scripts.js file to place a marker(s) on the map which lives on the index.twig page? I am still new to Craft and more so with Twig so I am still in the process of learning these things.
My folder structure is:
/assets
/css
/js
scripts.js
/templates
/includes
/blog
_category.twig
_entry.twig
index.twig
_layout.twig
index.html
Any help would be greatly appreciated!
Thank you
Ok some pointers first, you can add multiple data-* attributes to one element, also id's need to be unique. So I'd suggest you'd swap up the twig template to the following:
{% if entry.lotInfo|length %}
<div class="entry__coordinate">
<ul>
{% for row in entry.lotInfo %}
{% if row.createNewEntry == '1' %}
<li data-latCoordinate="{{ row.latitude }}" data-lngCoordinate="{{ row.longitude }}">
{{ row.latitude }}, {{ row.longitude }}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
Then we need to adjust your javascript to be able to add multiple dots on the map.
First remove the following line
// Set location array
var locations = [{ lat: 'SOME LATITUDE COORDINATE', lng: 'SOME LONGITUDE COORDINATE' }]
As you've defined the pointers in html we just need a selector that selects all the elements where the data-* attributes are defined in
<script>
document.querySelectorAll(".entry__coordinate ul li").forEach(row => {
addToMap({ 'lat': row.dataset.latcoordinate, 'lng' : row.dataset.lngcoordinate, });
});
</script>
shown below is template of blog.when user likes a post,ajax will call a corresponding view function to do job.For every post,it will have a unique id which i use here for reference.Problem is if i like anypost,the like is going to recently uploaded post.I don't know much about ajax..Please help me.Thank you.
{% load static %}
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>blog page</title>
</head>
<body>
{% for post in posts %}
<h1><a href='{% url "blog:blogpostdetails" post.id %}'>{{ post.post_title }}</h1>
<p>loc: <a href='#'>{{ post.post_location }}</a></p>
<p>{{ post.post_content|truncatewords:7 }}</p>
<p>posted on {{ post.post_timestamp }}</p>
<p>posted by <a href='{% url "index:userprofile" post.post_id.username %}'>{{ post.post_id }}</a></p>
<form method='POST' id='something'>
{% csrf_token %}
<input type='hidden' id='postid' name='postid' data-id='{{post.id}}'>
<input type='submit' value='like this post'>
</form>
<p>total like {{ post.likes }}</p>
<p>-------------------------------------------------------------------</p>
{% endfor %}
<div class='tooltip'><h3>new post</h3></div>
</body>
</html>
<style type="text/css">
.tooltip {
width: 200px;
position: fixed;
top:0px;
right:0px;
left:auto;
}
</style>
{% block javascript %}
<script type='text/javascript'>
$(document).on('submit','#something',function(e){
e.preventDefault();
console.log($('#postid').attr('data-id'))
$.ajax({
type:'POST',
url:'{% url "blog:blogpostlike" %}',
data:{
postid:$('#postid').attr('data-id'),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
success: function(){
alert('you liked post');
}
});
});
</script>
{% endblock %}
I have an issue. I could not trigger the onclick event on the link using Django and Python. I am providing my code below.
base.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
{% load static %}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var query='';
function pageTransition(){
var full_url = window.location.search;
var url = full_url.replace("?", '');
query=url.file;
console.log('query',query);
var url="'"+query+"'";
$.getScript(url,function(){
$('a').velocity("scroll", { duration: 1000 });
})
}
</script>
</head>
<body>
<header>
<h1>Nuclear Reactor</h1>
{% if count > 0 %}
<b>Hi, {{ user.username }}</b>
Home
View Reactor status
logout
{% else %}
login / signup
{% endif %}
<hr>
</header>
<main>
{% block content %}
{% endblock %}
</main>
</body>
</html>
home.html:
{% extends 'base.html' %}
{% block content %}
<center><h1>Welcome</h1>
<p>This App allow to control the life cycle of the Nuclear Reactor and Retrive the status report </p>
<p>Status reportControl panel</p>
</center>
{% endblock %}
total html generated output after click on home link:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var query='';
function pageTransition(){
var full_url = window.location.search;
var url = full_url.replace("?", '');
query=url.file;
console.log('query',query);
var url="'"+query+"'";
$.getScript(url,function(){
$('a').velocity("scroll", { duration: 1000 });
})
}
</script>
</head>
<body>
<header>
<h1>Nuclear Reactor</h1>
<b>Hi, </b>
Home
View Reactor status
logout
<hr>
</header>
<main>
<center><h1>Welcome</h1>
<p>This App allow to control the life cycle of the Nuclear Reactor and Retrive the status report </p>
<p>Status reportControl panel</p>
</center>
</main>
</body>
</html>
Here I need to get that query string value and include it inside that JavaScript function but the JavaScript function is not called at all.
I've been trying to create a webpage where after receiving user input, it would display the history of all user input after pressing submit, however this is working as intended. However I wanted to implement an alert box which would show additional information. However as everything else is printed correctly, since the alert box uses an onclick event, it would only output the very last sample of user input.
<!doctype html>
<html>
<head>
<title>Enrolment page</title>
</head>
<body>
{% if all_users %}
{% for user in all_users %}
<h1> Hi, {{ user[0] }}) </h1>
<button onclick="myFunction()">Details</button>
<script>
function myFunction() {
alert("{{ user[1] }}, {{ user[2] }}");
}
</script>
{% endfor %}
{%else%}
No users to show
{% endif %}
</body>
</html>
In my code, all_users is the information from a csv file, however that is working fine. My only problem is the alert is not showing the information I want. Is there a way to store each set of user details in each script to print out each button since it is only displaying the last set of user details.
You can bind the user[0] and user[1] in the myFunction() call like:
{% for user in all_users %}
<h1> Hi, {{ user[0] }}) </h1>
<button onclick="myFunction('{{user[1]}}, {{user[2]}}')">
Detail
</button>
{% endfor %}
Then change the function to:
function myFunction(users) {
alert(users);
}
To work this in Jinja2, you might try using a string variable and appending each value as in (code not tested):
<!doctype html>
<html>
<head>
<title>Enrolment page</title>
</head>
<body>
{% if all_users %}
{% set AllUserList = "" %}
{% for user in all_users %}
{% set AllUserList = AllUserList + user[1] + ", " + user[2] + "\n" %}
<h1> Hi, {{ user[0] }}) </h1>
<button onclick="myFunction()">Details</button>
<script>
function myFunction() {
alert("{{ AllUserList }}");
}
</script>
{% endfor %}
{%else%}
No users to show
{% endif %}
</body>
</html>
my issue when I search on my site using jquery it is only searching on the page that is displayed at the moment and I would like it to search all of my data and then display on the page accordingly, which is about 2.6 M entries. I am using the core django paginator for my pagination and using simple jquery and ajax for my search tool. Please help!
heres my view:
def tissues(request):
contact_list = TissueTable.objects.all()
paginator = Paginator(contact_list, 100) # Show 25 contacts per page
page = request.GET.get('page')
try:
contacts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
contacts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
contacts = paginator.page(paginator.num_pages)
return render(request, '.html', {'contacts': contacts})
heres my two templates, base and home,
base.html:
<html>
<head>
<title>Animal NGS DATA</font></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$('a[rel="external"]').attr('target', '_blank');
</script>
<style>
th
{
border-bottom: 1px solid #d6d6d6;
}
tr:nth-child(even)
{
background:#e9e9e9;
}
</style>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<h1 left>NGS CUFFLINK'S DATA</h1>
</div>
<div data-role="main" class="ui-content">
<form>
<input id="filterTable-input" data-type="search" placeholder="Search Tissue Data...">
</form>
<table data-role="table" data-mode="columntoggle" class="ui-responsive ui-shadow" id="myTable" data-filter="true" data-input="#filterTable-input">
</head>
<body>
<map title="Navigation Bar">
<P>
NGS Data
Genes
Experiment
Organisms
Tissue Data
</P>
</map>
<h1><font color='red'>Tissue Data</font></h1>
{% block content %}
{% endblock %}
</body>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'myapp/style.css' %}" />
</html>
and my home.html
{% extends "tissues/base.html" %}
{% block content %}
<!--<table id='table' data-mode="columntoggle" border = '10' bordercolor = 'mahogany'>-->
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
<table data-role="table" id="myTable" class="ui-responsive ui-shadow" data-filter="true" data-input="#filterTable-input" bgcolor = 'cyan'>
<thead>
<tr bgcolor = 'pink'>
<th>Tissue ID</th>
<th>Tissue Term</th>
<th>Definition</th>
</tr>
<thead>
<tbody>
{% for b in contacts.object_list%}
<tr>
<td>{{b.tissue_id}}</td>
<td>{{b.tissue_term}}</td>
<td>{{b.definition}}</td>
</tr>
{% endfor %}
</table>
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
{% endblock %}
Looks like you need separate view function, and deliver it results separately via ajax. May be something like this one:
def ajax_activity_objects_search(request):
search_phrase = request.GET.get('q')
matched = ActivityObject.objects.filter(
address__icontains=search_phrase,
)
response = ''
for act_object in matched:
response += '<option value="' + str(act_object.id) + '">' \
+ act_object.address + '</option>'
return HttpResponse(response)