Click here to Skip to main content
15,867,453 members
Articles / Web Development / HTML

MVC, Angular JS CRUD using WEB API 2 with Stored Procedure

Rate me:
Please Sign up or sign in to vote.
4.88/5 (48 votes)
27 Jul 2015CPOL10 min read 162.7K   7.4K   93   43
How to create simple web app using MVC 5, Angular JS, WEB API with stored procedure
In this article, we will see how to create a simple web application using MVC 5, Angular JS ,WEB API 2 to perform CRUD (Create/Read/Update and Delete) Operations using Entity Framework with Stored procedure.

Image 1

Introduction

On the internet, there are lots of examples related to WEB API using Entity Framework. But in community forum, I saw many questions were being asked by members for a simple example using WEB API Entity Framework with Stored Procedure. I searched a lot to find a simple article which explains a simple way to perform CRUD operation using Stored Procedure with MVC and Web API. But I wasn't able to find any article which explains all this. I plan to make a simple web application using MVC 5, Angular JS, WEB API to perform CRUD (Create/Read/Update and Delete) using Entity Framework with Stored procedure.

In this article, we will see how to:

  • C -> (Create - Insert New Student Details to database using EF and WEB API with Stored Procedure)
  • R -> (Read – Search/Select Student Details from database using EF and WEB API with Stored Procedure)
  • U -> (Update - Update Student Details to database using EF and WEB API with Stored Procedure)
  • D -> (Delete - Delete Student Details from database using EF and WEB API with Stored Procedure)

Prerequisites

Visual Studio 2015 - You can download it from here (In my example, I have used Visual Studio Community 2015 RC).

You can also view my previous articles related to AngularJs using MVC and the WCF Rest Service.

The previous articles are related to AngularJs using MVC and using Web API 2.

Angular JS

We might be familiar with what the Model, View, View Model (MVVM) and what Model, View and Controller (MVC) are. Angular JS is a JavaScript framework that is purely based on HTML, CSS and JavaScript.

The Angular JS Model View Whatever (MVW) pattern is similar to the MVC and MVVM patterns. In our example, I have used Model, View and Service. In the code part, let's see how to install and create Angular JS in our MVC application.

If you are interested in reading more about Angular JS, then kindly go through this link.

Using the Code

1) Create Database and Table

We will create a StudentMasters table under the 'studentDB' database. The following is the script to create a database, table and sample insert query. Run this script in your SQL Server. I have used SQL Server 2012.

SQL
-- =============================================                               
-- Author      : Shanu                                
-- Create date : 2015-07-13                                 
-- Description : To Create Database,Table and Sample Insert Query                            
-- Latest                               
-- Modifier    : Shanu                                
-- Modify date : 2015-07-13                           
-- =============================================
--Script to create DB,Table and sample Insert data
USE MASTER
GO

-- 1) Check for the Database Exists .If the database is exist then drop and create new DB
IF EXISTS (SELECT [name] FROM sys.databases WHERE [name] = 'studentDB' )
DROP DATABASE studentDB
GO

CREATE DATABASE studentDB
GO

USE studentDB
GO

-- 1) //////////// StudentMasters

IF EXISTS ( SELECT [name] FROM sys.tables WHERE [name] = 'StudentMasters' )
DROP TABLE StudentMasters
GO

CREATE TABLE [dbo].[StudentMasters](
        [StdID] INT IDENTITY PRIMARY KEY,
        [StdName] [varchar](100) NOT NULL,   
        [Email]  [varchar](100) NOT NULL,   
        [Phone]  [varchar](20) NOT NULL,   
        [Address]  [varchar](200) NOT NULL
)

-- insert sample data to Student Master table
INSERT INTO [StudentMasters]   ([StdName],[Email],[Phone],[Address])
     VALUES ('Shanu','syedshanumcain@gmail.com','01030550007','Madurai,India')

INSERT INTO [StudentMasters]   ([StdName],[Email],[Phone],[Address])
     VALUES ('Afraz','Afraz@afrazmail.com','01030550006','Madurai,India')
     
INSERT INTO [StudentMasters]   ([StdName],[Email],[Phone],[Address])
     VALUES ('Afreen','Afreen@afreenmail.com','01030550005','Madurai,India')
     
     
     select * from [StudentMasters]

