MediaWiki:Gadget-ResearchNotes-datatable.js: Difference between revisions

From Toolkit.Socialnetwork.Health
No edit summary
No edit summary
 
(105 intermediate revisions by the same user not shown)
Line 3: Line 3:
  * @example <>
  * @example <>
  */
  */
if( $('link[href$="datatables.min.css"]').length ){
 
    // do nothing
mw.loader.load( 'https://cdn.datatables.net/v/dt/dt-2.0.8/b-3.0.2/cr-2.0.3/date-1.5.2/fc-5.0.1/fh-4.0.1/r-3.0.2/rg-1.5.0/rr-1.5.0/sc-2.4.3/sb-1.7.1/sp-2.3.1/sl-2.0.3/sr-1.4.1/datatables.min.css', 'text/css' );
} else {
    $('<link/>', {
        rel: 'stylesheet',
        type: 'text/css',
        href: 'https://cdn.datatables.net/v/dt/dt-2.0.8/b-3.0.2/cr-2.0.3/date-1.5.2/fc-5.0.1/fh-4.0.1/r-3.0.2/rg-1.5.0/rr-1.5.0/sc-2.4.3/sb-1.7.1/sp-2.3.1/sl-2.0.3/sr-1.4.1/datatables.min.css'
    }).appendTo('head');
}


$.ajaxSetup({ cache: true });
$.ajaxSetup({ cache: true });


