-->

Friday, November 29, 2024

Library Management Project in AngularJS and ASP.NET CORE RESTFUL API

 Today, we are going to create a new project in Angular, which will be called the Library Management System. As you all know, a Library Management System has several key functionalities. The library contains books, each of which has an author, and books are categorized into different types. There are two types of users in the library: the admin and the student.




Now, let's start building the Library Management System in AngularJS. First, we will create a registration form that will include three fields: username, password, and confirm password. Our first task will be to implement validation for the confirm password field. Next, we will send the username and password to the API using a service through reactive forms. In this project, we will be using the ASP.NET Core RESTful API.

Step-1:  ng new library-management-system

Step-2:   ng g c credentials/registration --skip-tests


Html Part of Registration form

<form [formGroup]="registrationForm" (ngSubmit)="onSubmit()">

  <div>

    <label for="username">Username</label>

    <input id="username" formControlName="username" type="text">

    <div *ngIf="username.invalid && (username.dirty || username.touched)">

      <div *ngIf="username.errors?.['required']">Username is required.</div>

    </div>

  </div>


  <div>

    <label for="password">Password</label>

    <input id="password" formControlName="password" type="password">

    <div *ngIf="password.invalid && (password.dirty || password.touched)">

      <div *ngIf="password.errors?.['required']">Password is required.</div>

    </div>

  </div>


  <div>

    <label for="confirmPassword">Confirm Password</label>

    <input id="confirmPassword" formControlName="confirmPassword" type="password">

    <div *ngIf="confirmPassword.invalid && (confirmPassword.dirty || confirmPassword.touched)">

      <div *ngIf="confirmPassword.errors?.['required']">Confirm Password is required.</div>

      <div *ngIf="confirmPassword.errors?.['passwordMismatch']">Passwords do not match.</div>

    </div>

  </div>


  <button type="submit" [disabled]="registrationForm.invalid">Register</button>

</form>

Type Script File 

import { Component, OnInit } from '@angular/core';

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { UserService } from './user.service'; 


@Component({

  selector: 'app-registration',

  templateUrl: './registration.component.html',

  styleUrls: ['./registration.component.css']

})

export class RegistrationComponent implements OnInit {

  registrationForm: FormGroup;


  constructor(private fb: FormBuilder, private userService: UserService) {}


  ngOnInit(): void {

    this.registrationForm = this.fb.group({

      username: ['', Validators.required],

      password: ['', Validators.required],

      confirmPassword: ['', Validators.required]

    }, {

      validator: this.passwordMatchValidator

    });

  }


  get username() {

    return this.registrationForm.get('username');

  }


  get password() {

    return this.registrationForm.get('password');

  }


  get confirmPassword() {

    return this.registrationForm.get('confirmPassword');

  }

  passwordMatchValidator(form: FormGroup): { [key: string]: boolean } | null {

    return form.get('password')?.value === form.get('confirmPassword')?.value

      ? null : { 'passwordMismatch': true };

  }


  onSubmit(): void {

    if (this.registrationForm.valid) {

      const userData = this.registrationForm.value;

      this.userService.registerUser(userData).subscribe(response => {

        console.log('User registered successfully!', response);

      });

    }

  }

}


Step-3 :  ng g s Credentials/user --skip-tests

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs';


@Injectable({

  providedIn: 'root'

})

export class UserService {

  private apiUrl = 'https://your-api-url.com/register';


  constructor(private http: HttpClient) {}


  registerUser(userData: userModel): Observable<ResponseDto> {

    return this.http.post(this.apiUrl, userData);

  }

}

After registration, we will receive a confirmation message from the API, indicating that the registration is complete. Next, we will design the login form, which will include two fields: username and password. Using a service, we will send the login data to the API URL via a POST request. From the API, we will receive a token, which we will save in the browser's internal storage.

Steo-4 : ng g c Credentails/login


<form [formGroup]="loginForm" (ngSubmit)="onLogin()">

  <div>

    <label for="username">Username</label>

    <input id="username" formControlName="username" type="text">

    <div *ngIf="username.invalid && (username.dirty || username.touched)">

      <div *ngIf="username.errors?.['required']">Username is required.</div>

    </div>

  </div>


  <div>

    <label for="password">Password</label>

    <input id="password" formControlName="password" type="password">

    <div *ngIf="password.invalid && (password.dirty || password.touched)">

      <div *ngIf="password.errors?.['required']">Password is required.</div>

    </div>

  </div>


  <button type="submit" [disabled]="loginForm.invalid">Login</button>

