I want to create a page, some thing like browsing a file. Now I have this question:
I have some links in this page which are folders and files, and an "Open" button. I want when user press a key, the first link (file/folder) started with this character be selected. I also want when user double-clicks on each link or if clicks on each link and press "Open" button, i show the content of selected folder or if this is file the, I want the window to be closed. Now I want to know how can I understand when "Open" button is clicked, which item is selected?
<script type="text/javascript">
function func(id){
var label = $('<label/>').text(id).appendTo($('#div_for_labels'));
$('#div_show').html('waiting...').load('learning/?ajax=true&path='+id);
}
$('openButton').click(function(e){
e.preventDefault();
???
})
</script>
<div id="div_for_labels"></div>
<div id="div_show">
{% for f_name, f_type in list %}
{% if f_type == 'folder' %}
<p><a ondblclick="func(this.id)" id="{{ f_name }}" class="res"><img src="/media/img/folder.jpeg">{{ f_name }}</a></p>
{% else %}
<p><a ondblclick="func(this.id)" id="{{ f_name }}" class="res"><img src="/media/img/file.jpeg">{{ f_name }}</a></p>
{% endif %}
{% endfor %}
</div>
<div>
<input type="submit" id="openButton" value="Open">
</div>
I don't know what script should I write on "Open" button to understand which item is selected and so send its id to my view?
EDIT:
My views.py:
def learning(request):
if request.is_ajax():
if 'path' in request.GET:
# receives list
return render_to_response("path.html",{'list': list})
else:
# receives list
return render_to_response("learningPath.html",{'list': list})
The first time it goes to "learning.html" page which contains div for labels and "open" button. The other times because of preventing from repeating div for labels and "open" button, it goes to "path.html" which only contains:
{% for f_name, f_type in list %}
{% if f_type == 'folder' %}
<p><a ondblclick="func(this.id)" id="{{ f_name }}" class="res"><img src="/media/img/folder.jpeg">{{ f_name }}</a></p>
{% else %}
<p><a ondblclick="func(this.id)" id="{{ f_name }}" class="res"><img src="/media/img/file.jpeg">{{ f_name }}</a></p>
{% endif %}
{% endfor %}
Do not mix HTML and JavaScript, just do everything with jQuery.
<script type="text/javascript">
$(function() {
var _loadFile = function(file) {
if (file.type == 'folder') {
var label = $('<label/>').text(file.name).appendTo($('#div_for_labels'));
$('#div_show').html('waiting...').load('learning/?ajax=true&path='+file.name);
} else {
// load file here
}
};
var _selectedFile = null; // nothing selected;
// using '#div_show' as relative parent, fetch all 'a.res' elements...
$('a.res', $('#div_show')).live({ // bind now and any future elements
dblclick: function() {
var $this = $(this);
_loadFile($this.data('file'));
},
click: function() {
var $this = $(this);
$('#div_show a.res.file-selected').removeClass('file-selected'); // remove old selection (if any)
$this.addClass('file-selected');
_selectedFile = $this.data('file');
}
});
$('openButton').click(function(e){
e.preventDefault();
if (_selectedFile) {
_loadFile(_selectedFile);
} else {
alert("No file selected");
}
})
});
</script>
<div id="div_for_labels"></div>
<div id="div_show">
{% for f_name, f_type in list %}
<p><a data-file="{'name':'{{ f_name }}', 'type':'{{ f_type }}'}" class="res"><img src="/media/img/{{ f_type }}.jpeg">{{ f_name }}</a></p>
{% endfor %}
</div>
<div>
<input type="submit" id="openButton" value="Open">
</div>
Note : I assume that f_type is either folder or file.
** Edit **
Your path.html file should contain only the mentioned HTML chunk like above :
{% for f_name, f_type in list %}
<p><a data-file="{'name':'{{ f_name }}', 'type':'{{ f_type }}'}" class="res"><img src="/media/img/{{ f_type }}.jpeg">{{ f_name }}</a></p>
{% endfor %}
Related
I'm trying to create a way to export the HTML table to xlsx, but I have a large amount of data in the queries. So I need to use pagination with Paginator so the browser doesn't load the data all at once and end up causing TimeOut. But when applying the Paginator and exporting, it only exports what is on the current page. Any suggestions to improve this code, such as creating a loop so that it can export all pages?
View function:
def export_project_data(request, pk):
if str(request.user) != 'AnonymousUser': # só vai ter acesso se for diferente de AnonymousUser
individuals_list = Individual.objects.filter(Project=pk)
traps = Sample_unit_trap.objects.filter(Project=pk)
page = request.GET.get('page', 1)
paginator = Paginator(individuals_list, 1000)
try:
individuals = paginator.page(page)
except PageNotAnInteger:
individuals = paginator.page(1)
except EmptyPage:
individuals = paginator.page(paginator.num_pages)
path_info = request.META['PATH_INFO']
context = {
'individuals': individuals,
'pk': pk,
'traps': traps,
'header': 'export_project_data',
'path_info': path_info
}
return render(request, 'inv/index.html', context)
HTML paginator code:
<div class="table-div">
{% if individuals.has_other_pages %}
<ul class="pagination pagination-sm">
{% if individuals.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in individuals.paginator.page_range %}
{% if individuals.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if individuals.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
{% endif %}
Javascript html to xlsx code:
<script>
function html_table_to_excel(type)
{
var data = document.getElementById('data');
var file = XLSX.utils.table_to_book(data, {sheet: "Dados_Ecológicos"});
XLSX.write(file, { bookType: type, bookSST: true, type: 'base64' });
XLSX.writeFile(file, 'file.' + type);
}
const export_button = document.getElementById('export_button');
export_button.addEventListener('click', () => {
html_table_to_excel('xlsx');
});
</script>
It keep on saying:
"PAGE" is not defined.
My code:
{% if queryset.has_other_pages %}
<div class="pagination">
<ul class="container">
{% if queryset.has_previous %}
<li><a href="?page={{queryset.previous_page_number}}" class="btn page-link"
data-
page="{{queryset.previous_page_number}}">❮ Prev</a></li>
{% endif %}
{% for page in custom_range %}
{% if page == queryset.number %}
<li><a href="?page={{page}}" class="btn page-link btn--sub" dtata-page=
{{page}}">{{page}}</a></li>
{% else %}
<li><a href="?page={{page}}" class="btn page-link" dtata-page="{{page}}">
{{page}}</a></li>
{% endif %}
{% endfor %}
<!-- The below code works for Next button -->
{% if queryset.has_next %}
<li><a href="?page={{queryset.next_page_number}}" class="btn page-link"
data-page="{{queryset.next_page_number}}">Next ❯</a></li>
{% endif %}
</ul>
</div> {% endif %}
<script type="text/javascript">
//Get Page Search form and page links
let searchForm = document.getElementById('searchForm')
let pageLinks = document.getElementsByClassName('page-link')
// Ensure Search Form Exist
if(searchForm){
for (let i = 0; pageLinks.length > i; i++){
pageLinks[i].addEventListener('click', function (e) {
e.preventDefault()
//Get The Data Attribute
let page= this.dataset.page
//Add Hideen Search Input To Form
searchForm.innerHTML += `<input value=${page} name="page" hidden/>`
searchForm.submit()
})
}
} </script>
In my web site I want to show the user ratings - for that I used the infinite scroll but I am facing one problem.
When it first loads the data before calling the <a class="infinite-more-link" href="?page={{ ratings.next_page_number }}"></a> it is showing the star with the count of vote,but when after calling the <a class="infinite-more-link" href="?page={{ ratings.next_page_number }}"></a> it is not showing the star.
my views.py
#login_required
def ratings_user(request,pk):
ratings = VoteUser.objects.filter(the_user_id=pk).order_by('-pk')
paginator = Paginator(ratings, 1)
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request,request.session['is_mobile']+'profile/ratings.html',{'ratings':posts})
html
{% extends 'mobile/profile/base.html' %}
{% block title %}
Ratings
{% endblock %}
{% block leftcontent %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet">
{% endblock %}
{% block middlecontent %}
<div class="infinite-container">
{% for i in ratings %}
<div class="infinite-item">
<div class="w3-container w3-card w3-white w3-round w3-margin">
<img src="{{ i.the_user.profile.avatar.url }}" alt="Avatar" class="w3-left w3-circle w3-margin-right" style="width:40px;height:40px;border-radius:50%;">
{% with user=i.the_user.profile %}{{ user.prenom|title|truncatewords:2 }} {{ user.nom|title|truncatewords:1 }}{% endwith %}
<br>
<span class="stars" data-rating="{{ i.vote.vote }}" data-num-stars="5" ></span>
<hr class="w3-clear">
<p>
{{ i.commentaire|linebreaksbr }}
</p>
<span class="glyphicon glyphicon-user"></span> {% with user=i.the_sender.profile %}{{ user.prenom|title|truncatewords:2 }} {{ user.nom|title|truncatewords:1 }}{% endwith %}
</div>
</div>
{% endfor %}
</div>
{% if ratings.has_next %}
<a class="infinite-more-link" href="?page={{ ratings.next_page_number }}"></a>
{% endif %}
{% endblock %}
{% block rightcontent %}
{% endblock %}
{% block js %}
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0]
});
</script>
<script>
//ES5
$.fn.stars = function() {
return $(this).each(function() {
var rating = $(this).data("rating");
var fullStar = new Array(Math.floor(rating + 1)).join('<i class="fas fa-star"></i>');
var halfStar = ((rating%1) !== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
var noStar = new Array(Math.floor($(this).data("numStars") + 1 - rating)).join('<i class="far fa-star"></i>');
$(this).html(fullStar + halfStar + noStar);
});
}
//ES6
$.fn.stars = function() {
return $(this).each(function() {
const rating = $(this).data("rating");
const numStars = $(this).data("numStars");
const fullStar = '<i class="fas fa-star"></i>'.repeat(Math.floor(rating));
const halfStar = (rating%1!== 0) ? '<i class="fas fa-star-half-alt"></i>': '';
const noStar = '<i class="far fa-star"></i>'.repeat(Math.floor(numStars-rating));
$(this).html(`${fullStar}${halfStar}${noStar}`);
});
}
</script>
<script>
$(function(){
$('.stars').stars();
});
</script>
{% endblock %}
I have tried to put the <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet"> inside the class="infinite-item" but it does not help.what might be the reason for that ? Thanks.
Since yesterday I am on this question I tried everything.
This is another user that has tried to help me here https://stackoverflow.com/a/69930878/15042684 but I did not really understand could you please help me to understand it with some code.
this is his answer:
It doesn't look like .stars() will look for new elements being added to the DOM. You should look for a callback function configuration option within Waypoint.Infinite that you can call .stars() on the new elements.
Assuming you are using waypoint's Infinite Scroll, you can use the onAfterPageLoad callback
onAfterPageLoad
Default: $.noop.
Parameters: $items.
This is a callback that will fire at the end of the request cycle, after new items have been appended to the container. It is passed one parameter, which is a jQuery object of all the items that were appended during the page load.
Note that despite using the jquery convention of $name indicates a jquery object and stating is a jquery object, in this case, trial and error shows that $items are the DOM elements, not a jquery object.
No example provided in the docs, so it will probably look something like:
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
onAfterPageLoad: function(items) {
$(items).find(".stars").stars();
}
});
</script>
I'm building a web app using the Django framework. I'm attempting to use some JavaScript to disable a button that users can press to submit a text-based review.
The JavaScript in the listing.js file looks as follows:
document.addEventListener('DOMContentLoaded', function () {
hide_submit_review_button();
});
// Hide the 'Submit Review'button until the user begins typing a review
// Prevent the user from typing more than 100 characters
function hide_submit_review_button() {
var submit_review_button = document.getElementById('submit-review-button');
if (submit_review_button !== null) {
document.getElementById('submit-review-button').disabled = true;
document.getElementById('review-contents').onkeyup = () => {
if ((document.getElementById('review-contents').value.length > 0 &&
document.getElementById('review-contents').value.length <= 100 )) {
document.getElementById('submit-review-button').disabled = false;
} else {
document.getElementById('submit-review-button').disabled = true;
}
};
}
}
In my listing.html file, I identify the review-contents and submit-review-button. Here's the code:
{% extends "layout.html" %}
{% load static %}
{% block body %}
{% if user.is_authenticated %}
<form action="{% url 'review' listing.id %}" method="POST">
{% csrf_token %}
<input type="text" class="form-control" name="review" id="review-contents" placeholder="Write a review...">
<input class="btn btn-primary mt-1" type="submit" id="submit-review-button" value="Submit Review">
</form>
{% endif %}
{% endblock %}
{% block script %}
{% if user.is_authenticated %}
{{ block.super }}
<script src="{% static 'listing.js' %}"></script>
{% endif %}
{% endblock %}
An example of a page where the button appears is: http://127.0.0.1:8000/listings/7
And, here is what the urls.py file looks like (if it matters):
urlpatterns = [
path('', views.index, name='index'),
path('listings/<int:listing_id>', views.listing, name='listing'),
]
Can anyone see why this button doesn't disable?
Thanks!
The problem resulted from not having the following in the header tag in the layout.html file:
{% block script %}
{% endblock %}
(I know, bad title, pardon me)
So here's the thing:
I have a navbar with 3 icons and each one opens the same modal, but with different resources inside.
They are only clickable if resources exist for them, otherwise they are grayed out. Therefore 0, 1, 2 or all 3 of them can be visible or grayed out.
It works fine when all 3 are clickable, but if 1 or 2 are grayed out, the other opens an empty modal and the console shows assistance.js:29 Uncaught TypeError: Cannot read property 'style' of null.
This is how the twig looks and how the modal is populated and the modal itself:
<div class="assistance-body">
<nav>
<ul class="nav nav-tabs nav-justified nav-no-padding-top">
{% set allResources = ['videos', 'glossary', 'links'] %}
{% for key in allResources %}
{% if key in resources|keys %}
<li{% if loop.first %} ng-class="active" {% verbatim %}{{class}}{% endverbatim %} {% endif %} class="icon-resource">
<a
data-toggle=""
href="#assistance-{{ key }}"
segment-event="Modules: Tutor: Clicked {{ key|capitalize }} Section"
segment-not-track-if-class="active"
onclick="toggleAssistance('assistance-{{ key }}', ['assistance-videos', 'assistance-glossary', 'assistance-links'] )"
>
<i class="icon-{{ key }} icon-sm"></i>
<span class="sr-only">{{ ('resources.tabs.' ~ key ~ '.title') | trans }}</span>
</a>
</li>
{% else %}
<li{% if loop.first %} {% verbatim %}{{class}}{% endverbatim %} {% endif %} class="icon-resource">
<i class="icon-{{ key }} icon-sm icon-sm-gray"></i>
<span class="sr-only">{{ ('resources.tabs.' ~ key ~ '.title') | trans }}</span>
</li>
{% endif %}
{% endfor %}
</ul>
</nav>
<div id="assistance" class="assistance">
<div>
{% for key, data in resources %}
<div id="assistance-{{ key }}">
<button
type="button"
class="close"
onclick="toggleAssistance('assistance-{{ key }}', ['assistance-videos', 'assistance-glossary', 'assistance-links'] )"
aria-hidden="true">
×
</button>
{% include data.view with { 'category': data.category, 'resources': data.resources } %}
</div>
{% endfor %}
</div>
</div>
</div>
And this is the assistance.js:
function toggleAssistance (target, all) {
var targetAssistanceResource = document.getElementById(target);
var allAssistanceResources = [];
all.forEach(function (el) {
allAssistanceResources.push(document.getElementById(el));
});
// the resource is already opened, let's close it
if (getStyle(targetAssistanceResource, 'display') !== 'none') {
// hiding the main assistance div
document.getElementById('assistance').style.display = 'none';
// hiding all assistance resources
allAssistanceResources.forEach(function (res) {
res.style.display = 'none';
});
} else { // it's not opened, let's open it
// showing the main assistance div
document.getElementById('assistance').style.display = 'block';
// hiding all assistance resources
allAssistanceResources.forEach(function (res) {
res.style.display = 'none';
});
// showing the target assistance resource
targetAssistanceResource.style.display = 'block';
}
}
function getStyle (el, cssprop) {
if (el.currentStyle) { // IE
return el.currentStyle[cssprop];
} else if (window.getComputedStyle) {
return window.getComputedStyle(el)[cssprop];
}
// finally try and get inline style
return el.style[cssprop];
}