How to bind Json list item to pagination in angularJs? - javascript

I have large list of Json data and i arranged it in my page. Also i used paging for this. I am getting Json list in my page but the problem is, with the list generated. I have categories like(Animation, Comedy, MiniSeries, etc). When my page loads first time, listbox shows (All)- then everything is fine but when i select categories in the listbox, then the data is not displaying properly.
Each page should show pageSize(4) which is limited. this works fine when "All" is selected.
Other list items(Animation, Comedy, MiniSeries, etc) are not getting limited to pageSize properly and paging length is not reducing for
this categories.
Especially when i select "Horror", it is not displaying anything. pls help.
plnkr link
pls wait for few seconds if json data is not loaded.
// calculate page in place
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.pageSize === 0) {
$scope.pagedItems[Math.floor(i / $scope.pageSize)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.pageSize)].push($scope.filteredItems[i]);
}
}
};

The issue in this case is a confusion between the various selection methods.
If you look on page 6 when 'horror' is selected, you should see "Lost Girl" -- the horror movie.
Basically, the $scope.filteredItems is the list of items selected by the filter field. If you type "Lost" into that field while "horror" is the genre, it will seem to work. That is because, when nothing is typed into the "filter" field, you are searching all the items. Then, when you find an item on (say) page 6 -- it gets added to the $scope.pagedItems array as an item on page 6.
In order for this function to work, you need to modify the $scope.filteredItems list to only select elements that are in the selected genre and meet the filter criterion.

Related

Looping through array to store string values in objects in localStorage and retrieving them

I'm building a web app that lets the user curate a double-feature film showing. The user enters a title, a blurb, and two film titles. On a submit button a function is called that displays the user-submitted title, user-submitted blurb, and makes two separate API calls to retrieve movie information on each respective feature.
I'm trying to establish something of a favorites functionality that utilizes localStorage. Conceptualizing the solution, let alone implementing it may be my first mistake, so I'm open to alternative suggestions, but I believe the best way to do this is to capture each search field value (title, blurb, movie_1, movie_2), store these four string values in an object and then push that object to an array, placing each object into localStorage and then getting each object from localStorage later on with a button click.
I'm able to capture these items, store them in localStorage and dynamically generate buttons that when clicked populates the four search field values back into the respective search fields, allowing the user to click the submit button again which runs the api calls and displays all of the content (again: title, blurb, movie_1, movie_2).
My problem is looping through the objects and grabbing the different search field data values. I suppose the problem is in assigning a name or key to the different objects that I'm looping through in the array and then accessing the correct values from the appropriate button through localStorage. I seem to be setting the same localStorage object (or rewriting it) and accessing it over and over, as opposed to setting a new localStorage object and getItem'ing the right one.
I'll provide some code snippets below, but it might be easier to peruse my GitHub repo: https://github.com/mchellagnarls/double_feature
If you look at the repo, latest code is found in index_test.html and app_test.js, whereas a previous version without any of the broken favorite functionality is found in index.html and app.js.
Some code snippets:
// logic to capture search field values and to eventually display them as buttons
// empty array
var dfArray = [];
// object to hold each of the string values to populate the search fields
var doubleFeature = {
feature_1: movie_1,
feature_2: movie_2,
DFTitle: title,
DFBlurb: blurb
}
dfArray.push(doubleFeature);
for (var i = 0; i < dfArray.length; i++) {
localStorage.setItem("df", JSON.stringify(dfArray[i]));
var button = $("<button>");
button.addClass("df-favorite-button");
button.text(title);
$("#buttons-view").append(button);
}
$(document).on("click", ".df-favorite-button", function() {
event.preventDefault();
var savedDF = JSON.parse(localStorage.getItem("df"));
$("#movie-input-1").val(savedDF.feature_1);
$("#movie-input-2").val(savedDF.feature_2);
$("#df-title-input").val(savedDF.DFTitle);
$("#df-blurb-input").val(savedDF.DFBlurb);
})
Thanks for any help. I'm learning web development and I may be overcomplicating things or missing out on an easier way to think about it and/or solve it.
Instead of this loop:
for (var i = 0; i < dfArray.length; i++) {
localStorage.setItem("df", JSON.stringify(dfArray[i]));
var button = $("<button>");
button.addClass("df-favorite-button");
button.text(title);
$("#buttons-view").append(button);
}
I would place the whole array into local storage
localStorage.setItem("df", JSON.stringify(dfArray));
Also then you have to decide which object to get from array in click function
$(document).on("click", ".df-favorite-button", function() {
event.preventDefault();
var id = -1; // which one
var savedDF = (JSON.parse(localStorage.getItem("df")) || []).find(pr => pr.id === id);
$("#movie-input-1").val(savedDF.feature_1);
$("#movie-input-2").val(savedDF.feature_2);
$("#df-title-input").val(savedDF.DFTitle);
$("#df-blurb-input").val(savedDF.DFBlurb);
})

