How to iterate items into rows divided by 3 columns - javascript

As you will see in my JSFiddle link at the end of this post, I have a dropdown menu that filters items into categories. I have every item stored as objects in an array for each category. As of right now, everything is displayed in one column. I want to be able to count how many items that will be displayed for each category and then divide that by 3 in order to get how many will go in each column.
I'm thinking I'll need to use a for loop to count up to that number while putting the items in the first column, and when that loop finishes, I will have to do that for each column. The loops would be nested... the outer loop would say something like start a new row and the inner loop inserts the correct number of items... Does that make sense? I feel like it does, but the problem is that I have no idea how to do that. I'm a jQuery noob, let alone web programming.
Any help or advice would be greatly appreciated! Please and thank you!
My code:
HTML:
<div class="btn-group">
<button id="division-select" class="btn btn-info dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" data-target=".nav-collapse">Categories<span class="caret"></span></button>
<ul id="filterOptions" class="dropdown-menu">
<li id="get_cats">Cats</li>
<li id="get_dogs">Dogs</li>
<li id="get_birds">Birds</li>
<li id="get_all">Everything</li>
</ul>
</div> <!-- .btn-group -->
<div class="row">
<div class="col-md-4 text-center">
<a id="cats"></a>
<a id="dogs"></a>
<a id="birds"></a>
<a id="everything"></a>
</div>
</div>
JavaScript:
var data={
"cats":[
{"breed":"bengal"},
{"breed":"savannah"},
{"breed":"ragdoll"},
{"breed":"munchkin"},
{"breed":"siamese"}
],
"dogs":[
{"breed":"german shepherd"},
{"breed":"jack russell terrier"}
],
"birds":[
{"breed":"parrot"}
],
"everything":[
{"breed":"bengal"},
{"breed":"savannah"},
{"breed":"ragdoll"},
{"breed":"munchkin"},
{"breed":"siamese"},
{"breed":"german shepherd"},
{"breed":"jack russell terrier"},
{"breed":"parrot"}
]
}
$( document ).ready(function() {
everything();
});
$(document).ready(function () {
$("#get_cats").click(
function () {
cats();
}
);
});
$(document).ready(function () {
$("#get_dogs").click(
function () {
dogs();
}
);
});
$(document).ready(function () {
$("#get_birds").click(
function () {
birds();
}
);
});
$(document).ready(function () {
$("#get_all").click(
function () {
everything();
}
);
});
function cats() {
document.getElementById("dogs").innerHTML="";
document.getElementById("birds").innerHTML="";
document.getElementById("everything").innerHTML="";
var output="<div class='text-center'>";
for (var i in data.cats) {
output += "<a class='thumbnail'><h3>"+ data.cats[i].breed +"</h3></a>";
}
output+="</div>";
document.getElementById("cats").innerHTML=output;
}
function dogs() {
document.getElementById("cats").innerHTML="";
document.getElementById("birds").innerHTML="";
document.getElementById("everything").innerHTML="";
var output="<div class='text-center'>";
for (var i in data.dogs) {
output += "<a class='thumbnail'><h3>"+ data.dogs[i].breed +"</h3></a>";
}
output+="</div>";
document.getElementById("dogs").innerHTML=output;
}
function birds() {
document.getElementById("dogs").innerHTML="";
document.getElementById("cats").innerHTML="";
document.getElementById("everything").innerHTML="";
var output="<div class='text-center'>";
for (var i in data.birds) {
output += "<a class='thumbnail'><h3>"+ data.birds[i].breed +"</h3></a>";
}
output+="</div>";
document.getElementById("birds").innerHTML=output;
}
function everything() {
document.getElementById("dogs").innerHTML="";
document.getElementById("birds").innerHTML="";
document.getElementById("cats").innerHTML="";
var output="<div class='text-center'>";
for (var i in data.everything) {
output += "<a class='thumbnail'><h3>"+ data.everything[i].breed +"</h3></a>";
}
output+="</div>";
document.getElementById("everything").innerHTML=output;
}
JSFiddle

