jQuery UI draggable prevent duplicates - jquery-ui

I have a list of items on the left that can be dragged into any of the boxes on the right. The items can be in many boxes but should only occur once per box. I am trying to get hold of the ids of the draggable item and compare that against the id's of all the items already in the box, but can't seem to get it right. My code is as follows:
$(".sortable").sortable({
revert: true,
connectWith: ".draggable"
});
$(".draggable").draggable({
connectToSortable: ".sortable",
helper: "clone",
revert: "true",
placeholder: ".droppable-placeholder",
stop: function(event, ui) {
//console.dir(ui.helper[0]);
var listContainer = ui.helper[0].closest('ul');
if (listContainer) {
console.dir(listContainer);
listContainer.find('li').each(function() { //This is not right
var sortableItemId = $(this).attr("id");
console.dir($(this));
console.log("sortable item id " + sortableItemId);
});
}
}
});
$("ul, li").disableSelection();
$(".draggable-column, .droppable-column").on("click", ".close-list-item", function(event) {
event.preventDefault();
$(this).closest('li').remove();
});
ul {
list-style-type: none;
margin: 0;
padding: 0;
margin-bottom: 0.7em;
float: left;
}
li {
margin: 0.5em;
padding: 0.5em;
width: 200px;
border: 1px solid black;
}
.draggable-column {
height: 100%;
}
.droppable-item {
padding: 0.5em;
float: left;
align-content: space-between;
}
.droppable-item > h3 {
text-align: center;
}
.sortable {
width: 230px;
height: 10em;
overflow: auto;
border: 1px solid black;
background-color: lightgrey;
}
.droppable-placeholder {
background-color: yellow;
}
.row {
display: flex;
/* equal height of the children*/
}
.col {
flex: 1;
/* additionally, equal width */
padding: 1em;
border: solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="row">
<div class="col-xs-4 draggable-column">
<ul class="" id="draggable-column-list">
<li class="draggable " id="item1">1 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item2">2 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item3">3 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item4">4 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item5">5 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
</ul>
</div>
<div class="col-xs-8 droppable-column">
<div class="droppable-item">
<h3>
Item 1
</h3>
<ul class="sortable" id="ul-item1">
</ul>
</div>
<div class="droppable-item">
<h3 class="">
Item 2
</h3>
<ul class="sortable" id="ul-item2">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 3
</h3>
<ul class="sortable" id="ul-item3">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 4
</h3>
<ul class="sortable" id="ul-item4">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 5
</h3>
<ul class="sortable" id="ul-item5">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 6
</h3>
<ul class="sortable" id="ul-item6">
</ul>
</div>
</div>
</div>
I am basically trying to stop duplicates occurring in the same box.

So I finally worked out a possible solution although it is not particularly clean:
$(".sortable").sortable({
revert: true,
connectWith: ".draggable"
});
$(".draggable").draggable({
connectToSortable: ".sortable",
helper: "clone",
revert: "true",
placeholder: ".droppable-placeholder",
stop: function(event, ui) {
console.log("--start of stop");
var listContainer = $(ui.helper[0].parentElement);
var newListId = listContainer.attr("id");
var draggableId = $(this).attr("id");
var cloneId = newListId + "-" + draggableId;
console.log("new list id: " + newListId);
console.log("draggableId: " + draggableId);
console.log("cloneId: " + cloneId);
var itemExists = false;
$("#"+ newListId).find('li').each(function() {
var sortableItemId = $(this).attr("id");
console.log("sortable item id " + sortableItemId);
if (sortableItemId != undefined && sortableItemId == cloneId) {
console.log("*** sortable item already exists");
itemExists = true;
}
});
if (itemExists) {
$("#" + cloneId).remove();
}
$(ui.helper[0]).attr("id", cloneId);
console.log("--end of stop");
},
});
$("ul, li").disableSelection();
$(".draggable-column, .droppable-column").on("click", ".close-list-item", function(event) {
event.preventDefault();
$(this).closest('li').remove();
});
ul {
list-style-type: none;
margin: 0;
padding: 0;
margin-bottom: 0.7em;
float: left;
}
li {
margin: 0.5em;
padding: 0.5em;
width: 200px;
border: 1px solid black;
}
.draggable-column {
height: 100%;
}
.droppable-item {
padding: 0.5em;
float: left;
align-content: space-between;
}
.droppable-item > h3 {
text-align: center;
}
.sortable {
width: 230px;
height: 10em;
overflow: auto;
border: 1px solid black;
background-color: lightgrey;
}
.droppable-placeholder {
background-color: yellow;
}
.row {
display: flex;
/* equal height of the children*/
}
.col {
flex: 1;
/* additionally, equal width */
padding: 1em;
border: solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="row">
<div class="col-xs-4 draggable-column">
<ul class="" id="draggable-column-list">
<li class="draggable " id="item1">1 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item2">2 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item3">3 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item4">4 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
<li class="draggable " id="item5">5 Drag me onto item
<a href="#" class="close-list-item">
<i class="fa fa-window-close"></i>
</a>
</li>
</ul>
</div>
<div class="col-xs-8 droppable-column">
<div class="droppable-item">
<h3>
Item 1
</h3>
<ul class="sortable" id="ul-item1">
</ul>
</div>
<div class="droppable-item">
<h3 class="">
Item 2
</h3>
<ul class="sortable" id="ul-item2">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 3
</h3>
<ul class="sortable" id="ul-item3">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 4
</h3>
<ul class="sortable" id="ul-item4">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 5
</h3>
<ul class="sortable" id="ul-item5">
</ul>
</div>
<div class="droppable-item">
<h3>
Item 6
</h3>
<ul class="sortable" id="ul-item6">
</ul>
</div>
</div>
</div>

I struggled with this as well and could not make it work with the control's default functionality. I implemented a solution similar to the answer but in the 'Receive' handler. Basically after the item was added I look for duplicates and then just remove the current added duplicate. This also does not look very clean but works. I really think the sortable control should have this functionality and if it does, it is not well documented. I guess if you really want to add a proper solution, you would need to write an extension that hooks into the mousedrop event and try and prevent adding before the receive handler fires...
Note: I use a sortable list as the drop target and a list with draggable items as the source.
Here is my solution:
$(".sortable").sortable({
revert: "invalid",
connectWith: ".draggable",
placeholder: "ui-state-highlight",
forcePlaceholderSize: true,
receive: function (event, ui) {
var addedItem = $($(this).data().uiSortable.currentItem);
addedItem.prop("id", "dropped_" + $(ui.item[0]).prop("id"));
// Elaborate way to check duplicates and remove them when added. Could not find a way to prevent the item from being dropped
var childItems = $(this).children("li");
var idCount = {};
$.each(childItems, function (i, node) {
var currentId = $(node).prop("id");
if (idCount[currentId] != undefined) {
if (addedItem.prop("id") === currentId) {
addedItem.remove();
return false;
}
} else {
idCount[currentId] = true;
}
});
}
});
The draggable object as follows:
$(".draggable").draggable({
connectToSortable: ".sortable-droptarget",
helper: "clone",
revert: "invalid"
});

Related

drag and drop Div columns and Div rows using JQuery ui

we are creating a table structure using html div, inside that we need to drag and drag and drop the columns and rows , but the row head should be fixed. ie, Drag and drop Div columns and Div rows without moving row head
anybody knows how to solve this.
I need to create this using JQuery , html and css.
$(function() {
$("#tblcols").sortable({
items: '.rtab:not(.rtab:first-child)',
cursor: 'pointer',
axis: 'y',
dropOnEmpty: false,
start: function(e, ui) {
ui.item.addClass("selected");
},
stop: function(e, ui) {
ui.item.removeClass("selected");
$(this).find(".rtab").each(function(index) {
if (index > 0) {
$(this).find(".ctab").eq(2).html(index);
}
});
}
});
});
.Table {
display: table;
}
.Title {
display: table-caption;
text-align: center;
font-weight: bold;
font-size: larger;
}
.Heading {
display: table-row;
font-weight: bold;
text-align: center;
}
.rtab {
display: table-row;
}
.ctab {
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
.htab {
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.24/themes/smoothness/jquery-ui.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.2/jquery-ui.min.js"></script>
<div class="Table">
<div class="Title">
<p>Drag table rows and columns</p>
</div>
<div class="Heading">
<div class="htab">
<p>Sl</p>
</div>
<div class="htab">
<p>Name</p>
</div>
<div class="htab">
<p>Designation</p>
</div>
<div class="htab">
<p>Salary</p>
</div>
<div class="htab">
<p>Location</p>
</div>
</div>
<div class="rtab" id="tblcols">
<div class="ctab">
<p>1</p>
</div>
<div class="ctab">
<p>Athira</p>
</div>
<div class="ctab">
<p>Developer</p>
</div>
<div class="ctab">
<p>6l</p>
</div>
<div class="ctab">
<p>Kottayam</p>
</div>
</div>
<div class="rtab">
<div class="ctab">
<p>2</p>
</div>
<div class="ctab">
<p>Timy</p>
</div>
<div class="ctab">
<p>Designer</p>
</div>
<div class="ctab">
<p>5l</p>
</div>
<div class="ctab">
<p>wayanad</p>
</div>
</div>
<div class="rtab">
<div class="ctab">
<p>3</p>
</div>
<div class="ctab">
<p>Liya</p>
</div>
<div class="ctab">
<p>Team Lead</p>
</div>
<div class="ctab">
<p>7l</p>
</div>
<div class="ctab">
<p>Kollam</p>
</div>
</div>
</div>
I'm a little unsure what you mean. I hope I captured the main idea, that you want the first cell in each row to remain in order after items are sorted. Here is an example that might work for you.
$(function() {
$(".Table .Heading").sortable({
items: '> .htab:not(:eq(0))',
cursor: 'pointer',
axis: 'x',
dropOnEmpty: false,
placeholder: "htab placeholder",
start: function(e, ui) {
var ind = ui.item.index();
$(".Table .rtab").each(function() {
$(".ctab", this).eq(ind).css("opacity", "0.25");
});
ui.item.data("orig-index", ind);
},
stop: function() {
$(".Table .rtab .ctab").css("opacity", "");
},
update: function(e, ui) {
var oInd = ui.item.data("orig-index");
var cInd = ui.item.index();
var cols = $(".Table .htab").length;
$(".Table .rtab").each(function() {
var cell = $(".ctab", this).eq(oInd).detach();
if (cInd < (cols - 1)) {
// Mid Col
cell.insertBefore($(".ctab", this).eq(cInd));
} else {
// Last Col
$(this).append(cell);
}
})
}
});
$(".Table").sortable({
items: '> .rtab',
cursor: 'pointer',
axis: 'y',
dropOnEmpty: false,
start: function(e, ui) {
$(".ctab", ui.item).eq(0).html(" ");
},
stop: function(e, ui) {
$(".Table .rtab").each(function(ind, el) {
$(".ctab", el).eq(0).html((ind + 1));
});
}
});
});
.Table {
display: table;
}
.Title {
display: table-caption;
text-align: center;
font-weight: bold;
font-size: larger;
}
.Heading {
display: table-row;
font-weight: bold;
text-align: center;
}
.rtab {
display: table-row;
}
.ctab {
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
.htab {
display: table-cell;
border: solid;
border-width: thin;
padding-left: 5px;
padding-right: 5px;
}
.htab.placeholder {
background: #ccc;
width: 20px;
}
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css" />
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="Table">
<div class="Title">
<p>Drag table rows and columns</p>
</div>
<div class="Heading">
<div class="htab">
<p>Sl</p>
</div>
<div class="htab">
<p>Name</p>
</div>
<div class="htab">
<p>Designation</p>
</div>
<div class="htab">
<p>Salary</p>
</div>
<div class="htab">
<p>Location</p>
</div>
</div>
<div class="rtab" id="tblcols">
<div class="ctab">
<p>1</p>
</div>
<div class="ctab">
<p>Athira</p>
</div>
<div class="ctab">
<p>Developer</p>
</div>
<div class="ctab">
<p>6l</p>
</div>
<div class="ctab">
<p>Kottayam</p>
</div>
</div>
<div class="rtab">
<div class="ctab">
<p>2</p>
</div>
<div class="ctab">
<p>Timy</p>
</div>
<div class="ctab">
<p>Designer</p>
</div>
<div class="ctab">
<p>5l</p>
</div>
<div class="ctab">
<p>wayanad</p>
</div>
</div>
<div class="rtab">
<div class="ctab">
<p>3</p>
</div>
<div class="ctab">
<p>Liya</p>
</div>
<div class="ctab">
<p>Team Lead</p>
</div>
<div class="ctab">
<p>7l</p>
</div>
<div class="ctab">
<p>Kollam</p>
</div>
</div>
</div>
For the Header, we can sort the header items and then move the cells that correspond with it. Due to the relationship of the elements in Rows, there is not an element that contains all the column items. It effectively does what is needed, yet looks a little weird in doing it. With items we can exclude the first header.
When using Sortable for the Rows, you want to target the parent and then using items option, you can target the rows that you want to sort and those you want to exclude. Since we're sorting the rows and not the items inside, there is not a good way to exclude an item in the row.
When Sort starts, cell 0 is change to so it does not shrink too much. Once sort is stopped, it re-indexes the rows back into order. If we use update it will only fire when a change is performed. So if the user grabs a row and doesn't move it, there is not update. To address this, we can use stop to re-index.
Hope that helps.

MVC page with Bootstrap layout, after loading the page, automatically scrolls up a bit, how to avoid that

This is the main page
then after loading the page , it automatically scroll to this position.
This is layout page
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
</head>
<body>
<div class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("My Dashboard", "Index", "Client")</li>
<li>#Html.ActionLink("Domain Registration", "ClientRegistration", "User")</li>
<li>#Html.ActionLink("Employee", "EmployeeList", "Client")</li>
<li>#Html.ActionLink("Work Hour Manage", "WorkHourManage", "Client")</li>
<li>#Html.ActionLink("Department", "DepartmentList", "Client")</li>
<li>#Html.ActionLink("Company", "CompanyList", "Client")</li>
<li>#Html.ActionLink("Logout", "UserLogout", "Login")</li>
</ul>
<div style="color: #ada8a8;float: right;margin-top: 10px;">
#{
var UserType = Request.Cookies["UserType"];
var UserName = Request.Cookies["UserName"];
if (UserName != null && UserType !=null)
{
<text>#(UserType.Value+"-"+UserName.Value)</text>
}
}
</div>
</div>
</div>
</div>
<div class="container-fluid body-content">
#RenderBody()
<hr />
<footer>
<p>© #CommonFunction.GetCurrentDateTime().Year - Employee Tracking & Management Information System.</p>
</footer>
</div>
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
This is the index page, not only index moves, but all pages scroll up automatically
#{
ViewBag.Title = "My Dashboard";
}
#Html.Raw(TempData["Status"])
<div class="HeadingSite">
My Dashboard <div style="float:right;font-weight:normal;">#(Session["DaysLeft"]) Days Left</div>
</div>
<style>
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
.box {
cursor: pointer;
}
.box > .icon {
text-align: center;
position: relative;
}
.box > .icon > .image {
position: relative;
z-index: 2;
margin: auto;
width: 88px;
height: 88px;
border: 8px solid white;
line-height: 88px;
border-radius: 50%;
background: #63B76C;
vertical-align: middle;
}
.box > .icon:hover > .image {
background: #333;
}
.box > .icon > .image > i {
font-size: 36px !important;
color: #fff !important;
}
.box > .icon:hover > .image > i {
color: white !important;
}
.box > .icon > .info {
margin-top: -24px;
background: rgba(0, 0, 0, 0.04);
border: 1px solid #e0e0e0;
padding: 15px 0 10px 0;
}
.box > .icon:hover > .info {
background: rgba(0, 0, 0, 0.04);
border-color: #e0e0e0;
color: white;
}
.box > .icon > .info > h4.title {
font-family: "Roboto",sans-serif !important;
font-size: 16px;
color: #222;
font-weight: 500;
}
.box > .icon > .info > p {
font-family: "Roboto",sans-serif !important;
font-size: 13px;
color: #666;
line-height: 1.5em;
margin: 20px;
}
.box > .icon:hover > .info > h4.title, .box > .icon:hover > .info > p, .box > .icon:hover > .info > .more > a {
color: #222;
}
.box > .icon > .info > .more a {
font-family: "Roboto",sans-serif !important;
font-size: 12px;
color: #222;
line-height: 12px;
text-transform: uppercase;
text-decoration: none;
}
.box > .icon:hover > .info > .more > a {
color: #fff;
padding: 6px 8px;
background-color: #63B76C;
}
.box .space {
height: 30px;
}
</style>
<div class="row">
<div onclick="location.href = '../Client/WorkHourManage';" class="col-sm-4 col-lg-2">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-cog"></i></div>
<div class="info">
<h4 class="title">Manage Work Hour</h4>
<p>
Manage and view work hours of the company..
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/CompanyList';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-industry"></i></div>
<div class="info">
<h4 class="title">Manage Company List</h4>
<p>
Manage or view Company List of this company..
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/EmployeeList';" class="col-sm-4 col-lg-2">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-users"></i></div>
<div class="info">
<h4 class="title">Manage Employees</h4>
<p>
Manage or view Employee of this company..
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/DepartmentList';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-tag"></i></div>
<div class="info">
<h4 class="title">Manage Department</h4>
<p>
Departments are added to employee details..
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/EmployeeBackgroundTrackHistory';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-street-view"></i></div>
<div class="info">
<h4 class="title">Employee Background Tracking</h4>
<p>
Details of Employee presence on different days.
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/EmployeeTrackRouteEstimateList';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-map-marker"></i></div>
<div class="info">
<h4 class="title">Employee Track Route & Estimate</h4>
<p>
Details regarding traveling details, traveling report and conveyance calculation.
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/TravelCostManage';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-money"></i></div>
<div class="info">
<h4 class="title">Manage Base Travelling Cost</h4>
<p>
Details regarding traveling cost of the company. This is a rough calculation and different employees are assigned different amounts for travelling modes.
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/EmployeeEnquiryReport';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-book"></i></div>
<div class="info">
<h4 class="title">Employee Visit Report</h4>
<p>
Reports of employee visits.
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/ChatWithEmployee';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-comments"></i></div>
<div class="info">
<h4 class="title">Chat with Employee</h4>
<p>
You can send messages and view replies from you Employees.
</p>
</div>
</div>
</div>
</div>
<div onclick="location.href = '../Client/UnlockModules';" class="col-sm-4 col-lg-2 noselect">
<div class="box">
<div class="icon">
<div class="image"><i class="fa fa-unlock-alt"></i></div>
<div class="info">
<h4 class="title">Unlock Modules</h4>
<p>
Unlock or Activate modules. Also can temporarily turn of unwanted modules.
</p>
</div>
</div>
</div>
</div>
</div>
I had this same issue, and disabling Browser Link in Visual Studio fixed it for me. From what I observed on the console, Browser Link runs some Javascript which shifts the page. Hope this helps!
I think it is something wrong with my system. Works perfectly in other pcs.
I used Webessential with autoreload on change options like that. May be my debugger problem.

bootstrap responsive sidemenu

I've been trying to get my site which has a sidemenu to override the normal functionality for the top menu when mobile view is operated.
i.e. i want the menuitems to be full width.
<div class="col-md3 pull-left">
<div class="bs-sidebar hidden-print affix-top" id="sidemenu">
<ul class="nav bs-sidenav">
<li class="nav-header">
<a data-toggle="collapse" data-parent="#sidemenu" href="#Admincontainer" class=""><span>Admin</span><i class=" pull-right glyphicon glyphicon-chevron-down"></i></a>
<ul style="list-style-type: none; margin-left:10px" id="Admincontainer" class="nav collapse ">
<li class="">
<a href="lnk" title="">
Manage Members
<i class=" glyphicon glyphicon-chevron-right pull-right">
</i>
</a>
</li>
<li>
<a href="/Admin/Member/addnew" title="">
Add A New Member
<i class=" glyphicon glyphicon-chevron-right pull-right">
</i>
</a>
</li>
</ul>
</li>
<li class="nav-header">
<a data-toggle="collapse" data-parent="#sidemenu" href="#Publiccontainer" class=""><span>Committee</span><i class=" pull-right glyphicon glyphicon-chevron-down"></i></a>
<ul style="list-style-type: none; margin-left:10px" id="Publiccontainer" class="nav collapse ">
<li>
<a href="/Public" title="">
Home
<i class=" glyphicon glyphicon-chevron-right pull-right">
</i>
</a>
</li>
<li>
<a href="/Public/Contact" title="">
Contact Us
<i class=" glyphicon glyphicon-chevron-right pull-right">
</i>
</a>
</li>
</ul>
</li>
</div>
</div>
I've tried and failed with a few approaches so ive created a "vanilla" template of how my menu looks before i try and "fix" it. I basically want the sidemenu to become that fullwidth top menu when the viewport becomes too small to accommodate both sidemenu and main content side by side.
I've hacked an example from a default bootstrap template below.
jsbin example
Default template
Default template's in mobile with vertically stacked menu
Example showing the sidemenu i want to replace the vertically stacked menu in previous image.
You need two navbars (one at the top and one at the side) and then use JQuery to move the side navbar to the top of the page.
So if you have two navbars like so:
<div class="navbar navbar-inverse navbar-fixed-top ">
<div class="container ">
<div class="navbar-header ">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#topmenu">
<span class="icon-bar "></span>
<span class="icon-bar "></span>
<span class="icon-bar "></span>
</button>
<a class="navbar-brand " href="/ ">Application name</a>
</div>
<div id="topmenu" class="navbar-collapse collapse ">
<ul class="nav navbar-nav ">
<li>
Home
</li>
<li>
About
</li>
<li>
Contact
</li>
</ul>
<ul class="nav navbar-nav navbar-right ">
<li>
Register
</li>
<li>
Log in
</li>
</ul>
</div>
</div>
</div>
<div id="navbar" class="navbar navbar-inverse navbar-fixed-top">
<ul class="nav nav-stacked" id="menu-bar">
<li class="panel dropdown">
<a data-toggle="collapse" data-parent="#menu-bar" href="#collapseOne">
Admin
</a>
<ul id="collapseOne" class="panel-collapse collapse">
<li>Manage Members</li>
<li>Add a new Member</li>
</ul>
</li>
<li class="panel dropdown">
<a data-toggle="collapse" data-parent="#menu-bar" href="#collapseTwo">
Committee
</a>
<ul id="collapseTwo" class="panel-collapse collapse">
<li>Home</li>
<li>Contact Us</li>
</ul>
</li>
<li>Page 2</li>
<li>Page 3</li>
</ul>
</div>
<div class="clearfix"></div>
<div class="content">
<div class="container bodycontent">
<div class="jumbotron">
<h1>Testing Responsive sidemenu</h1>
<p class="lead">Trying to get my side menu to replace the top menu when the size goes too small.
</p>
</div>
<div class="row">
<div class="col-md-12">
<div class="row">
<article>
<h1>Content</h1>
<p>Content here</p>
</article>
</div>
</div>
</div>
</div>
</div>
The JQuery is as follows:
var $window = $(window),
$html = $('#menu-bar');
$window.resize(function resize(){
if ($window.width() < 768) {
// When the side bar is moved to the top, this stops it being fixed in place
$("#navbar").removeClass('navbar-fixed-top');
return $html.removeClass('nav-stacked');
}
$("#navbar").addClass('navbar-fixed-top');
$html.addClass('nav-stacked');
}).trigger('resize');
And CSS:
/* CSS used here will be applied after bootstrap.css */
#media (max-width: 767px) {
.content {
padding: 15px;
margin-top: 10px;
}
}
#media (min-width: 768px) {
#menu-bar .panel {
margin-bottom: 0;
background-color: rgba(0,0,0,0);
border: none;
border-radius: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
#menu-bar li a {
color: #fff;
font-size: 16px;
font-weight: bold;
}
#navbar {
float: left;
width: 200px;
height: 100%;
}
.content {
margin-left: 200px;
min-height: 100%;
margin-top: 60px;
}
.container {
margin-left: 10px;
padding-right: 150px;
}
}
.navbar-brand > h3 {
margin-top: 0;
margin-bottom: 0;
}
.body-content {
padding-left: 15px;
padding-right: 15px;
}
#navbar {
margin-top: 50px
}
If you want the left hand side bar to have certain CSS, you should specify the CSS like so:
#media (min-width: 768px) {
#menu-bar {
/* Put your CSS here. It will not apply to the menu-bar when it moves to the top */
}
}
Bootply here

