Accordion header content - javascript

I have created accordion in javascript. I would like to make accordion header content size smaller (50% percent). However I could not able to figure that out.
$.each(myData.offsetFormations, function(i,aut) {
headerList = '<h3><ul><li contenteditable="true">'+
'<text class="formationName">'+ aut.FormationName + '</text>'+
' | ' +
'<text class="bitSize">'+this.BitSize.toFixed(2) + '</text>'+
' | ' +
'<text class="bitType">'+this.BitType + '</text>'+
'</li></ul></h3>';
wellNameList = '<div class="table-holder"><table>';
$.each(myData.wellList, function(k,mano){
if(aut.AssociatedwellList.some(function(w) { return w.WellName === mano.WellName; }))
{
wellNameList += '<td><div>'+ mano.WellName+'</div></td>';
}
else
{
wellNameList += '<td style="color:gray;" ><div>'+ mano.WellName+'</div></td>';
}
});
wellNameList += '</table></div>';
headerList += '<div>'+wellNameList +'</div>';
$(headerList).appendTo('#accordion');
});

By default, ul elements have a 1em top and bottom margin, which is causing your boxes to have an additional 2em of height.
You can remove this with:
.ui-accordion ul {
margin: 0;
}
Updated fiddle: http://jsfiddle.net/xg7cr0g4/44/

Related

Why does setting objectPosition cause my JavaScript to crash?

Style objectPosition Property gives this example of setting objectPosition:
document.getElementById("myImg").style.objectPosition = "0 10%";
However, when I try to set objectPosition it causes my JavaScript to crash.
In the following code I use CSS to set objectPosition like this:
#img1 {
object-position: 0 0;
width: 635px ;
height: 580px ;
}
Near the bottom of function getImg, my debug code (the “insert” statement) shows it set to “0px 0px”. However, if I proceed this with
imgStyle.objectPosition = "0 0";
The “insert” statement and all following statements are not executed. Here’s my full code with the offending statement commented out:
"use strict";
const numberOfFigures = document.getElementsByTagName('figure').length;
const scale = 3; // scaling up factor
// The function "insert" is used purely for debug purposes
function insert(figNum) {
document.getElementById("para").innerHTML = "OK so far" + figNum;
}
// Create all thumbnails & big images.
for (let i = 0; i < numberOfFigures; i++) {
getImg(i + 1);
}
function getImg(figNum) {
// Create the thumbnails and big images
let startPosn = "0px"; // x-coordinate of object-position for thumbnail
var btnDiv = document.createElement('div');
btnDiv.setAttribute("id", "bigImg" + figNum);
btnDiv.style.backgroundColor = "white";
// Get the figure caption
const figcap = document.getElementById("fig" + figNum).firstElementChild;
btnDiv.innerHTML =
'<button type="button"' +
'class="displayBtn"' +
'onclick="hideBigImg (' +
figNum +
')">Hide large image</button>';
const btnPtr = figcap.appendChild(btnDiv);
/* Append the button to the
figcaption */
var imgDiv = document.createElement('div');
imgDiv.setAttribute("id", "imgDiv" + figNum);
if (figNum === 1) {
/* First image needs height: 100vh or only the top slice is
displayed. Other images may be messed up if this is applied to
them. */
imgDiv.innerHTML = '<' + 'img id="img' + figNum + '" ' +
'class = "sprite-img" ' +
'src="bates-sprite.jpeg" ' +
'style="height: 100vh; ' +
'transform-origin: top left; ' +
'transform: scale(' +
scale + ');">';
} else {
imgDiv.innerHTML = '<' + 'img id="img' + figNum + '" ' +
'class = "sprite-img" ' +
'src="bates-sprite.jpeg" ' +
'style="transform-origin: top left; ' +
'transform: scale(' +
scale + ');">';
}
const imgPtr = btnPtr.appendChild(imgDiv);
/* Append the img to the
button */
/* Make imgDiv high enough to hold the scaled up image & make the
accompanying text visible.
IMPORTANT to do this AFTER creating & appending the. */
// Get the height and width of the image
let img = document.getElementById("img" + figNum);
const imgStyle = getComputedStyle(img);
// Set imgDiv to exactly hold image
imgDiv.style.width = parseInt(imgStyle.width) * scale + "px";
imgDiv.style.height = parseInt(imgStyle.height) * scale + "px";
imgDiv.style.overflow = "hidden"; // Clip off rest of sprite
/*********************** Create thumbnail here *************/
let thumbHTML = '<' + 'div id="thumbDiv' + figNum + '" ' +
'onclick = "showBigImg(' +
figNum + ')" ' +
'style="float: left; ' +
'height: imgStyle.height; ' +
'width: imgStyle.width; ' +
'margin-right: 1.5em; ' +
'background-color: white; ' +
'border: thick solid black;"> ' +
'<' + 'img id="img' + figNum + '" ' +
'class = "sprite-img" ' +
'src="bates-sprite.jpeg" ' +
'style="transform-origin: top left; ' +
'transform: scale(0.5);" ' +
'onclick = "showBigImg(' +
figNum + ')";>' +
'</div>';
figcap.insertAdjacentHTML("afterend", thumbHTML);
/* Append the
thumbnail to the
figcaption */
/* Shrink the div to match the size of the thumbnail, and free up all the
blank space which the full size image would have occupied if it hadn't
been reduced with transform: scale */
let thumbnail = document.getElementById("thumbDiv" + figNum);
thumbnail.style.width = parseInt(imgStyle.width) / 2 + "px";
thumbnail.style.height = parseInt(imgStyle.height) / 2 + "px";
// Set object-position for image in sprite
//imgStyle.objectPosition = "0 0";
insert(imgStyle.objectPosition);
hideBigImg(figNum);
}
function showBigImg(figNum) {
document.getElementById('bigImg' + figNum).style.display = 'block';
document.getElementById('thumbDiv' + figNum).style.display = 'none';
}
function hideBigImg(figNum) {
document.getElementById('bigImg' + figNum).style.display = 'none';
document.getElementById('thumbDiv' + figNum).style.display = 'block';
}
/* Global constants */
:root {
--shrink: 0.30;
/* Size compressed to 30% */
}
figure {
display: block;
width: 96%;
float: left;
border-width: thin;
}
figcaption {
background-color: yellow;
}
.sprite-img {
background-repeat: no-repeat;
object-fit: none;
}
#img1 {
object-position: 0 0;
width: 635px;
height: 580px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="general.css">
</head>
<body>
<figure id="fig1">
<figcaption>Camberley Mail</figcaption>
<p id="para">Text to go with picture.</p>
</figure>
</body>
</html>
The reason why the program 'crashes' or more specifically throws an Exception is because you are trying to modify the properties of a read-only object.
In detail:
const img = document.querySelector("img");
const imgStyle = getComputedStyle(img); // imgStyle is a read-only object
imgStyle.objectPosition = "0 0";
The above code will throw:
Uncaught DOMException: Failed to set the 'object-position' property on 'CSSStyleDeclaration': These styles are computed, and therefore the 'object-position' property is read-only.
As stated in the MDN documentation:
"The object from getComputedStyle is read-only, and should be used to inspect the element's style — including those set by a element or an external stylesheet.
The element.style object should be used to set styles on that element, or inspect styles directly added to it from JavaScript manipulation or the global style attribute."
So, based on the docs, you should use the element.style object for setting the properties:
img.style.objectPosition = "0 0";