Do you want to show the sub categories in three columns instead of one column?
If yes , then you can simply do it by CSS , no need of java script.
<a id="everything"><div class="text-center"><a class="thumbnail"><h3>bengal</h3></a><a class="thumbnail"><h3>savannah</h3></a><a class="thumbnail"><h3>ragdoll</h3></a><a class="thumbnail"><h3>munchkin</h3></a><a class="thumbnail"><h3>siamese</h3></a><a class="thumbnail"><h3>german shepherd</h3></a><a class="thumbnail"><h3>jack russell terrier</h3></a><a class="thumbnail"><h3>parrot</h3></a></div></a>
Instead of using use UL > LI , provide 33% width to LI and float:left;
Hope this will solve your question.
You can also use , CSS on .thumnail class.
Note : Your fiddle link doesn't give any output.
.thumbnail {
width:30%;
float:left;
margin:4px;
}
.thumbnail h3 {
min-height:80px;
}
use this link : http://jsfiddle.net/pragneshkaria/BZ63R/4/

Related

AngularJs filter not updating view

The view in my html is not getting filtered on selecting any li element.
But when I console the filter functions the output generated is correct.Also how to clear the filter so it is reusable again.I'm getting a blank page on clicking open or close select elements.Can anyone help me with this.
I have used two filters in a controller inside the functions like this-
indexController Functions-
this.UserTickets = ()=> {
//code to get the tickets
}
this.openTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "open" } );
console.log(index.filteredTickets);
};
//filter closed tickets
this.closeTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "close" } );
console.log(index.filteredTickets);
};
this.clearFilter = () => {
//clear the filter
};
HTML-
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a ng-click="indexCtrl.clearfilter()">None</a></li>
<li><a ng-click="indexCtrl.openTickets()">Open</a></li>
<li><a ng-click="indexCtrl.closeTickets()">Close</a></li>
</ul>
<div ng-repeat="ticket in indexCtrl.tickets | filter:tickets |filter:indexCtrl.filteredTickets">
<div class="ticket-no">
<h4>Ticket No:<span>{{ticket}}</span></h4>
</div>
<div class="ticket-title">
<a ng-href="/ticketView/{{ticket.ticketid}}"><h3>{{ticket.title}}</h3></a>
</div>
<div class="ticket-info">
<p class="pull-left">{{ticket.username}} On {{ticket.created | date:"MMM d, y h:mm a"}}</p>
<p class="pull-right">Status:<span>{{ticket.status}}</span></p>
</div>
<hr class="hr">
</div>
You are mixing both angular filter options. I would recommend the javascript filters, index.filteredTickets=$filter('filter')(index.tickets,{status:"open"}); rather than the html template syntax, ng-repeat="ticket in indexCtrl.tickets | filter:tickets...". The key difference between these methods is how often they are run. The html template syntax filters are run on every digest cycle, the javascript filters are only run when the method is called, in your case, on each button click. For small apps or when the lists are small, this difference won't be noticeable, but if your app grows in size, the constant filtering on each digest cycle can cause page lag.
The filters in the controller are my preferred way of handling this, so I will show you how to clean up your code for these to work. You are almost there, just a few small changes are needed.
In your html, you can remove the inline filters in the ng-repeat, these aren't needed, and change the array to be your filter list, index.filteredTickets.
.html
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a ng-click="indexCtrl.clearfilter()">None</a></li>
<li><a ng-click="indexCtrl.openTickets()">Open</a></li>
<li><a ng-click="indexCtrl.closeTickets()">Close</a></li>
</ul>
<div ng-repeat="ticket in indexCtrl.filteredTickets">
<div class="ticket-no">
<h4>Ticket No:<span>{{ticket}}</span></h4>
</div>
<div class="ticket-title">
<a ng-href="/ticketView/{{ticket.ticketid}}"><h3>{{ticket.title}}</h3></a>
</div>
<div class="ticket-info">
<p class="pull-left">{{ticket.username}} On {{ticket.created | date:"MMM d, y h:mm a"}}</p>
<p class="pull-right">Status:<span>{{ticket.status}}</span></p>
</div>
<hr class="hr">
</div>
For the javascript, you need to make sure the filteredTickets are accessible in the html. I'm not sure if index == this, if not, you may need to attach the filtered tickets to the scope. The one other change needed is to set the filteredTickets to your original list if the none button is pressed. You will also want to call clearFilter after you load the list, otherwise index.filteredList will be undefined/null.
.js
this.UserTickets = () => {
//code to get the tickets
....
//after getting list, call clear filter
this.clearFilter();
}
this.openTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "open" } );
console.log(index.filteredTickets);
};
//filter closed tickets
this.closeTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "close" } );
console.log(index.filteredTickets);
};
this.clearFilter = () => {
//clear the filter
index.filteredTickets = index.tickets;
};