$.when(
$.when(
     mw.loader.getScript( 'https://cdn.datatables.net/v/dt/dt-2.0.8/b-3.0.2/cr-2.0.3/date-1.5.2/fc-5.0.1/fh-4.0.1/r-3.0.2/rg-1.5.0/rr-1.5.0/sc-2.4.3/sb-1.7.1/sp-2.3.1/sl-2.0.3/sr-1.4.1/datatables.min.js' )
     mw.loader.getScript(  
    'https://cdn.datatables.net/v/dt/dt-2.0.8/b-3.0.2/cr-2.0.3/date-1.5.2/fc-5.0.1/fh-4.0.1/r-3.0.2/rg-1.5.0/rr-1.5.0/sc-2.4.3/sb-1.7.1/sp-2.3.1/sl-2.0.3/sr-1.4.1/datatables.min.js'
    )
)
)
.then(
.then(
function () {
function () {
if( $('#research-notes').length ) {
if( $('#research-notes').length ) {
var cuser = mw.config.get( 'wgUserName');
var table = $('#research-notes').DataTable({
var table = $('#research-notes').DataTable({
dom: '<"top"lf>rt<"bottom"ip><"clear">',
responsive: {
        details: {
            display: DataTable.Responsive.display.modal({
            header: function (row) {
                    var data = row.data();
                    return 'Details for ' + data[0];
                }
            }),
            renderer: DataTable.Responsive.renderer.tableAll()
        }
    },
dom: '<"top"Qlf>rt<"bottom"ip><"clear">',
     columns: [
     columns: [
     { "title": "Page" },
     { "title": "Page" },
Line 28: Line 35:
{ "title": "URL" },
{ "title": "URL" },
{ "title": "Topic" },
{ "title": "Topic" },
{ "title": "Note" },
{ "title": "Note", "className": 'none' },
{ "title": "User" },
{ "title": "User" },
{ "title": "Date" }
{ "title": "Date" }
Line 35: Line 42:
{
{
type: 'date',
type: 'date',
className: 'text-nowrap',
targets: [ 6 ]
targets: [ 6 ]
},
{
visible: false,
searchable: true,
sortable: false,
targets: [ 3 ]
},
{
responsivePriority: 1,
targets: [ 0 ]
}
}
],
],
aaSorting: [
aaSorting: [
[ 1, "desc" ]
[ 0, "asc" ]
],
],
pageLength: 100,
pageLength: 100,
Line 46: Line 64:
['50 per page', '100 per page', '250 per page', 'Show all']
['50 per page', '100 per page', '250 per page', 'Show all']
],
],
searchBuilder: {
columns: [ 5, 6 ],
depthLimit: 1,
greyscale: true,
preDefined: {
                    criteria: [
                        {
                            condition: '=',
                            data: 'User',
                            value: [cuser]
                        },
                        {
                            condition: 'between',
                            data: 'Date',
                        },
                        ],
                        logic: 'AND'
}
},
     language: {
     language: {
    search: '',
     searchPlaceholder: 'Search in notes',
     searchPlaceholder: 'Search in notes',
searchBuilder: {
searchBuilder: {
    title: ''
    title: ''
},
},
lengthMenu: '_MENU_',
lengthMenu: '_MENU_',
},
},
initComplete: function () {
initComplete: function () {
var checkboxes = document.querySelectorAll('input[name="topic"]');


function applySearchMode() {
// Toggle filter dropdown
 
$('#toggle-filters').on('click', function () {
var searchMode = localStorage.getItem('searchMode') || 'AND';
updateFilterList();
 
toggleFilters();
                // Set the dropdown value based on localStorage
});
                document.getElementById('search-mode').value = searchMode;
 
// Hide filter dropdown
                // Remove previous custom search functions
$('#hide-filters').on('click', function () {
                $.fn.dataTable.ext.search = $.fn.dataTable.ext.search.filter(function(filter) {
toggleFilters();
                    return filter.name !== 'customSearch';
});
                });
               
$('input:checkbox').on('click', function () {
                if (searchMode === 'AND') {
applyFilters();
 
});
                var topics = $('input:checkbox[name="topic"]:checked').map(function() {
                return '' + this.value.replace('+', '.') + '';
// OR filtering
}).get().join(',');
$('input:checkbox').on('click', function () {
applyFilters();
});
table.column(3).search(topics, true, false, false).draw(false);
// Clear filters
 
$('.clear-filter').click(function(){
                } else if (searchMode === 'OR') {
$('#topics').find('input:checkbox:checked').prop('checked', false);
                   
applyFilters();
                var topics = $('input:checkbox[name="topic"]:checked').map(function() {
});
                return '' + this.value.replace('+', '.') + '';
}).get().join('|');
                   
table.column(3).search(topics, true, false, false).draw(false);
                }
// Update filters on texts search
updateFilters();
var input = document.querySelector('.dt-search input[type="search"]');
        //       table.draw();
        }


$('input:checkbox').on('click', function () {
                input.addEventListener('keyup', function(event) {
applySearchMode();
                     updateFilterList();
});
            // Set the initial search mode from localStorage
            applySearchMode();
 
            // Event listener for toggler change
            document.getElementById('search-mode').addEventListener('change', function() {
                localStorage.setItem('searchMode', this.value);
                applySearchMode();
            });
           
           
                $('.clear-filter').click(function(){
                            var filter = false;
                            $(this).closest('.topics-filter-group').find('input:checkbox:checked').prop('checked', false);
                            $(this).closest('.topics-filter-group').find('.mw-ui-button').removeClass('shaded');
                            $(this).hide();
                            filter = $(this).closest('.topics-filter-group').prop('id');
                            switch (filter) {
                                case "topics":
                                    var topics = $('input:checkbox[name="topic"]:checked').map(function() {
                                        return this.value;
                                    }).get().join('|');
 
                                    //now filter in column 3, with no regex, no smart filtering, not case sensitive
                                    table.column(3).search(topics, true, false, false).draw(false);
 
                                $('#current-filters-topics').empty();
 
                                break;
                            }
                            updateFilters();
                        });
 
                $('input').click(function(){
                    var children = $(this).closest('.topics-filter-group').find($('input:checked'));
                    var close = $(this).closest('.topics-filter-group').find('.clear-filter');
                    var fbutton = $(this).closest('.topics-filter-group').find('h4');
                    if ($(children).length) {
                        close.show();
                        fbutton.addClass('shaded');
                    } else {
                        close.hide();
                        fbutton.removeClass('shaded');
                    }
                     updateFilters();
                 });
                 });
                  
                  
                function toggleFilters(){
                $('#topics-filter').toggleClass('d-none d-flex');
                positionFilters();
                }
                  
                  
                 window.table=table;
                 function applyFilters(){
//build a regex filter string with an or(|) condition
                    var topic = $('input:checkbox[name="topic"]:checked').map(function() {
return this.value.trim();
}).get().join('|');


                $('input[name="topic"]').change(function() {
//filter in column 3, with an regex, no smart filtering, not case sensitive
                    var value = $(this).val(); // Get the value of the checkbox
table.column(3).search(topic, true, false, false).draw(false);
                    var isChecked = $(this).prop('checked'); // Check if checkbox is checked
 
var monitor = $('#monitor');
                    if (isChecked) {
$(monitor).html(topic);
                        // If checkbox is checked, append its value to the div
                        $('#current-filters-topics').append('<span>' + value + '</span>');
updateFilterList();
                    } else {
}
                        // If checkbox is unchecked, remove its value from the div
                        $('#current-filters-topics').find('span:contains(' + value + ')').remove();
function updateFilterList(){
                    }
                });
 
    var input = document.querySelector('[id^="dt-search"]');
 
                input.addEventListener('keyup', function(event) {
                    updateFilters();
                });


                function updateFilters() {
var dataArray =[];
                    var filterData = {
                        3: { array: [], name: 'topic' }
table.columns(3, { search: 'applied' }).data().eq(0).unique().toArray().forEach(function(item) {
                    };
    item.split(',').forEach(function(subItem) {
 
        dataArray.push(subItem.trim());
                    // Build unique arrays for each filter type
    });
                    for (var key in filterData) {
});
                        var column = parseInt(key, 10);
                        var dataArray = filterData[key].array;
dataArray = Array.from(new Set(dataArray)); // Deduplicate array
 
                        table.columns(column, { search: 'applied' }).data().eq(0).unique().toArray().forEach(function(item) {
                            dataArray.push.apply(dataArray, item.split(','));
                        });
 
                        dataArray = Array.from(new Set(dataArray)); // Deduplicate array
                    }


                     // Filter checkboxes based on available data
                     // Filter checkboxes based on available data
                    for (var key in filterData) {
for (var i = 0; i < checkboxes.length; i++) {
                        var dataArray = filterData[key].array;
var checkbox = checkboxes[i];
                        var filterName = filterData[key].name;
var value = checkbox.value;
var isAvailable = dataArray.indexOf(value) !== -1;
if (isAvailable) {
checkbox.parentNode.classList.remove('d-none');
checkbox.parentNode.classList.add('d-flex');
} else {
checkbox.parentNode.classList.remove('d-flex');
checkbox.parentNode.classList.add('d-none');
}
}
                }
               
                function positionFilters() {
    var dropdownButton = document.getElementById('toggle-filters');
var dropdownMenu = document.getElementById('topics-filter');
dropdownMenu.style.display = 'block';
        // Get the width of the dropdown menu and the viewport
        var dropdownWidth = dropdownMenu.offsetWidth;
        var viewportWidth = window.innerWidth;


                        var checkboxes = document.querySelectorAll('input[name="' + filterName + '"]');
dropdownButton.addEventListener('click', function(event) {
                        for (var i = 0; i < checkboxes.length; i++) {
var cursorX = event.clientX;
                            var checkbox = checkboxes[i];
if (( cursorX / 2 ) + dropdownWidth > viewportWidth) {
                            var value = checkbox.value;
            leftPosition = viewportWidth - dropdownWidth;
                            var isAvailable = dataArray.indexOf(value) !== -1;
        } else {
                            if (isAvailable) {
        leftPosition = ( cursorX / 2 );
                                checkbox.parentNode.classList.remove('d-none');
        }
                                checkbox.parentNode.classList.add('d-flex');
        // Set the position of the dropdown menu
                            } else {
        dropdownMenu.style.left = leftPosition + 'px';
                                checkbox.parentNode.classList.remove('d-flex');
    });
                                checkbox.parentNode.classList.add('d-none');
                            }
                        }
                    }
                 }
                 }
               
                function displaySearchBuilder() {
    var sbToggle = document.getElementById('search-builder');
var sbDisplay = $('.dtsb-searchBuilder');
sbToggle.addEventListener('click', function(event) {
        $(sbDisplay).toggle();
        this.classList.toggle('mw-ui-progressive');
    });
                }
               
                displaySearchBuilder();
                $('#research-notes').show();
}
}
});
});
}
}
});
});