After creating our Table, we will create a Stored procedure to perform our CRUD Operations.

SQL
-- 1) Stored procedure to Select Student Details

-- Author      : Shanu                                                                
-- Create date : 2015-07-13                                                                
-- Description : Student Details                                              
-- Tables used :  StudentMasters                                                               
-- Modifier    : Shanu                                                                
-- Modify date : 2015-07-13                                                                
-- =============================================   
-- exec USP_Student_Select '',''
-- =============================================                                                           
Create PROCEDURE [dbo].[USP_Student_Select]                                              
   (                            
     @StdName           VARCHAR(100)     = '',
     @email               VARCHAR(100)     = ''    
      )                                                        
AS                                                                
BEGIN        
         Select [StdID],
                [StdName],
                [Email],
                [Phone],
                [Address]
            FROM 
                StudentMasters 
            WHERE
                StdName like  @StdName +'%'
                AND Email like @email +'%'
            ORDER BY
                StdName    
END

-- 2) Stored procedure to insert Student Details

-- Author      : Shanu                                                                
-- Create date : 2015-07-13                                                                
-- Description : Student Details                                              
-- Tables used :  StudentMasters                                                               
-- Modifier    : Shanu                                                                
-- Modify date : 2015-07-13                                                                
-- =============================================    
-- exec USP_Student_Insert 'Raj','raj@rajmail.com','01030550008','seoul,Korea'
-- =============================================                                                          
Create PROCEDURE [dbo].[USP_Student_Insert]                                              
   (                       
     @StdName           VARCHAR(100)     = '',
     @email               VARCHAR(100)     = '',
     @Phone               VARCHAR(20)     = '',
     @Address           VARCHAR(200)     = ''
      )                                                        
AS                                                                
BEGIN        
        IF NOT EXISTS (SELECT * FROM StudentMasters WHERE StdName=@StdName)
            BEGIN

                    INSERT INTO [StudentMasters] 
                    ([StdName],[Email],[Phone],[Address])
                     VALUES (@StdName,@Email,@Phone,@Address)
                               
                    Select 'Inserted' as results
                        
            END
         ELSE
             BEGIN
                     Select 'Exists' as results
              END

END

-- 3) Stored procedure to Update Student Details
    
-- Author      : Shanu                                                                
-- Create date : 2015-07-13                                                                
-- Description : Update Student Details                                              
-- Tables used :  StudentMasters                                                               
-- Modifier    : Shanu                                                                
-- Modify date : 2015-07-13                                                                
-- =============================================      
-- exec USP_Student_Update 'Raj','raj@rajmail.com','01030550008','seoul,Korea'
-- =============================================                                                           
Create PROCEDURE [dbo].[USP_Student_Update]                                              
   ( @StdID               Int=0,                           
     @StdName           VARCHAR(100)     = '',
     @email               VARCHAR(100)     = '',
     @Phone               VARCHAR(20)     = '',
     @Address           VARCHAR(200)     = ''
      )                                                        
AS                                                                
BEGIN        
        IF NOT EXISTS (SELECT * FROM StudentMasters WHERE StdID!=@StdID AND StdName=@StdName)
            BEGIN
                    UPDATE StudentMasters
                    SET    [StdName]=@StdName,
                    [Email]=@email,
                    [Phone]=@Phone,
                    [Address]=@Address
                    WHERE
                        StdID=@StdID
                               
                    Select 'updated' as results                        
            END
         ELSE
             BEGIN
                     Select 'Exists' as results
              END
END

-- 4) Stored procedure to Delete Student Details
    
-- Author      : Shanu                                                                
-- Create date : 2015-07-13                                                                
-- Description : Delete Student Details                                              
-- Tables used :  StudentMasters                                                               
-- Modifier    : Shanu                                                                
-- Modify date : 2015-07-13                                                                
-- =============================================  
-- exec USP_Student_Delete '0'
-- =============================================
Create PROCEDURE [dbo].[USP_Student_Delete]                                              
   ( @StdID     Int=0 )                                                        
AS                                                                
BEGIN        
        DELETE FROM StudentMasters WHERE StdID=@StdID                
            
END

2) Create Our MVC Web Application in Visual Studio 2015

