drag & drop using jQuery in a table to create a copy for every drag - html

I'm using jQuery for drag & drop in a table , the requirement is like when I drag image to multiple cells(one by one) I'm dynamically adding a div and to the div s, I'm adding span text like wise I want that to all the cells . I'm trying clone() to the compose so the copy can we created but when I drag span text also it is creating copy of 'div'. please run the snippet and see the issue.
Please Response.
Thanks in advance :)
$(function() {
var compose = $("<div>", {
id: "data-hide",
class: "db-click"
});
$("<p>", {
class: "margin5 strong drop-able"
}).appendTo(compose);
$("<img>", {
src: "xyz.png"
}).appendTo($("p", compose));
$("<p>", {
class: "margin5 strong drop-able"
}).appendTo(compose);
$("<img>", {
src: "abc.png"
}).appendTo($("p:eq(1)", compose));
$("#init").draggable({
opacity: 0.5,
helper: "clone",
});
$(".drag-able").draggable({
opacity: 0.5,
helper: "clone",
});
$("td").droppable({
tolerance: 'pointer',
drop: function(event, ui) {
$(compose).clone().appendTo(this);
$(".drop-able").droppable({
drop: function(event, ui) {
$(this).append(ui.draggable.clone());
}
});
}
});
});
#slot {
border: 1px dashed black;
width: 100px;
height: 40px;
}
#slot1 {
border: 1px dashed black;
width: 100px;
height: 40px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div><img src="xyz.png" id="init" /></div>
<div class="textdata">
<span class="drag-able">hello</span>
<span class="drag-able">morning</span>
</div>
<table>
<tr style="border : 1px dotted rgba(0, 0, 0, 0.15);">
<td id="slot"></td>
<td id="slot1"></td>
</tr>
</table>

I remodified few thing and this will do the thing.
$(function() {
var compose = $("<div>", {
id: "data-hide",
class: "db-click"
});
$("<p>", {
class: "margin5 strong drop-able"
}).appendTo(compose);
$("<img>", {
src: "xyz.png"
}).appendTo($("p", compose));
$("<p>", {
class: "margin5 strong drop-able"
}).appendTo(compose);
$("<img>", {
src: "abc.png"
}).appendTo($("p:eq(1)", compose));
$("#init").draggable({
opacity: 0.5,
helper: "clone",
});
$(".drag-able").draggable({
opacity: 0.5,
helper: "clone",
});
$("td").droppable({
tolerance: 'pointer',
drop: function(event, ui) {
$("td").droppable('enable');
$(compose).clone().appendTo(this);
$(".drop-able").droppable({
drop: function(event, ui) {
$(this).append(ui.draggable.clone());
}
});
if($(this).has('#data-hide').length) {
$(this).droppable('disable');
}
}
});
});
#slot {
border: 1px dashed black;
width: 100px;
height: 40px;
}
#slot1 {
border: 1px dashed black;
width: 100px;
height: 40px;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div><img src="xyz.png" id="init" /></div>
<div class="textdata">
<span class="drag-able">hello</span>
<span class="drag-able">morning</span>
</div>
<table>
<tr style="border : 1px dotted rgba(0, 0, 0, 0.15);">
<td id="slot"></td>
<td id="slot1"></td>
</tr>
</table>

Related

jquery html duplicating on drag and drop

