Responsive Design Drag and Drop

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:

<html>
<!– DESIGN BY JINAN KORDAB –>
<!– DATE: APRIL 9, 2019 –>
<!– BOOTSTRAP RESPONSIVE DESIGN – FRONT END ONLY –>
<!– DEMO USAGE OFDRAG AND DROP FUNCTIONALITY. –>
<!– I FOUND THAT JAVASCRIPT IS THE BEST OPTIONS O FAR FOR HANDLING DRAG AND DROP SINCE THERE ARE MANY THIRD PARTY LIBRARIES AS WELL –>
<!– THIS PAGE SHOWS AN OPTIONS MENU,WITH BOOTSTRAP FOR RESPONSIVE DESIGN, WHEN DROPPED INTO THE MIDDLE CONTAINER,TRIGGERS THE droppable EVENT. –>
<!– INSIDE droppable EVENT,WE CAN ADD AJAX CALLS TO BACK END OT TO ASP.NET MVC CONTROLLERS AND ACTION RESULTS TO GET DATA FROMD ATA BASE –>
<!– YOU CAN USE THIS CODE AS YOU WISH –>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Jinan Kordab Draggable with Boostrap Example</title>
<link rel="stylesheet" href="bootstrap.min.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script&gt;
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script&gt;
<script src="bootstrap.min.js"></script>
<script>
$( function() {
$( "#draggable" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>TIPS DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable2" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>SALES DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable3" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>MONTHLY DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable4" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>WEEKLY DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable5" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>YTD DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable6" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>OPTION ONE DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable7" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>OPTION TWO DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable8" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>OPTION THREE DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable9" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>OPTION FOUR DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable10" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>OPTION FIVE DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#draggable11" ).draggable({
opacity: 0.35,
containment: "#droppable",
revert: true,
helper: "clone",
helper: function( event ) {
return $( "<div class='badge badge-success'>OPTION SIX DETAILS</div>" );
},
snap: "#droppable",
start: function() {
},
drag: function() {
},
stop: function() {
}
});
$( "#droppable" ).droppable({
drop: function( event, ui ) {
var options = {};
var draggable = ui.draggable;
//alert(draggable.attr('id'));
if(draggable.attr('id') == "draggable")
{
$( "#draggable" ).effect( "bounce", options, 500, callback );
//$( "#draggable" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable2")
{
$( "#draggable2" ).effect( "bounce", options, 500, callback );
//$( "#draggable2" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable3")
{
$( "#draggable3" ).effect( "bounce", options, 500, callback );
//$( "#draggable3" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable4")
{
$( "#draggable4" ).effect( "bounce", options, 500, callback );
//$( "#draggable4" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable5")
{
$( "#draggable5" ).effect( "bounce", options, 500, callback );
//$( "#draggable5" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable6")
{
$( "#draggable6" ).effect( "bounce", options, 500, callback );
//$( "#draggable6" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable7")
{
$( "#draggable7" ).effect( "bounce", options, 500, callback );
//$( "#draggable7" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable8")
{
$( "#draggable8" ).effect( "bounce", options, 500, callback );
//$( "#draggable8" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable9")
{
$( "#draggable9" ).effect( "bounce", options, 500, callback );
//$( "#draggable9" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable10")
{
$( "#draggable10" ).effect( "bounce", options, 500, callback );
//$( "#draggable10" ).parent().innerText = $( "#draggable" ).innerText;
}
else if(draggable.attr('id') == "draggable11")
{
$( "#draggable11" ).effect( "bounce", options, 500, callback );
//$( "#draggable11" ).parent().innerText = $( "#draggable" ).innerText;
}
}
});
} );
function callback() {
};
</script>
<style type="text/css">
.col-sm.border.rounded.border-warning:hover {
border: 1px solid #6c757d !important;
}
.block {
/* display: block; */
width: 100%;
height: 45px;
/* border: none; */
/* background-color: silver; */
/* padding: 0px 0px; */
/* font-size: 13px; */
/* cursor: pointer; */
/* text-align: center; */
/* color: white; */
font-weight: bold;
overflow: hidden;
}
</style>
</head>
<body class="bg-light">
<nav class="navbar navbar-expand-lg navbar-light bg-info ">
<a class="navbar-brand text-white" href="#">LOGO</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active"><a class="nav-link text-white" href="#">HOME
<span class="sr-only">(current)</span></a> </li>
<li class="nav-item"><a class="nav-link text-white" href="#">CONTACT</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle text-white" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
SERVICES </a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">SERVICE A</a>
<a class="dropdown-item" href="#">SERVICE B</a>
<div class="dropdown-divider">
</div>
<a class="dropdown-item" href="#">SERVICE C</a> </div>
</li>
<li class="nav-item"><a class="nav-link disabled text-white" href="#">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-warning my-2 my-sm-0 text-white" type="submit">
Search</button>
</form>
</div>
</nav>
<hr>
<div class="container-fluid" id="mainMenu">
<div class="row">
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important;">
<div id="draggable" class="btn btn-warning block" style="width:100%">
TIPS</div>
</div>
<div class="col-sm border rounded " style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable2" class="btn btn-warning block" style="width:100%">
SALES</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable3" class="btn btn-warning block" style="width:100%">
MONTHLY</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable4" class="btn btn-warning block" style="width:100%">
WEEKLY</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable5" class="btn btn-warning block" style="width:100%">
YTD</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable6" class="btn btn-warning block" style="width:100%">
OPTION</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable7" class="btn btn-warning block" style="width:100%">
OPTION</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable8" class="btn btn-warning block" style="width:100%">
OPTION</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable9" class="btn btn-warning block" style="width:100%">
OPTION</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable10" class="btn btn-warning block" style="width:100%">
OPTION</div>
</div>
<div class="col-sm border rounded" style="padding-left:0px !important; padding-right:0px !important;padding-bottom:0px !important">
<div id="draggable11" class="btn btn-warning block" style="width:100%">
OPTION</div>
</div>
</div>
</div>
</div>
<div class="container-fluid" id="droppable" style="border:2px solid red;width:100%;height:98%;margin-top:5px">
</div>
</body>
</html>
view raw Draggable.html hosted with ❤ by GitHub
Drag and Drop for responsive design

Fibonacci Sequence Responsive Web Template – The Golden Spiral

When we mention patterns, we come across many programming language patterns like MVC, Gang Of Four, Repository, and many others. They are called design patterns. And when used in programming, they help write and complete projects, small and big, faster than usual, because in each pattern, a system is defined, by which one can successfully come to desired results and achieve the best optiomal end-result.
Fibonacci Sequence, or golden ratio spiral,can be observed in spirals in nature.The man who observed this sequence is Fibonacci. This sequence looks something like this: 1,1,2,3,5,8 … The next number is the sum of previous two. The formula is F(n) = F(n-1) + F(n-2). And the golden ratio of dividing upper number by previous saller number is always 1.61803 approaching infinity as the numbers grow bigger.

I read a lot of materials on Fibonacci Sequence. Moreover, I was interested in its applications in real life. And nothing much is said about it.Either because it is used by many people and no one wants to tell their secret to the world, although it is not their sequence but a nature’s way of sayign “hi”. Or because indeed it is not applicable or not yet revealed how to apply it in real world. Some examples that I came across is eqyption pyramids proportions, stock market percentages. In stock market buying and selling,Fibonacci Sequence for example is integrate into graphs of rising and falling stocks,where one can make predictions on buying or selling a particular stock, after coputing Fibonacci Sequence from high and low of a trend or stock.

And I did not find much else.Oh, sorry. I also found how people, many people describe where they see the spirals in nature. That is about it.

Since I write software, I thought how can it be applied to software. Proportional web template, based on Fibonacci Sequence, is the first thing that came to my mind.If you search the web for Fibonacci Sequence, you will find the golden ratio picture drawn in squares first, with proportions (height and width) starting with 1,1,2,3,5,8 ..meaning that first two squares have width and height of 1.Then 2X2. Then 3X3. then 5×5, and so on. And with the help of Drafting Compasses, if you draw arcs from one end of each square to its opposite, and continue as the numbers increase, you get the famous Fibonacci Sequence golden spiral which you see all over the web.

So, to design Fibonacci Sequence web template, it needs to be proportional, and maintain its ratio across all screens that the page is opened. In short, it needs to be responsive. So we have width and height that we will need to base on the golden proportion of 1.61803, meaning that the total width of the screen, when bigger column width is divided by shorter column width should equal to 1.61803,no matter what the size of the screen is. Same with height.

For our case, we will consider that for segment AB, AC will be < CB, and AC is left side of a segment and CB is right segment, so AC = left = smaller part, and CB = right = bigger part.

And we will use this JavaScript code to compute left, and right segments’ width and height respectively:


function computeGoldenRatio(widthOrHeight) {
if (!widthOrHeight) {
return {};
}
return {
width: widthOrHeight,
right: Math.round(widthOrHeight/ 1.61803),
total: Math.round(widthOrHeight* 1.61803),
left: widthOrHeight- Math.round(widthOrHeight/ 1.61803)
};
}

view raw

GoldenRatio.js

hosted with ❤ by GitHub

Then we design our basic HTML table, which in theory should have two rows, and two columns, where first column of first row is also divided into two rows, as shown below:


<table width="100%" id="tblMain" bgcolor="#FFFFFF">
<tr>
<td id="col3">
<table border="1" width="100%">
<tr>
<td colspan="2" id="col33" >
<p align="center"><font style="font-size:27px"><b>(3)</b></font></td>
</tr>
<tr>
<td id="col32">
<p align="center"><font style="font-size:27px"><b>(2)</b></font></td>
<td>
<table width="100%" >
<tr>
<td id="col31">
<p align="center"><font style="font-size:27px"><b>(1)</b></font></td>
</tr>
<tr>
<td id="col311">
<p align="center"><font style="font-size:27px"><b>(1)</b></font></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td id="col5">
<p align="center"><font style="font-size:27px"><b>(5)</b></font></td>
</tr>
<tr>
<td colspan="2" id="col8">
<p align="center"><font style="font-size:27px"><b>(8)</b></font></td>
</tr>
</table>

As you can see, the numbers 1, 1, 3, 5, and 8 resectively denote and represent visually the Fibonacci Sequence proportions.

The next step, for it to be responsive, in $(document).ready or when the document or page that we are loading is ready, we will set proportions. Here is the code for that:


$(document).ready(function () {
var GRWidth = computeGoldenRatio($(window).width());
var GRHeight = computeGoldenRatio($(window).height());
$("#tblMain").height($(window).height() + "px");
$("#tblMain").width($(window).width() + "px");
$("#col3").width(GRWidth.left + "px");
$("#col5").width(GRWidth.right + "px");
$("#col3").height(GRHeight.left + "px");
var GRcol3332H = computeGoldenRatio(GRHeight.left);
$("#col33").height(GRcol3332H.right + "px");
$("#col32").height(GRcol3332H.left + "px");
$("#col31").height((GRcol3332H.left/2) + "px");
$("#col311").height((GRcol3332H.left/2) + "px");
});

So, after doing this,as you can see, wherever the page is opened, even on TV screen, it will have Fibonacci Sequence proportions, and the golden ratio among its squares.

Let’s add very basic but important styles also, in order for content inside to stay inside each cell, and color borders, to see the first Fibonacci Sequence Responsive Web Template:


<style type=text/css>
table
{
table-layout:fixed;
border:1px solid grey;
cell-padding:0px;
cell-spacing:0px;
border-collapse:collapse
}
td{
border:1px solid grey
}
</style>

Also let’s add width to 100% to the body because we want it to scale to the container’s maximum width and height, thus obtaining Golden Ratio on whatever screen or device it is opened:

<body style=”width:100%”>

And, in the head, please add JQuery script, or translate it to pure javascript if you want, but I use JQuery:

jquery-3.3.1.min.js

All the scripts are included !

Below are the pictures of emulators on major phones and devices. And as you can see, it maintains its ratio.

 

And the code for basic phase one:


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Language" content="en-ca">
<script src="jquery-3.3.1.min.js"></script>
<meta charset="utf-8" />
<title></title>
<script type="text/javascript">
$(document).ready(function () {
var GRWidth = computeGoldenRatio($(window).width());
var GRHeight = computeGoldenRatio($(window).height());
$("#tblMain").height($(window).height() + "px");
$("#tblMain").width($(window).width() + "px");
$("#col3").width(GRWidth.left + "px");
$("#col5").width(GRWidth.right + "px");
$("#col3").height(GRHeight.left + "px");
var GRcol3332H = computeGoldenRatio(GRHeight.left);
$("#col33").height(GRcol3332H.right + "px");
$("#col32").height(GRcol3332H.left + "px");
$("#col31").height((GRcol3332H.left/2) + "px");
$("#col311").height((GRcol3332H.left/2) + "px");
});
function computeGoldenRatio(widthOrHeight) {
if (!widthOrHeight) {
return {};
}
return {
width: widthOrHeight,
right: Math.round(widthOrHeight/ 1.61803),
total: Math.round(widthOrHeight* 1.61803),
left: widthOrHeight- Math.round(widthOrHeight/ 1.61803)
};
}
</script>
<style type=text/css>
table
{
table-layout:fixed;
border:1px solid grey;
cell-padding:0px;
cell-spacing:0px;
border-collapse:collapse
}
td{
border:1px solid grey
}
</style>
</head>
<body style="width:100%">
<table width="100%" id="tblMain" bgcolor="#FFFFFF">
<tr>
<td id="col3">
<table border="1" width="100%">
<tr>
<td colspan="2" id="col33" >
<p align="center"><font style="font-size:27px"><b>(3)</b></font></td>
</tr>
<tr>
<td id="col32">
<p align="center"><font style="font-size:27px"><b>(2)</b></font></td>
<td>
<table width="100%" >
<tr>
<td id="col31">
<p align="center"><font style="font-size:27px"><b>(1)</b></font></td>
</tr>
<tr>
<td id="col311">
<p align="center"><font style="font-size:27px"><b>(1)</b></font></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td id="col5">
<p align="center"><font style="font-size:27px"><b>(5)</b></font></td>
</tr>
<tr>
<td colspan="2" id="col8">
<p align="center"><font style="font-size:27px"><b>(8)</b></font></td>
</tr>
</table>
</body>
</html>

The next phase or step is to include content. I decided it would be great to include bootstrap css and javascript.So we will add two bootstrap scripts:


<link rel="stylesheet" href="bootstrap.min.css">
<script src="bootstrap.min.js"></script>

Then, for each Fibonacci Square, or td, in our case, we need to add following CSS:

style=”overflow-y: scroll;text-overflow: ellipsis;white-space: nowrap;position:relative;vertical-align:top”

And, here is the important part, include all the content that we want to put inside container of any kind, (div with class = container in our case), with position absolute. This is in order to achieve respectively full elements content stretch, and overflow scroll, which is when content is higher than the square, it will add a scroll bar on Y-axis. An example would be a twitter feed in one of the suares, 1,2, 3, 5, or 8.

In short, you can put anything in those squares.

Square 2, I left it for LOGO, BRAND name, TITLE, or NAME. The rest is content, bootstrap content, whichever you want.

In reality, we added a CSS wrapper outside bootstrap, which is Fibonacci Sequence Responsive Web Template, and then inside, we have bootstrap elements.

As an example, I added the following, as shown in the pictures below:

And the code after the bootstrap was added:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="bootstrap.min.css">
<script src="jquery-3.3.1.min.js"></script>
<script src="bootstrap.min.js"></script>
<title></title>
<script type="text/javascript">
$(document).ready(function () {
var GRWidth = computeGoldenRatio($(window).width());
var GRHeight = computeGoldenRatio($(window).height());
$("#tblMain").height($(window).height() + "px");
$("#tblMain").width($(window).width() + "px");
$("#col3").width(GRWidth.left + "px");
$("#col5").width(GRWidth.right + "px");
$("#col3").height(GRHeight.left + "px");
var GRcol3332H = computeGoldenRatio(GRHeight.left);
$("#col33").height(GRcol3332H.right + "px");
$("#col32").height(GRcol3332H.left + "px");
$("#col31").height((GRcol3332H.left/2) + "px");
$("#col311").height((GRcol3332H.left/2) + "px");
});
function computeGoldenRatio(widthOrHeight) {
if (!widthOrHeight) {
return {};
}
return {
width: widthOrHeight,
right: Math.round(widthOrHeight/ 1.61803),
total: Math.round(widthOrHeight* 1.61803),
left: widthOrHeight- Math.round(widthOrHeight/ 1.61803)
};
}
</script>
<style type="text/css">
table
{
table-layout:fixed;
border:0px solid grey;
cell-padding:0px;
cell-spacing:0px;
border-collapse:collapse
}
td{
border:0px solid grey;
white-space: nowrap;
overflow:hidden
}
</style>
</head>
<body style="width:100%">
<table width="100%" id="tblMain" bgcolor="#FFFFFF">
<tr>
<td id="col3">
<table border="1" width="100%">
<tr>
<td colspan="2" id="col33" style="overflow-y: scroll;text-overflow: ellipsis;white-space: nowrap;position:relative;vertical-align:top">
<div class="container" style="position:absolute">
<div class="list-group" style="max-width: 100%;">
<a href="#!" class="list-group-item list-group-item-action">
Lorem ipsum dolor sit amet, mollis diceret est in.</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-primary">
Ut sea periculis argumentum suscipiantur.</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-secondary">
Mei persequeris reprehendunt in, an qui malorum contentiones</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-success">
Pri hinc tamquam maiestatis te</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-danger">
Percipit legendos argumentum ut eam</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-warning">
Mutat commodo pro ad</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-info">
Ea nihil mollis definitionem sea</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-light">
Ius saepe dicunt ne, movet dicunt tamquam ei pri</a>
<a href="#!" class="list-group-item list-group-item-action list-group-item-dark">
Ex diceret placerat adipisci nec, sumo audiam platonem vix
id</a> </div>
</div>
</td>
</tr>
<tr>
<td id="col32">
<img src="phi-logo-2.png" style="width:100%;height:100%"></td>
<td>
<table width="100%">
<tr>
<td id="col31">
<button type="button" class="btn btn-info" style="width:100%;height:100%">
Sign In</button></td>
</tr>
<tr>
<td id="col311">
<button type="button" class="btn btn-info" style="width:100%;height:100%">
Sign Up</button></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
<td id="col5" style="overflow-y: scroll;text-overflow: ellipsis;white-space: nowrap;position:relative;vertical-align:top">
<div class="container" style="position:absolute">
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Te adipisci salutatus duo</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary float-right">Go somewhere</a>
</div>
</div>
<div class="card border-secondary mb-3" style="max-width: 100%;">
<div class="card-header">
Lorem ipsum</div>
<div class="card-body text-secondary">
<h5 class="card-title">Pro an postea tacimates</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
</div>
</div>
<div class="card text-white bg-dark mb-3" style="max-width: 100%;">
<div class="card-header">
Lorem ipsum</div>
<div class="card-body">
<h5 class="card-title">At dictas commodo vim</h5>
<p class="card-text text-white">Lorem ipsum dolor sit amet,
mollis diceret est in. Ut sea periculis argumentum suscipiantur.</p>
</div>
</div>
<div class="card text-white bg-warning mb-3" style="max-width: 100%;">
<div class="card-header">
Lorem ipsum</div>
<div class="card-body">
<h5 class="card-title">Suas vituperatoribus sit no</h5>
<p class="card-text text-white">Lorem ipsum dolor sit amet,
mollis diceret est in. Ut sea periculis argumentum suscipiantur.</p>
</div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Assum vivendum tacimates per id</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary float-right">Go somewhere</a>
</div>
</div>
<div class="card text-white bg-primary mb-3" style="max-width: 100%;">
<div class="card-header">
Lorem ipsum</div>
<div class="card-body">
<h5 class="card-title">Primary Panel title</h5>
<p class="card-text text-white">Lorem ipsum dolor sit amet,
mollis diceret est in. Ut sea periculis argumentum suscipiantur.</p>
</div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">His quem sumo latine cu, vix quod</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary">Go somewhere</a> </div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Mei porro aperiri suavitate te</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary">Go somewhere</a> </div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Mel te volumus placerat philosophia</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary">Go somewhere</a> </div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Ea mei iisque sapientem</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary">Go somewhere</a> </div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Ea posse oblique eos</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary float-right">Go somewhere</a>
</div>
</div>
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Ea sale alienum pri</h5>
<p class="card-text">Lorem ipsum dolor sit amet, mollis diceret
est in. Ut sea periculis argumentum suscipiantur.</p>
<a href="#!" class="btn btn-primary">Go somewhere</a> </div>
</div>
</div>
</td>
</tr>
<tr>
<td colspan="2" id="col8" style="overflow-y: scroll;text-overflow: ellipsis;white-space: nowrap;position:relative;vertical-align:top">
<div class="container" style="position:absolute;max-width:100%">
<div class="card">
<h5 class="card-header h5">Lorem ipsum</h5>
<div class="card-body">
<h5 class="card-title">Data Table</h5>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Middle</th>
<th scope="col">Last</th>
</tr>
</thead>
<tr>
<th scope="row">1</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">4</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">5</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">6</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">7</th>
<td>Fname</td>
<td>Mname</td>
<td>@logo</td>
</tr>
<tr>
<th scope="row">8</th>
<td>Fname</td>
<td>Mname</td>
<td>Lnaem</td>
</tr>
<tr>
<th scope="row">9</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">10</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">11</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">12</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">13</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">14</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">15</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">16</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">17</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
<tr>
<th scope="row">18</th>
<td>Fname</td>
<td>Mname</td>
<td>Lname</td>
</tr>
</table>
</div>
</div>
</div>
</td>
</tr>
</table>
</div>
</body>
</html>

Moving from Classic ASP to ASP.NET Mobile with Credit Card Payment API.

Sometimes a client asks to update his current web solution, with credit card payment page to mobile and web solution.

The functionality should stay intact, but user interface must change to accommodate mobile devices view ports.

And not only that. On the old classic ASP website, a client has credit card payment page, linked directly to their API, which uses iFrame with their src property.

I especially prepared an example explanation sketch to illustrate the old asp page, to some extent, architecture:

As you can see here the page looks a little bit similar to the old style “Secure Cross Domain Communication in the Browser” with IFrame URL technique except that when the user presses the submit button on pop up iFrame box, we call the Submit Page function that will trigger AJAX POST request, and onSuccess: we will set the content of the whole ‘htmlContentDiv’ with the TOKEN, plus client details.

The pop up iFrame was just to generate token. It do not get confused here, we are not using OAuth, neither we are using the iFrame URL technique. What we are doing here is we are simply generating secret token ( from client API) and returning it to us via Ajax and JavaScript, but before that generating secure link with correct post parameters. That’s all.

Now, when moving this little bit old functionality to new ASP.NET pages, we can do the following:

As you can see, on page load we also generate our secure secret link with correct parameters, and we directly assign it to the src attribute of our visible iFrame, without the need of clicking on a separate button to generate the popular iFrame. The src of the iFrame is generated directly when we load the page.

Then, when we hit the actual submit button, we will call JavaScript Function SubmitMyForm, which will take only the credit card number, send it via JavaScript Ajax post method, receive a response with generated token, then create new form programmatically from JavaScript, and finally submit our “on the fly” generated form, with token .

As you can see all this functionality was needed just to generate token, because the client does not want to submit a form with raw credit card numbers, compliance works that way.

We first generate token via AJAX and then submit a form via AJAX also, with token and not bare credit card number.

Subscription with rates form – Custom Step Wizard

Code on GitHub:

https://github.com/thoughtsonprogramming/SubscriptionFormUIUX

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:

This slideshow requires JavaScript.

Download source code from my google drive here:

https://drive.google.com/file/d/1-VQ_PSZ9LFjF0ZpclfqNohvMG2-wuHY-/view?usp=sharing

And working video, you can watch it directly also on google drive here:

https://drive.google.com/file/d/1_KH1r9kmDbuVtv1AExWxbr3eNEJCaDPF/view?usp=sharing

It is SPA or Single Page Application.

Man in the middle attack and how to avoid it

MD5 – Avoiding man in the middle attacks

Use Case:

Your client is asking to securely transfer sensitive information like email, tel numbers, addresses, and names once the user submits a form.

One way to do this, and to avoid man in the middle attacks, is to hash your information with MD5.

First, you and the client, or a party to where you are submitting your form with sensitive data, must agree on secret key. Example: TICKTACKTOE , or CHARLIE11.

You then use JavaScript library like:

* JavaScript MD5
* https://github.com/blueimp/JavaScript-MD5

Which is:

* Licensed under the MIT license:
* https://opensource.org/licenses/MIT

The first step is to get the secret key from server side. For simplicity, we add new web form ( because it already has onLoad method defined in its default framework Page Lifecycle ). And we call that page using XmlHttp from client side where our form is.

We do this because on client side if someone inspects page source through available browser tools, he will find the secret key and get access to our sensitive data.


function SubmitFormButtonClick()
{
var salt = "";
//1st part : get salt via ajax//
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 &amp;amp;amp;amp;amp;&amp;amp;amp;amp;amp; this.status == 200)
{
var rData = this.responseText;
salt = rData;
alert("The salt is:"+ slt); } };

xmlhttp.open("GET", "GetMySalt.aspx?query=getmysalt&amp;amp;amp;amp;amp;uval=" +
new Date().getTime(), true);
xmlhttp.send();

//2nd part : Assign hidden form values new hashed values, or call Web Api REST directly via
//Ajax and pass all those values directly in the QueryString

var todaysDateForHash= new Date().toISOString(); //Todays date: ISO-8601 : YYYY-MM-DDTHH:mm:ss.sssZ
var providedEmail = $("#usersEmailFormField").val();
var hashString = providedEmail + todaysDateForHash;
var emailHash = md5(hashString + salt );
$("#hiddenEmailField").val(emailHash);
}

Then we have our button submit which calls SubmitFormButtonClick javascript function

<input id="mySubmitButton" type="button" value="SubmitMyForm" class="btn btn-primary" onclick="SubmitFormButtonClick(); this.disabled = true;" />

As you can see, the second part of javascript function ges todays ISO date string which is standard date format
and can be used as a standard between you and client, so both parties can get the exact same value. Here it is added as an additional security
feature.

The hashString variable joins the email that the user entered plus our ISO date.
Then line: var emailHash = md5(hashString + salt ); computes the actual hash
for theform’s email field.

We can repeat step two for all our form’s fields, and hash all our form values that need to be submitted.
Then the form submits itself, or you can make AJAX REST call from second part of
our javascript function and pass all those values either through GET or through POST, the way you like.

And here is GetMySalt.aspx page, for example that stores the secret. It could be any server side page:

public partial class GetMySalt: System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string ReturnSalt= "";

if (Request["query"] != null)
{
var q = Request["query"].ToString();
if (q == "getmysalt")
{
ReturnSalt = "TICKTACKTOE";
}
}

Response.Write(ReturnSalt);
}
}