After installing our Visual Studio 2015, click Start -> Programs -> select Visual Studio 2015 - click Visual Studio 2015 RC.

Image 2

Click New -> Project - > Select Web -> ASP.NET Web Application. Select your project location and enter your web application Name.

Image 3

Select MVC and in Add Folders and Core reference. Select the Web API and click OK.

Image 4

Now we have created our MVC Application as a next step, we add our SQL server database as Entity Data Model to our application.

Add Database using ADO.NET Entity Data Model

Right click our project and click Add -> New Item.

Image 5

Select Data->Select ADO.NET Entity Data Model> Give the name for our EF and click Add.

Image 6

Select EF Designer from database and click Next.

Image 7

Here click New Connection and provide your SQL-Server Server Name and connect to your database.

Image 8

Here, we can see I have given my SQL server name, Id and PWD and after it connected, I have selected the database as studentDB as we have created the database using my SQL Script.

Image 9

Click Next and select our tables that need to be used and click Finish.

Image 10

Here, we can see I have selected our table studentMasters. To use our Stored Procedure, select the entire SP which needs to be used in our project. Here, we can see for performing CRUD operation, I have created 4 SP for Select/Insert/Update and Delete. Select the entire SP and click Finish.

Image 11

Here, we can see now I have created our StudentDetailsEntities.

Image 12

Once Entity has been created next step, we add WEB API to our controller and write function to select/Insert/Update and Delete.

Steps to Add Our WEB API Controller

Right click Controllers folder-> Click Add-> Click Controller.

Image 13

As we are going to create our WEB API Controller, select Controller and Add Empty WEB API 2 Controller. Give your Name to Web API controller and click OK. Here, for my Web API Controller, I have given name as “StudentsController”.

Image 14

As we have created Web API controller, we can see our controller has been inherited ApiController.

Image 15

As we all know, Web API is a simple and easy to build HTTP Services for Browsers and Mobiles.

Web API has four methods as Get/Post/Put and Delete where:

  • Get is to request for the data. (Select)
  • Post is to create a data. (Insert)
  • Put is to update the data.
  • Delete is to delete data.

In our example, we will use both Get and Post as we need to get all image name and descriptions from database and to insert new Image Name and Image Description to database.

Get Method

In our example, I have used only Get method as I am using only Stored Procedure. We need to create object for our Entity and write our Get method to perform Select/Insert/Update and Delete operations.

Select Operation

We use get method to get all the details of StudentMasters table using entity object and we return the result as IEnumerable. We use this method in our AngularJS and display the result in MVC page from AngularJs controller using the Ng-Repeat, we can see details step by step as follows.

Here, we can see in get method, I have passed the search parameter to the USP_Student_Select Stored procedure method. In SP, I have used the like ‘%’ to return all records if the search parameter is empty.