Prevent animation of list items on div refresh every second

I have a page which lists files from database every second.
DESIRED RESULTS
I want all the li elements to fadeIn one by one on page load.
Then fadeIn only the new li elements when new files are added to the database otherwise no animation to the already listed elements.
To get the fresh list of files I am using setInterval which in turn is causing the all the list items to fadeIn one by one every second. What should I do to achieve the desired results?
TO SUM UP WHAT I AM ASKING
I am asking for a way to show the elements as if they are fading in on by on on page load. Then if new items are added to the database then show them only one by one with the fading effect but at that time the fading effect should not be applied to the older items.
JS
$(document).ready(function() {
var filelist = $('#file_list');
$('#loading').show();
var checkUpdate = function () {
$.ajax({
type: "GET",
url: "generate_list.php",
success: function (result) {
$('#loading').hide();
var arr = JSON.parse(result);
console.log(arr);
if (arr.length > 0) {
$('#empty_storage').hide();
filelist.html(arr);
$('li').each(function (i) {
$(this).delay(400*i).fadeIn(400);
});
}
else {
filelist.html('');
$('#empty_storage').show();
}
},
error: function (response) {
$('#loading').hide();
$.alert({
theme: 'black',
title: false,
content: response
});
}
});
setTimeout(checkUpdate, 1700);
};
setTimeout(checkUpdate, 1700);
});
CSS
#file_list li
{
overflow: hidden;
padding-top: 4px;
padding-bottom: 4px;
margin-bottom: 5px;
display: none;
}
PHP SNIPPET
// Fetching only last 10 records LIFO
$query = $dbh->prepare("SELECT * FROM uploads ORDER BY id DESC LIMIT 10");
$query->execute();
$items = array();
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
// Generate respective data to display
$file_id = $row['id'];
$ico_path = $base_icon_src.get_logo($row['file_ext']);
$full_file_name = $row['file_name'].'.'.$row['file_ext'];
$file_ext = $row['file_ext'];
$file_code = $row['file_code'];
$download_file_path = './storage/'.$file_code.'.'.$file_ext;
$file_size = $row['file_size'];
$file_upload_time = $row['timestamps'];
if(file_exists($download_file_path)) {
// Generating markup
$items[] = '<li>
<div class="f_icon"><img src="' . $ico_path . '"></div>
<div class="left_wing">
<div class="progressbar"></div>
<a class="download_link" href="#" id="'.$file_id.'"><div class="f_name">' . $full_file_name . '</div></a>
<div class="f_time_size">' . date("M d, Y", $file_upload_time) . ' • ' . human_filesize($file_size) . '</div>
</div>
<div class="right_wing">
<div class="f_delete">
<a class="btn btn-danger" href="#" aria-label="Delete" data-id="'.$file_id.'" data-filename="'.$full_file_name.'">
<i class="fa fa-trash-o fa-lg" aria-hidden="true" title="Delete this?"></i>
</a>
</div>
</div>
</li>';
}
}
//content in $items must be in UTF-8
echo json_encode($items);
In general - this is the workflow you should follow:
On page load (first time) get the list of the files you want to preview (it can be all of them, or only the last X). Make sure you have the id (from the database) of the last item (the largest id, if your items are orders). We will call this MAX_ID.
Once loaded - animate them one by one.
Using setTimeout, get the "next bulk" of files (you need to pass to the php script the ID that you saved from #1, so you can get only the files where id > max_id).
If you got new files - add them (you can animate them one by one).
Update the MAX_ID to be the new id you got from the "new bulk".
Inside the success function you should call again (using the setTimeout function to the code the gets the "next bulk" (#3).
Here is a simple example:
$(function() {
$('li').hide();
$($("li").get().reverse()).each(function(i) {
$(this).delay(400*i).fadeIn(400);
});
});
items = ['a', 'b', 'c', 'd']
$('#a1').click(function() {
$(items).each(function(i, val) {
li = $('<li>').text(val).hide();
$('#u1').prepend(li);
li.delay(400*i).fadeIn(400);
});
});
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="u1">
<li>5</li>
<li>4</li>
<li>3</li>
<li>2</li>
<li>1</li>
</ul>
<div id="a1">Click to add more items</div>

Serializing unordered lists using jquery

I have used Lists within a list and I intend to send the id's using jquery to another php file(updateDB.php).
I tried serializing the list but couldn't get the data. I'm not sure if i've got it right, tried looking around every place but couldn't figure out what's wrong with the code.
<ul>
<li id="recordsArray_<?some number?>"><?php echo content?>`
<ul>
<?php
while (some condition) {
?>
<div>
<li id="subArray_<another number?>"><?php echo content?></li>
</div>
<?php
//conditions - increment within the loop
}
?>
</ul>
</li></ul>
the jquery code is something like this,
$(document).ready(function() {
$(function() {
$("#contentLeft ul").sortable({opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable('serialize') + '&action=updateMenuListings';
$.post("updateDB.php", order, function(theResponse) {
$("#contentRight").html(theResponse);
});
}});
});
$(function() {
$("#contentLeft ul li ul").sortable({opacity: 0.6, cursor: 'move', update: function() {
var order = $(this).sortable('serialize') + '&action=updateSubListings';
$.post("updateDB.php", order, function(theResponse) {
$("#contentRight").html(theResponse);
});
}});
});
});
the id's contentLeft are just the id's for before the lists.
I intend to make it draggable hence used sortable.
On debugging, i'm unable to get any id's of the lists in the variable 'order'.
Please do check out the code and help out.
Thanks
Below you'll find some HTML that is structure like yours along with the JavaScript and jQuery to do what you want. This allows you to move the top level items, with all their respective subitems or just rearrange the subitems. Both options generate a body that you can use in the commented out post line.
You can see it in action here: http://jsfiddle.net/WTjsG/
HTML:
<div id="ContentLeft">Sortable With Update
<ul id="Nav" class="sortable navLevel1">
<li id="Nav_1">Nav1
<!-- NOTE: format id's for UL and LI items as <name>_<int> for serialize to work properly -->
<ul id="NavRecords_1" class="sortable navLevel2">
<li id="Nav1_1">Nav1 Item1</li>
<li id="Nav1_2">Nav1 Item2</li>
<li id="Nav1_3">Nav1 Item3</li>
<li id="Nav1_4">Nav1 Item4</li>
</ul>
</li>
<li id="Nav_2">Nav2
<ul id="NavRecords_2" class="sortable navLevel2">
<li id="Nav2_1">Nav2 Item1</li>
<li id="Nav2_2">Nav2 Item2</li>
<li id="Nav2_3">Nav2 Item3</li>
<li id="Nav2_4">Nav2 Item4</li>
</ul>
</li>
</ul>
</div>
JavaScript w/ jQuery:
$(document).ready(function () {
var isDebugMode = true;
//Set common sort settings for all lists
$(".sortable").sortable({
opacity: 0.6,
cursor: 'move'
});
//Function used to configure update calls for each sort
function setSortAction(selector, updatePage, updateAction, itemLabel) {
$(selector).sortable({
update: function () {
var itemList = $(this).sortable(
"serialize", {
attribute: "id",
key: itemLabel
});
//Create POST request to persist the update
var bodyContent = "action=" + updateAction + "&" + itemList;
if (isDebugMode) { alert("DEBUG: bodyContent = \n" + bodyContent); }
//$.post(updatePage, bodyContent, function (postResult) { alert(postResult); });
}
});
}
//Set sort update action for top level and second level
setSortAction(".navLevel1", "updateDB.php", "updateMenuListings", "record");
setSortAction(".navLevel2", "updateDB.php", "updateMenuItemListings", "record");
});

table row filtering with js or jquery

im not so close with js or jquery, but i have a table with some entries. now i'd like to filter this table by a list on the left side.
i wrote an example. http://jsfiddle.net/B2Muh/2/
<ul class="filter">
<li class="filter-header"> Filter argument 1: </li>
<li> Yahoo </li>
<li> Google </li>
<li class="filter-header"> Filter argument 2: </li>
<li> GPH_est </li>
<li> Q_est </li>
</ul>
<div class="tableResult">
<table class="table">
<tr>
<td>Yahoo</td>
<td>GPH_est</td>
</tr>
<tr>
<td>Google</td>
<td>Q_est</td>
</tr>
</table>
</div>
the example is very simple. so what i want is, that i can click on any filter argument 1, set this active, and the table shows all entries with the first argument, then if i click on any filter argument 2, the table only shall show entries with the first and the second argument.
i use python and django.
i hope anyone can help me, because i have no idea :)
EDIT: now i have added the markups
Mocked up the functionaltiy you requested, using some slow, simple, exhaustive checks. --http://jsfiddle.net/B2Muh/3/
$(function () {
$filterArgs = $("ul li").filter(function () {
var txt = $(this).text();
return txt.indexOf("Filter") < 0;
});
$filterArgs.click(function () {
$(this).toggleClass('active');
$("table tr").hide();
$("table tr td").each(function () {
$rowData = $(this);
$filterArgs.filter(".active").each(function () {
if ($rowData.text() == $(this).text()) {
$rowData.parent().show();
return false;
}
});
});
});
});
I've written a sample code. I think this is what you want.
$('body').on('click','li',function(){
var filterText=$(this).html().trim();
var splicedTextArray=filterText.split(" ");
var filter=splicedTextArray[0].toLowerCase();
$('tr').each(function(index,value){
var valueText=$(this).find('td:first').html();
var isRegexmatch=valueText.toLowerCase().indexOf(filter);
if(isRegexmatch<0)
{
$(this).hide();
}else
{
$(this).show();
}
});
});
See it in action on JSFiddle

How to develop two jqgrids on the same page with same context menu for both the grids?

I have two jqgrids on a single page. And those two are supposed to have context menus. It is possible if I have two different context menus, say 'myMenu1' and 'myMenu2'. But I would like to have only one context menu and i want to use it for both the grids and I actually took reference from the link from oleg. Please suggest how can i achieve??
<div class="contextMenu" id="myMenu1" style="display:none">
<ul style="width: 200px">
<li id="edit">
<span class="ui-icon ui-icon-pencil" style="float:left"></span>
<span style="font-size:11px; font-family:Verdana">Edit Row</span>
</li>
<li id="del">
<span class="ui-icon ui-icon-trash" style="float:left"></span>
<span style="font-size:11px; font-family:Verdana">Delete Row</span>
</li>
</ul>
</div>
And the binding i am doing is like the below.
loadComplete: function() {
$("tr.jqgrow", this).contextMenu('myMenu1', {
bindings: {
'edit': function(trigger) {
if (trigger.id && trigger.id !== lastSelection) {
grid_location.restoreRow(lastSelection);
grid_location.editRow(trigger.id, true);
lastSelection = trigger.id;
}
},
'del': function(trigger) {
if ($('#del').hasClass('ui-state-disabled') === false) {
// disabled item can do be choosed
if (trigger.id && trigger.id !== lastSelection) {
grid_location.restoreRow(lastSelection);
//grid.editRow(trigger.id, true);
//lastSelection = trigger.id;
}
grid_location.delGridRow(trigger.id, delSettings);
}
}
},
onContextMenu: function(event/*, menu*/) {
var rowId = $(event.target).closest("tr.jqgrow").attr("id");
//grid.setSelection(rowId);
return true;
}
});
}
I think that $(event.target).closest("table") is the reference to the current jqgrid, if there are no subgrids of course.
I solved this for local data, and I am posting the entire code over here. The only concern is that for the date picker is not picking the date if the columns of type date in the two grids have same names( or indexes). So for that I have used different names(inv_date and invdate) but in the case of server side data i am still confused.
onContextMenu: function(event/*, menu*/) {
/*
In this line we will be specifying on which grid the context menu has to perform
and this variable 'grid' has to be used in the 'onclickSubmitLocal' function.
*/
grid = $("#currnt_grid");
var rowId = $(event.target).closest("tr.jqgrow").attr("id");
return true;
}

Categories

Resources