I am using jQuery and using a drag and drop function. My image keeps duplicating and I have no idea why. Any help would be great. I am pretty sure my issue is at line:
$('#' + seat).append('<div class="studentCard" id="' + id + '"><img class="studentImage" src="Images/' + id + '.jpg" style="height:150px; width:150px;" />' + student + '</div>');
Here is my function:
$('.seat').droppable({
drop: function (event, ui) {
var seat = $(this).attr('id');
var id = $(ui.draggable).attr('id');
var student = $(ui.draggable).html();
$.ajax({
success: function () {
if ($('#' + seat + '> div').length > 0) {
alert('Desk already occupied');
}
else {
$(ui.draggable).remove();
$('#' + seat).append('<div class="studentCard" id="' + id + '"><img class="studentImage" src="Images/' + id + '.jpg" style="height:150px; width:150px;" />' + student + '</div>');
$('div#' + id).draggable({
helper: 'clone'
});
}
}
});
}
});
Consider the following example. You might also consider using Sortable instead.
$(function() {
function moveStudent(source, target) {
$(target).append($(".student", source).detach());
}
$(".student").draggable({
helper: "clone",
revert: "invalid",
zIndex: 100
});
$(".seat").droppable({
accept: function() {
if ($(this).children().length == 0) {
return true;
}
return false;
},
drop: function(event, ui) {
moveStudent(ui.draggable.parent(), this);
}
});
});
.seat {
width: 150px;
height: 150px;
float: left;
margin: 10px;
}
.student {
display: inline-block;
width: 140px;
height: 140px;
border: 1px solid #CCC;
position: relative;
background-color: #FFFFFF;
background-repeat: no-repeat;
background-position: center;
background-size: cover;
margin: 5px;
}
.studentName {
position: absolute;
top: 120px;
left: 5px;
font-size: 11pt;
text-shadow: -1px 0 white, 0 1px white, 1px 0 white, 0 -1px white;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="seat-1" class="seat ui-widget-header">
<div id="student-1" class="student" style="background-image: url('https://i.imgur.com/QjxuZB5.png');" data-student-id="1001">
<div class="studentName">Thomas</div>
</div>
</div>
<div id="seat-2" class="seat ui-widget-header">
<div id="student-2" class="student" style="background-image: url('https://imgur.com/Gvmj4y5.png');" data-student-id="1002">
<div class="studentName">Trinity</div>
</div>
</div>
<div id="seat-3" class="seat ui-widget-header">
</div>
<div id="seat-4" class="seat ui-widget-header">
</div>
Instead of creating a new element, you can use .detach() and more easily move the original draggable item to the new drop zone.
It is sometimes better to use accept option to determine if a droppable should accept an item or not. This option does allow the use of a Function:
Function: A function that will be called for each draggable on the page (passed as the first argument to the function). The function must return true if the draggable should be accepted.
See More: https://api.jqueryui.com/droppable/#option-accept
This allows you to re-arrange the items without stacking.

How to drag and drop same element multiple times into another div box in JavaScript or jQuery?

I have two HTML div boxes. Let's say box A and box B. I want to drag and drop box A multiple times into box B. If I drop box A outside of box B then box A will revert back to it's original position. After I dropped the box A (clone) into box B I want to move box A (clone) into any position in box B. For now I did the codes to do that.
Now what I want is after I dropped box A into Box B, then if I drag and drop box A (clone) outside of box B, then box A (clone) need to hide or revert into it's original position (box A parent position).
HTML Codes
<div id="boxB"></div>
<br>
<div class="boxA">BOX A</div>
CSS Codes
#boxB {
width: 200px;
border: 5px solid black;
padding: 50px 50px;
margin: auto;
text-align: center;
background-color: #FFFFFF;
}
.boxA {
width: 40px;
border: 2px solid black;
text-align: center;
background-color: #F5D938;
cursor: pointer;
}
JavaScript + jQuery Codes
$(document).ready(function()
{
var x;
$(".boxA").draggable(
{
helper: "clone",
cursor: "move",
revert: true
});
$("#boxB").droppable(
{
accept: ".boxA",
drop: function(event, ui)
{
x = ui.helper.clone();
ui.helper.remove();
x.appendTo('#boxB');
$(x).draggable();
}
});
});
You can see demo : https://jsfiddle.net/zajjith/3kedjgb0/10/
If I drag and drop box A (clone) outside from box B then that clone box A need to revert back to it's original parent box A position or hide or delete.
I hope you understand what I want. Please check my codes and help me.
Refer to the Example at https://jqueryui.com/droppable/#revert
Using your code, you can do the following.
$(function() {
function getBounds(el) {
var p = $(el).position();
p.right = p.left + $(el).width();
p.bottom = p.top + $(el).height();
return p;
}
function isOver(a, b) {
var ap;
if (typeof a == "object") {
ap = a;
} else {
ap = getBounds(a);
}
var bp = getBounds(b);
return (ap.left > bp.left && ap.right < bp.right) && (ap.top > bp.top && ap.bottom < bp.bottom);
}
$(".boxA").draggable({
helper: "clone",
cursor: "move",
revert: "invalid"
});
$("#boxB").droppable({
accept: ".boxA",
drop: function(event, ui) {
var cl = ui.helper.clone();
cl.appendTo(this).draggable({
appendTo: "body",
stop: function(e, ui) {
if (isOver($.extend({}, ui.position, {
right: ui.position.left + ui.helper.width(),
bottom: ui.position.top + ui.helper.height()
}), $("#boxB")) == false) {
var a = getBounds($("body > .boxA"));
ui.helper.animate({
top: a.top,
left: a.left
}, function() {
ui.helper.remove();
});
} else {
console.log("Drop Inside");
}
}
});
ui.helper.remove();
}
});
});
#boxB {
width: 200px;
border: 5px solid black;
padding: 50px 50px;
margin: auto;
text-align: center;
background-color: #FFFFFF;
}
.boxA {
width: 50px;
border: 2px solid black;
text-align: center;
background-color: #F5D938;
cursor: pointer;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="boxB"></div>
<br />
<div class="boxA">BOX A</div>

Unable to change the dragged item on drop

I am new to jQuery. I have a requirement of drag and drop where i got '3 draggable div' with id 'parent1, parent2 and parent3' to be dropped in a "container div drop-parent".
Scenario:
When i drag the div with id 'parent1' on container div 'drop-parent' it get dropped but when i choose 'parent 2' div to drop it isn't able to replace the div 'parent1' and to come at its inital position. Please refer below JSBin link for same [click here]
$(".child").draggable({
revert: "invalid",
containment: ".drag_drop_container"
});
$('.drop-parent').droppable({
accept: ".drag-parent > .child",
drop: function(event, ui) {
Dropped($(this), ui.draggable.click());
}
});
$('.drag-parent').droppable({
accept: function(draggable) {
if($(this).attr('id').split('parent')[1] == draggable.attr('data-id')) {
return true;
}
},
drop: function(event, ui) {
Reverted($(this), ui.draggable.click());
}
});
function Dropped($this, $item) {
$item.css({'left': '0px', 'top': '0px'});
$this.droppable("disable").css('opacity',0.9);;
if($item.parent().hasClass('drop-parent')) {
$item.parent().droppable("enable");
} else {
$('.text-input').val($item.attr('data-id'));
}
$this.append($item);
$this.sortable();
}
function Reverted($this, $item) {
$item.css({'left': '0px', 'top': '0px'});
$item.parent().droppable("enable");
$this.append($item);
$('.droped_val').val('');
}
.drop-parent {
//border: 1px solid red!important;
/* background-color: red; */
//width: 640px; /*can be in percentage also.*/
height: 42px;
width: 100px;
//margin: 0 auto;
left:-4px;
//padding: 10px;
top:184px;
position: relative;
}
.dragbody {
//border: 1px solid blue!important;
/* background-color: red; */
//width: 281px;
//position: relative;
//height: 53px;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://emea.focusvision.com/survey/selfserve/2140/190505/drag1.js"></script>
<script src="https://emea.focusvision.com/survey/selfserve/2140/190505/drag2.js"></script>
</head>
<body>
<div class="drag_drop_container">
<div class="cards">
<table align="center" class="Table1">
<tr>
<td>
<div class="drag-parent" id="parent1">
<div class="child" data-id=1><img src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/happy.png"/></div>
</div>
</td>
<td>
<div class="drag-parent" id="parent2">
<div class="child" data-id=2><img src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/neutral.png"/></div>
</div>
</td>
<td>
<div class="drag-parent" id="parent3">
<div class="child" data-id=3><img src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/sad.png"/></div>
</div>
</td>
</tr>
</table>
</div>
<div align="center" class="dragbody">
<div align="center" class="drop-parent">
</div>
<img src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/body.png" width="250px"/>
</div>
</div>
</body>
</html>
I've edited the Dropped() function so that it moves all old elements that where on the body back to their parent and then adds the new one.
$(".child").draggable({
revert: "invalid",
containment: ".drag_drop_container"
});
$('.drop-parent').droppable({
accept: ".drag-parent > .child",
drop: function(event, ui) {
Dropped($(this), ui.draggable.click());
}
});
$('.drag-parent').droppable({
accept: function(draggable) {
if ($(this).attr('id').split('parent')[1] == draggable.attr('data-id')) {
return true;
}
},
drop: function(event, ui) {
Reverted($(this), ui.draggable.click());
}
});
function Dropped($this, $item) {
$item.css({
'left': '0px',
'top': '0px'
});
if ($item.parent().hasClass('drop-parent')) {
$item.parent().droppable("enable");
} else {
$('.text-input').val($item.attr('data-id'));
}
for (i = 0; i < $this.children().length; i++) {
$oldElement = $($this.children()[i]);
$("#parent" + $oldElement.data("id")).append($oldElement);
}
$this.append($item);
$this.sortable();
}
function Reverted($this, $item) {
$item.css({
'left': '0px',
'top': '0px'
});
$item.parent().droppable("enable");
$this.append($item);
$('.droped_val').val('');
}
.drop-parent {
//border: 1px solid red!important;
/* background-color: red; */
//width: 640px; /*can be in percentage also.*/
height: 42px;
width: 100px;
//margin: 0 auto;
left:-4px;
//padding: 10px;
top:184px;
position: relative;
}
.dragbody {
//border: 1px solid blue!important;
/* background-color: red; */
//width: 281px;
//position: relative;
//height: 53px;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://emea.focusvision.com/survey/selfserve/2140/190505/drag1.js"></script>
<script src="https://emea.focusvision.com/survey/selfserve/2140/190505/drag2.js"></script>
</head>
<body>
<div class="drag_drop_container">
<div class="cards">
<table align="center" class="Table1">
<tr>
<td>
<div class="drag-parent" id="parent1">
<div class="child" data-id=1>
<img data-parent-id="1" src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/happy.png" />
</div>
</div>
</td>
<td>
<div class="drag-parent" id="parent2">
<div class="child" data-id=2>
<img data-parent-id="2" src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/neutral.png" />
</div>
</div>
</td>
<td>
<div class="drag-parent" id="parent3">
<div class="child" data-id=3>
<img data-parent-id="3" src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/sad.png" />
</div>
</div>
</td>
</tr>
</table>
</div>
<div align="center" class="dragbody">
<div align="center" class="drop-parent">
</div>
<img src="https://singapore.decipherinc.com/survey/selfserve/54e/200701/body.png" width="250px" />
</div>
</div>
</body>
</html>

Cannot change div height after adding Layout

I have a razor view web page that has a div that i fill data into it in some way (lazy load, or loop, doesn't matter).
If i dont use a Layout, IE:
#{
Layout = "_Layout";
}
Then the div will use my configured height, and also shows a scrollbar if needed (using overflow: auto)
However, when i add a layout, even an empty one, i cannot seem to modify the div's height, which causes it to take all the screen from the layout to the bottom, and shows no scrolling.
What disabled my ability to change the height?
(the div im loading data into is div id container)
index.cshtml:
#{
Layout = "_Layout";
}
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 5px;
text-align: center;
width: 15%;
}
.Good {
background-color: green
}
.Bad {
background-color: red
}
#container {
background: #eee;
}
</style>
<head>
<script src="/JQuery/jquery-3.3.1.min.js"></script>
</head>
<body style="overflow: hidden;">
<div>
<div>
<h3 id="Progression"></h3>
</div>
<div id="container" style="width: 100%; height: 80%; overflow: auto;">
</div>
<div id="progress" style="display: none; height: 20%">
<h4>Loading...</h4>
</div>
</div>
</body>
_Layout.cshtml:
<!DOCTYPE html>
<style>
.main-header {
background: url(/images/bg-header.png) transparent repeat-x 0 0;
}
</style>
<html>
<head>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<header class="main-header" role="banner">
<div>
<a href="/" title="Home" rel="home">
<img src="/images/COMPANY-logo.png" style="background-color:white;" alt="Home">
</a>
</div>
</header>
<div>
#RenderBody()
</div>
</body>
</html>
Empty _Layout.cshtml: (having issues with this layout as well)
<!DOCTYPE html>
<style>
.main-header {
background: url(/images/bg-header.png) transparent repeat-x 0 0;
}
</style>
<html>
<head>
</head>
<body>
<div>
#RenderBody()
</div>
</body>
</html>
Generated page (The empty layout was used):
<!DOCTYPE html>
<style>
.main-header {
background: url(/images/bg-header.png) transparent repeat-x 0 0;
}
</style>
<html>
<head>
</head>
<body>
<div>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 5px;
text-align: center;
width: 15%;
}
.Good {
background-color: green
}
.Bad {
background-color: red
}
#container {
background: #eee;
}
</style>
<head>
<script src="/JQuery/jquery-3.3.1.min.js"></script>
</head>
<body style="overflow: hidden;">
<div>
<div>
<h3 id="Progression"></h3>
</div>
<div id="container" style="width: 100%; height: 80%; overflow: auto;">
</div>
<div id="progress" style="display: none; height: 20%">
<h4>Loading...</h4>
</div>
</div>
</body>
<script>
var pageSize = 50;
var pageIndex = 0;
var totalItemsDisplayed = 0;
$(document).ready(function() {
lazyLoadCards(0);
$('#container').scroll(function() {
var scrollTop = $(this).scrollTop();
var scrollHeight = $(this).prop('scrollHeight');
var clientHeight = $(this).prop('clientHeight');
if (scrollTop + clientHeight === scrollHeight) {
pageIndex++;
lazyLoadCards(pageIndex);
}
});
function lazyLoadCards(index) {
$.ajax({
type: 'GET',
url: '/AllCards/OnScrollEnd',
data: { "startIndex": index, "size": pageSize },
dataType: 'json',
success: function(data) {
if (data != null) {
totalItemsDisplayed += data.length;
for (var i = 0; i < data.length; i++) {
$("#container").append("<h2>" +
data[i].cardNumber +
"</h2>");
}
updateProgression();
}
},
beforeSend: function() {
$("#progress").show();
},
complete: function() {
$("#progress").hide();
},
error: function() {
alert("Error while retrieving data!");
}
});
}
function loadCards(index) {
$.ajax({
type: 'GET',
url: '/AllCards/OnScrollEnd',
data: { "startIndex": index, "size": pageSize },
dataType: 'json',
success: function(data) {
if (data != null) {
totalItemsDisplayed += data.length;
for (var i = 0; i < data.length; i++) {
$("#container").append("<h2>" +
data[i].cardNumber +
"</h2>");
}
updateProgression();
if (data.length > 0) {
loadCards(index + 1);
}
}
},
beforeSend: function() {
$("#progress").show();
},
complete: function() {
$("#progress").hide();
},
error: function() {
alert("Error while retrieving data!");
}
});
}
function updateProgression() {
$('#Progression').text("Displaying " + totalItemsDisplayed + " Cards out of " + 6930);
}
});
</script>
</div>
</body>
</html>
Visual to see current output and desired outcome:
(Note that thetext inside the gray box is just elements with some text. thats what the ajax call does)
Generated code after adding #section and #style and removing body everyone besides _Layout
<!DOCTYPE html>
<html>
<head>
<style>
.main-header {
background: url(/images/bg-header.png) transparent repeat-x 0 0;
}
</style>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 5px;
text-align: center;
width: 15%;
}
.Good {
background-color: green
}
.Bad {
background-color: red
}
#container {
background: #eee;
}
</style>
</head>
<body>
<header class="main-header" role="banner">
<div>
<a href="/" title="Home" rel="home">
<img src="/images/COMPANY-logo.png" style="background-color:white;" alt="Home">
</a>
</div>
</header>
<div>
<div>
<div>
<h3 id="Progression"></h3>
</div>
<div id="container" style="width: 100%; height: 80%; overflow: visible;">
</div>
<div id="progress" style="display: none; height: 20%">
<h4>Loading...</h4>
</div>
</div>
</div>
<script src="/JQuery/jquery-3.3.1.min.js"></script>
<script>
var pageSize = 50;
var pageIndex = 0;
var totalItemsDisplayed = 0;
$(document).ready(function() {
lazyLoadCards(0);
$('#container').scroll(function() {
var scrollTop = $(this).scrollTop();
var scrollHeight = $(this).prop('scrollHeight');
var clientHeight = $(this).prop('clientHeight');
if (scrollTop + clientHeight === scrollHeight) {
pageIndex++;
lazyLoadCards(pageIndex);
}
});
function lazyLoadCards(index) {
$.ajax({
type: 'GET',
url: '/AllCards/OnScrollEnd',
data: { "startIndex": index, "size": pageSize },
dataType: 'json',
success: function(data) {
if (data != null) {
totalItemsDisplayed += data.length;
for (var i = 0; i < data.length; i++) {
$("#container").append("<h2>" +
data[i].cardNumber +
"</h2>");
}
updateProgression();
}
},
beforeSend: function() {
$("#progress").show();
},
complete: function() {
$("#progress").hide();
},
error: function() {
alert("Error while retrieving data!");
}
});
}
function loadCards(index) {
$.ajax({
type: 'GET',
url: '/AllCards/OnScrollEnd',
data: { "startIndex": index, "size": pageSize },
dataType: 'json',
success: function(data) {
if (data != null) {
totalItemsDisplayed += data.length;
for (var i = 0; i < data.length; i++) {
$("#container").append("<h2>" +
data[i].cardNumber +
"</h2>");
}
updateProgression();
if (data.length > 0) {
loadCards(index + 1);
}
}
},
beforeSend: function() {
$("#progress").show();
},
complete: function() {
$("#progress").hide();
},
error: function() {
alert("Error while retrieving data!");
}
});
}
function updateProgression() {
$('#Progression').text("Displaying " + totalItemsDisplayed + " Cards out of " + 6930);
}
});
</script>
</body>
</html>
You should be using sections. Sections allow you to add styles, scripts, etc. on the layout. You can't have the head and body tags anywhere except the layout page.
Empty _Layout.cshtml:
<!DOCTYPE html>
<head>
<style>
.main-header {
background: url(/images/bg-header.png) transparent repeat-x 0 0;
}
</style>
#RenderSection("Styles", required: false)
</head>
<body>
<div>
#RenderBody()
</div>
#RenderSection("Scripts", required: false)
</body>
</html>
Index.cshtml:
#{
Layout = "_Layout";
}
#section Styles {
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
width: 100%;
}
th, td {
padding: 5px;
text-align: center;
width: 15%;
}
.Good {
background-color: green
}
.Bad {
background-color: red
}
#container {
background: #eee;
}
</style>
}
<div>
<div>
<h3 id="Progression"></h3>
</div>
<div id="container" style="width: 100%; height: 80%; overflow: auto;">
</div>
<div id="progress" style="display: none; height: 20%">
<h4>Loading...</h4>
</div>
</div>
#section Scripts {
<script src="/JQuery/jquery-3.3.1.min.js"></script>
}
UPDATE
You need to make the following change:
<div id="container" style="width: 100%;height: 155px;overflow: scroll;display: block;">
You can't use a percentage for height unless you add position:absolute;. If you only want the vertical scroll bar, you'll need to use overflow-y:scroll; instead.