</form>



import { Component, OnInit } from '@angular/core';

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { AuthService } from './auth.service'; // Import your auth service here


@Component({

  selector: 'app-login',

  templateUrl: './login.component.html',

  styleUrls: ['./login.component.css']

})

export class LoginComponent implements OnInit {

  loginForm: FormGroup;


  constructor(private fb: FormBuilder, private authService: AuthService) {}


  ngOnInit(): void {

    this.loginForm = this.fb.group({

      username: ['', Validators.required],

      password: ['', Validators.required]

    });

  }


  get username() {

    return this.loginForm.get('username');

  }


  get password() {

    return this.loginForm.get('password');

  }


  onLogin(): void {

    if (this.loginForm.valid) {

      const loginData = this.loginForm.value;

      this.authService.loginUser(loginData).subscribe(response => {

        

        localStorage.setItem('authToken', response.token);

        console.log('Login successful! Token saved.');

      }, error => {

        console.error('Login failed', error);

      });

    }

  }

}

Now, let's move on to issuing books. Before issuing a book, we need to log in the admin. Once the admin logs in, they will receive a token from the API, which will include the user's role. Based on this role, we can hide or display menu items in AngularJS.

ng g s Credentails/auth --skip-tests

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs';


@Injectable({

  providedIn: 'root'

})

export class AuthService {

  private apiUrl = 'https://your-api-url.com/login';


  constructor(private http: HttpClient) {}


  loginUser(loginData: any): Observable<any> {

    return this.http.post<any>(this.apiUrl, loginData);

  }

}

import { HttpClient, HttpHeaders } from '@angular/common/http';

const token = localStorage.getItem('authToken');

const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);

this.http.get('https://your-api-url.com/protected-route', { headers })

  .subscribe(response => {

    console.log('Protected data', response);

  });


The menu design needs to be done in such a way that the menu items are shown or hidden based on the user's role."

When the admin logs in, the menu items will be different compared to when a student logs in. First, we will log in the admin, and the menu items will be as follows: Home, Category, Author, Book, and Issue and Return History.

import { Injectable } from '@angular/core';

import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs';


@Injectable({

  providedIn: 'root'

})

export class AuthService {

  private apiUrl = 'https://your-api-url.com/login';


  constructor(private http: HttpClient) {}


  loginUser(loginData: any): Observable<any> {

    return this.http.post<any>(this.apiUrl, loginData);

  }

  storeUserData(token: string, role: string): void {

    localStorage.setItem('authToken', token);

    localStorage.setItem('userRole', role);

  }

  getRole(): string | null {

    return localStorage.getItem('userRole');

  }

}


import { Component, OnInit } from '@angular/core';

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { AuthService } from './auth.service'; // Import your auth service here


@Component({

  selector: 'app-login',

  templateUrl: './login.component.html',

  styleUrls: ['./login.component.css']

})

export class LoginComponent implements OnInit {

  loginForm: FormGroup;


  constructor(private fb: FormBuilder, private authService: AuthService) {}


  ngOnInit(): void {

    this.loginForm = this.fb.group({

      username: ['', Validators.required],

      password: ['', Validators.required]

    });

  }


  get username() {

    return this.loginForm.get('username');

  }


  get password() {

    return this.loginForm.get('password');

  }


  onLogin(): void {

    if (this.loginForm.valid) {

      const loginData = this.loginForm.value;

      this.authService.loginUser(loginData).subscribe(response => {

        this.authService.storeUserData(response.token, response.role);

        console.log('Login successful! Token and role saved.');

        // Redirect to the home page or dashboard

      }, error => {

        console.error('Login failed', error);

      });

    }

  }

}


Step-5 : ng g c credentials/menu --skip-tests


import { Component, OnInit } from '@angular/core';

import { AuthService } from '../auth.service'; 

@Component({

  selector: 'app-menu',

  templateUrl: './menu.component.html',

  styleUrls: ['./menu.component.css']

})

