CSS doesn't work on HTML element - javascript

I have small piece of code written in JavaScript and CSS.
The problem is that the 'div column' is not affected by the CSS code. The border and background should appear and their color should be red.
What am I missing?
Here is the code:
https://codepen.io/orc2000/pen/VdEXVY
var text = "";
text += '<div class="row">';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 1' + '</h4>';
text += '<img src="SomePicture 1"' + 'width="100" height="100" align = "center" > ';
text += '<p>' + 'Price 20' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 2' + '</h4>';
text += '<img src = "SomePicture 2"' + 'width="100" height="100" align = "center" > ';
text += '<p>' + 'Pret 10' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '</div>';
document.getElementById("delta").innerHTML = text;
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.wrapper-elem {
float: left;
width: 50 %;
background-color: white;
padding: 10px;
border: 2px solid blue;
}
.column {
border: 5px solid red;
background-color: red;
}
/* Clear floats after the columns */
.row: after {
content: "";
display: table;
clear: both;
}
<div id="delta"></div>

You had:
some missing HTML tag parts (2 closing >), when you constructed the HTML using JavaScript
a space in the CSS (width: 50_%)
var text = `
<div class="row">
<div class="wrapper-elem">
<div class="column">
<h4>Column 1</h4>
<img src="SomePicture 1" width="100" height="100" align="center">
<p>Price 20</p>
<p>DryFood</p>
</div>
</div>
<div class="wrapper-elem">
<div class="column">
<h4>Column2</h4>
<img src="SomePicture 2"width="100" height="100" align="center">
<p>Pret 10</p>
<p>DryFood</p>
</div>
</div>
`;
document.getElementById("delta").innerHTML = text;
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.wrapper-elem {
float: left;
width: 50%;
background-color: white;
padding: 10px;
border: 2px solid blue;
}
.column {
border: 5px solid red;
background-color: red;
}
/* Clear floats after the columns */
.row: after {
content: "";
display: table;
clear: both;
}
<html>
<head>
<title>Test Page</title>
<link rel="stylesheet" type="text/css" href="test.css">
</head>
<body>
<div id="delta"> </div>
<script src="test.js"></script>
</body>
</html>

It's better to call your js, after DOM will be ready:)
Small refactoring
"use strict"
function generateText() {
var text = "";
text += '<div class="row">';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 1' + '</h4>';
text += '<img src="SomePicture 1"' + 'width="100" height="100" align="center">';
text += '<p>' + 'Price 20' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 2' + '</h4>';
text += '<img src = "SomePicture 2"' + 'width="100" height="100" align="center">';
text += '<p>' + 'Pret 10' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '</div>';
return text;
}
document.addEventListener("DOMContentLoaded", function(){
document.getElementById("delta").innerHTML = generateText();
});

Related

Run CSS animation only once when regenerating a grid

function draw_flex (){
html_string = '';
for( let i=0; i < notes.length; i++) {
html_string += '<div class=" col-12 col-sm-12 col-md-4 col-lg-4 col-xl-2 ">'
html_string += '<div class="container">';
html_string += '<div class="text">' + notes[i].task + '</div>';
html_string += '<div class="date">' + notes[i].date + '</div>';
html_string += '<div class="time">' + notes[i].time + '</div>';
html_string += '<div class="button" onClick="delete_note_by_key(' + i + ')"><i class="fa fa-times"></i></div>';
html_string += '</div>';
html_string += '</div>';
}
html_string += '</div>';
document.getElementById('my-flex').innerHTML = html_string;
}
CSS class Container has an animation:
div.container {
background: url('notebg.png') no-repeat;
height: 250px;
animation-duration: 4s;
animation-name: fadeIn;
}
Draw_flex() function runs on form submit, so each time I submit a new Container, the animation runs once again. Ho to make it run only once?
you could look for a div.container element at the beginning of the function draw_flex: if the element exists add a no-animation class to the #my-flex container
function draw_flex() {
if (document.querySelectorAll('#my-flex div.container').length > 0) {
document.getElementById('my-flex').classList.add('no-animation');
}
...
}
and the CSS becomes
div.container {
background: url('notebg.png') no-repeat;
height: 250px;
}
#my-flex:not(.no-animation) div.container {
animation-duration: 4s;
animation-name: fadeIn;
}
so after the first call to the draw_flex function the animation will be disabled.

How do i keep a set of elements wrapped in a div inline?

