Keyboard-controlled Table Scrolling

I have a table with 40 rows, displayed in a div that shows 18 rows and hides the rest using overflow-x:scroll.

I've written a JavaScript code to enable row selection and navigation using the 'up' and 'down' arrow keys on the keyboard.

There are two issues I'm looking to address:

  1. I want the table scrolling to start when the last of the initial 18 rows becomes active.

  2. If I'm on the first record and press 'up' or 'down', I lose the active state of the row.

Here's a link to the jsfiddle where I'm working on solving these problems http://jsfiddle.net/kmcbride/cJjRH/, and below you can find the code snippets.

HTML:

<div class="table">
    <table>
        <thead>
            <tr>
                <th><span>End User</span></th>
                <th><span>Reseller</span></th>
                <th><span>Distributor</span></th>
                <th><span>Product Instance</span></th>
                <th><span>Created On</span></th>
                <th><span>Created By</span></th>
            </tr>
        </thead>
        <tbody>
            <!-- Rows go here -->
        </tbody>
    </table>
    <div class="load-more-btn">Load More</div>
</div>

JavaScript (JS):

$(".openPane").click(function() {
    // Code snippet for row selection
});

$(document).keydown(function (e) {
    // Code snippet for arrow key navigation
});

CSS:

.table {
    width: 100%;
    height: 400px;
    overflow-x: scroll;
}
.table table {
    width: 100%;
}
.table table th {
    text-align: left;
}
.rowActive {
    background-color: #EDF4F9!important;
}

Answer №1

Dealing with issue 2 simply involves checking whether $(currentRow).next().length or $(currentRow).prev().length is not zero before moving to another row.

Instead of repeating code, it's more efficient to create a single function for selecting a new row and call that function from the click and key event handlers. This way, you only need to check $(newRow).length within the new function.

This resolves problem 2, but tackling the scrolling challenge is a bit trickier.

To prevent default scrolling triggered by the up and down keys, remember to return false in their event handlers.

You can instruct the browser to scroll to a specific row using

location.hash = '#' + $(newRow).attr('id');
, but this method positions the row at the top of the table instead of waiting until the selected row reaches the bottom as desired.

To achieve the preferred scrolling behavior, add position: relative; to your table styling; utilize the $(currentRow).position() function to determine the row's position relative to the table; then calculate and apply appropriate math to $('.table').scrollTop() for scrolling.


var rowTop = newRow.position().top;
var rowBottom = rowTop + newRow.height();
var $table = $('.table'); // store for efficiency
var tableHeight = $table.height();
var currentScroll = $table.scrollTop();

if (rowTop < 0) {
    $('.table').scrollTop(currentScroll + rowTop); // scroll up
} else if (rowBottom  > tableHeight) {
    var scrollAmount = rowBottom - tableHeight;
    $('.table').scrollTop(currentScroll + scrollAmount); // scroll down
}

Ensure overflow-y is used in your .table styling, not overflow-x.

All these adjustments have been implemented in an updated version of your fiddle: http://jsfiddle.net/cJjRH/4/

 

EDIT: For improved functionality when pressing up beyond the first record or down past the last one, take a look at http://jsfiddle.net/cJjRH/5/. This modification allows the default browser scrolling to resume when a new row isn't selected, indicated by returning true from the event handler.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Despite using .on and .delegate, jQuery seems to be failing to apply to elements loaded via Ajax

I am currently working with Django and utilizing Django Endless Pagination along with Twitter style loading. However, I am facing issues with getting my jQuery code to bind to the newly injected elements. Despite trying to use .on and .delegate as recommen ...

Unable to open a directory in PHP using a passed value as it is not functioning properly

This is a snippet of my HTML and PHP code: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Gallery</title> <script src="js/jquery-1.7.2.min.js"></script> <script ...

Preserve the content in an input text field within ASP.NET

In my web application, I have an input text field that acts as a datepicker. When a button is clicked, the form data is validated, and if any condition fails, an alert is displayed to the user. <script src="https://code.jquery.com/jquery-1.12.4.js"> ...

injecting a parameter into a JavaScript function