Align div at the bottom of the print page

I am fetching data from database using ajax. In this data, I have a textarea which I want to align at the bottom of every page and every textarea have different data. I tried CSS positions, it's only working for the first page because I have different data in every textarea.
var response = {
row1: [{
group: 'Group A'
}],
row2: [{
team: 'Team A',
player: 'Jema',
result: 43,
note: 'won'
},
{
team: 'Team B',
player: 'Deno',
result: 34,
note: 'lost'
},
{
team: 'Team B',
player: 'Niob',
result: 56,
note: 'lost'
},
{
team: 'Team B',
player: 'Skion',
result: 49,
note: 'lost'
},
],
};
var teams = {}
let count = -1;
response.row2.forEach(e => {
if (!(e.team in teams)) {
count++;
teams[e.team] = ["", e.note];
}
teams[e.team][0] += "<tr><td>" + e.player + "<td><input type='text' value='" + e.result + "'></td></tr>";
})
var table = "";
console.log(teams)
for (let team in teams) {
table += '<h2 class="group" style="border: 1px solid black">' +
response.row1[0].group + '</h2>'
table += '<table class="table bordered"><thead><th>Name</th><th>Result</th>
</thead></tbody>';
table += '<tr colspan="2" ><td>' + team + '</td></tr>';
table += teams[team][0];
table += '<div class="notesFooter"><textarea class="note">' +
catg[category][1] + '</textarea></div>';
table += '</tbody></table>';
if (count) table += "<div class='break'></div>"
count--;
}
$("#print").html(table);
var PrintThis = document.getElementById('print');
var PrintStyle = '<style type="text/css">' +
'#media print{' +
'.break { page-break-after: always }' +
'}' +
'</style>';
PrintStyle += PrintThis.innerHTML;
myWin = window.open("");
myWin.document.write(PrintStyle);
myWin.print();
myWin.close();
Js Fiddle
Position fixed or absolute causes an overlapping of textareas, so I think you need to put the textarea position relative to the top. You could add this .textarea{margin-top: 100%;} in PrintStyle var and add the class textarea to each textarea. Here the example: https://jsfiddle.net/L67rohc1/
But if you have tables with different numbers of rows this margin-top: 100%; is not accurate, you should calculate the top margin of each texarea, using something like this:
$(".table").each(function(i){
prev = $(this).outerHeight()/2;//<-- table height
//90vh in chrome to go closer to the bottom
$(this).next().css( "margin-top", "calc(70vh - "+prev+"px)" );
})
vh is Equal to 1% of the height of the viewport's initial containing block. It seems that 70 is a good value for Firefox and 90 for Chrome, but keep in mind that the number could change. Here the full example: https://jsfiddle.net/ob30p19d/
Make a div before the textarea by giving style="min-height: 800px; max-height: 800px">
as in https://jsfiddle.net/ob30p19d/6/
I hope it will help you.

