Sometimes we need drag and drop functionality on websites. Maybe we need to drag one element into another element, or just reorder something just by dragging.
I researched a lot of libraries open source available online, and came to conclusion that JQuery library for Draggable and Droppable is the best so far. Because its methods are very simple, or event handlers for drag and drop. Besides, many other libraries build on top of this JQuery library.
Also because it is very simple to use and implement.
Here is the source code for the HTML page I created. video follows it:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Adding charts to your project, usually takes a little bit thinking. Because there are many open source plugins available, but choosing the right one that fits your needs, and the needs of your client could be tricky sometimes.
I choose Chart.js. It is lightweight JavaScript open source plugin available on GitHub because it has all basic functionality that I need, with a lot of easy customization options, including, for example, percentage display of your data, multiple data sets is a single chart, labeling plugin if you want, coloring choices, and nice hover style options.
It is also very simple to set its size to fit desktop, tablet, and mobile devices.
And as you might have guessed, mobile internet browsers are increasing day by day, with smart phones becoming the preferred choice for everyday busy users, and Chart.js does an amazing job of displaying our charts on mobile devices, in order for users to see clearly our data, and very fast.
In this project, I am going to use also Bootstrap.css, for presentation purposes, and for mobile and tablet visibility. So we are going to include only two references to two libraries: Bootstrap.css and Chart.js.
First, we will create a new ASP.NET MVC project, and in Models folder we will add new class called ChartModel.cs. The class is below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
As you can see from above, our first chart has only one data set, with three data points. Our second chart, has two data sets with five data points each.
Now open _Layout.cshtml, which is our layout page for Index view, and add the code below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
As you can see from above code, we have a reference to bootstrap.css and Chart.js inside our project. Then we add jumbotron for presentation purposes, and add a title and description.
Next, and the our core functionality is our Index.cshtml view:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Those are model values that we set in the home controller.And this is our home controller:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
As you can see from the code above, we set our points in the Index Action result, and return our Model to our view, that we created earlier:
returnView(“Index“,myChartModel);
Also, in order to draw our data points on the chart itself, each percentage in its according place on the Pie chart, we need to use plugin, as shown above. To draw only on first chart, our first chart has only one data set, so we check for this condition inside our plugin as such:
First we initiate a variable to hold number of data sets, because this plugin loops for each chart on the page, thus letting us know how much data sets each chart has:
Since we know that our Pie chart has only one data set, we can check for its condition here:
if (numberOfDatasets==1) {
And, accordingly, if the condition is true, continue to draw the percentages. The percentages, we need to generate by ourselves too, they are not included. To do this, we compute each percentage and put it in our datastring variable as such:
I was asked to write a new user subscription form, for a newspaper. I decided to make it cross browser, mobile friendly to capture bigger and wider audience, and cross platform. I will post images first, then show how to implement it.
It is pure Java Script, with bootstrap for cross platform. Why ? In order for it to be fast, no page hanging, attractive and yet simple.
Below are the images, with different sizes for mobile, desktop, and browser with zoomed viewport:
I enjoy creating databases, it trains my analytical part of my mind. Besides, when creating it working with someone else, there is a lot of room for improvement, from hearing someone else’s opinion, because business rules are set there, at least the most of them.
I also used to work in a distribution warehouse center, where big trucks would come in, products in a boxes unloaded with help of workers and put on wooden square plates,those plates put on Jigger Lifts or a Forklift and moved to their correct location temporary storage in the warehouse.
Jigger Lift
Forklift
Then, workers would make new carton boxes for new orders, that will be delivered to different shops and outlets, label them based on clients name,and put in a line.
Carton Boxes
In other place in the same warehouse, a special space is dedicated for ORDERS. Orders are printed on paper by warehouse manager, with different product names and quantity per order and per client perhaps, on a single sheet.And workers would go and get all the boxes needed for a single order from different sections of the warehouse, and bring them there.
Then those boxes, per order, would be distributed to the boxes that are in a long line.
Once the box in that line is full, it is closed, sealed with regular scotch paper, and again put on a wooden plate for order sending. Now I am intentionally not using word shipment here not to confuse you, developer and programmer, with something else. I will tell you later why.
As you might have guessed, inventory management systems are so many here and there, and almost every store who has a warehouse has some kind of tracking mechanism for his merchandise.
This particular example is not IMS ( inventory management system ). It is more like general distribution warehouse outlet software program, that warehouse managers, and their co-managers use to track, label, and instantly count products that come in from supplier, and at the same day maybe, leave the warehouse.
I am going to use SHIPPING, only related to SUPPLIER’s coming products to our warehouse, because some may confuse shipment with shipments to the client. In fact some use shipping referencing shipping to clients their orders, but we are not going to do this because later it gets very confusing what is SHIPPING and what is SHIPMENT, the definition of those words I mean.
We will use Database First approach, because this design is available to our disposal, it is convenient for our situation, it is necessary actually for our warehouse distribution outlet because in this environment, there are many nuances that are better off handled from the beginning in the database logic.
We will do the heavy thinking in the database layer, design our logical and real database, clarify all definitions, set our own definitions and standards, and then do the simple and light front end design.
So we are going to separate our app into three layers, back end, which is database design and implementation, front end, which is a web page, bootstrap built from beginning to accommodate of-course mobiles of all sorts, as well as browsers of all sorts, and then we are going to jump a little bit into our middle layer implementation which handles such logic as copying a product, adding new product and so on.
In short this is what is going to happen:
SUPPLIER is going to send us a SHIPMENTof the products that we need
Our distribution warehouse app is going to store all our products, label them, name them, order them and copy them,because copying helps us later on creating new or similar products by simply selecting from existing copied one and configuring it a bit.
Our clients are going to make ORDERS . We will make our order and send it to client, making revenue and selling products.
To start designing our database, I think it is a good idea to keep up with the chain. At least this helps me not to forget where our database objects are.
If we keep up with the chain, then we can save a lot of time designing this, finish quickly, and hand it to the client ASAP.
Ok. Chain !
Let’s go !
We will begin with SUPPLIER. I will not bore you with details, as you might have guessed, all tables have IDs, Primary Keys, and essential columns that describe and relate ONLY to SUPPLIER object and definition.
So, we will need those columns:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
As you can see, we put only nouns that describe SUPPLIER, his country, fax number, tel number, his address. Country ID is foreign key to Country table, which in our chain we will create next.
So, the Country table and object which we will use to refer our supplier to , or in other words, one country can have many suppliers, or there could be many suppliers from one single country. Therefore, we need to put one to many relationship from COUNTRY table to SUPPLIER table. Therefore, our SUPPLIER table will have foreign key countryID relating to countryID Primary Key in COUNTRY table. Here is COUNTRY table:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
So below are our two tables that we have just created: SUPPLIER and COUNTRY. We need this to see how to create relationship one to many from COUNTRY to SUPPLIER:
To create one to many relationships in SSMS from COUNTRY to SUPPLIER , always start with Foreign Key table, which is SUPPLIER in our case. Right click on it, go to Design, in the white space to the right, right click, and you will see those options below, click on relationships, as shown below:
Once you click on relationships, we see the following window in SSMS:
Please click on Add to the left, a new relationship is added, then to the left click on ellipsis next to Tables And Columns Specific to see this window, to configure foreign key column(many) and primary key column (one) in one to many relationship.
Click OK. So, as you can see, we have configured one to many relationship from COUNTRY table to SUPPLIER table. And so on . I am not going to repeat this again because we will do the same for other tables in our Chain of tables.
It is also very important to normalize our database to first normal form, or at least close to first normal form, meaning that we need to eliminate repeating values in rows completely. It is not impossible if you try hard enough.
Then, we create another table called SHIPMENT.It will hold products that our SUPPLIER sends us. Remember, as mentioned earlier, SHIPMENT in our case is NOT orders to our clients, but it is the shipment that our supplier sends us with products that we asked. We will refer to shipment to our clients as ORDER, inside our middle tier layer later on.
Shipment Table:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Now, to achieve first normal form between SHIPMENT and SUPPLIER, we need to create new table, intermediate, between SHIPMENT and SUPPLIER called SHIPMENT_SUPPLIER. And, of-course, as you may have guessed, we will add relations to join those two tables, on our third table. So, we will add one to many relationship from SUPPLIER to SHIPMENT_SUPPLIER and from SHIPMENT to SHIPMENT_SUPPLIER, where :
SUPPLIER PK -> SHIPMENT_SUPPLIER FK
SHIPMENT PK -> SHIPMENT_SUPPLIER FK
Now we are done joining shipment to supplier.
Next, we need details about our shipment, like shipment date , shipment arrival date and so on. So we will add new table that describes our shipment in more detail. We will call this table SHIPMENT_DETAIL:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
And we need to add one to many relationships from SHIPMENT table to SHIPMENT_DETAIL table
SHIPMENT PK -> SHIPMENT_DETAIL FK
Now this is our first part of our database, or first general section if you wish, that deals with suppliers shipments and its details, and keeping track of them.
The second part of our database design, will have to do of-course with PRODUCT, that is stored in our distribution warehouse on shelves, rotated around here and there, assembled and packed in cardboard boxes, and then sent to clients and their ORDERS.
Let’s create PRODUCT table, simple table with three columns. The details of PRODUCT we will separate to another table called PRODUCT_DESCRIPTION and the details of each product like size, price and weight yet go into third table called PRODUCT_DESCRIPTION_DETAIL.As you can see this is also a small CHAIN of three tables.
So, to summarize our second part of our database design, we need three tables that describe PRODUCT:
PRODUCT
PRODUCT_DESCRIPTION
PRODUCT_DESCRIPTION_DETAIL
PRODUCT:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Now add one to many relationship from PRODUCT to PRODUCT_DESCRIPTION on corresponding productID fields in both tables. They do not need to be named the same, as long as they have exactly the same data type.
PRODUCT PK on productID (one) -> PRODUCT_DESCRIPTION FK on productID (many)
Now add third table:
PRODUCT_DESCRIPTION_DETAIL:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
And add one to many relationship in our CHAIN from PRODUCT_DESCRIPTION to PRODUCT_DESCRIPTION_DETAIL:
PRODUCT_DESCRIPTION on productDescriptionID PK (one) –> PRODUCT_DESCRIPTION_DETAIL on productDescriptionID FK (many)
So the second part is done. But we are missing something. Those two parts, the SUPPLIER and SHIPMENT part , and PRODUCT part are not linked. They are separate clouds in the sky, floating, not related in any way.
So we will relate them by creating new table called SHIPMENT_PRODUCT_DETAIL, which will join the two sections through, and using two tables from each section corresponding:
SHIPMENT_DETAIL (SECTION ONE)
PRODUCT (SECTION TWO)
So here is the table SHIPMENT_PRODUCT_DETAIL:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
And now we create two relationshipsto those two tables:
SHIPMENT_DETAIL on PK shipmentDetailsID(one) –> SHIPMENT_PRODUCT_DETAIL on FK shipmentDetailsID (many)
PRODUCT on PK productID (one) –> SHIPMENT_PRODUCT_DETAIL on FK productID (many)
After finishing our third part, we review everything, all database logic, and we see that something is missing.
What is missing is BOXING DETAILS, and how much of each product boxes has arrived, and how much tiny boxes inside big boxes has arrived, and how many pieces are there in each of these sub -boxes.
Now, to add all those details to PRODUCT table would not be fair, because logically, it is shipment related matter, but at the same time,it is also product related matter.
So to settle this dispute, we create new table called: PRODUCT_BOXING_DETAILS and create one to many relationship from our last created table: SHIPMENT_PRODUCT_DETAIL which joins our so called two database design theoretical sections.
PRODUCT_BOXING_DETAILS:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
And create one to many relationship from SHIPMENT_PRODUCT_DETAIL to PRODUCT_BOXING_DETAILS
SHIPMENT_PRODUCT_DETAIL on shipmentProductDetailsID PK (one) –> PRODUCT_BOXING_DETAILS on shipmentProductDetailsID FK (many)
As you can see, all those design issues happen in theory, because database thinks otherwise. Of-course, one can design his database in whatever way he wants.
Also, it is a good idea to set NON-CLUSTERED indexes on columns that we might use a lot. This will help speed up our SELECT Queries and BULK SELECT. You can as well combine CLUSTERED with NON-CLUSTERED indexes, depending on your needs of-course. There are also third party open source plugins for SSMS that let you do execution plans and at the end literally suggest what INDEX with what columns and what options to add, which will speed your query pretty much visible even to the naked eye, which is amazing because everyone is obsessed with speeding up his SQL queries.Tell me otherwise.
Below is the image of our created Distribution Outlet Database .
And SQL for this database is below, I named this database WH01:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[PRODUCT_BOXING_DETAILS] WITH CHECK ADD CONSTRAINT [FK_PRODUCT_BOXING_DETAILS_SHIPMENT_PRODUCT_DETAIL] FOREIGN KEY([shipmentProductDetailsID])
ALTER TABLE [dbo].[PRODUCT_BOXING_DETAILS] CHECK CONSTRAINT [FK_PRODUCT_BOXING_DETAILS_SHIPMENT_PRODUCT_DETAIL]
GO
ALTER TABLE [dbo].[PRODUCT_DESCRIPTION] WITH CHECK ADD CONSTRAINT [FK_PRODUCT_DESCRIPTION_PRODUCT] FOREIGN KEY([productID])
REFERENCES [dbo].[PRODUCT] ([productID])
GO
ALTER TABLE [dbo].[PRODUCT_DESCRIPTION] CHECK CONSTRAINT [FK_PRODUCT_DESCRIPTION_PRODUCT]
GO
ALTER TABLE [dbo].[PRODUCT_DESCRIPTION_DETAIL] WITH CHECK ADD CONSTRAINT [FK_PRODUCT_DESCRIPTION_DETAIL_PRODUCT_DESCRIPTION] FOREIGN KEY([productDescriptionID])
Once database is done, we will go to Front End design, as mentioned in the beginning of this article, and create ASP.NET MVC project, add entity framework for our database, generate some test data,create nice cross device and cross browser design, and run our project first page.
We will use Bootstrap Cards. Below is picture of bootstrap card, captured and edited from my mobile phone,since cards fit similar information on the same sheet called Card.
I am not surprised if we will start programming using phones in the future as well .
But first lets populate our database with some test data:
Test Data:
At the end of this post, a link to download Visual Studio Solution
will be provided. There a file named WH01testdata.sql inside the
project has SQL to add data to our database.
Using Visual Studio 2015, let’s create new ASP.NET MVC with WebAPI support new project, name it MyDistributionOutlet,as shown in the image below:
The next step is to add EntityFramework to our newly created WH01 database.
Now, of-course you can build data access layer within your client app or program that will use your database. It does not need to be Entity Framework.But for me it is easier to use LINQ to SQL because it saves time, security against SQL injection built in, like parameterized query and even better, direct conversion to IEnumerable and easy direct way of manipulating and working with IQueryable, and of course transaction like approach to objects with the ability to commit multiple ADD operations at the same time, for example, with single commit.
So it is convenient as you can see, that’s why I use it.
To be honest with you, I am only going to write first page of searching product, the logic behind it, and copying a product functionality, in case you want to add similar product later on.
Now remember, all this is taking place in the context of our Distribution Outlet and people who are going to be using it there or “actors “.
The rest of the code I will let you write it on your own, like making a new ORDER object, saving it, and preparing to print it for the end user.
You can use this code as you wish, it is open source and with no license at all.
I will put the download link for the code and working video in the end,as with my other blog posts.
We will use Visual Studio 2012. Just for a change. You can use any version, but the process of creation ASP.NET MVC WEB API project is a little bit different.
Please create new ASP.NET WEB API Project and name it MyDistributionOutlet.
In the Views –> Shared directory, in _Layout.cshtml page, in the header, add the following links:
And in the <body> tag, right after it, and before @RenderBody() add our newly designed SEARCH and NAVIGATION Cross Device, mobile and desktop menu: by the way, I spent quite a while designing this menu because I did not want anything there, and also I wanted and needed text box to be the same size on desktop and also when zoomed on mobile viewport:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Run the project in debug or release mode, and you will see those two images respectively:
DESKTOP VIEW:
DESKTOP VIEW
MOBILE VIEW:
MOBILE IPHONE 8 VIEW
ZOOMED AND MINIMIZED BROWSER VIEWPORT VIEW:
BROWSER ZOOMED VIEW
As you can see, HTML5 Rocks ! Anyways, this is just front page when the app starts. You can also add login capability so the start screen would be your desired login screen, but it is up to you to add it or not.
This menu contains search box, where you can type product name and get all products by that or similar name, also, you can select Grid View, and instead of default Cards view you will have regular gridview with sub menu for supplier for each product.
The shipment or search by shipment is intentionally left for you on your choice to implement or not.
We will continue by our plan, if you scroll back to the beginning of this post, I said that we will first do database design, which is back end, then switch completely to front end design, (what we are doing now).So we will continue thinking in those terms and not jump around here and there.
Next in our front end design, we need a search page that will display our search results. Lets design it ! Here is the code for search page that we have designed once the user clicks on search button, goes to search Action Result (ActionResult Search), which in its turn will return GridSearch view OR SearchProduct view respectively.
GridSearch view will display our search results in a grid view, and SearchProduct view will display our results in Cards layout. You can as well, mix,and create views with traditional web forms.
Since both of these views will contain our Model data as in Model View Controller, we need a model, we will create two classes in Models folder:
SearchProductModel
SearchProductModelList
And at the top of GridSearch view and at the top of SearchProduct.aspx page we will add the following:
Notice the inherits directive. This is how we pass the model to ASP.NET web page.
Also, we used master page, in order not to put search box on each page.
OK,Then we add new folder called EntityFramework, and add to it EDMX or ADO.NET Entity Data Model, and call it WH01Entities
Now switch to Controllers folder as per Model View Controller and in our HomeController add Search ActionResult, as shown below:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Also, as I mentioned before, we will add functionality to COPY a product. Copying a product is nothing but adding a prodctCopied field in PRODUCT_DESCRIPTION table.
We will add this code below in our HomeController:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
The test data and database creation script is available inside the project folder once you download the solution, in test-data.sql file and wh01-tables.sql respectively.
So once we do all this, and fill in some test data,we will see those pages:
DESKTOP CARDS DEFAULT RESULT (AFTER SEARCH CLICK)
DESKTOP CARDS MOBILE RESULT (AFTER SEARCH CLICK)
And card list continues down below if you scroll down.
And:
DESKTOP ZOOMED HTML 5 VIEW PORT:
Also, if you scroll the list will go down and down, with the cards list that our search returned.
The GRID VIEW page:
It contains sub-report, and EDIT functionality on the same page.