Rendered HTML differs from source

I've come across some strange behaviour when I want to view a page in my ASP.NET MVC app.
I've created a small HTML helper that should generate a specific layout to display one of my classes.
It is invoked as such:
<div id="tabs-3" style="display:block; float:left;width:95%;">
#foreach (Trade trade in ViewBag.Trades)
{
#Html.Trade(trade, userLanguage)
}
</div>
The expected HTML that is generated looks like this:
<div id="tabs-3" style="display:block; float:left;width:95%;">
<div style="display:block; margin-top:0px; margin-left:auto; margin-right:auto; text-align:center;">
<a href="/en/Trade/Details/1" class="blocklink">
<div style="display:inline-block; margin-top:0px; margin-left:auto; margin-right:auto; border:2px solid black;">
<div style="display:inline-block; vertical-align:middle;">
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<img style='height:50px; width:50px; vertical-align:middle;' alt="User" src="http://localhost:50254/Images/Avatars/01.png">
</div>
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<span style="font-size:16pt; display:block; font-weight:bold;">
User
</span>
<span style="font-size:8pt; display:block;">
<br/>0 Trades (100%)
</span>
</div>
</div>
<div style="display:inline-block; padding-left:50px; padding-right:50px; vertical-align:middle;">
<div style="display:inline-block; vertical-align:middle; position:relative; margin-left:auto; margin-right:auto;">
<span style="font-size:10pt; display:block; font-weight:bold; text-align:center;">Sat 19 Apr 2014 20:00</span>
</div>
<div style="display:block; vertical-align:middle; position:relative; margin-left:auto; margin-right:auto; padding-top:5px; padding-bottom:5px; ">
<img alt="" src="/Images/Blank.png" style="background: url(/Images/Icons.png) -465px 0; display: block; width: 20px;height: 20px; text-indent: -9999px; margin-left:auto; margin-right:auto;" />
</div>
<div style="display:block; vertical-align:middle; position:relative; margin-left:auto; margin-right:auto;">
<span style="font-size:10pt; display:block; font-weight:bold; text-align:center;">3 Trades</span>
</div>
</div>
<div style="display:inline-block; vertical-align:middle;">
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<span style="font-size:16pt; display:block; font-weight:bold; text-align:right;">
User2
</span>
<span style="font-size:8pt; display:block; text-align:right;">
<br/>0 Trades (100%)
</span>
</div>
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<img style='height:50px; width:50px; vertical-align:middle;' alt="User2" src="http://localhost:50254/Images/Avatars/09.png">
</div>
</div>
</div>
</a>
</div>
<!-- Other records-->
</div>
I've used breakpoints to look at the generated string and it does look like it should. When I look at the source in a browser it also looks like the above.
However the rendered HTML differs from it (I've checked it with the debugging tools of IE 11, FF 28 and Chrome 34), it looks like this:
<div id="tabs-3" style="display:block; float:left;width:95%;">
<div style="display:block; margin-top:0px; margin-left:auto; margin-right:auto; text-align:center;">
<div style="display:inline-block; margin-top:0px; margin-left:auto; margin-right:auto; border:2px solid black;">
<div style="display:inline-block; vertical-align:middle;">
<a href="/en/Trade/Details/1" class="blocklink">
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<img style="height:50px; width:50px; vertical-align:middle;" alt="User" src="http://localhost:50254/Images/Avatars/01.png">
</div>
</a>
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<a href="/en/Trade/Details/1" class="blocklink">
<span style="font-size:16pt; display:block; font-weight:bold;"></span>
</a>
User
<span style="font-size:8pt; display:block;">
<br>0 Trades (100%)
</span>
</div>
</div>
<div style="display:inline-block; padding-left:50px; padding-right:50px; vertical-align:middle;">
<div style="display:inline-block; vertical-align:middle; position:relative; margin-left:auto; margin-right:auto;">
<span style="font-size:10pt; display:block; font-weight:bold; text-align:center;">Sat 19 Apr 2014 20:00</span>
</div>
<div style="display:block; vertical-align:middle; position:relative; margin-left:auto; margin-right:auto; padding-top:5px; padding-bottom:5px; ">
<img alt="" src="/Images/Blank.png" style="background: url(/Images/Icons.png) -465px 0; display: block; width: 20px;height: 20px; text-indent: -9999px; margin-left:auto; margin-right:auto;">
</div>
<div style="display:block; vertical-align:middle; position:relative; margin-left:auto; margin-right:auto;">
<span style="font-size:10pt; display:block; font-weight:bold; text-align:center;">3 Trades</span>
</div>
</div>
<div style="display:inline-block; vertical-align:middle;">
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<span style="font-size:16pt; display:block; font-weight:bold; text-align:right;">
User2
</span>
<span style="font-size:8pt; display:block; text-align:right;">
<br>0 Trades (100%)
</span>
</div>
<div style="display:inline-block; vertical-align:middle; position:relative; ">
<img style="height:50px; width:50px; vertical-align:middle;" alt="User2" src="http://localhost:50254/Images/Avatars/09.png">
</div>
</div>
</div>
</div>
<!--Other records-->
</div>
In case it isn't clear at first sight the Hyperlink (with class="blocklink" on the 3rd row of the good HTML) is not rendered as a single tag around the div, but is rendered several times within the code either with nothing in between or around a <span> tag, breaking what should be in that tag.
The blocklink style class is something I found looking for a way to add a link around a div:
.blockLink
{
position:absolute;
top:0;
left: 0;
width:100%;
height:100%;
z-index: 1;
background-color:#ffffff;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
opacity:0;
}
Has anyone come across such an issue? I'm really in the dark on why the rendered HTML looks different.
All is done on the build-in IIS Express directly from within VS 2012.4. I can't try it on an external server, since the app is still being developed and no server has been assigned yet.
That's because your html contains nested <a> elements, which is not standards compliant HTML. From the W3C spec for <a>:
The a element may be wrapped around entire paragraphs, lists, tables,
and so forth, even entire sections, so long as there is no interactive
content within (e.g. buttons or other links).
You also have related discussions on SO, like in this question. The way the browsers render this scenario is discussed here which explains why you see a different rendered html.
I have created this fiddle with a simplified html code that reproduces this issue:
<a class="blockLink" href="#">
<div class="blockLinkContent">
<h1>Link with inner link</h1>
<a class="innerLink" href="#">inner link</a>
</div>
</a>
The rendered html looks like this on Chrome:
<a class="blockLink" href="#">
</a>
<div class="blockLinkContent"><a class="blockLink" href="#">
<h1>Link with inner link</h1>
</a><a class="innerLink" href="#">inner link</a>
</div>
In order to fix this, you can get rid of one of the links. Then use Javascript\CSS to handle the click event and add any styling you might need like active/hover states or text underline.
For example, you could get rid of the inner link, replacing it with a span and use Javascript to handle clicking on the new inner span:
<a class="blockLink" href="#">
<div class="blockLinkContent">
<h1>Outer link only</h1>
<span class="innerLink">inner link</span>
</div>
</a>
$(function(){
$(".innerLink").click(function(){ alert("inner clicked"); return false; });
});
You can play around with this code in this other fiddler.
Hope this helps!

Is it possible to have buttons take the appearance of links in a jQuery Mobile Listview?

I'm trying to create a Listview that contains a mix of buttons and links. Is there any additions/adjustments I can make to the markup to have buttons appear the same as links? At this stage, I'm trying to do as much as I can in markup and not custom CSS (or JS!)
The markup I'm using is:
<ul data-role="listview" data-inset="true">
<li>Edit</li>
<li>
<form action="#">
<button type="submit">Publish</button>
</form>
</li>
<li>
<form action="#">
<button type="submit">Delete</button>
</form>
</li>
</ul>
What I'd like is this:
(source: reb4.me)
I only seem able to get this:
(source: reb4.me)
Here is a way to do it.
jQM 1.4
To get the arrow icons on the right, add the classes ui-btn ui-btn-icon-right ui-icon-carat-r to the buttons:
<ul data-role="listview" data-inset="true">
<li>Edit
</li>
<li>
<form action="#">
<button type="submit" class="ui-btn ui-btn-icon-right ui-icon-carat-r">Publish</button>
</form>
</li>
<li>
<form action="#">
<button type="submit" class="ui-btn ui-btn-icon-right ui-icon-carat-r">Delete</button>
</form>
</li>
</ul>
Then to remove the extra padding, borders, shadows etc. add this CSS:
.ui-li-static {
padding: 0 !important;
}
.ui-li-static form button {
margin: 0;
box-shadow: none !important;
border: 0;
text-align: left;
}
Here is a DEMO
jQM 1.3
If you are stuck with jQM 1.3 it is a little more complicated:
<ul data-role="listview" data-inset="true">
<li>Edit
</li>
<li>
<form action="#">
<button type="submit" class="ui-btn ui-btn-icon-right ui-icon-carat-r">Publish</button>
</form>
<span class="ui-icon ui-icon-arrow-r ui-icon-shadow fakeLinkIcon"> </span>
</li>
<li>
<form action="#">
<button type="submit" class="ui-btn ui-btn-icon-right ui-icon-carat-r">Delete</button>
</form>
<span class="ui-icon ui-icon-arrow-r ui-icon-shadow fakeLinkIcon"> </span>
</li>
</ul>
.ui-li-static {
padding: 0 !important;
}
.fakeLinkIcon {
position: absolute;
right: 10px;
top: 50%;
margin-top: -9px;
}
.ui-li-static form div.ui-submit{
padding-right: 2.5em;
}
.ui-li-static form div.ui-submit {
margin: 0;
box-shadow: none !important;
border: 0;
text-align: left;
border-radius: 0;
}
.ui-li-static form div.ui-submit .ui-btn-inner{
padding-left: 15px;
}
.ui-last-child form div.ui-submit {
border-bottom-right-radius: 16px;
border-bottom-left-radius: 16px;
}
.ui-first-child form div.ui-submit {
border-top-right-radius: 16px;
border-top-left-radius: 16px;
}
DEMO

Resources