Latest revision as of 08:58, 8 October 2024

/**
 * Datatables definitions
 * @example <>
 */

mw.loader.load( 'https://cdn.datatables.net/v/dt/dt-2.0.8/b-3.0.2/cr-2.0.3/date-1.5.2/fc-5.0.1/fh-4.0.1/r-3.0.2/rg-1.5.0/rr-1.5.0/sc-2.4.3/sb-1.7.1/sp-2.3.1/sl-2.0.3/sr-1.4.1/datatables.min.css', 'text/css' );

$.ajaxSetup({ cache: true });

$.when(
    mw.loader.getScript( 
    	'https://cdn.datatables.net/v/dt/dt-2.0.8/b-3.0.2/cr-2.0.3/date-1.5.2/fc-5.0.1/fh-4.0.1/r-3.0.2/rg-1.5.0/rr-1.5.0/sc-2.4.3/sb-1.7.1/sp-2.3.1/sl-2.0.3/sr-1.4.1/datatables.min.js'
    )
)
.then(
	function () {
		if( $('#research-notes').length ) {
			var cuser = mw.config.get( 'wgUserName');
			var table = $('#research-notes').DataTable({
				responsive: {
        			details: {
            			display: DataTable.Responsive.display.modal({
            				header: function (row) {
                    				var data = row.data();
                    				return 'Details for ' + data[0];
                				}
            				}),
            			renderer: DataTable.Responsive.renderer.tableAll()
        			}
    			},
				dom: '<"top"Qlf>rt<"bottom"ip><"clear">',
    			columns: [
    				{ "title": "Page" },
					{ "title": "File" },
					{ "title": "URL" },
					{ "title": "Topic" },
					{ "title": "Note",	"className": 'none' },
					{ "title": "User" },
					{ "title": "Date" }
				],
				columnDefs: [
					{
						type: 'date',
						className: 'text-nowrap',
						targets: [ 6 ]
					},
					{
						visible: false,
						searchable: true,
						sortable: false,
						targets: [ 3 ]
					},
					{
						responsivePriority: 1,
						targets: [ 0 ]
					}
				],
				aaSorting: [
					[ 0, "asc" ]
				],
				pageLength: 100,
				lengthMenu: [
					[50, 100, 250, -1],
					['50 per page', '100 per page', '250 per page', 'Show all']
				],
				searchBuilder: {
					columns: [ 5, 6 ],
					depthLimit: 1,
					greyscale: true,
					preDefined: {
                    	criteria: [
                        	{
                            	condition: '=',
                            	data: 'User',
                            	value: [cuser]
                        	},
                        	{
                            	condition: 'between',
                            	data: 'Date',
                        	},
                        ],
                        logic: 'AND'
					}
				},
    			language: {
    				search: '',
    				searchPlaceholder: 'Search in notes',
					searchBuilder: {
    					title: ''
					},
				lengthMenu: '_MENU_',
			},
			initComplete: function () {
				
				var checkboxes = document.querySelectorAll('input[name="topic"]');

				// Toggle filter dropdown
				$('#toggle-filters').on('click', function () {
					updateFilterList();
					toggleFilters();
				});
				
				// Hide filter dropdown
				$('#hide-filters').on('click', function () {
					toggleFilters();
				});
				
				$('input:checkbox').on('click', function () {
					applyFilters();
				});
				
				// OR filtering
				$('input:checkbox').on('click', function () {
					applyFilters();
				});
				
				// Clear filters
				$('.clear-filter').click(function(){
					$('#topics').find('input:checkbox:checked').prop('checked', false);
					applyFilters();
				});
				
				// Update filters on texts search
				var input = document.querySelector('.dt-search input[type="search"]');

                input.addEventListener('keyup', function(event) {
                    updateFilterList();
                });
                
                function toggleFilters(){
                	$('#topics-filter').toggleClass('d-none d-flex');
                	positionFilters();
                }
                
                function applyFilters(){
					//build a regex filter string with an or(|) condition
                    var topic = $('input:checkbox[name="topic"]:checked').map(function() {
						return this.value.trim();
					}).get().join('|');

					//filter in column 3, with an regex, no smart filtering, not case sensitive
					table.column(3).search(topic, true, false, false).draw(false);
					
					var monitor = $('#monitor');
					$(monitor).html(topic);
					
					updateFilterList();
				}
				
				function updateFilterList(){

					var dataArray =[];
					
					table.columns(3, { search: 'applied' }).data().eq(0).unique().toArray().forEach(function(item) {
    					item.split(',').forEach(function(subItem) {
        					dataArray.push(subItem.trim());
    					});
					});
						
					dataArray = Array.from(new Set(dataArray)); // Deduplicate array

                    // Filter checkboxes based on available data
					for (var i = 0; i < checkboxes.length; i++) {
						var checkbox = checkboxes[i];
						var value = checkbox.value;
						var isAvailable = dataArray.indexOf(value) !== -1;
						if (isAvailable) {
							checkbox.parentNode.classList.remove('d-none');
							checkbox.parentNode.classList.add('d-flex');
						} else {
							checkbox.parentNode.classList.remove('d-flex');
							checkbox.parentNode.classList.add('d-none');
						}
					}
                }
                
                function positionFilters() {
    				var dropdownButton = document.getElementById('toggle-filters');
					var dropdownMenu = document.getElementById('topics-filter');
					
					dropdownMenu.style.display = 'block';
        			// Get the width of the dropdown menu and the viewport
        			var dropdownWidth = dropdownMenu.offsetWidth;
        			var viewportWidth = window.innerWidth;

					dropdownButton.addEventListener('click', function(event) {
						var cursorX = event.clientX;
						if (( cursorX / 2 ) + dropdownWidth > viewportWidth) {
				            leftPosition = viewportWidth - dropdownWidth;
        				} else {
        					leftPosition = ( cursorX / 2 );
        				}
        				// Set the position of the dropdown menu
        				dropdownMenu.style.left = leftPosition + 'px';
    				});
                }
                
                function displaySearchBuilder() {
    				var sbToggle = document.getElementById('search-builder');
					var sbDisplay = $('.dtsb-searchBuilder');
					
					sbToggle.addEventListener('click', function(event) {
        				$(sbDisplay).toggle();
        				this.classList.toggle('mw-ui-progressive');
    				});
                }
                
                displaySearchBuilder();
                $('#research-notes').show();
			}
		});
	}		
});