export class MenuComponent implements OnInit {

  userRole: string | null = '';

  constructor(private authService: AuthService) {}

  ngOnInit(): void {

    this.userRole = this.authService.getRole();

  }

}

First, the admin will need to add book categories, as both the author and category are required for entering a book. So, the admin will have to add the category or author first, and then proceed to enter the book details. To add a category, we will perform CRUD operations on the Category, and then do the same for the Author.

However, it’s important to note that the admin should not be able to directly access menu items like Category and Author via routing. We will need to protect these routes using guards to ensure that only authorized users can access them.

Now, we will create the category form, which will require just a textbox and a submit button. This form will be designed using reactive forms. When the submit button is clicked, the category name should be posted to the API using an Angular service.


We will also create an IndexCategoryComponent, which will contain a table. Using the API, we will load all the categories into this table. In addition to the categories, we will have two buttons: one for editing the category and the other for deleting the category. When the 'Edit Category' button is clicked, the URL should include the category ID. Based on this ID, we will load the corresponding category in the EditCategoryComponent.


In the EditCategoryComponent, we will also have a textbox and a submit button. However, when we navigate to the edit form from the IndexCategoryComponent, the textbox should be pre-filled with the category details based on the ID passed in the URL.

Now, if we want to change the category, we can do so by updating the category in the textbox and then clicking the submit button. The updated category will be posted to the API through an Angular service. To achieve this, we will make a PUT request to the API to update the category.

Continue in Next Post...

Friday, September 7, 2018

How to use Tabs in ASP.NET CORE



I want to show Components in a tabs , so first of all create few components. In this project we have three components,

First View Component

 public class AllViewComponent : ViewComponent
    {

        private readonly UserManager<ApplicationUser> _userManager;

        public AllViewComponent(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }
        public async Task<IViewComponentResult> InvokeAsync()
        {
            List<StudentViewModel> allUsers = new List<StudentViewModel>();
            var items = await _userManager.Users.ToListAsync();
            foreach (var item in items)
            {
                allUsers.Add(new StudentViewModel {Id=item.Id, EnrollmentNo = item.EnrollmentNo, FatherName = item.FatherName, Name = item.Name, Age = item.Age, Birthdate = item.Birthdate, Address = item.Address, Gender = item.Gender, Email = item.Email });
            }

            return View(allUsers);
        }
    }

Second View Component

 public class StudentsViewComponent : ViewComponent
    {

        private readonly UserManager<ApplicationUser> _userManager;

        public StudentsViewComponent(UserManager<ApplicationUser> userManager)
        {
           _userManager = userManager;
        }
        public async Task<IViewComponentResult> InvokeAsync()
        {
            List<StudentViewModel> students = new List<StudentViewModel>();
            var items = await _userManager.GetUsersInRoleAsync("Student");
            foreach (var item in items)
            {
                students.Add(new StudentViewModel {EnrollmentNo=item.EnrollmentNo,FatherName=item.FatherName, Name = item.Name, Age = item.Age, Birthdate = item.Birthdate, Address = item.Address, Gender = item.Gender, Email = item.Email });
            }

            return View(students);
        }
    }

Third View Component

public class TeacherViewComponent : ViewComponent
    {
        private readonly UserManager<ApplicationUser> _userManager;
     
        public TeacherViewComponent(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }
        public async Task<IViewComponentResult> InvokeAsync()
        {
            List<TeacherViewModel> teachers = new List<TeacherViewModel>();
            var items = await _userManager.GetUsersInRoleAsync("Teacher");
            foreach (var item in items)
            {
                teachers.Add(new TeacherViewModel {FatherName=item.FatherName, Name = item.Name, Age = item.Age, Birthdate = item.Birthdate, Address = item.Address, Gender = item.Gender, Email = item.Email });
            }
     
            return View(teachers);
        }

       
    }


Under Shred Folder Create tree structured directory like this 
/Shared/Components/All
/Shared/Components/Teacher
/Shared/Components/Students

Under All Directory , you can create a view which default name is "Default"

@model IEnumerable<StudentManagementSystem.ViewModels.StudentViewModel>

@{
    ViewData["Title"] = "Default";
}



