Choosing items by pressing "shift + up arrow"

I have a collection of elements, each representing one line of text. When you click on an element, it changes color. If you then hold down "shift + arrow up," the items above it are also selected. How can this functionality be implemented? My initial approach was to focus on a specific element in the ng-click function and then use the ng-keydown function to select other elements. However, this method does not seem to be working as expected.

<div ng-repeat="elem in listCtrl.availableElements" class="list-elem" ng-class="{ 'selected' : listCtrl.availableElements[$index].selected }" ng-click="listCtrl.listHandler($event, listCtrl.availableElements[$index])" ng-keydown="$event.shiftKey && ($event.which == 38 || $event.which == 40) && listCtrl.listHandler($event, listCtrl.availableElements[$index])">
    <div>
        {{elem.text}}
    </div>
</div>

Answer №1

Check out this functional plunker example

This is the provided HTML code snippet:

<div tabindex="{{$index}}" ng-keydown="moveCursor($event)" ng-repeat="elem in elements" ng-click="setCursor($index)">
    <span ng-class="{ 'selected' : elements[$index].selected }">{{$index}} : {{elem.text}}</span>
</div>

The use of tabindex ensures focus on the element.

Upon ng-click, a cursor is set for selection purposes.

$scope.setCursor = function(index){
  var wasSelected = $scope.elements[index].selected;
  $scope.unselectAll();
  $scope.elements[index].selected = !wasSelected;
  $scope.cursor = index;
  $scope.initialCursor = index;
}  

The cursor serves as a reference point for selecting other elements, with initialCursor saving the starting position.

Event handling and lock management are done within ng-keydown.

$scope.moveCursor = function(event){
  if(event.shiftKey && event.which == 38){
    if($scope.cursor > 0){
      $scope.selectUp();
    }
  }else if(event.shiftKey && event.which == 40){
    if($scope.cursor < $scope.elements.length-1){
      $scope.selectDown();
    }
  } 
}

selectUp() and selectDown() functions exhibit similar behaviors:

$scope.selectDown = function(){
   if($scope.cursor < $scope.initialCursor){
      $scope.elements[$scope.cursor].selected = !$scope.elements[$scope.cursor].selected;
      $scope.cursor += 1;
   }else{
      $scope.cursor += 1;
      $scope.elements[$scope.cursor].selected = !$scope.elements[$scope.cursor].selected;
   }
}

$scope.selectUp = function(){
   if($scope.cursor > $scope.initialCursor){
      $scope.elements[$scope.cursor].selected = !$scope.elements[$scope.cursor].selected;
      $scope.cursor -= 1;
   }else{
      $scope.cursor -= 1;
      $scope.elements[$scope.cursor].selected = !$scope.elements[$scope.cursor].selected;
   }
}

Focus now on the implementation of the selectUp method.

Two distinct behaviors need to be implemented:

If ahead of initial click when selecting upward, move to next item upwards.

If behind initial click when selecting upward, undo selection of last item chosen.

Hoping this explanation proves beneficial.

If dissatisfied with this approach, consider utilizing the "tabindex" suggestion to craft your own solution.

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

Whenever I use Vue JS, I notice that it displays [Object object] on console.log and returns Undefined when

Currently, I'm developing Vue.JS code to showcase data fetched by PHP from a server. The PHP sends a JSON object to the Vue for display. Below is my existing code snippet: axiosPost(); } function axiosPost() { axios.post( './Conver ...

Guide to dynamically inserting an audio file into a div with jQuery

I am looking to dynamically insert an audio file. Below are the declared tags: <div> <audio id="myaudio"> </audio> </div> Now, I am trying to add the source dynamically. Can anyone help me with how to add it to the div or audi ...

Beginning external plugin in Angular 4 application

Is it possible to incorporate an external plugin into an Angular 4 application? I am looking to utilize the niceScroll plugin for a scrollable div, which is defined within a component. <div class="d-flex" id="scrollable"> <app-threads-list> ...

There appears to be an issue with the error handling function within React

I am facing an issue with my error function while checking the browser error, and I am unsure why adding a console.log with the error is causing trouble. I need some assistance in troubleshooting this problem which seems to be occurring at line 29 of my im ...

Screen the $http request information prior to transmission

