I need to display 10 Song objects at a time with a load more button at bottom that loads 10 more results. This keeps on happening until no more results are available and the load more button is not displayed at that time.
This is what i've come up with
$(document).ready(function () {
$('#song_list div:lt(10)').show();
//var items = ?
//var shown = ?
$('#loadMore').click(function () {
shown = $('#song_list div:visible').size()+10;
if(shown<items) {$('#song_list div:lt('+shown+')').show();}
else {$('#myList li:lt('+items+')').show();
$('#loadMore').hide();
}
});
});
How can I get the values of number of items and number of items shown?
This is the code to display the song list
<div id='song_list'>
{% for song in dj_song_list %}
<div>
<p class="song"><h3>#{{ forloop.counter}} {{ song.name }}</h3></p>
</div>
{% endfor %}
</div>
<button id='loadMore'>Load more</button>
Close the paragraph..."</p>"
<div id='song_list'>
{% for song in dj_song_list %}
<div>
<p class="song"><h3>#{{ forloop.counter}} {{ song.name }]</h3></p>
</div>
{% endfor %}
</div>
<button id='loadMore'>Load more</button>
Try this: http://jsfiddle.net/gebm4/2/
var max_items_page = 2;
$('#song_list div:lt('+max_items_page+')').show();
var shown = null;
var items = $("#song_list").find('div').length;
$('#loadMore').on('click',function(e){
shown = $('#song_list div:visible').length+max_items_page;
if(shown<items) {
$('#song_list div:lt('+shown+')').show();
}else {
$('#myList li:lt('+items+')').show();
$('#loadMore').hide();
}
});
Related
So what I have is a simple form with couple of fields that is located inside a menu, that slides in when I click button 'btn-openmenu'. I am trying to use htmx to dynamically update the page to show results instantly and also Javascript to control the menu where the form is located.
What I am trying to accomplish is that when the submit button on the form is pushed, it will submit the form and close the menu.
What happens now is that the menu closes okay when the form is submitted. What also can happen is that if the form is not valid and a error pops up, but the menu still closes and the form is never submitted.
Here is the html where form is located form (/items/new-item/):
{% load crispy_forms_tags %}
<form id="createnewitem"
hx-post="/items/new-item/">
{% csrf_token %}
{{ newcoreprocess|crispy }}
<div style="margin-top: 10px;">
<button type="submit" class="btn submit-new">Create item</button>
<a class="btn" id="clear">Clear</button>
</div>
</form>
<script>
$(document).ready(() => {
$('#clear').on('click', function () {
var form = $("#createnewitem");
form[0].reset();
})
})
</script>
<script>
$(document).ready(() => {
$('.submit-new').click(function () {
var pagecontent = $("#content");
var menu = $(".menu");
var buttonSpan = $("#btn_openmenu").find('span');
pagecontent.css('marginLeft', '0');
menu.css('width', '0');
buttonSpan.text('Close');
})
})
</script>
Here is the html where the menu is opened and updated list would be rendered (/items/):
<div class="items-content" id="itemcontent">
<div class="container-fluid">
<div class="row" id="items-list">
{% include 'items/items-list.html' %}
</div>
</div>
<button class="btn" id="btn_openmenu"
hx-get="/items/new-item/"
hx-target="#createitemmenu"
hx-swap="innerHTML">
<i class="fas fa-plus-circle" id="add-item-icon"></i><span class="spanicon" id="add-item-span">Create item</span>
</button>
<div class="menu">
<div class="container-fluid" id="createitemmenu">
</div>
</div>
</div>
<script>
$(document).ready(() => {
$('#btn_openmenu').on('click', function () {
var thisElement = $(this);
var buttonSpan = thisElement.find('span');
var pagecontent = $("#itemcontent");
var menu = $(".menu");
if(buttonSpan.text() === "Close"){
buttonSpan.text('Create item');
menu.css('width', '0');
pagecontent.css('marginLeft', '0');
}
else {
if(buttonSpan.text() === "Create item"){
buttonSpan.text('Close');
pagecontent.css('marginLeft', '20%');
menu.css('width', '20%');
}
}
})
})
</script>
And here is the list (/items/item-list/)
{% if items %}
<nav class="nav processnav flex-column" style="padding-top: 10px;">
{% for item in items %}
<a class="nav-link" href="#">{{ item.order }} {{ item.name }}</a>
{% endfor %}
</nav>
{% else %}
<div class="container-fluid mt-3">
<span>No created items</span>
</div>
{% endif %}
What is working:
menu opens correctly
htmx renders the form in the menu
form can be submitted and if valid, the menu will close
What is not working:
if errors on submit, it still closes the menu
I have tried to edit the function submit-new.click, but whatever I change in that, it stops working at all and this is only function I got to work with valid submit
htmx doesn't render the updated list where new item is created
I have tried to edit the hx-post in the form, but whatever I edit the new item submit stops working and it renders some other content to the place, where the form is located.
I think there are just little things I am missing, but I cannot seem to get it function the way I want. Any help for the issue?
This is my drop down
<div class="dropdown" >
<button onclick="myFunction()" class="dropbtn">Course List</button>
<div id="myDropdown" class="dropdown-content">
<input type="text" placeholder="Search.." id="myInput" onkeyup="filterFunction()">
{% for list in list1%}
<a id="courseName" onclick="addCourse()"> {{list.courseName}}</a>
{% endfor %}
</div>
</div>
here i am trying to access value of the selected course name
function addCourse() {
var x = document.getElementById("courseName").value
document.getElementById("demo").innerHTML = x;
}
But this is giving me "undefined" as a result.
looks like you are running a loop, don't use the id for multiple elements, Id's must be unique, instead use classes.
not sure what what language you are using, laravel? anyway try this.
{% for list in key=>list1%}
<a class="courseName" onclick="addCourse(e)"> {{list.courseName}}</a>
{% endfor %}
</div>
function addCourse(e){
var x = e.target.textContent
document.getElementById("demo").innerHTML = x;
}
I think you want a dynamic element
` {% for list in list1%}
<a id="courseName" onclick="addCourse(this)" name ={{list.courseName}} >
{{list.courseName}}</a>`
{% endfor %}
function addCourse(obj){
var x = $(obj).attr("name");
alert(x);
}
`
Im working on an interactive gantt chart with django and jquery.
I build the table like this:
<div class="gantt">
<div class="gantt-labels">
{% for item in items2 %}
<tr>
<div class="gantt-labels" id="labels"> </div>
</tr>
{% endfor %}
</div>
<div class="gantt_timeline">
<div class="table gantt_table" id="myTable">
<thead>
<div class="gantt-tr time-bar">
{% for item in items2 %}
<div class="gantt-td chart-values">{{ item.y|date:"D" }}</div>
{% endfor %}
</div>
</thead>
<tbody>
{% include "datamodel3.html" %}
{% for item in items2 %}
<div class="tr gantt-tr rows" id="row{{ forloop.counter }}" >
{% for item in items2 %}
<div class="td gantt-td"> </div>
{% endfor %}
</div>
{% endfor %}
</tbody>
</div>
</div>
</div>
The queryset "items2" holds the data for the table (amount of rows and cells in dates)
Example:
row1 01/01/2012
row2 02/01/2012
...
row31 31/01/2012
datamodel3.html
Here are the bars:
{% for item in items3 %}
<div class='bar resizable bars' style="pointer-events:visible;" id="bar{{ forloop.counter }}" data-duration="{{ item.start|date:'D' }}-{{ item.end|date:'D' }}">
<div class='resizers'>
<div class='resizer top-left'></div>
<div class='resizer top-right'></div>
<div class='resizer bottom-left'></div>
<div class='resizer bottom-right'></div>
</div>
</div>
{% endfor %}
The queryset "items3" holds the data for the bars (name, start- and finish-date)
Example:
bar1 01/01/2012 10/01/2012
bar2 08/01/2012 14/01/2012
I use this to make the bars draggable:
(function() {
$(".bar").draggable({
containment: "parent"
});
})();
I use this to make the bars resizable:
https://codepen.io/ZeroX-DG/pen/vjdoYe
I use this to schedule them:
https://codepen.io/tutsplus/pen/ZEzerNB
I use this to assign a label to each row:
var iLabel = 0;
document.querySelectorAll('#labels').forEach(function (element, index) {
element.innerHTML = iLabel < labels.length ?
labels[iLabel] :
'';
iLabel++;
})
So far, the bars have the right length (start and finish date), are draggable and resizable.
The only thing for now is to append each bar to its row (first bar to first row and so on....)
I tried different ways, but ended up assigning each row and bar an ID and attaching them to one another:
$(document).ready(function(){
newfunction();
});
function newfunction(){
var thisrows = $("#row1");
var thisbars = $("#bar1");
/* var fragment = document.createDocumentFragment(); fragment.appendChild(thisbars); */
$(thisrows).html(thisbars);
}
When I try to use fragments, I get: TypeError: Argument 1 ('node') to Node.appendChild must be an instance of Node.
Now, instead of hard-coding every id, I tried to do something like this:
function newfunction(){
var n = 0;
var e = 0;
$(".rows").each(function(){
var thisrows = $(this).attr("id") + n;
n++;
});
$(".bars").each(function(){
var thisbars = $(this).attr("id") + e;
var fragment = document.createDocumentFragment();
fragment.appendChild(thisbars);
e++;
});
$(thisrows).appendChild(fragment);
};
Which doesnt work, even without using fragments. Any suggestions?
Also, I want to save the new position and length of the bar when I move/resize it.
What would be the best approach to do this?
Thank you in advance
Here is my first post about this with an image of the table:
Django + JQuery - Append bars to table rows
I am not entirely sure I get the entire context but I think there some errors in the code, here is my attempt to resolve the script:
The only thing for now is to append each bar to its row (first bar to first row and so on....)
function newfunction(){
const bars = $(".bars");
$(".rows").each(function(index){
$(this).html(bars[index]);
});
};
To save the new position and length of the bar when I move/resize it, boils down to having an object with unique id for the bar { [bar id]: { position: ... , size: .... }, ...} or straight up array of bars [{ id: ..., size: ... } , ...] where you can easily switch positions. You update the object in the observer/listener.
What I'm trying to do is very straightforward: close every instance of a div each time the close button is clicked. What I'm getting instead is only the first clicked-on instance closes but the remaining ones can't.
I must say I come from Python and I'm not very familiar with Javascript. I think there is someway using ID instead of class? Here is my html (with Jinja) code for dynamically creating the objects I would want to close when clicked on:
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages%}
<div class="notification {{ category }} is-bold">
<button class="delete"></button>
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
And here is my Javascript code:
// notification remover
document.addEventListener('DOMContentLoaded', () => {
(document.querySelectorAll('.notification .delete') || []).forEach(($delete) => {
$notification = $delete.parentNode;
$delete.addEventListener('click', () => {
$notification.parentNode.removeChild($notification);
});
});
});
Example of generated html:
<div class="notification is-info is-bold">
<button class="delete"></button>
<div class="notification is-info is-bold">
<button class="delete"></button>
<div class="notification is-info is-bold">
<button class="delete"></button>
Try this instead:
document.addEventListener('DOMContentLoaded', () => {
(document.querySelectorAll('.notification .delete') || []).forEach(($delete) => {
$delete.addEventListener('click', (event) => {
event.target.parentNode.remove();
});
});
});
The problem with your code is that you are setting $notification with the last one, so when the eventListener triggers $notification is always the last.
I am trying to filter a table by the room name of the records which are in each row. My table rows look like this:
<tr data-room="{{ record.room.room_name|lower|field_name_format}}">
So, when the user checks kitchen, rows related to kitchen shows up in the table and not rows related to other rooms.
And this is the code in the header of my HTML:
{% for room in user_related_rooms %}
document.querySelector('#{{room.room_name|lower|field_name_format}}').addEventListener('change',function (evt) {
updateTableView("{{room.room_name|lower|field_name_format}}", evt.target.checked);
});
{% endfor %}
function updateTableView(room_name, bVisible) {
var dataSelectorVal = "";
switch (room_name)
{
{% for room in user_related_rooms %}
case "{{room.room_name|lower|field_name_format}}":
dataSelectorVal = ".site-table tbody tr[data-room='{{room.room_name|lower|field_name_format}}']";
break;
{% endfor %}
}
$(".site-table tbody tr").has(dataSelectorVal).css('display', bVisible ? "" : "none");
}
Here is the code for the filter:
<!-- Filters -->
<div class="col-md-1">
<h1>Filters</h1>
<form>
<span> by room:</span>
<div class="side-filter-list">
<ul>
{% for room in user_related_rooms %}
<li class="flex-field">
<input type="checkbox" id="cb_{{room.room_name|lower|field_name_format}}" />
<label for="{{room.room_name}}">{{room.room_name}}</label>
</li>
{% endfor %}
</ul>
</div>
</form>
</div>
The browser pauses on the exception. I get error on this line, living_room being the first room in the loop (i.e. the first iteration of the loop):
document.querySelector( '#cb_living_room' ).addEventListener('change', function (evt) {
It seems the above line returns null whereas when I comment out the code and use the console to look for it, it finds it without complaining:
document.querySelector( '#cb_living_room')
Console gives me the output:
<input id="cb_living_room" type="checkbox">
What am I doing wrong? What is going on?