Polymer.lazyRegister destroy style while upgrading from, v1.2.3 to v1.4.0

i'm developping an application with Polymer.
My old version was v1.2.3.
I try since this morning to optimize my application about import using the importHref function to load some files on the fly.
I've found that there is a bug (https://github.com/Polymer/polymer/issues/3638) so I tried to update to the last version to have the bugfix (v1.7.0). After upgrading, i seems that some problems occurs with styling.
After some search, i've found that the problem is here when I update from v1.2.3 to v1.4.0 and using
window.Polymer.lazyRegister = true;
It adds some scrollbars (don't find why or where or how), shift some styles, .... and absolutely don't know why.
Does anyone have any idea?
thanks a lot
Edit : add before / after screenshot
edit : add code
index.html
<title>my app</title>
<script src="bower_components/lodash/lodash.js"></script>
<script src="lib/md5/md5.js"></script>
<script src="bower_components/page/page.js"></script>
<link rel="import" href="utils/behaviors/i18n/i18n.html">
<script>
// Setup Polymer options
window.Polymer = {
dom: 'shady',
lazyRegister: true
};
(function() {
'use strict';
var onload = function() {
if (!window.HTMLImports) {
document.dispatchEvent(
new CustomEvent('WebComponentsReady', {bubbles: true})
);
}
};
var webComponentsSupported = (
'registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template')
);
if (!webComponentsSupported) {
var script = document.createElement('script');
script.async = true;
script.src = '/bower_components/webcomponentsjs/webcomponents-lite.min.js';
script.onload = onload;
document.head.appendChild(script);
} else {
onload();
}
})();
</script>
<link rel="import" href="bower_components/polymer/polymer.html">
<!-- not paste, but here are the polymer elements papaer-*, iron-*, ... -->
<!-- elements.html is just an external file with all my own elements -->
<link rel="import" href="elements/elements.html">
<link href="res/css/app.css" rel="stylesheet"/>
<style>
body {
margin: 0;
height: 100vh;
}
</style>
</head>
<body class="layout vertical">
<template is="dom-bind" id="myApp">
<my-application id="application"></my-application>
</template>
</body>
</html>
my-application.html
<dom-module id="my-application">
<style>
:host {
height : 100%;
}
iron-pages {
height : 100%;
}
#popin {
position: absolute;
display: none;
z-index: 100;
}
#mainCtn {
height: 100%;
width: 100%;
}
my-loader-synchronizer {
z-index: 100;
height: 100%;
width: 100%;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<template>
<div id="mainCtn" on-click="_onMainCtnClick">
<iron-pages attr-for-selected="data-route" selected="{{route}}">
<my-login id="log" data-route="login"></my-login>
<paper-header-panel data-route="dashboard">
<my-header class="paper-header"></my-header>
<my-dashboard id="dashboard" class="fit"></my-dashboard>
</paper-header-panel>
</iron-pages>
<my-dialog id="dialog"></my-dialog>
<my-loader-synchronizer id="loaderSynchronizer" hidden$="{{!synchro}}"></my-loader-synchronizer>
<div id="popin"></div>
<my-dialog-selector id="dialogSelector"></my-dialog-selector>
</div>
<my-toast id="toast"></my-toast>
</template>
<link rel="import" href="../../utils/behaviors/storage/ramCache.html">
<link rel="import" href="../../utils/behaviors/session/session.html">
<link rel="import" href="../../utils/behaviors/communication/applicationCommunication.html">
<script>
Polymer({
is: 'my-application',
properties: {
"synchro" : {
"type" : Boolean,
"value" : false
},
"amIConnected" : {
"type" : Boolean,
"value" : false
},
animationConfig : {
type : Object,
value : function () {
return {
"fadeOut" : [{
name : 'fade-out-animation',
node : this.$$("#loaderSynchronizer")
}],
}
}
}
},
behaviors : [applicationCommunication, Polymer.NeonAnimationRunnerBehavior],
listeners : {
"neon-animation-finish": "fadeComplete"
},
ready: function ready() {
// all listeners are registered here
this.addEventListener("mousemove", this._onGlobalMouseMove.bind(this));
this._disconnectTimeout = setTimeout(this._disconnect.bind(this), 3600000);
},
_onGlobalMouseMove : function _onGlobalMouseMove (e) {
if (this.amIConnected == true) {
if (e.movementX != 0 || e.movementY != 0) {
clearTimeout(this._disconnectTimeout);
this._disconnectTimeout = setTimeout(this._disconnect.bind(this), 3600000);
}
}
},
_disconnect : function _disconnect () {
clearTimeout(this._disconnectTimeout);
session.getInstance().disconnect();
},
attached : function () {
page("/", function () {
this.route = "login";
}.bind(this));
page("/dashboard", function () {
this.amIConnected = true;
this.synchro = true;
this.$$("#loaderSynchronizer").synchronizeData();
this.$.dashboard.onShow();
this.route = "dashboard";
}.bind(this));
page({
hashbang: true
});
},
fadeComplete : function fadeComplete () {
this.synchro = false;
},
_closeLoaderSynchronizer : function _closeLoaderSynchronizer () {
this.cancelAnimation();
this.playAnimation("fadeOut");
},
});
</script>
</dom-module>
my-login.html
<dom-module id="my-login">
<style>
:host {
font-family : "Roboto-Bold";
font-size: 16pt;
--paper-input-container-underline: {
background-color: var(--paper-grey-400);
}
--paper-input-container-label: {
color: var(--paper-grey-400);
}
--paper-input-container-input: {
color: var(--paper-black);
}
--paper-input-container-focus-color: var(--paper-blue-600);
}
#container {
height: 100%;
width: 100%;
background-image: url("../../res/img/loginBack.jpg");
background-size: cover;
background-color: white;
}
#logomyCtn {
z-index: 100;
position: absolute;
margin-left: 80px;
margin-top: 150px;
}
#logomyCtn iron-image {
--iron-image-width: 16vw;
--iron-image-height: 10vw;
}
paper-card {
--paper-card-header: {
#apply(--layout-horizontal);
#apply(--layout-end);
background-color: var(--paper-blue-600);
height: 100px;
}
--paper-card-content: {
margin-right: 50px;
margin-left: 50px;
}
--paper-card-actions: {
#apply(--layout-vertical);
#apply(--layout-center);
}
--paper-card-header-text: {
color: #fff;
position: absolute;
font-family: "Roboto-Light";
bottom: 0px;
left: 0px;
}
--paper-card-header-image: {
width: 146px;
height: 32px;
margin-left: auto;
margin-right: auto;
margin-bottom: 16px;
}
}
paper-button.blue {
font-size: 12pt;
background: var(--paper-blue-600);
color: #fff;
font-family: "Roboto-Medium";
margin-top: 10px;
width: 14vw;
}
paper-button.small {
font-size: 13px;
text-transform: lowercase;
--paper-button-ink-color: transparent;
font-family: "Roboto-Light";
color: var(--paper-grey-700);
}
paper-button.pwd {
font-size: 13px;
text-transform: lowercase;
--paper-button-ink-color: transparent;
font-family: "Roboto-Light";
color: var(--paper-grey-700);
}
#logoContainer {
width: 100%;
height: 20%;
#apply(--layout-horizontal);
#apply(--layout-center);
}
iron-image {
margin-left: auto;
margin-right: auto;
}
#loginContainer {
width: 400px;
height: 60%;
margin-left: auto;
margin-right: auto;
#apply(--layout-vertical);
#apply(--layout-center-justified);
}
#versionContainer {
width: 100%;
height: 20%;
#apply(--layout-horizontal);
#apply(--layout-end);
}
#version {
margin-left: auto;
margin-right: auto;
margin-bottom: 25px;
font-family: "Roboto-Light";
font-size: 13px;
color: var(--paper-grey-700);
}
</style>
<template>
<div id="container">
<div id="logomyCtn">
<iron-image src="../../res/img/logo.png"></iron-image>
</div>
<div id="logoContainer"></div>
<div id="loginContainer">
<paper-card elevation="1" image="../../res/img/logologin.png">
<div class="card-content" on-keypress="_keyHandler">
<paper-input id="login" label="[[i18n('uid')]]"></paper-input>
<paper-input id="pwd" label="[[i18n('pwd')]]" type="password"></paper-input>
<paper-input id="server" label="[[i18n('server')]]"></paper-input>
</div>
<div class="card-actions">
<paper-button class="blue" on-click="_login">[[i18n("connect")]]</paper-button>
<paper-button class="pwd" on-click="_openPwd">[[i18n("forgotPwd")]]</paper-button>
</div>
</paper-card>
</div>
<div id="versionContainer">
<div id="version">
[[i18n("version")]]
<paper-button class="small" on-click="_openContact">[[i18n("contact")]]</paper-button>
</div>
</div>
<my-dialog id="dialog"></my-dialog>
</div>
</template>
<link rel="import" href="../../utils/behaviors/communication/loginCommunication.html">
<link rel="import" href="../../utils/behaviors/storage/localCache.html">
<link rel="import" href="../../utils/behaviors/storage/sessionCache.html">
<script>
Polymer({
is: 'my-login',
// don't paste code, only classical login code
});
</script>
</dom-module>
my-loader-synchronizer.html
<dom-module id="my-loader-synchronizer">
<style>
:host {
display: block;
background-image: url("../../res/img/loginBack.jpg");
background-size: cover;
}
#mainCtn {
height: 100%;
width: 100%;
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#loading {
margin-top: 16px;
font-size: 20px;
font-family: "Roboto";
color: var(--paper-grey-700);
}
paper-progress {
width: 50%;
--paper-progress-active-color: var(--paper-blue-500);
}
#logoCtn {
z-index: 100;
position: absolute;
margin-left: 80px;
margin-top: 150px;
}
#logoCtn iron-image {
--iron-image-width: 16vw;
--iron-image-height: 10vw;
}
</style>
<template>
<div id="mainCtn">
<paper-progress class="transiting" value="{{currentResponse}}" max="{{totalData}}"></paper-progress>
<div id="loading">[[i18n("loading")]]</div>
</div>
<div id="logoCtn">
<iron-image src="../../res/img/logo.png"></iron-image>
</div>
</template>
<link rel="import" href="../../utils/behaviors/storage/ramCache.html">
<link rel="import" href="../../utils/behaviors/storage/sessionCache.html">
<link rel="import" href="../../utils/behaviors/entities/entitiesParser.html">
<link rel="import" href="../../utils/behaviors/communication/loaderSynchronizerCommunication.html">
<script>
Polymer({
is: 'my-loader-synchronizer',
created : function () {
this.i18n = i18n.getInstance();
},
properties: {
"data" : {
"type" : Array,
"value" : function () {
return [{
"entity" : "UserEntity",
"okCb" : this.usersCallback.bind(this),
"koCb" : this.usersCallbackError.bind(this)
},{
"entity" : "VehicleGroup",
"okCb" : this.vehicleGroupCallback.bind(this),
"koCb" : this.vehicleGroupCallbackError.bind(this)
},{
// multiple definitions
}]
}
}
},
behaviors : [loaderSynchronizerCommunication, entitiesParser],
ready: function ready() {
this.ramCache = ramCache.getInstance();
this.sessionCache = sessionCache.getInstance();
},
synchronizeData : function synchronizeData () {
this.totalData = this.data.length;
this.currentResponse = 0;
var i = this.data.length,
params = {
"token" : this.sessionCache.get("token")
};
while (i--) {
if (this.data[i].entity) {
var entity = this.data[i];
if (!entity.type || entity.type == "entity") {
this.prepareEntityRequest(entity.entity, params, entity.okCb, entity.koCb);
} else if (entity.type == "light") {
this.prepareLightRequest(entity.entity, params, entity.okCb, entity.koCb);
}
}
}
},
_updateRoutine : function _updateRoutine () {
var i = this.routine.length,
params = {
"token" : this.sessionCache.get("token")
};
while (i--) {
if (this.routine[i].entity) {
var entity = this.routine[i];
this.prepareEntityRequest(entity.entity, params, entity.okCb, entity.koCb);
}
}
},
_changeProgress : function _changeProgress (entity) {
this.currentResponse++;
if (this.currentResponse == this.totalData) {
this.timeoutCtrl = setTimeout(this._fireClose.bind(this), 1000);
}
},
_fireClose : function _fireClose () {
clearTimeout(this.timeoutCtrl);
// will be catch by my-application
this.fire("close-loader-synchronizer");
},
/* CALLBACK */
/*********/
/* USERS */
/*********/
usersCallback : function usersCallback (response) {
this.parseUsers(response);
this._changeProgress("UserEntity");
},
usersCallbackError : function usersCallbackError (error) {
this.fire("show-toast", {"type" : "error", "text" : "userEntityError"});
},
/*****************/
/* VEHICLES GROUP*/
/*****************/
vehicleGroupCallback : function vehicleGroupCallback (response) {
this.parseVehicleGroup(response);
this._changeProgress("VehicleGroup");
},
vehicleGroupCallbackError : function vehicleGroupCallbackError (error) {
this.fire("show-toast", {"type" : "error", "text" : "vehicleGroupEntityError"});
},
});
</script>
</dom-module>
my-header.html
<dom-module id="my-header">
<style>
:host {}
paper-toolbar {
--paper-toolbar-background: var(--paper-blue-500);
}
.first {
font-family : "Roboto-Bold";
}
.last {
font-family: "Roboto-Light";
}
</style>
<template>
<paper-toolbar>
<my-menu-button on-tap="_tapToggleButton"></my-menu-button>
<div class="title">[[i18n("product")]] [[i18n("version")]]</div>
</paper-toolbar>
</template>
<script>
Polymer({
is: 'my-header',
created : function () {
this.i18n = i18n.getInstance();
},
properties: {},
ready: function ready() {},
_tapToggleButton : function _tapToggleButton () {
this.fire("toggle-drawer");
},
});
</script>
</dom-module>
my-dashboard.html
<dom-module id="my-dashboard">
<style>
:host {
font-family : "Roboto";
}
</style>
<template>
<paper-drawer-panel id="drawerPanel" responsive-width="1300px">
<my-dashboard-left-panel drawer id="leftpanel"></my-dashboard-left-panel>
<my-dashboard-content main id="content"></my-dashboard-content>
</paper-drawer-panel>
</template>
<link rel="import" href="../../utils/behaviors/communication/childNotifications.html">
<script>
Polymer({
is: 'my-dashboard',
properties: {},
behaviors : [childNotifications, Polymer.IronResizableBehavior],
ready: function ready() {},
/************************/
/*** PUBLIC FUNCTIONS ***/
/************************/
onShow : function onShow () {
this.notifyChild("showDashboard");
},
/**
* toggle left panel
**/
toggleDrawer : function toggleDrawer () {
var responsiveWidth = parseInt(this.$.drawerPanel.responsiveWidth.replace("px", ""));
if (responsiveWidth < this.$.drawerPanel.offsetWidth) {
this.$.drawerPanel.forceNarrow = !this.$.drawerPanel.forceNarrow;
setTimeout(function () {
clearInterval(this.toto)
}.bind(this), 1000);
setInterval(function () {
this.$.content.resize();
// notify children that they need to resize
this.notifyResize();
}.bind(this), 100)
} else {
this.$.drawerPanel.togglePanel();
}
}
});
</script>
</dom-module>
I past only files which seems to be important.
So, how it works?
At first, when display my-login will be display to allow user to log in (routing is made with page.js)
There is no problem on the login screen.
When user is logged, route to /dashboard, and display the paper-header-panel and my-loader-synchronizer to sync all data and display a progress bar. When all is done, the synchronizer will be hide to make the paper-header-panel visible (screenshot are take at this moment)
When the synchronize is shown, the styles problems start.
If you need more files, don't hesitate.
thanks a lot !