C#
public class studentsController : ApiController
    {
        studentDBEntities objapi = new studentDBEntities();    

        // to Search Student Details and display the result

        [HttpGet]
        public IEnumerable<USP_Student_Select_Result> 
               Get(string StudentName, string StudentEmail)
        {
            if (StudentName == null)
                StudentName = "";

            if (StudentEmail == null)
                StudentEmail = "";

            return objapi.USP_Student_Select(StudentName, StudentEmail).AsEnumerable();
        }

Here in my example, I have used the get method for all Select/Insert/Update and Delete operation as in my stored procedure after insert/update and delete, I have returned the message from database.

Insert Operation

Same like select, I have passed all the parameters to insert procedure. This insert method will return the result from database as record Inserted or not. I will get the result and display it from the Angular JS Controller to MVC application.

C#
// To Insert new Student Details

        [HttpGet]
        public IEnumerable<string> insertStudent
        (string StudentName, string StudentEmail, string Phone, string Address)
        { 
        return  objapi.USP_Student_Insert
        (StudentName, StudentEmail, Phone, Address).AsEnumerable(); 
        }

Update Operation

Same like Insert, I have passed all the parameters to insert procedure. This Update method will return the result from database as record updated or not. I will pass the Student ID to update procedure to update the record for the Student ID. I will get the result and display it from the Angular JS Controller to MVC application.

C#
//to Update Student Details

        [HttpGet]
        public IEnumerable<string> updateStudent
        (int stdID,string StudentName, string StudentEmail, string Phone, string Address)
        {
     return objapi.USP_Student_Update
            (stdID,StudentName, StudentEmail, Phone, Address).AsEnumerable();
        }

Update Operation

Similar to Update, I have passed the Student ID to the procedure to delete the record.

C#
//to Update Student Details

        [HttpGet]
        public string deleteStudent(int stdID)
        {
            objapi.USP_Student_Delete(stdID);
           return "deleted";
        }

Now we have created our Web API Controller Class. In the next step, we need to create our AngularJs Module and Controller. Let’s see how to create our AngularJS Controller. In Visual Studio 2015, it’s much easy to add our AngularJs Controller. Let’s see step by step how to create and write our AngularJs Controller.

Creating AngularJs Controller

First, create a folder inside the Script Folder and I given the folder name as “MyAngular”.

Image 16

Now add your Angular Controller inside the folder.

Right click the MyAngular folder and click Add and New Item. Select Web and select AngularJs Controller and give name to Controller. I have given my Angular JS Controller as “Controller.js

Image 17

Once the AngularJs Controller is created, we can see by default the controller will have the code with default module definition and all.

Image 18

I have changed the above code like adding Module and controller like below.

If the Angular JS package is missing, then add the package to your project.

Right click your MVC project and Click-> Manage NuGet Packages. Search for AngularJs and click Install.

Image 19

Now we can see all Angular JS package has been installed and we can all the files in Script folder.

Image 20

Steps to Create Angular Js Script Files

Modules.js: Here, we add the reference to the Angular.js JavaScript and create a Angular Module named “RESTClientModule”:

JavaScript
// <reference path="../angular.js" /> 
/// <reference path="../angular.min.js" />  
/// <reference path="../angular-animate.js" />  
/// <reference path="../angular-animate.min.js" />  

var app;

(function () {

    app = angular.module("RESTClientModule", ['ngAnimate']);

})();

Controllers: In Angular JS Controller, I have performed all the business logic and return the data from WEB API to our MVC HTML page.

1) Variable Declarations

First, I declared all the local Variables which need to be used.