<table class="table">
    <thead>
        <tr>
                <th>
                    @Html.DisplayNameFor(model => model.EnrollmentNo)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Age)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Birthdate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Gender)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Address)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.FatherName)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Email)
                </th>
               
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.EnrollmentNo)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Age)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Birthdate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Gender)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Address)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FatherName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Email)
            </td>
           
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

Similarly you can create view to other two views.

Now, If you want to implements tabs view then create a ViewModel Class for tabs 

namespace StudentManagementSystem.ViewModels
{
    public class UsersTabViewModel
    {
        public Tab ActiveTab { get; set; }
    }

    public enum Tab
    {
        All,
        Teachers,
        Students
    }
}

Now, You can use it in cshtml file like this 

@model StudentManagementSystem.ViewModels.UsersTabViewModel
@{
    ViewData["Title"] = "Index";
}

<h2>Users Table</h2>
<ul class="nav nav-tabs">
    <li role="presentation" class="@(Model.ActiveTab == StudentManagementSystem.ViewModels.Tab.All ? "active" : string.Empty )"><a asp-route-tabname="All" asp-action="SwitchToTabs">All</a></li>
    <li role="presentation" class="@(Model.ActiveTab == StudentManagementSystem.ViewModels.Tab.Teachers ? "active" : string.Empty )"><a asp-route-tabname="Teachers" asp-action="SwitchToTabs">Teachers</a></li>
    <li role="presentation" class="@(Model.ActiveTab == StudentManagementSystem.ViewModels.Tab.Students ? "active" : string.Empty )"><a asp-route-tabname="Students" asp-action="SwitchToTabs">Students</a></li>
</ul>
@switch (Model.ActiveTab)
{
    case StudentManagementSystem.ViewModels.Tab.All:
        @await Component.InvokeAsync("All");
        break;
    case StudentManagementSystem.ViewModels.Tab.Teachers:
        @await Component.InvokeAsync("Teacher");
        break;
    case StudentManagementSystem.ViewModels.Tab.Students:
        @await Component.InvokeAsync("Students");
        break;
    default:
        break;
}


Now, The controller section for each route value are

 public IActionResult Index(UsersTabViewModel vm)
        {
            if (vm == null)
            {
                vm = new UsersTabViewModel
                {
                    ActiveTab = Tab.All
                };
            }
            return View(vm);
        }
        public IActionResult SwitchToTabs(string tabname)
        {
            var vm = new UsersTabViewModel();
            switch (tabname)
            {
                case "All":
                    vm.ActiveTab = Tab.All;
                    break;
                case "Teachers":
                    vm.ActiveTab = Tab.Teachers;
                    break;
                case "Students":
                    vm.ActiveTab = Tab.Students;
                    break;
                default:
                    vm.ActiveTab = Tab.All;
                    break;
            }
            return RedirectToAction(nameof(AdminController.Index), vm);
        }



Sunday, August 12, 2018

Add control dynamically in ASP.NET CORE also save value into Database



public class PersonViewModel
    {
        public string Name { get; set; }
        public string FatherName { get; set; }
       
    }

public class PeopleViewModel
    {
        public List<PersonViewModel> People { get; set; }
    }

Home Controller

 public IActionResult People()
        {
            return View();
        }

[HttpPost]
        public IActionResult People(PeopleViewModel vm)
        {
            return View();
        }

cshtml file

@model dynamicTextBox.Models.PeopleViewModel

@{
    ViewData["Title"] = "People";
}

<h2>People</h2>

<h4>PeopleViewModel</h4>
<hr />


<div class="row">
    <div class="col-md-4">
        <form asp-action="People">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="singlePerson">
                <div class="form-group">
                    <label asp-for="People[0].Name"></label>
                    <input asp-for="People[0].Name" />
                </div>
                <div class="form-group">
                    <label asp-for="People[0].FatherName"></label>
                    <input asp-for="People[0].FatherName" />
                </div>
                           </div>
            <div class="form-group">
                <input id="Addbutton" type="button" value="Add" />
            </div>
            <div id="TextBoxContainer">

            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </form>
    </div>