https://jsfiddle.net//2L4t9saq/61/ is my code
this is the output of one line of iterations
<span class="inline"><div class="pixels" x="1" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="2" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="3" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="4" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="5" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="6" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="7" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="8" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="9" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="10" y="1" style="background-color: red; width: 10px; height: 10px;"></div></span>
this creates 10 divs with width/height of 10px with the background color red, all 10 divs are wrapped in the span with class inline. this process is then repeated 10 times to create the 10*10 array.
this can be configured, currently all that can be configured are the width and height of the array, and the width and height of each individual pixel
currently it is just a vertical 100 block line of red squares.
how would i make all element wrapped in classinline stay inline? as to turn it from a 1*100 line to a 10*10 square
thanks in advance
/*
$("#body").append(
"<div x='1'></div>"
);
$("div[x=1]").css("background-color","red")
$("div[x=1]").css("width","16")
$("div[x=1]").css("height","16")
*/
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<div class='inline'>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<div class='pixels' x='"
var midtag = "' y='"
var endtag = "'></div>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</div>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>
span should be inside the div and make them inline-block to be able to specify width/height
var createGrid = function(dimx,dimy,pixx,pixy){
for(var n = 1; n <dimy+1; n++){
var str = "<div>"
for(var i=1;i<dimx+1;i++){
var opentag = "<span class='pixels' x='"
var midtag = "' y='"
var endtag = "'></span>"
str = str+opentag+i+midtag+n+endtag
}
str=str+"</div>"
$("#main").append(str)
}
$(".pixels").css("background-color","red")
$(".pixels").css("width",pixx)
$(".pixels").css("height",pixy)
};
createGrid(10,10,10,10)
#main {
font-size:0; /* To fix white-space issue*/
}
.pixels {
display:inline-block;
border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>
Add display: flex on canvas div.
And no need of making the inline element as span, make it a div instead.
/*
$("#body").append(
"<div x='1'></div>"
);
$("div[x=1]").css("background-color","red")
$("div[x=1]").css("width","16")
$("div[x=1]").css("height","16")
*/
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<div class='inline'>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<div class='pixels' x='"
var midtag = "' y='"
var endtag = "'></div>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</div>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main" style="display: flex;">
</div>
The parent element should be display: block and the inner elements could be display: inline-block for them to display in a grid-like manner. Changing only the CSS:
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<span class='inline'>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<div class='pixels' x='"
var midtag = "' y='"
var endtag = "'></div>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</span>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
.inline {
display: block;
height: 10px;
}
.pixels {
display: inline-block
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>
But it would be better to put spans inside divs, not the other way around (divs are display: block by default):
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<div>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<span class='pixels' x='"
var midtag = "' y='"
var endtag = "'></span>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</div>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
.pixels {
display: inline-block
}
#main > div {
height: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>

Javascript width of span element

I create via a String some DOM-Elements and assign it via innerHTML to a div.
Now I need a flexible width of the span element (span_homebase). What I experience is that sometimes (for me it looks randomly) it returns other width than expected. I need the width of this span element because after this in the same line there is an Information Button but the width of the span could be different. So I use the width of span element as margin for the information button. Code is as follows. I searched for a async handler of innerHTML but in another post somebody said that it is not required because it is assigned instantly.
Are there any thoughts what to try? Because the information is now sometimes on the right place and sometimes not.
string = string + "<span id ='span_homebase'>" + homebaseCity + "</span>";
string = string + "<div class='section-end'></div>";
element.innerHTML = string;
var marginInfoHomebase = document.getElementById('span_homebase').offsetWidth + 20;
document.getElementById("information_button_homebase").style.margin = "5px 0 0 " + marginInfoHomebase + "px";
Now if I open the respective site for me sometimes the marginInfoHomebase sometimes returns 108 and sometimes 183 even if the same value is assigned to span element. Very strange. Any thoughts?
EDIT:
Working Example:
function createHomeSettingsView(settingsA){
var element = document.getElementById("table-settings");
var string = "";
for(var i = 0; i < settingsA.length; i++){
for(var z = 0; z < settingsA[i].length; z++){
if(i == 1){
//Notification buttons
if(z == 1){
//homebase setting
if(window.localStorage.getItem("switch_homebase") == 1){
//homebase on
var homebaseCity = settingsA[i][z] + ": " + window.localStorage.getItem("homebase_loc");
string = string + " \
<div class='row' style='height:100px;' id='settings-sec-"+ i +"-row-" + z +"'> \
<div class='text'> \
<span id='span_homebase'>" + homebaseCity + "</span> \
</div> \
<div onClick='homebaseInfoClick();' class='information_button' id='information_button_homebase'></div>\
<div id='handleAutoSwitcherHomebase'></div>\
<div id='showRadiusRangeHomebase'>Radius: 30km</div>\
<input class='sliders' id='changeRadiusRangeHomebase' type='range' min='5' max='100' step='5' oninput='handleChangeHomebase(this.value)' onchange='handleInputHomebase(this.value)' >\
</div>";
}
else{
//homebase off
string = string + " \
<div class='row' id='settings-sec-"+ i +"-row-" + z +"'> \
<div class='text'>\
<span id='span_homebase'>" + settingsA[i][z] + "</span> \
</div> \
<div onClick='homebaseInfoClick();' class='information_button' id='information_button_homebase'></div>\
<div id='handleAutoSwitcherHomebase'></div>\
</div>";
}
}
}
}
}
element.innerHTML = string;
var marginInfoHomebase = document.getElementById("span_homebase").offsetWidth + 25;
var marginText = "5px 0 0 " + marginInfoHomebase + "px";
console.log("Span: " + marginInfoHomebase);
document.getElementById("information_button_homebase").style.margin = marginText;
}
CSS:
.container .table-settings{
top: 64px;
position: absolute;
padding:0;
left: 0;
right: 0;
bottom:0;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
background-color: #ECEBF3;
}
.container .table-settings .row{
background-color: white;
padding-top: 14px;
height:50px;
border-bottom: 1px solid LightGray;
}
.container .table-settings .row .text{
margin-left: 15px;
color: black;
float: left;
}
#span_homebase{
display: inline-block;
}
To get an inline element's width use getBoundingClientRect method:
var mySpan = document.getElementById("mySpan");
var spanWidth = mySpan.getBoundingClientRect().width;
var spanHeight = mySpan.getBoundingClientRect().height;
By default a span element has no dimension because its CSS display property is inline.
If you want to give it a width, you should change that property to inline-block.
<style>
span {
display: inline-block ;
}
</style>
Now you can play with its dimensions.

Masonry not working with dynamic content

Masonry is not working with my dynamic content, I don't know why. I don't think it's a bug on my side, at least I've looked at the code for a few hours now and I can't find anything that isn't working.
//reads listbox.php and cycles through the array calling createbox
function listboxs() {
$.ajax({
url: '_php/listbox.php',
success: function (output) {
var jsonArray = $.parseJSON(output);
$.each(jsonArray, function (i, box) {
createbox(box.id, box.name, box.link, box.description, box.tags);
});
}
});
}
//create the code for 1 box
function createbox(id, name, link, description, tags) {
var boxHtml = "",
tagsHtml = "",
descriptionHtml = "";
boxHtml = '' + '<div class="box" id="' + id + '">' + '<div class="boxinfo">' + '<label class="boxname">' + name + '</label>';
$.each(tags, function (i, tag) {
tagsHtml += '<label class="boxtag">' + ((!tag.name) ? tags[i] : tag.name) + '</label>';
});
//if(description.trim().length > 0){
descriptionHtml = '<textarea class="boxdescription" readonly rows="1">' + description + '</textarea>';
//}
boxHtml += tagsHtml + '</div>' + descriptionHtml + '</div>';
$content.html($content.html() + boxHtml);
}
Below is the simplified HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="_css/index.css" />
<link href='http://fonts.googleapis.com/css?family=Marck+Script' rel='stylesheet'
type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Rosario' rel='stylesheet'
type='text/css'>
<script src="_resources/jquery-2.0.3.min.js" type="text/javascript" language="javascript"></script>
<script src="_resources/masonry.pkgd.min.js"></script>
<script type="text/javascript" language="javascript">
$('#content').masonry();
</script>
</head>
<body>
<div id="content" class="js-masonry"></div>
</body>
</html>
I know that I don't need the inline javascript calling masonry on content but it's one of my many tests...
Below is part of the CSS:
#content{
padding: 15px;
min-height: 400px;
}
/*
################################
box
*/
.box{
border: 1px solid black;
float: left;
padding: 5px;
background: #F0F0F0;
margin-left: 5px;
margin-bottom: 5px;
}
.boxinfo{
border-bottom: 1px solid black;
}
.boxname{
font-weight: bold;
}
.boxdescription{
border: none;
outline: none;
background: white;
overflow: hidden;
}
.boxtag{
margin-left: 5px;
}
#boxdecoy{
height: 45px;
}
.boxname, .boxtag, .boxdescription{
font-family: 'Rosario', sans-serif;
font-size: 12px;
}
.boxlink{
text-decoration: none;
color: black;
}
.boxlink:hover{
text-decoration: underline;
}
I'm really going crazy with all of it because I tested creating boxes by hand (this means writting in the html) in content, and if i do masonry works fine. If i create them through the function that you see there it doesn't work... i call listboxs right in the begining of the javascript file after I declare all my vars...
Hope I was clear and you can help me.
You should use appended method. From docs:
Add and lay out newly appended item elements.
Look at this jsfiddle
Try to change your code to
boxHtml += tagsHtml +
'</div>' +
descriptionHtml +
'</div>';
var $boxHtml = $(boxHtml);
$content.append($boxHtml).masonry('appended', $boxHtml);
Adding up to Grin's answer:
You should also apply data-masonry-options='{ "columnWidth": 200, "itemSelector": ".item" }' to your #container.
<div id="content" class="js-masonry" data-masonry-options='{ "columnWidth": 200, "itemSelector": ".item" }'></div>
Like so. It might help with your comment response. I don't have the rep to answer as a comment.

