Donate

Add Dropdown Or Select Control With OnchangeEvent To Bootstrap-Table Wenzhixin In ASP.NET Core MVC

Hello and Good day!

In this blog post I will demonstrate on how to add a select or dropdown control in Bootstrap-Table by Wenzhixin with an OnChange() event in ASP.NET Core MVC. For this tutorial, I will only fetch records from a List variable with fake information and not from a database for simplicity sake. To begin create an ASP.NET Core MVC using Visual Studio that targets the .NET 5 Framework and perform the rest of the steps below.
I. Project Setup
A. Add via libman the Bootstrap-Table by Wenzhixin using CDN as the option.
B. Add via libman font-awesome using CDN as the option.
C. Add the latest tableExport.js to bootstrap-table folder.
D. Add Nuget Package Microsoft.AspNetCore.Mvc.NewtonsoftJson 5.x
E. Add a new class in the Models folder called Product.cs
Here's the project structure.
Add Dropdown Or Select Control With OnchangeEvent To Bootstrap-Table Wenzhixin In ASP.NET Core MVC
II. Coding The Project
A. Product.cs - Add properties that describe a product. The status property is where the Dropdown of the Boostrap-Table is bound to.
public class Product
{
  public int ProductCode { get; set; }
  public string ProductName { get; set; }
  public string CategoryName { get; set; }
  public string Status { get; set; }
  public double Price { get; set; }

  public Product()
  {
	 ProductCode = 0;
	 ProductName = string.Empty;
	 CategoryName = string.Empty;
	 Status = string.Empty;
	 Price = 0;
  }
}
B. Startup.cs - reference the Newtonsoft.Json.Serialization class and call the AddNewtonsoftJson() method inside the ConfigureServices() method.
public void ConfigureServices(IServiceCollection services)
{
	services.AddControllersWithViews();
	services.AddControllers().AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
}
C. Reference the font-awesome in Layout.cshtml.
<link href="~/lib/font-awesome/css/all.css" rel="stylesheet" />
D. Home Controller.cs - Create a Products variable with pre-populated data. Then I added two methods that get's the products from the List variable which is used in the data-url property of the Bootstrap-Table. Next is to define a ProductStatusChanged() method with two parameters productCode and productStatus that will update the product status of the product.
public class HomeController : Controller
{
  private static List<Product> Products = new List<Product>
  {
	 new Product {
		ProductCode = 10001,
		ProductName = "ThinkPad E14 Gen 2 (Intel)",
		CategoryName = "Thinkpad E14",
		Price = 40995.00,
		Status = "In Stock"
	 },
	 new Product {
		ProductCode = 10002,
		ProductName = "ThinkPad E15 Gen 2 (Intel)",
		CategoryName = "Thinkpad E15",
		Price = 41995.00,
		Status = "In Stock"
	 },
	 new Product {
		ProductCode = 10003,
		ProductName = "ThinkPad E14 Gen 4 (14\" AMD)", 
		CategoryName = "Thinkpad E14",
		Price = 62195.00,
		Status = "No Stock"
	 },
	 new Product {
		ProductCode = 10004,
		ProductName = "ThinkPad E15 Gen 4 (15\" AMD)",
		CategoryName = "Thinkpad E15",
		Price = 63395.00,
		Status = "Discontinued"
	 },
	 new Product {
		ProductCode = 10005,
		ProductName = "ThinkPad T14 Gen 2 (Intel)",
		CategoryName = "Thinkpad T14",
		Price = 74995.00,
		Status = "Discontinued"
	 }
  };

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

  [HttpGet]
  public JsonResult GetProducts()
  {
	 JsonResult result;

	 if (Products.Count > 0)
		result = Json(Products);
	 else
		result = Json(null);

	 return result;
  }

  [HttpGet]
  public IActionResult ProductStatusChanged(int productCode, string productStatus)
  {
	 var product = Products.FirstOrDefault(x => x.ProductCode.Equals(productCode));

	 if (product != null)
		product.Status = productStatus;

	 return RedirectToAction("Index");
  }
}
E. Index.chtml - In this page, I have a Bootstrap Table that loads the records from the list through the data-url property which calls the ActionResult method in the controller. In the Status field, I set the data-formatter property which is a method called DropdownFormatterStatus() that returns an HTML template with the Select/Dropdown control. I then set the name and id property to be the productCode and the Onchange to specifically call the ProductStatusChanged() method passing in the object itself as the parameter. This method will then send a request along with the product code and product status to the ProductStatusChanged ActionResult Method in HomeController.cs. Here's the entire Index.cshtml markup.
@{
   ViewData["Title"] = "Products Page";
}