</div>
@section scripts
    {
<script type="text/javascript">
    $(document).ready(function () {
        var i = 1;
    $("#Addbutton").click(function () {
        var div = $("<div />");
        var value = "";
     
        var nameBox = $("<input />").attr("type", "textbox").attr("name", "People["+ i +"].Name");
        var fatherBox = $("<input />").attr("type", "textbox").attr("name", "People[" + i + "].FatherName");
       
        nameBox.val(value);
        fatherBox.val(value);
         
        div.append(nameBox);
        div.append(fatherBox);
   

        var button = $("<input />").attr("type", "button").attr("value", "Remove");
        button.attr("onclick", "RemoveTextBox(this)");
        div.append(button);
        $("#TextBoxContainer").append(div);
       
        i++;
    });


        });
        function RemoveTextBox(button) {
            $(button).parent().remove();
    }
    function binddata() {
       
    }
</script>
}
<div>
    <a asp-action="Index">Back to List</a>
</div>



Thursday, June 28, 2018

Highlight Table Row based on some Condition in ASP.NET Core

Model Class

public class Products
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Price { get; set; }
    }

Controller Code 

public IActionResult Index()
        {
            List<Products> p1 = new List<Products>();
            p1.Add(new Products { Id = 1, Name = "Samsung", Price = 50 });
            p1.Add(new Products { Id = 2, Name = "Samsung1", Price = 50 });
            p1.Add(new Products { Id = 3, Name = "Samsung2", Price = 150 });
            p1.Add(new Products { Id = 4, Name = "Samsung3", Price = 150 });
            p1.Add(new Products { Id = 5, Name = "Samsung4", Price = 550 });
            p1.Add(new Products { Id = 6, Name = "Samsung5", Price = 550 });
            return View(p1);
        }

View Section

@model IEnumerable<TestingApplication.Models.Products>

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Price)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            @if (item.Price > 0 && item.Price < 100)
            {
                <tr class="label-success">
                    <td>

                        @Html.DisplayFor(modelItem => item.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                    </td>
                </tr>
            }
            @if (item.Price > 100 && item.Price < 200)
            {
                <tr class="label-warning">
                    <td>

                        @Html.DisplayFor(modelItem => item.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                    </td>
                </tr>
            }
            @if (item.Price > 150 && item.Price < 600)
            {
                <tr class="label-primary">
                    <td>

                        @Html.DisplayFor(modelItem => item.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                    <td>
                        @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                        @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
                    </td>
                </tr>
            }
        }
    </tbody>
</table>



Sunday, January 7, 2018

Dynamically Add or remove control in asp.net core using JavaScript

If you want to add some controls on your web browser, i mean to say if you want to add controls on run time then you can easily dome with any script control, without using c# code. So, here i used Java Script code to add controls on a page. And your code is

Index.cshtml

<form method="post">
    <div id="firstdiv">
        <input type="text" name="testinput" />
                <input type="button" value="add dynamic" onclick="DynamicText()"/>

            </div>
            <input type="submit" value="submit"/>
</form>

JS----file

function DynamicText() {
    var division = document.createElement('DIV');
    division.innerHTML = DynamictextBox("");
    document.getElementById("firstdiv").appendChild(division);
}
function DynamictextBox(value) {
    return '<div><input type="text" name="dyntxt" /><input type="button" onclick="ReTextBox(this)" value="Remove"/></div>';
}
function ReTextBox(div) {
    document.getElementById("firstdiv").removeChild(div.parentNode.parentNode);
}


If you want to use this code , learn :

Friday, August 4, 2017

Thursday, March 23, 2017

How to create Database in ASP.NET CORE 1.1 using model first

Technology changes, code optimization, newly design asp.net core 1.1. This article i wrote for you who want to make database in asp.net core 1.1, its a very simple technique provide by Microsoft developers. Thanks guys. Let start how to do this,  you can follow these steps to design database in it.

Step-1: Create a new project in ASP.NET CORE using Visual Studio 2017 by the using following picture
Create new project
select aspnet core version 1.1

change authentication in aspnet core

Step-2: In Model folder, add a new Student.cs class. Add some properties in it. But make sure , one primary key have in it.
Step-3: Similarly in previous make, a new DataContext class for communicating table.

Check this video for full details


© Copyright 2013 Computer Programming | All Right Reserved