Assigning a value to innerHTML not working

Looking for a second set of eyes here...
I am calling this function:
customPanel(map, "map2", dirn, document.getElementById("path2"), 1);
In customPanel, I am then building html, then trying to assign it to the page:
Here is the function, the innerHTML is near the very bottom. If I throw an alert before I try to assign the html to the innerHTML of div, it alerts correctly:
<script type="text/javascript">
var map = "";
function customPanel(map, mapname, dirn, div) {
var html = "";
function waypoint(point, type, address) {
var target = '"' + mapname + ".showMapBlowup(new GLatLng(" + point.toUrlValue(6) + "))" + '"';
html += '<table style="border: 1px solid silver; margin: 10px 0px; background-color: rgb(238, 238, 238); border-collapse: collapse; color: rgb(0, 0, 0);">';
html += ' <tr style="cursor: pointer;" onclick=' + target + '>';
html += ' <td style="padding: 4px 15px 0px 5px; vertical-align: middle; width: 20px;">';
html += ' <img src="http://maps.gstatic.com/intl/en_us/mapfiles/marker_green' + type + '.png">'
html += ' <\/td>';
html += ' <td style="vertical-align: middle; width: 100%;">';
html += address;
html += ' <\/td>';
html += ' <\/tr>';
html += '<\/table>';
}
function routeDistance(dist) {
html += '<div style="text-align: right; padding-bottom: 0.3em;">' + dist + '<\/div>';
}
function detail(point, num, description, dist) {
var target = '"' + mapname + ".showMapBlowup(new GLatLng(" + point.toUrlValue(6) + "))" + '"';
html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
html += ' <tr style="cursor: pointer;" onclick=' + target + '>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
html += ' <a href="javascript:void(0)"> ' + num + '. <\/a>';
html += ' <\/td>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
html += description;
html += ' <\/td>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
html += dist;
html += ' <\/td>';
html += ' <\/tr>';
html += '<\/table>';
}
function copyright(text) {
html += '<div style="font-size: 0.86em;">' + text + "<\/div>";
}
// === read through the GRoutes and GSteps ===
for (var i = 0; i < dirn.getNumRoutes(); i++) {
if (i == 0) {
var type = "A";
} else {
var type = "B";
}
var route = dirn.getRoute(i);
var geocode = route.getStartGeocode();
var point = route.getStep(0).getLatLng();
// === Waypoint at the start of each GRoute
waypoint(point, type, geocode.address);
routeDistance(route.getDistance().html + " (about " + route.getDuration().html + ")");
for (var j = 0; j < route.getNumSteps(); j++) {
var step = route.getStep(j);
// === detail lines for each step ===
detail(step.getLatLng(), j + 1, step.getDescriptionHtml(), step.getDistance().html);
}
}
// === the final destination waypoint ===
var geocode = route.getEndGeocode();
var point = route.getEndLatLng();
waypoint(point, "B", geocode.address);
// === the copyright text ===
copyright(dirn.getCopyrightsHtml());
// === drop the whole thing into the target div
div.innerHTML = html;
}
</script>
EDIT:
Here is the HTML as requested. It's just two divs:
<div class="mapWrapper">
<div id="path2"> </div>
<div id="map2"> </div>
</div>
To clarify, the path2 and map2 are being generated dynamically by looping through $_POST values in PHP. Here is a snippit:
foreach($post_entries as $e){
echo "
<div class=\"mapWrapper\">
<div id=\"path" . $increased_counter ."\"> </div>
<div id=\"map" . $increased_counter ."\"> </div>
</div>";
}
EDIT #2
As requested by #user1090190, a public version of the page:
http://qxxiv6yc.myutilitydomain.com/trip-planned
I suspect that path2 has not already been loaded when you call that function. It doesn't matter that you're generating it via PHP. You have to wait for the DOM to load in the browser first before you can reference specific elements. There are two solutions to this:
Call the function after page load. I.e.
<body onload="customPanel(map, "map2", dirn, document.getElementById("path2"), 1);">
Put all your Javascript at the bottom

Categories