Is it possible to pass a variable called "templateBody" into a function in this code snippet? function GetMenu(){ var templates = [{name:"maher",body:"<p>Maher test</p>"},{name:"Jeremy",body:"<p>Jeremy test</p>"}] var payload = ...

Issues encountered with invoking function in CodeIgniter controller through Ajax

Running a codeigniter website with an add to cart functionality. When the user clicks the add to cart button, the product is successfully added to the cart after the page reloads. The controller code for this feature is as follows: public function buy($ ...

Using jQuery to toggle a class on the appropriate element

Currently trying to master jQuery, specifically toggleClass. Main Objective: Load a div with a fixed height and hide the overflow... by clicking an element, the full content of the div should be revealed. Similar to an accordion, but with the initial part ...

Leveraging flot in conjunction with NPM, React, and Node

I've been attempting to utilize flot in a Node.js React project, but I'm running into issues with the import. The browser console is showing the error: Uncaught TypeError: _jquery2.default.plot is not a function This error is essentially the sa ...

The image displaying "Loading" fails to appear

My webpage includes a div styled with the following CSS: .modal { display: none; position: fixed; z-index: 1000; top: 0; left: 0; height: 100%; width: 100%; background: rgba( 255, 255, 255, .35 ...

Display Further/Hide Fewer every third item using Jquery

I am looking to display only the first 3 list items within each div.content. Then, upon clicking "SHOW MORE", I want to reveal the next 3 items. If the user clicks on "SHOW LESS", I need the display to revert back to showing only the initial 3 list items. ...

Issue with Vue plugin syntax causing component not to load

I'm facing an issue with a Vue plugin that I have. The code for the plugin is as follows: import _Vue from "vue"; import particles from "./Particles.vue"; const VueParticles = (Vue: typeof _Vue, options: unknown) => { _Vue. ...

What are the steps to create a function that behaves like instanceof when given a string as input

Is there a way to achieve something similar to this? var isChild = isInstanceOf( var1, 'Constructor') so that it is equivalent to var isChild = (var1 instanceof Constructor) The challenge is that the function Constructor is not available in t ...

Inspect only the form fields that have a specific class rather than all fields

I am looking for a way to modify the code below so that it only checks and automatically submits form fields with the class "must_be_filled" instead of every field. Can anyone provide guidance on how I can achieve this? $(document).ready(function() { ...

What is the best way to run code once a callback function has completed its task?

I am looking for a way to execute line(s) of code after every callback function has finished processing. Currently, I am utilizing the rcon package to send a rcon command to a Half-Life Dedicated Server (HLDS) hosting Counter Strike 1.6 server and receive ...

Can search criteria be saved for later use?

I operate a classifieds website that allows users to search through ads. I am contemplating ways to save search criteria so that users can easily reuse them for future searches without having to input the same details over and over again. For instance, th ...

Can you explain the functions of this "malicious" JavaScript code?

I came across this piece of code on a website that labeled it as "malicious" javascript. Given my limited knowledge of javascript and the potential risks involved in trying out the code on my own site, I was hoping someone here might be able to shed some l ...

Navigating the root path that is defined in the gulp task within an Angular application

My current task involves building my application with the following code: const app = new Metalsmith(config.styleguide.path.root); app.use( msDefine({ production: false, rootPath: '/' }) ); app.use( ms ...

"Resizing a Javascript file resulting in the creation of a faulty base64

I have been attempting to resize images on the client side using HTML5 before uploading. However, it seems that the base64 string is broken as it contains spaces, line breaks, and other unexpected characters. Even after removing them, the string remains br ...

Storing data from an API response into the localStorage using Vue.js upon clicking

My objective is to save specific data in the browser's localStorage upon clicking a link. However, the output I receive is either undefined or completely empty. <li v-for="(category, index) in categories" :key="index"> ...

Tips for displaying a horizontal scrollbar on a div within a div that has a hidden scrollbar

To ensure that a horizontal scrollbar is displayed on my "content" div when the screen size is smaller than the specified minimum width, I have set the overflow-x property of the parent "container" to hidden. This prevents the scroll from appearing across ...

Ways to craft an interactive drop down menu

Here is the unique HTML code snippet. <dl id="unique-sample" class="unique-dropdown"> <dt><a href="#"></a></dt> <dd> <ul> <li><a href="#">Info</a></li> <li><a h ...