Filter data with JSLink Sharepoint - javascript

I use JSLink to customize a SharePoint display list.
I managed to filter data as you can see in the following link:
https://sharepoint.stackexchange.com/questions/91317/filter-out-items-in-list-view-using-jslink
When I click on the title of a column to try to filter a data second time, it systematically brings back all the old data instead of sorting out the previously filtered ones.

In the provided example the filter is applied by row index and this is explains why different rows are displayed before and after sorting applied.
The below example demonstrates how to hide rows by list item id, in that case the filter will be applied consistently to the same rows:
(function () {
function listPreRender(renderCtx) {
var excludeItemIds = [1]; //hide list item with Id=1
var rows = renderCtx.ListData.Row; //get current rows
var filteredRows = rows.filter(function(row){
var curItemId = parseInt(row.ID);
if(excludeItemIds.indexOf(curItemId) === -1)
return row;
});
renderCtx.ListData.Row = filteredRows;
renderCtx.ListData.LastRow = filteredRows.length; //update ListData.LastRow property
}
function registerListRenderer()
{
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
Templates : {
OnPreRender : listPreRender
}
});
}
ExecuteOrDelayUntilScriptLoaded(registerListRenderer, 'clienttemplates.js');
})();
Results
Filtered list view
Filtered list view after applying sorting

Related

Jquery data tables need to show only selected rows from an integer array of IDs

I have a drop down with checkboxes in it. When I select multiple items, I have a method which gets those IDs in an integer array. In my data table one of the column, lets say 'User_ID:name' has those IDs. I want to loop through the data table and show only rows of selected IDs in the integer array. If array is empty, no rows should be visible.
I wrote a method, but it's only showing me only 1 row and it keeps overwriting that row when looping through.
var Gridupdate = function () {
int[] checked = Checkbox.getCheckedIds(); /// integer array of selectedIDs from a checkbox
if (dtable) {
for (i = 0; i < checked.length; i++) {
dtable.column("User_ID:name").search(checked[i].toString()).draw();
}
}
}
You can use regex in "DataTables" to achieve this. Add this to your "DataTables' initialisation options".
"search": {
"regex": true, // enables the table to be filtered using regular expresion
"smart": false // disables the table's "smart search" ability. Ensures a more accurate search.
}
Example:
$('#example').DataTable( {
"search": {
"regex": true,
"smart": false
}
});
And change your method to this
var Gridupdate = function () {
var checked = Checkbox.getCheckedIds(); /// integer array of selectedIDs from a checkbox
if (dtable) {
dtable.column("User_ID:name").search(checked.join('|')).draw(); // eg .search(1|2|4)
}
};

JQuery Datatables Row Data From AJAX Source

In the past I've always used this to get a hidden column's data. I would hide the column with a css class, but the responsive feature doesn't work well with these.
var td = $('td', this);
var ID = $(td[0]).text();
So I found an alternative, by hiding the columns with these classes with the responsive feature.
"columnDefs": [
//Responsive classes
{ className: 'never', targets: 0 }, //Hide on all devices
{ className: 'all', targets: 1 }, //Show on all devices
]
and then I use either one of these.
var rowData = oTable1.fnGetData(this);
var rowData = oTable1.api().row(this).data();
//Grab the first indexed item in the list
var ID = rowData[0];
That works well if you don't have an AJAX source. It will return a comma separated list of the row data. However, when I try to use this with an AJAX source I just get [object Object] back (instead of a comma separated list) if I output the rowData variable in an alert.
How do I get the row data out of a table with an AJAX source?
It seem to be stored as string so [1, 2, 3] became [object Object] when you turn it into string. Do yourString = yourList.join(',') and store yourString to keep the coma-separated string.
For an object:
yourString = (function () {
var list = [];
for(var i in yourList)
if(yourList.hasOwnProperty(i))
list.push(yourList[i]);
return list.join(',');
})();
The function is not needed, it's just to limit the variables scope.
I ended up using an answer I found here.
Converting a JS object to an array
I can pull the entire row data from the table with this.
var rowData = oTable1.api().row(this).data();
In the console log I can see that it returns a javascript object like this.
Object { id="123456", full_name="Samuel Smith", Last_name="Smith" }
I use this function to convert the object into an array.
var array = $.map(rowData, function (value, index) {
return [value];
});
In the console log, my array would appear like this.
["123456", "Samuel Smith", "Smith"]
I can then extract any item from the array like this.
alert(array[0]);
Simplifying madvora's example:
var rowData = oTable1.api().row(this).data().to$();
rowDataArray = rowData.toArray();

Dojo: option[selected ='selected'] not working for run-time change