How to wrap divs inside a new div?

I'm trying to wrap the two divs <div class="cm-cp-title"> and <div class="cm-cp-value"> inside a div called cm-cp-container. Actually it is working, but it merges all together, it is shown like below after I put the wrapAll();
what is that issues? im wonder how to separate each of it?
Below is the result i needed,
$(function() {
// document
'use strict';
var coupon = $('div.cm-coupon');
// Settings
coupon.each(function() {
var _coupon = $(this);
var cpValue = _coupon.attr("data-value") + "";
// Different Data type
if (_coupon.data('type') == "c1")
{
_coupon.addClass('red').css(
{
"background" : "black",
"display": "table"}
);
_coupon.append(
'<div class="cm-cp-title">' + 'black here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>'
);
}
else if (_coupon.data('type') == "c2")
{
_coupon.addClass('green').css(
{
"background" : "green",
"display": "table"}
);
_coupon.append('<div class="cm-cp-title">'+ 'green here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>');
}
else if (_coupon.data('type') == "c3")
{
_coupon.addClass('blue').css(
{
"background" :"blue",
"display": "table"}
);
_coupon.append('<div class="cm-cp-title">'+ 'blue here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>');
} else {
return false;
}
});
$('.cm-cp-title, .cm-cp-value').wrapAll("<div class='cm-cp-container'/>");
// alignment to middle
$('.cm-coupon').on('resize',function() {
$(".cm-cp-container").css('margin-top', function() {
return($('.cm-coupon').height() - $(this).height()) / 2
});
}).resize();
});//end
.cm-coupon {
width: 340px;
height: 156px;
float: left;color: #fff;
margin: 0 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cm-coupon" data-type="c1" data-value="50"></div>
<div class="cm-coupon" data-type="c2" data-value="20"></div>
<div class="cm-coupon" data-type="c3" data-value="70"></div>
Working Snippet :
$(function() {
'use strict';
var coupon = $('div.cm-coupon');
var colors = new Map([["c1", "black"], ["c2", "green"], ["c3", "blue"]]);
// Settings
coupon.each(function() {
var _coupon = $(this);
var cpValue = _coupon.attr("data-value") + "";
var color = colors.get(_coupon.data('type'));
_coupon.addClass(color).css({
"background" : color,
"display": "table"
});
_coupon.append('<div class="cm-cp-title">' + color + ' here' + '</div>' + '\n' + '<div class="cm-cp-value">' + cpValue + '</div>');
$(_coupon.children()).wrapAll("<div class='cm-cp-container'/>");
});
// alignment to middle
$('.cm-coupon').on('resize',function() {
$(".cm-cp-container").css('margin-top', function() {
return($('.cm-coupon').height() - $(this).height()) / 2
});
}).resize();
});//end
.cm-coupon {
width: 340px;
height: 156px;
float: left;
color: #fff;
margin: 0 10px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="cm-coupon" data-type="c1" data-value="50"></div>
<div class="cm-coupon" data-type="c2" data-value="20"></div>
<div class="cm-coupon" data-type="c3" data-value="70"></div>
Explanation :
First
I reduced the code removing the if statements because the only difference between the blocks if/else/else was the color ("black"/"green"/"blue"). I used a Map instead, to switch the value of the color according to the type.
What I did:
var colors = new Map([["c1", "black"], ["c2", "green"], ["c3", "blue"]]);
coupon.each(function () {
var _coupon = $(this);
var color = colors.get(_coupon.data('type'));
And then use color where need to.
Second
The problem you are encoutering is because you are not wrapping all the divs into the container, but wrapping the children of the divs.
So
$('.cm-cp-title, .cm-cp-value').wrapAll("<div class='cm-cp-container'/>");
becomes
$(coupon).wrapAll("<div class='cm-cp-container'/>");
EDIT :
It seems like you want to wrap the inner elements of the coupons instead.
Then use _coupon.children() instead, like this
$(_coupon.children()).wrapAll("<div class='cm-cp-container'/>");
and move it inside the each loop.
I edited the snippet. you can check.
In fact, the way you did it in your code, it is selecting all the matching elements in the document and wrapping it altogether. That is why the last two were moving inside the black div.

Easy Pagination add extra navi bar on top

Easy pagination plugin has default bottom bar under list.
I tried to add extra navi bar on top.
It displays. But it doesn't work pagination.
here is original code.
var displayNav = function() {
htmlNav = '<div class="easyPaginateNav">';
if(plugin.settings.firstButton) {
htmlNav += ''+plugin.settings.firstButtonText+'';
}
if(plugin.settings.prevButton) {
htmlNav += ''+plugin.settings.prevButtonText+'';
}
for(i = 1;i <= plugin.settings.pages;i++) {
htmlNav += ''+i+'';
};
if(plugin.settings.nextButton) {
htmlNav += ''+plugin.settings.nextButtonText+'';
}
if(plugin.settings.lastButton) {
htmlNav += ''+plugin.settings.lastButtonText+'';
}
htmlNav += '</div>';
plugin.nav = $(htmlNav);
plugin.nav.css({
'width': plugin.el.width()
});
plugin.el.before(plugin.nav);
plugin.el.after(plugin.nav);
var elSelector = '#' + plugin.el.get(0).id + ' + ';
$(elSelector + ' .easyPaginateNav a.page,'
+ elSelector + ' .easyPaginateNav a.first,'
+ elSelector + ' .easyPaginateNav a.last').on('click', function(e) {
e.preventDefault();
displayPage($(this).attr('rel'));
});
$(elSelector + ' .easyPaginateNav a.prev').on('click', function(e) {
e.preventDefault();
page = plugin.settings.currentPage > 1?parseInt(plugin.settings.currentPage) - 1:1;
displayPage(page);
});
$(elSelector + ' .easyPaginateNav a.next').on('click', function(e) {
e.preventDefault();
page = plugin.settings.currentPage < plugin.settings.pages?parseInt(plugin.settings.currentPage) + 1:plugin.settings.pages;
displayPage(page);
});
};
I tried to put plugin.nav .before and .after plugin.el at the same time but top doesn't display and work but buttom one does.
here is jSFiddle link - https://jsfiddle.net/ezq9zf1j/
Use clone to clone the navigation and prepend it to the parent element
$('#easyPaginate').easyPaginate({
paginateElement: 'img',
elementsPerPage: 3,
effect: 'climb'
});
var nav = $('.easyPaginateNav').clone(true,true);
nav.prependTo('body');
demo:http://jsfiddle.net/s41buqkc/

shifting all child divs inside a parent div when a child div is destroyed

I created this jsbin : http://jsbin.com/qoriqihapara/1/edit
as you can see i have two problems i don't know how to solve
if you opened the first chat window then the second and you close the first,then open again the first ,you see the two chat windows are overlapped and that because the calculation of right is not perfect
when closing a chat window that is not the first or the last ( considering having multiple chat window opened ), is there any method wish can shift all the chat window to the right ???
code :
var right = 10;
var rightPadding = 10;
function CreateDiv(id)
{
var ToAppend = "<div class='Msg_container_dv' id='Msg_container_dv_" + id + "' style='right:" + right + "px' >"
+ "<div class='Chat_Header_dv'>"
+ "<table><tr>"
+ "<td><a href='javascript:void(0)' onclick='closeChatwnd(\"Msg_container_dv_" + id + "\")' >close window</a></td>"
+ "</tr></table>"
+ "</div>"
+ "<div class='Chat_Body_Container' id='Chat_Body_Container_" + id + "'>" + id + "...</div>"
+ "<div class='Chat_Footer_Container'>text here...</div>"
+ "</div>";
right = right + (280 + rightPadding); // 280 is the width of the chat window
$("#chat_div_container").append(ToAppend);
}
function closeChatwnd(id)
{
$("#" + id).remove();
right = right - (280 + rightPadding);
}
I suggest to do like this:
#chat_div_container
{
padding-right:15px;
position:fixed;
bottom:0px;
right:0px;
width:200%; /*or more*/
}
and for Msg_container_dv
.Msg_container_dv
{
height:280px;
width:280px;
border:1px solid #868686;
bottom:0px;
float:right;
}
Simple and easy.
Don't forget to remove style='right:" + right + "px' from Msg_container_dv

Categories