Angular has a built-in feature that removes properties with a prefix of $$ from request data or params objects. I want to filter out my own UI-specific properties that I don't want to send to the server, but I don't want to rely on using $$. Is ...

Having trouble passing arguments to button methods in jasmine when applying vue and moment libraries

I am working on unit testing a Vue app using `jasmine` and `karma`. Here is an example of the code inside one of my components: After fetching data from a database with `v-for=(data,index)`, I am displaying the `data.date` in the template: <p class=&qu ...

How can I dynamically change a key in an object and replace it with a custom name while also updating its value?

Transform this =>>>>> {1: "Baroque", 2: "Glitch Pop ", 3: "Nu Jazz", 4: "Drumfunk", 5: "Bitpop", 6: "Latin Pop", 7: "Carnatic"} into this ==>>>> [{id: 1 name ...

What is the method for setting a default image to be preloaded in filepond?

Currently, I am working on a Laravel view for editing a record which includes an associated image. My goal is to have the image preloaded inside the input file so that when you submit the form, the same image is sent or you can choose to change it. // Con ...

Simulating a PubSub publish functionality

I have been trying to follow the instructions provided in this guide on mocking new Function() with Jest to mock PubSub, but unfortunately I am facing some issues. jest.mock('@google-cloud/pubsub', () => jest.fn()) ... const topic = jest.fn( ...

The style of the button label does not persist when onChange occurs

Encountered an interesting issue here. There is a button designed for selection purposes, similar to a select item. Here's the code snippet: <button class="btn btn-primary dropdown-toggle" style="width: 166%;" type="button" id="dropdownMe ...

Excessive JSON formatting is consuming an excessive amount of storage space

As I work on developing a website that recommends locations to visit in NYC, I am facing an issue with saving JSON data in local storage. My goal is to allow users to add their own suggestions and eventually integrate MongoDB into the site. To build the si ...

Template for developing projects using JavaScript, HTML5, and CSS3 in Visual Studio 2013

After recently downloading Visual Studio 2013 Express for Web, I am struggling to figure out how to deploy projects that only consist of JavaScript, HTML5, and CSS3. Despite searching online for JavaScript templates and even trying to download Visual Stu ...

Error message in JQuery Ajax: "Invalid request to web service, parameter value for 'Object' is missing"

I'm struggling to successfully post a form to my web service. Before sending it to the server, I am converting the form into an object. However, I encounter an error when trying to post the form as an Object to my Asmx web service. Here is my Ajax co ...

Encountering a "SyntaxError: Unexpected token '/' in... index.ejs while compiling ejs" issue following the recent npm package updates

After upgrading EJS from version 2.7.4 to 3.1.5 along with some other packages in my project, I am encountering a problem where I can no longer access any of the webpages. Instead, an error is being thrown on every page. Additionally, after the update, I s ...

What is the best way to make a Modal triggered by a loop embedded within a table function properly on mobile devices?

While the modal is functioning properly on desktop, it seems to be encountering issues on mobile devices. The modal appears behind the background and is confined by the boundaries of the table (tbody). Below is the code snippet for triggering the modal: ...

Vue: Opening all GmapInfoWindows simultaneously upon clicking one

I am working on a platform where users can report crimes or incidents by placing markers on a map. These markers with all the reported incidents are then displayed on another map. Each marker has an info window that provides details about the incident and ...

What advantages does using `prestart` offer compared to `&&` in a command within `package.json`?

I believe the title speaks for itself, but let's dive in: What advantages does using the pre-script of npm package.json, like prestart, have over simply combining commands with && in the start script? { prestart: "parcel build", start "n ...

What is the best way to trigger the ajax request with the same post parameter upon pressing the browser's back button?

Is there a way to remember the post parameters and resend an AJAX request when the browser back button is pressed? I have searched online and found a couple of methods: Using localsotrage or document.location.hash when the page unloads. Using cookie ...

Cease running code post while loop (do not use break)

I need help with my code that checks if a user is already in a Database. Once the while Loop runs, it verifies the presence of the MC Player in their Database through the Mojang API. However, if the user is already in my Database, I want to skip the Mojang ...

Function in nodejs throwing an error: Return type missing

I am facing an issue with this code snippet while trying to compile the application. public async test(options?: { engine?: Config }): Promise<any> { const hostel = new Service({ list: this.servicesList, createService ...