<div id="divPageContainer">
   <div id="toolbar">
      <select class="form-control">
         <option value="">Export Page</option>
         <option value="all">Export All</option>
      </select>
   </div>
   <div id="divProducts" class="table-responsive">
      <table id="tblProducts"
             class="table-condensed table-striped"
             data-toggle="table"
             data-search="true"
             data-sort-name="ProductCode"
             data-sort-order="asc"
             data-show-columns="true"
             data-advanced-search="true"
             data-id-table="advancedTable"
             data-show-multi-sort="true"
             data-show-export="true"
             data-toolbar="#toolbar"
             data-click-to-select="true"
             data-cookie="true"
             data-pagination="true"
             data-show-jump-to="true"
             data-url='@Url.Action("GetProducts", "Home")'
             data-cookie-id-table="tblProductsID"
             data-page-size="10"
             data-page-list="[10, 25, 500, 1000, 10000, All]">
         <thead>
            <tr style="background-color: #FFFFFF;">
               <th data-field="ProductCode" data-visible="true" data-searchable="true">Product Code</th>
               <th data-field="ProductName" data-sortable="true" data-searchable="true">Product Name</th>
               <th data-field="CategoryName" data-sortable="true" data-searchable="true">Category Name</th>
               <th data-field="Price" data-sortable="true" data-searchable="true">Price</th>
               <th data-field="Status" data-sortable="true" data-searchable="true" data-formatter="DropdownFormatterStatus">Status</th>
            </tr>
         </thead>
      </table>
   </div>
</div>
@section scripts{
   <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
   <link href="~/lib/bootstrap-table/bootstrap-table.min.css" rel="stylesheet" />

   <script type="text/javascript">

      $(function () {
         ToolbarInit();
      });

      function DropdownFormatterStatus (value, row, index) {
         var productCode = row.ProductCode;
         var status = row.Status;
         var html = '<select class="form-control" onchange="ProductStatusChanged(this)" name="' + productCode + '"' + 'id="' + productCode + '">';

         if (status === 'In Stock' || status === '') {
            html += '<option selected value="' + 'In Stock' + '">' + 'In Stock' + '</option>';
            html += '<option value="' + 'No Stock' + '">' + 'No Stock' + '</option>';
            html += '<option value="' + 'Discontinued' + '">' + 'Discontinued' + '</option>';
         }
         else if (status === 'No Stock') {
            html += '<option value="' + 'In Stock' + '">' + 'In Stock' + '</option>';
            html += '<option selected value="' + 'No Stock' + '">' + 'No Stock' + '</option>';
            html += '<option value="' + 'Discontinued' + '">' + 'Discontinued' + '</option>';
         }
         else {
            html += '<option value="' + 'In Stock' + '">' + 'In Stock' + '</option>';
            html += '<option value="' + 'No Stock' + '">' + 'No Stock' + '</option>';
            html += '<option selected value="' + 'Discontinued' + '"   >' + 'Discontinued' + '</option>';
         }

         html += '</select>';

         return html;
      };

      function ProductStatusChanged (objDropdown) {
         var productStatus = encodeURIComponent($(objDropdown).val());
         var productCode = encodeURIComponent($(objDropdown).prop('id'));
         var urlProductStatus = '@Url.Action("ProductStatusChanged", "Home")';
         
         window.location.href = urlProductStatus + '?productCode=' + productCode + '&productStatus=' + productStatus;
      };

      function ToolbarInit() {
         $('#toolbar').find('select').change(function () {
            $('#tblProductsID').bootstrapTable('destroy').bootstrapTable({
               exportDataType: $(this).val(),
               exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel']
            })
         }).trigger('change');
      }
   </script>
   <link href="~/lib/bootstrap-table/extensions/page-jump-to/bootstrap-table-page-jump-to.css" rel="stylesheet" />
   <link href="~/lib/bootstrap-table/extensions/filter-control/bootstrap-table-filter-control.css" rel="stylesheet" />
   <script src="~/lib/bootstrap-table/bootstrap-table.js" type="module"></script>
   <script src="~/lib/bootstrap-table/extensions/toolbar/bootstrap-table-toolbar.js" type="module"></script>
   <script src="~/lib/bootstrap-table/extensions/multiple-sort/bootstrap-table-multiple-sort.js" type="module"></script>
   <script src="~/lib/bootstrap-table/extensions/export/bootstrap-table-export.js" type="module"></script>
   <script src="~/lib/bootstrap-table/extensions/cookie/bootstrap-table-cookie.js" type="module"></script>
   <script src="~/lib/bootstrap-table/extensions/page-jump-to/bootstrap-table-page-jump-to.js" type="module"></script>
   <script src="~/lib/bootstrap-table/tableExport.js"></script>
   <style type="text/css">
      #divProducts {
         margin-bottom: 150px;
      }

      #divPageContainer {
         width: 80%;
         margin: auto;
      }
   </style>
}
Original Records On Page Load.
Add Dropdown Or Select Control With OnchangeEvent To Bootstrap-Table Wenzhixin In ASP.NET Core MVC
Updated Records As Soon As Product status Is Changed.


That's it!

Comments

Donate

Popular Posts From This Blog

WPF CRUD Application Using DataGrid, MVVM Pattern, Entity Framework, And C#.NET

TypeScript Error Or Bug: The term 'tsc' is not recognized as the name of a cmdlet, function, script file, or operable program.

Invalid nested tag div found, expected closing tag input