JavaScript
app.controller("AngularJs_studentsController", 
                function ($scope, $timeout, $rootScope, $window, $http) {

    $scope.date = new Date();
    $scope.MyName = "shanu";
    $scope.stdName = "";
    $scope.stdemail = "";

    $scope.showStudentAdd = true;
    $scope.addEditStudents = false;
    $scope.StudentsList=true;
    $scope.showItem = true;

    //This variable will be used for Insert/Edit/Delete Students details.
    $scope.StdIDs = 0;
    $scope.stdNames = "";
    $scope.stdEmails = "";
    $scope.Phones = "";
    $scope.Addresss = "";

2) Methods

Select Method

In select method, I have used the $http.get to get the details from WEB API. In get method, I will give our API Controller name and method to get the details. Here, we can see that I have passed the search parameter of StudentName and studentEmail using { params: { StudentName: StudentName, StudentEmail: StudentEmail }. The final result will be displayed to the MVC HTML page using the data-ng-repeat:

JavaScript
function selectStudentDetails(StudentName, StudentEmail) {

        $http.get('/api/students/', { params: 
        { StudentName: StudentName, StudentEmail: StudentEmail } }).success(function (data) {

            $scope.Students = data;
           $scope.showStudentAdd = true;
            $scope.addEditStudents = false;
            $scope.StudentsList = true;
            $scope.showItem = true;      
        })
   .error(function () {
       $scope.error = "An Error has occurred while loading posts!";

   });

Search Button Click

In search button click, I will call the SearchMethod to bind the result. Here, we can see in the search Name and Email text box that I have used the ng-model="stdName". Using the ng-model in Angular JS Controller, we can get the Textbox input value or we can set the value to the Textbox.

HTML part:

HTML
<input type="text" name="txtstudName" ng-model="stdName" value="" />

<input type="text" name="txtemail" ng-model="stdemail" />

<input type="submit" value="Search" style="background-color:#336699;color:#FFFFFF" 
 ng-click="searchStudentDetails()" />

Angular JS Controller code part for search click:

JavaScript
//Search

    $scope.searchStudentDetails = function () {     
        selectStudentDetails($scope.stdName, $scope.stdemail);
    }

Image 21

Insert New Student Details

In ADD New Student Detail button click, I will make visible Add Student table where user can enter the new student information. For new student, I will make the Student ID as 0. In New Student save button click, I will call the save method.

JavaScript
// New Student Add Details

    $scope.showStudentDetails = function () {
        cleardetails();
        $scope.showStudentAdd = true;
        $scope.addEditStudents = true;
        $scope.StudentsList = true;
        $scope.showItem = true;
    }

Image 22

In save method, I will check for the Student ID. If the student ID is “0”, then it is to insert the new student details here, I will call the Insert WEB API method and if the Student ID is > 0 means to update the student record, then I will call the Update WEB API method.

To Insert WEB API Method, I will pass all the Input parameter. In my Stored procedure, I will check whether the Student Name already exists or not. If the Student name does not exist in database, then I will insert the records and return the success message as “inserted” and if the student name already exists, then I will return the message as “Exists”.

Image 23

JavaScript
//Save Student

    $scope.saveDetails = function () {

        $scope.IsFormSubmitted = true;
        if ($scope.IsFormValid ) {

      //if the Student ID=0 means its new Student insert here 
      //I will call the Web API insert method

            if ($scope.StdIDs == 0) {           

                $http.get('/api/students/insertStudent/', 
                { params: { StudentName: $scope.stdNames, 
                StudentEmail: $scope.stdEmails, Phone: $scope.Phones, 
                Address: $scope.Addresss } }).success(function (data) {

                    $scope.StudentsInserted = data;
                    alert($scope.StudentsInserted);    
                    cleardetails();
                    selectStudentDetails('', '');
                })
         .error(function () {
             $scope.error = "An Error has occurred while loading posts!";
         });
            }
            else {  // to update to the student details
                $http.get('/api/students/updateStudent/', 
                { params: { stdID: $scope.StdIDs, StudentName: $scope.stdNames, 
                StudentEmail: $scope.stdEmails, Phone: $scope.Phones, 
                Address: $scope.Addresss } }).success(function (data) {
                    $scope.StudentsUpdated = data;
                    alert($scope.StudentsUpdated);
                    cleardetails();
                    selectStudentDetails('', '');
                })
        .error(function () {
            $scope.error = "An Error has occurred while loading posts!";
        });
         }
        }
        else {
            $scope.Message = "All the fields are required.";
        }
    }

Update Student Details

Same like Insert, I will display the update details for user to edit the details and save. In Edit method, I will get all the details for the Row where user clicks on Edit Icon and set all the result to the appropriate textbox. In save button click, I will call the save method to save all the changes to the database same like Insert.

JavaScript
//Edit Student Details

    $scope.studentEdit = function studentEdit(StudentID, Name, Email, Phone, Address)
   {
        cleardetails();
        $scope.StdIDs = StudentID;
        $scope.stdNames = Name
        $scope.stdEmails = Email;
        $scope.Phones = Phone;
        $scope.Addresss = Address;     

        $scope.showStudentAdd = true;
        $scope.addEditStudents = true;
        $scope.StudentsList = true;
        $scope.showItem = true;
    }

Image 24

Delete Student Details

In Delete button click, I will display the confirmation message to the user as to delete the detail or not. If the user clicks on OK button, then I will call the pass the Student ID to the delete method of WEB API to delete the record from the database.

JavaScript
//Delete Dtudent Detail

    $scope.studentDelete = function studentDelete(StudentID, Name) {
        cleardetails();
        $scope.StdIDs = StudentID;
        var delConfirm = confirm
                         ("Are you sure you want to delete the Student " + Name + " ?");
        if (delConfirm == true) {

 $http.get('/api/students/deleteStudent/', 
            { params: { stdID: $scope.StdIDs } }).success(function (data) {
                alert("Student Deleted Successfully!!");
                cleardetails();
                selectStudentDetails('', '');
            })
      .error(function () {
          $scope.error = "An Error has occurred while loading posts!";
      });       
        }    
      }

Image 25

Conclusion

The main aim of this article is to create a simple MVC Web Based CRUD Operation using Angular JS WEB API 2 with Stored Procedure.

Supported Browsers: Chrome and Firefox.

History

  • 15th July, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader
India India
Microsoft MVP | Code Project MVP | CSharp Corner MVP | Author | Blogger and always happy to Share what he knows to others. MyBlog

My Interview on Microsoft TechNet Wiki Ninja Link

Comments and Discussions

 
QuestionThank you for this database-first approach Pin
Michael Lockwood7-Jan-17 8:45
professionalMichael Lockwood7-Jan-17 8:45 
AnswerRe: Thank you for this database-first approach Pin
syed shanu8-Jan-17 12:58
mvasyed shanu8-Jan-17 12:58 
QuestionWithout Entity Framework Pin
Member 128017052-Jan-17 23:01
Member 128017052-Jan-17 23:01 
Questionwhile loading the page, i'm getting js errors Pin
G.Ram Mohan7-Feb-16 20:21
G.Ram Mohan7-Feb-16 20:21 
Questioni was reoslved my probs, but api controller selectsutdentlist is not able to call from angular js file Pin
G.Ram Mohan7-Feb-16 19:55
G.Ram Mohan7-Feb-16 19:55 
Questionwhile running the appln i'm getting the below error , studlist is not dispalying any recors.. Pin
G.Ram Mohan7-Feb-16 19:34
G.Ram Mohan7-Feb-16 19:34 
Question.chtml files for student is not aviliable in Views folder Pin
G.Ram Mohan5-Feb-16 0:28
G.Ram Mohan5-Feb-16 0:28 
Suggestiona little enhancement Pin
Member 1215552631-Dec-15 23:40
Member 1215552631-Dec-15 23:40 
GeneralRe: a little enhancement Pin
syed shanu3-Jan-16 13:44
mvasyed shanu3-Jan-16 13:44 
QuestionWhere is the html part? Pin
Member 1215552630-Dec-15 7:29
Member 1215552630-Dec-15 7:29 
AnswerRe: Where is the html part? Pin
syed shanu30-Dec-15 14:55
mvasyed shanu30-Dec-15 14:55 
GeneralRe: Where is the html part? Pin
Member 1215552630-Dec-15 16:24
Member 1215552630-Dec-15 16:24 
PraiseGood overview of using SPs. Worked great! The db scripts need modification to run in MSSQL Pin
Member 47595473-Nov-15 14:06
Member 47595473-Nov-15 14:06 
GeneralRe: Good overview of using SPs. Worked great! The db scripts need modification to run in MSSQL Pin
syed shanu3-Nov-15 14:11
mvasyed shanu3-Nov-15 14:11 
QuestionNice Tutorial Pin
Sohaib Javed28-Sep-15 7:29
Sohaib Javed28-Sep-15 7:29 
AnswerRe: Nice Tutorial Pin
syed shanu28-Sep-15 14:08
mvasyed shanu28-Sep-15 14:08 
QuestionAltering procedures Pin
Jens_Andersen21-Sep-15 23:14
Jens_Andersen21-Sep-15 23:14 
AnswerRe: Altering procedures Pin
syed shanu21-Sep-15 23:16
mvasyed shanu21-Sep-15 23:16 
GeneralRe: Altering procedures Pin
Jens_Andersen27-Sep-15 23:36
Jens_Andersen27-Sep-15 23:36 
QuestionI have problem the data does not appear in the table Pin
Member 1193248929-Aug-15 6:35
Member 1193248929-Aug-15 6:35 
QuestionWhat is USP_Student_Select_Result in the Controller Method: IEnumerable<USP_Student_Select_Result> ? Pin
RAFTOGI24-Aug-15 0:15
RAFTOGI24-Aug-15 0:15 
AnswerRe: What is USP_Student_Select_Result in the Controller Method: IEnumerable<USP_Student_Select_Result> ? Pin
syed shanu24-Aug-15 1:00
mvasyed shanu24-Aug-15 1:00 
GeneralThanks and have a 5 Pin
Member 118880045-Aug-15 4:31
Member 118880045-Aug-15 4:31 
QuestionVS 2013 Pin
kiquenet.com28-Jul-15 2:51
professionalkiquenet.com28-Jul-15 2:51 
AnswerRe: VS 2013 Pin
syed shanu28-Jul-15 3:17
mvasyed shanu28-Jul-15 3:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.