Reputation: 37
I would like to sort each "panel" into one div each depending on what class my element has, any help would be greatly appreciated.
I've gotten to the point of where I'm dynamically setting the class tag for each panel, but I can't figure out how to group them into one div per dynamic class that I set based off my json array element "PressNo".
//this is where I set the panel data
function Panel(opts) {
return ['<div class="', opts.classcontrol, '">',
'<div class="panel">',
' <div class="panel-heading">',
' <h4>',
' <span class="status"><b class="fa fa-', opts.icon, '"></b></span>',
' <span class="name">', Utils.escapeHtml(opts.title), '</span>',
' </h4>',
' </div>',
' <div class="panel-body">',
(opts.trustedBody || Utils.escapeHtml(opts.body)),
' </div>',
'</div></div>'].join('');
}
// get json data for panel
function ConfigurationController(element) {
if ( !element ) { throw new Error('Cannot create ConfigurationController: Element Required');}
var self = this,
_limit = 2,
apiUrl = "http://localhost:58938/api/ShopViewDisplay/PLTO/PLTO/10";
// Expose Public method(s)
this.load = load;
//this.render = render;
function load() {
reset()
$.ajax({
url : apiUrl,
type : 'GET',
dataType:'json',
success : function(data) {
data.map(renderItem, function(el) {
element.append(el);
});
},
error : function(request,error)
{
alert("Request: "+JSON.stringify(request));
}
});
}
// this renders each item
function renderItem(obj, index, list) {
var callback = typeof this === 'function' ? this : false;
// This could use document create fragment, possible speed boost
// 20% of the time, pick random status icon, in all other cases pick the 'good' check icon.
function renderItem(obj) {
var callback = typeof this === 'function' ? this : false;
var statusIcon = "fire";
var itemPanel = Panel({
icon: statusIcon,
title: obj.WorkOrderNumber,
classcontrol: obj.PressNo,
trustedBody: [
' <div class="PressNo"><b></b> Machine: <br>', Utils.escapeHtml(obj.PressNo), '</br></div>',
' <br> ',
' <div class="Priority"><b></b> Priority: <br>', Utils.escapeHtml(obj.Priority),
'</br></div>',
' <br> ',
' <div class="PartNo"><b></b> Part: <br>', Utils.escapeHtml(obj.Part), '</br></div>',
' <br> ',
' <div class="Material"><b></b> Material: <br>', Utils.escapeHtml(obj.PartDesc), '</br></div>',
' <br> ',
' <div class="Setup"><b></b> Setup(E/A): <br>',
Utils.escapeHtml(obj.EstActSetupHrs).replace('\r\n', ' / '), '</br></div>',
' <br> ',
' <div class="Run"><b></b> Run (E/A): <br>',
Utils.escapeHtml(obj.EstActRunHrs).replace('\r\n', ' / '), '</br></div>',
' <br> ',
' <div class="Qty"><b></b> Qty: <br>',
Utils.escapeHtml(obj.CalEndCompleteQty).replace('\r\n', ' / '), ' </br></div>'
].join('\n')
});
itemPanel = $(itemPanel);
myFunction();
return (typeof(callback) === 'function' ? callback(itemPanel) : itemPanel);}
<body>
<div id="configurationList">
<h2>
<b class="fa fa-refresh fa-spin"></b>
<i>Loading, please wait...</i>
</h2>
</div>
</body>
Example of what I would like to see happen:
<div class="5-1">
panel 1 - class="panel" - I have PressNo 5-1
panel 6 - class="panel" - I have PressNo 5-1
</div>
<div class="7">
panel 2 - class="panel" - I have PressNo 7
panel 8 - class="panel" - I have PressNo 7
</div>
<div class="9-3">
panel 9 - class="panel" - I have PressNo 9-3
panel 10 - class="panel" - I have PressNo 9-3
</div>
This is what it looks like now
This is what I would like it to look like
I get the following in my browser console -
TypeError: theDiv[0] is undefined
When I console log I get the following output (it looks like my data hasn't been loaded yet).
console.log(id, document.getElementsByClassName(id));
1 HTMLCollection { length: 0 } index:116:25
@{
Layout = "";
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="http://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet" type="text/css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
'use strict';
var Utils = {
escapeHtml: function _escapeHtml(s) { // Prevent code injection and rendering issues
return String(s).replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<');
}
};
function Panel(opts) {
/*return ['<div class="', opts.classcontrol, '">',
'<div class="panel">',
' <div class="panel-heading">',
' <h4>',
' <span class="status"><b class="fa fa-', opts.icon, '"></b></span>',
' <span class="name">', Utils.escapeHtml(opts.title), '</span>',
' </h4>',
' </div>',
' <div class="panel-body">',
(opts.trustedBody || Utils.escapeHtml(opts.body)),
' </div>',
'</div></div>'].join('');
*/
return ['<div class="', opts.classcontrol, '">',
'<div class="panel">',
' <div class="panel-heading">',
' <h4>',
' <span class="status"><b class="fa fa-', opts.icon, '"></b></span>',
' <span class="name">', Utils.escapeHtml(opts.title), '</span>',
' </h4>',
' </div>',
' <div class="panel-body">',
(opts.trustedBody || Utils.escapeHtml(opts.body)),
' </div>',
'</div></div>'].join('');
}
function ConfigurationController(element) {
if (!element) {
throw new Error('Cannot create ConfigurationController: Element Required');
}
var self = this,
apiUrl = "http://pdapi.pennunited.com/api/ShopViewDisplay/" + "@ViewBag.pathProc";
console.log(apiUrl);
// Expose Public method(s)
this.load = load;
//this.render = render;
function load() {
// Attempt ajax call; on fail: use dummy data
reset();
$.ajax({
url: apiUrl,
type: 'GET',
dataType: 'json',
success: function(data) {
data.map(renderItem,
function(el) {
element.append(el);
});
},
error: function(request, error) {
alert("Request: " + JSON.stringify(request) + " Error: " + error);
}
});
}
function reset() {
element.children().remove();
return element;
}
function renderItem(obj) {
var callback = typeof this === 'function' ? this : false;
var statusIcon = "fire";
var itemPanel = Panel({
icon: statusIcon,
title: obj.WorkOrderNumber,
classcontrol: obj.PressNo,
trustedBody: [
' <div class="PressNo"><b></b> Machine: <br>', Utils.escapeHtml(obj.PressNo), '</br></div>',
' <br> ',
' <div class="Priority"><b></b> Priority: <br>', Utils.escapeHtml(obj.Priority),
'</br></div>',
' <br> ',
' <div class="PartNo"><b></b> Part: <br>', Utils.escapeHtml(obj.Part), '</br></div>',
' <br> ',
' <div class="Material"><b></b> Material: <br>', Utils.escapeHtml(obj.PartDesc), '</br></div>',
' <br> ',
' <div class="Setup"><b></b> Setup(E/A): <br>',
Utils.escapeHtml(obj.EstActSetupHrs).replace('\r\n', ' / '), '</br></div>',
' <br> ',
' <div class="Run"><b></b> Run (E/A): <br>',
Utils.escapeHtml(obj.EstActRunHrs).replace('\r\n', ' / '), '</br></div>',
' <br> ',
' <div class="Qty"><b></b> Qty: <br>',
Utils.escapeHtml(obj.CalEndCompleteQty).replace('\r\n', ' / '), ' </br></div>'
].join('\n')
});
itemPanel = $(itemPanel);
var id = Utils.escapeHtml(obj.PressNo);
console.log(id, document.getElementsByClassName(id));
var theDiv=document.getElementsByClassName(id);
theDiv[0].appendChild(itemPanel);
//myFunction();
return (typeof (callback) === 'function' ? callback(itemPanel) : itemPanel);
}
}
function scroll(speed) {
$('html, body').animate({ scrollTop: $(document).height() - $(window).height() }, speed, function() {
$(this).animate({ scrollTop: 0 }, speed);
});
}
$(document).ready(function _onLoad() {
var ctrl = new ConfigurationController($('#configurationList'));
ctrl.load();
//ctrl.load();
//var speed = 15000;
//scroll(speed)
//setInterval(function () { scroll(speed) }, speed * 8);
//setInterval(ctrl.load(), 900000);
});
</script>
<style>
body {
background-color: black;
font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin: 0px;
padding: 82px 0px 0px 0px;
/* for fixed heading */
/*padding-top: 67px;*/
}
h1 { margin: 4px 2px; }
h4 { margin: 2px 2px; }
.page-header-fixed {
left: 0;
position: fixed;
right: 0;
top: 0px;
}
/* Define a bootstrap-ish minimal style
---- 425363 */
.text-success { color: #94c0e9; }
.text-info { color: #0071ce; }
.text-warning { color: #ff8300; }
.PressNo { color: green; }
.Priority { color: red; }
.page-header {
background: #425363;
box-shadow: rgba(0, 0, 0, 0.90) 5px 1px 4px 0px;
color: #FFF;
margin-bottom: 10px;
padding: 6px 10px;
/*line-height: 48px;*/
transition: all 0.2s;
}
.panel {
background-color: #FFF;
border: 1px solid #DEDEDE;
border-radius: 2px 2px 2px 2px;
border-top: none;
box-sizing: border-box;
color: #666666;
font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 15px;
line-height: 20px;
margin: 8px 2px;
transition: all 0.25s ease-in;
}
.panel-heading {
background-color: #0071ce;
border-color: #2196F3;
box-sizing: border-box;
color: #fff;
cursor: pointer;
display: block;
font-family: Roboto, 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 18px;
font-weight: 400;
line-height: 19px;
padding: 10px 15px 10px 15px;
transition: background-color 0.25s ease-in, color 0.25s ease-in;
}
.panel-body {
padding: 15px;
transition: background-color 0.25s ease-in, color 0.25s ease-in;
}
/*.btn {
border: none;
font-family: inherit;
cursor: pointer;
padding: 25px 80px;
display: inline-block;
margin: 15px 30px;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: 700;
outline: none;
position: relative;
}*/
.status .fa {
font-size: 22px;
margin: 6px;
}
.panel-footer {
text-align: right;
width: 100%;
}
.panel-footer .fa {
cursor: pointer;
font-size: 18px;
margin: 8px;
}
.panel .fa { opacity: 1; }
.panel:hover .panel-heading { background-color: #ff8300; }
.panel:hover { box-shadow: 2px 2px 3px 3px rgba(102, 102, 102, 0.8); }
.panel:hover .fa {
color: #ff8300;
text-shadow: 2px 2px 0px #FFFFFF;
transition: all 0.2s ease, font-size 0.2s ease-in;
}
.panel:hover .panel-heading .fa { color: #333333; }
.panel-heading .fa-exclamation-circle { color: yellow; }
.panel-heading .fa-check { color: #FFF; }
.panel-heading .fa-fire {
color: #ff8300;
font-size: 26px;
}
.panel-body b.fa {
font-size: 20px;
text-align: center;
width: 30px;
}
#configurationList {
-webkit-flex-flow: row wrap;
display: flex;
flex-flow: row wrap;
justify-content: space-around;
width: 99%;
}
#configurationList .panel {
display: inline-block;
min-height: 100px;
width: 250px;
}
</style>
</head>
<body>
<div id="configurationList">
<h2>
<b class="fa fa-refresh fa-spin"></b>
<i>Loading, please wait...</i>
</h2>
</div>
</body>
</html>
Upvotes: 3
Views: 601
Reputation: 12891
At the moment you're generating each container DIV - e.g. class="5.1" with each panel.
function Panel(opts) {
return ['<div class="', opts.classcontrol, '">',
'<div class="panel">',
' <div class="panel-heading">',
' <h4>',
' <span class="status"><b class="fa fa-', opts.icon, '"></b></span>',
' <span class="name">', Utils.escapeHtml(opts.title), '</span>',
' </h4>',
' </div>',
' <div class="panel-body">',
(opts.trustedBody || Utils.escapeHtml(opts.body)),
' </div>',
'</div></div>'].join('');
}
I assume '<div class="', opts.classcontrol, '">'
is the target div.
Anyway, this means you're generating a new container div each time you generate a new panel. You should make sure that there isn't a div that uses that specific class before you create a new one.
function Panel(opts) {
var theDiv = document.getElementsByClassName(opts.classcontrol);
var theArray = ['<div class="panel">',
' <div class="panel-heading">',
' <h4>',
' <span class="status"><b class="fa fa-', opts.icon, '"></b></span>',
' <span class="name">', Utils.escapeHtml(opts.title), '</span>',
' </h4>',
' </div>',
' <div class="panel-body">',
(opts.trustedBody || Utils.escapeHtml(opts.body)),
' </div>',
'</div></div>'
];
if (theDiv.length == 0) {
theArray.splice(0, 0, '<div class="', opts.classcontrol, '">');
theArray.push("</div>");
}
return theArray.join('');
}
Inside the function renderItem() we need to make this distinction once more.
Right after
itemPanel = $(itemPanel);
Insert this
var theDiv = document.getElementsByClassName(obj.PressNo);
if (theDiv.length == 0) {
return (typeof(callback) === 'function' ? callback(itemPanel) : itemPanel);
} else {
theDiv[0].appendChild(itemPanel);
return undefined;
}
and remove
return (typeof(callback) === 'function' ? callback(itemPanel) : itemPanel);
at the end of that function.
This appends the newly created panel to the corresponding parent div - in case it exists. The return undefined
is a workaround
for this code inside your load() function
function(el) {
element.append(el);
});
it would try to append whatever el is to element. Since we might already appended the panel before we need to make sure it won't get appended a second time. So modify the above to
function(el) {
if (el != undefined) {
element.append(el);
}
});
Upvotes: 1