I am working on a multi-select box and found
var count = dojo.query("option[selected ='selected']", dojo.byId('select_id')).length;
Always returns whatever original from the page(database) but yet what user selected at run-time. I am running on Dojo 1.6. So how can I count number of selected options from multi-select box AT RUN-TIME?
I made a page that shows users and the groups they are in. Here is some of the code. I had to rip some stuff out to make it concise. The last line of code answers the question. It returns an array with the checked values.
// Programattically create the select.
var _groups = new dojox.form.CheckedMultiSelect({
multiple : true,
class : "cssThing"
}, "groups" + _userNumber);
// Fill the CheckedMultiSelect boxes with unchecked data.
var tempArray = new Array();
dojo.forEach(groupList, function(row, index) {
tempArray.push({
value : row.value,
label : row.label,
selected : false,
});
});
_groups.addOption(tempArray);
// Populate the CheckedMultiSelect with an array.
var tempArray = [];
dojo.forEach(user.groups, function(row) {
tempArray.push(String(row.groupName));
});
_groups.set('value', tempArray);
// Get the CheckedMultiSelect values as an array.
_groups.get('value');

Sorting grouped items in listview

I need to sort individual items in groups.
The Listview api lets me to create sorted groups or sort whole list.
I need to sort item in the respective groups.
Is it possible?
I was struggling with the same issue and neither found a useful example, nor a hint. Then I started to combine SortedListProjection and GroupedSortedListProjection, and by that, finally made it work.
My use case was to have groups in alphabetical, ascending order, but within a group, have the items ordered by a timestamp, descending.
Here is how I set it up in the JavaScript file:
var list = new WinJS.Binding.List(); // list gets populated later in the code
var sortedList = list.createSorted(compareItems);
var groupedList = list.createGrouped(getGroupKey, getGroupData, compareGroups);
WinJS.Namespace.define("my.stuff", {
sortedList: sortedList,
groupedList: groupedList
});
The important thing was to keep the item sorting in sync with the grouping. Therefore the item sorting function is calling grouping functions.
Below are all four functions used for sorting and grouping:
compareItems = function (leftItem, rightItem) {
let leftKey = getGroupKey(leftItem);
let rightKey = getGroupKey(rightItem);
let compare = compareGroups(leftKey, rightKey);
if (compare == 0) { // if keys are equal compare timestamps
return leftItem.timestamp < rightItem.timestamp ? 1
: leftItem.timestamp > rightItem.timestamp ? -1 : 0;
}
return compare;
};
getGroupKey = function (item) {
return item.name + item.category;
};
getGroupData = function (item) {
return {
name: item.name + " (" + item.category + ")"
};
};
compareGroups = function (leftKey, rightKey) {
return leftKey.toUpperCase().localeCompare(rightKey);
};
Finally, the combined declaration of both lists for the ListView:
<div id="dataDeliveriesList" class="hidden"
data-win-control="WinJS.UI.ListView"
data-win-options="{
itemDataSource: my.stuff.sortedList.dataSource,
itemTemplate: select('#itemTemplate'),
groupDataSource: my.stuff.groupedList.groups.dataSource,
groupHeaderTemplate: select('#groupHeaderTemplate'),
layout: {
type: WinJS.UI.ListLayout
}
}">
</div>
It's possible. ObservableCollection doesn't provide a sorting option, and therefore you'll have to create a new collection that's sorted on a selected property. See sample code below. For other sorting options, read the blog post here and another stackoverflow thread.
// TODO: Create an appropriate data model for your problem domain to replace the sample data
var group = SampleDataSource.GetGroup((String)navigationParameter);
this.DefaultViewModel["Group"] = group;
//this.DefaultViewModel["Items"] = group.Items;
// Sort items by creating a new collection
ObservableCollection<SampleDataItem> grpSorted = new ObservableCollection<SampleDataItem>(
group.Items.OrderBy(grp => grp.Title));
this.DefaultViewModel["Items"] = grpSorted;

Applying a date range filter to a crossfilter dimension

I'm attempting to use the crossfilter javascript library (in conjunction with D3.js) to group and filter json data.
My json data has the following fields: week_date, category, team_name, title, subtitle
I've been able to successfully group on all records to produce YTD totals, using something like this:
var dimension = data.dimension(function(d) { return d[target]; });
var dimensionGrouped = dimension.group().all();
Where target is either category or team_name.
In addition to keeping the YTD totals, I also want to display totals for a given range. For example, a user-selected week (i.e. Oct 1st - 5th).
How do I create a filtered group which returns the totals for a given date range? Using my week_date field.
Well, after some superficial research, including skimming over crossfilter's issues list, I've concluded that crossfilter does not currently support grouping on multiple fields.
I was able to work around this by using a filtered copy of the data instead, as such:
// YTD rows
var crossfilterData = crossfilter(data);
var ytdDimension = crossfilterData.dimension(function(d) { return d[target]; });
var ytdDimensionGrouped = ytdDimension.group().all();
ytdDimensionGrouped.forEach(function (item) {
// ...
});
// Ranged rows
var filteredData = data.filter(function (d) {
return d.week_date >= filter[0] && d.week_date <= filter[1];
});
crossfilterData = crossfilter(filteredData);
var rangeDimension = crossfilterData.dimension(function(d) { return d[target]; });
var rangeDimensionGrouped = rangeDimension.group().all();
rangeDimensionGrouped.forEach(function (item) {
// ...
});

Categories

Resources