how to get the searched data in datatable but not show it

I want to check if the data is already exist in datatable in certain column but I don't know how to do it.
Heres what I tried
var issueData = $('#table').DataTable().column(2).search($('input[name=search]').val()).rows({search: 'applied'}).data().toArray();
if(issueData == '')
{
var data = [];
data.push(rowData[0]);
data.push(rowData[3]);
data.push(rowData[2]);
data.push(rowData[4]);
data.push(rowData[6]);
$('#table').DataTable().row.add(data).draw(false);
}
the problem on this is I if the issueData is empty it will just overwrite the existing data and have filter on the bottom of the datatable
here's what the filter
Showing 1 to 1 of 1 entries (filtered from 3 total entries)
I don't want to filter it I just want to check if the data is existing already on a certain column then add the data if its not existing if it exist then do nothing.
search() as you say will search the actual table. To filter it without changing the user's view of the table, use filter(). See docs here: https://datatables.net/reference/api/filter()

I can't seem to get list.js to filter items with multiple categories

I'm using list.js to sort a list of items by category. It's easy to make work if each list item only fits in one category, but I am struggling with making this sort correctly if something is assigned more than one category.
This is what I have so far on Codepen.io
Basically, I want to be able to tag things with both beverage AND game. I'm obviously not cycling through the array I've created for each item's categories correctly... So it only ever acknowledges the first item?
There isn't much help in the docs of List.js as to how to use it in this manner. I found an issue the list.js maintainer marked as closed that seemed related, but he basically just told the person to ask for help over here, so that's what I'm trying. https://github.com/javve/list.js/issues/189
I think this is the problem
for (var i=0, j=tryThis.length; i<j; i++) {
if (tryThis[i] == selection) {
return true;
} else {
return false;
}
}
If the first category fits, you return true, but if the first does not fit you immediately return false, preventing any more compares.
You should not return false within the loop but only after the loop, when you know that no category was a match.
===== UPDATE
featureList.filter(function(item) {
This call, does it change the list, or does it return the filtered list?
If it returns the filtered list (as is the usual way) you never saves the returned values?
To save values returned from a filter function you usually just assign the return value.
list = list.filter(function(i) { });
If this works in this case depends on the design of the filter function, but try it.

Two way binding with AngularJS select for a child object

I have an angular form with this select element:
<select ng-model="expense.category" ng-options="category.code for category in categories"></select>
where expense is my object to create/edit in the form and expense.category points to child object category (with properties "id" and "code"), which is to be selected by this control.
This all works perfect for creating new expenses - category gets saved just the way it should be. When loading an expense for editing everything is fine also - the expense has its category in the controller. But on the form the select does not get pre-filled with the correct category-entry, it is empty, although all the categories are loaded into the select element. So binding works only one way (from form to model) but not in the other way (from model to form) for the select field. All the other fields (properties of expense) get filled correctly into the edit form though.
Any ideas how to solve this?
The expense.category model must be an existing item in the categories array.
What you can do to make this happen is to search for the right item in the array (with the help of the code property) and replace your existing copy of the category with the reference in the categories array.
This could be done like this:
myApp.controller('ctrl', function($scope) {
$scope.categories = [{code: 'sport'}, {code: 'music'}, {code: 'culture'}];
$scope.expense = {category: {code: 'sport'}};
function replaceWithReference(expense) {
var code = expense.category.code;
for(var i=0; i < $scope.categories.length; i++) {
if($scope.categories[i].code === code) {
expense.category = $scope.categories[i];
return;
}
}
}
replaceWithReference($scope.expense);
});
Here is the working jsfiddle-demo
Comparison between ng-options and ng-model is done by reference, not value. I suspect your expense.category, when loaded, is a separate entity from the ones in the categories array.
You should probably populate your expense.category with a category from categories.
Another option would be to replace the select with a dropdown. This would represent a bit more code (you would have to handle the binding yourself on the ng-click) but would give you more control on comparison and display.

Assigning ajaxed data into paginated data, and best way to go about it?

So, I am asking about how to create the appropriate concept/solution for a problem I have coming up. I am pretty sure I an cover it, but after talking with some on here, I see there are more than one way to skin a cat, and more often - better. lol.
So, I have some data coming in.. via ajax call. Ok great. That all gets bundled in a basket that I think create page paginations.
For instance, I get a bucket of 4 items, and my pagination is 2 per page.. equals 2 pages. I only build the pages one pagination is clicked.. I have the data, but then I build it out. (for the sake of the example below).
So here is my issue. I have a second set of data that i must retrieve (it is a seperate ajax call) and that second set of data might append additional data to the first set of items.
How best to map that second set to the first even when their display is not built yet.
So, - for the sake of argument, I have my first set of data that i just received. Lets say there is only 2 items per page.
In total, my first bucket has the following data:
data = [
{name:ITEM1, desc: Greatest Book in History, id: 98987 },
{name:ITEM2, desc: Second Greatest Book in History, id: 76557 },
{name:ITEM3, desc: Third Greatest Book in History, id: 121212 },
{name:ITEM4, desc: Fourth Greatest Book in History, id: 09546 }
]
page one.
ITEM 1 - Greatest Book in history
ITEM 2 - Second Greatest Book in history
Page 2 pagination is clicked
ITEM 3 - Third Book in history (**special sale: Special Edition**)
ITEM 4 - Fourth Greatest Book in history
Now, my second second data has the following
specialData = [
{121212 : special sale: Special Edition}
]
So, the second ajax call is gonna send all my First Bucket IDS and get returned any "new" information that is available. If there is, I am gonna append the display with the new data.
Now, my guess to do this is:
1). Wait for the second request to finish then append the first bucket data with the second set of info, so when I build out the pagination, the data is there gets build as pagination is requested.
or
2). Build the first bucket of data as normal and then apply an * element id * that is the same as the item id number.... and when the second data bucket is fetched, I append to the html element id with the new info.. that is how I find the appropriate match. THe only thing is, I have to know that that particular element ID dom item is present (visible/built to the current pagination page) before I can append that new info.
<div>ITEM 3 - Third Book in history<span id="121212"></span></div>
What am I missing here? Is this simpler than I am making it?
I'd probably go with the second approach for both cleanliness and the nature of the data structures provided by JavaScript. Given you've tagged the question with jQuery, here is an implementation.
var dataBucket = {};
function enrichBucket(incomingData) {
for(var i = 0, len = incomingData.length; i < len; i++) {
var dataEntry = incomingData[i];
dataBucket[dataEntry.id] = $.extend( dataBucket[dataEntry.id]||{}, dataEntry);
}
}
http://api.jquery.com/jQuery.extend/ Check out the [deep] flag if you want to do a deep merge.

Categories

Resources