I would like to display my row on 2 columns,
but for a reason it is only displaying the first entry on 2 rows.('name' on 1 row /'grouped_id' other row.
Not all entries of my database.
I missed something know with $row=.
Can you help me ? I would like display 'name' 'grouped_id' on each row:
my code
<title>TITLE</title>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#700;800;900&display=swap" rel="stylesheet">
<style>
body {background-color: #000000;}
table {
background-color: #000000;
border-collapse: collapse;
width: 100%;
}
table, .table {
color: #fff;
font-family: "Montserrat", sans-serif;
font-size: 18px;
font-weight:800;
font-weight:Extra-bold;
}
tr:nth-child(even) {
background-color: #60451e;
}
</style>
<div class="container">
<div class="row">
<?php
include_once("inc/db_connect.php");
$sqlQuery = "SELECT name, GROUP_CONCAT(id ORDER BY id SEPARATOR ' | ') as grouped_id FROM developers GROUP BY name";
$resultSet = mysqli_query($conn, $sqlQuery) or die("database error:". mysqli_error($conn));
?>
<table id="editableTable" class="table table-bordered">
<tbody>
<?php
// represents your database rows
$rows = mysqli_fetch_array($resultSet);
$length = count($rows);
$halfIndex = ceil($length / 2);
$currentRow = 0;
while ($currentRow < $halfIndex) {
$leftIndex = $currentRow;
$rightIndex = $halfIndex + $currentRow;
$leftColumn = $rows[$leftIndex] ?? '--';
$rightColumn = $rows[$rightIndex] ?? '--';
echo "<tr>";
echo "<td>{$leftColumn}</td>";
echo "<td>{$rightColumn}</td>";
echo "</tr>";
$currentRow++;
}
?>
</tbody>
</table>
</div>
</div>
Have a look at the official documentation https://www.php.net/manual/en/mysqli-result.fetch-array.php
or here for a brief summary https://www.w3schools.com/php/func_mysqli_fetch_array.asp
The result of mysqli_fetch_array is a an array of array: a list of samples where each sample is a list of fields from the query table.
Related
I am really trying to use preg_replace an entire div and it's contents.
I've looked around quite a bit and found some similar examples.
Being a total newbie, i would greatly appreciate your advise.
Please be aware that there are nested divs within this div, but with different classes or id.
This is what i have tried, but with no success.
[preg_replace("/<div class="ads-wrapper">/(.+?)<\/div>s","",{title_article[1]})]
I should also point out that this is to be used with WP All Import.
EDIT //
Sample HTML
<body>
<div class="ads-wrapper">
<div style="margin-left: auto; margin-right: auto; text-align: center; " id="filexxxxxxx" data-cfptl="1" data-cfpa="69067" data-cfpw="69067"><script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-xxxxxxxxxxx" crossorigin="anonymous" data-checked-head="true"></script><ins class="adsbygoogle" style="display: block; height: 280px;" data-ad-client="ca-pub-xxxxxxxxxxxx" data-ad-slot="xxxxxxx" data-ad-format="auto" data-full-width-responsive="true" data-adsbygoogle-status="done" data-ad-status="filled"><p></p>
<div id="aswift_2_host" style="border: medium none; height: 280px; width: 752px; margin: 0px; padding: 0px; position: relative; visibility: visible; background-color: transparent; display: inline-block; overflow: visible;" tabindex="0" title="Advertisement" aria-label="Advertisement"><iframe id="aswift_2" name="aswift_2" style="left:0;position:absolute;top:0;border:0;width:752px;height:280px;" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" src="https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-xxxxxxxxxx&output=html&h=280&slotname=7139257958&adk=4289402179&adf=1131929206&pi=t.ma~as.7139257958&w=752&fwrn=4&fwrnh=100&lmt=1671441700&rafmt=1&format=752x280&url=https%3A%2F%2Ffilecr.com%2Fwindows%2Fadobe-indesign-2022-0002%2F%3Fid%3D937678064&fwr=0&fwrattr=true&rpe=1&resp_fmts=3&wgl=1&dt=1671441699033&bpp=5&bdt=1086&idt=828&shv=r20221207&mjsv=m202212050101&ptt=9&saldr=aa&abxe=1&cookie=ID%3D65a8c8bc760cb659-229ca8d322d90053%3AT%3D1671441677%3ART%3D1671441677%3AS%3DALNI_MYstdfFdvqDMbBT89kWi_GbmnW5Fw&gpic=UID%3D000008d9fc9b2725%3AT%3D1671441677%3ART%3D1671441677%3AS%3DALNI_MaA7dhdMS9LxBPtWwmg_Ho-5cQXWg&prev_fmts=0x0%2C1158x280&nras=1&correlator=536657398109&frm=20&pv=1&ga_vid=223145590.1671441677&ga_sid=1671441700&ga_hid=667781215&ga_fc=1&u_tz=0&u_his=1&u_h=1080&u_w=1920&u_ah=1080&u_aw=1920&u_cd=24&u_sd=1&adx=240&ady=1017&biw=1587&bih=1080&scr_x=0&scr_y=0&eid=44759875%2C44759926%2C44759837%2C44777508%2C31071219%2C31071259%2C44780792&oid=2&pvsid=4107435780668556&tmod=302213105&nvt=1&ref=https%3A%2F%2Ffilecr.com%2F%3Fs%3DAdobe&eae=0&fc=1920&brdim=%2C%2C0%2C0%2C1920%2C0%2C1920%2C1080%2C1600%2C1080&vis=1&rsz=%7C%7CeE%7C&abl=CS&pfx=0&fu=128&bc=29&ifi=3&uci=a!3&xpc=qnZUlMsEJP&p=https%3A//filecr.com&dtd=1078" data-google-container-id="a!3" data-google-query-id="CMm1s8athfwCFUrdhwodNQoNmA" data-load-complete="true" width="752" height="280" frameborder="0"></iframe></div>
<p><br>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</p></ins></div>
<p><script type="text/javascript">;new advadsCfpAd( 69067 );</script> </p></div>
</body>
Here is the code tested on https://www.jdoodle.com/php-online-editor/
I am using a small HTML minifier function vh_html_minifier that will remove the line breaks since I am unsure if the preg replace can be done with keeping the line breaks or not.
/**
* HTML Minifier function
*
* #param string $code HTML string.
* #return string
*/
function vh_html_minifier( $code ) {
$search = array(
// Remove whitespaces after tags.
'/\>[^\S ]+/s',
// Remove whitespaces before tags.
'/[^\S ]+\</s',
// Remove multiple whitespace sequences.
'/(\s)+/s',
// Removes comments.
'/<!--(.|\s)*?-->/',
);
$replace = array( '>', '<', '\\1' );
$code = preg_replace( $search, $replace, $code );
return $code;
}
$html = '<body>
<div class="ads-wrapper">
<div style="margin-left: auto; margin-right: auto; text-align: center; " id="filexxxxxxx" data-cfptl="1" data-cfpa="69067" data-cfpw="69067"><script async="" src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-xxxxxxxxxxx" crossorigin="anonymous" data-checked-head="true"></script><ins class="adsbygoogle" style="display: block; height: 280px;" data-ad-client="ca-pub-xxxxxxxxxxxx" data-ad-slot="xxxxxxx" data-ad-format="auto" data-full-width-responsive="true" data-adsbygoogle-status="done" data-ad-status="filled"><p></p>
<div id="aswift_2_host" style="border: medium none; height: 280px; width: 752px; margin: 0px; padding: 0px; position: relative; visibility: visible; background-color: transparent; display: inline-block; overflow: visible;" tabindex="0" title="Advertisement" aria-label="Advertisement"><iframe id="aswift_2" name="aswift_2" style="left:0;position:absolute;top:0;border:0;width:752px;height:280px;" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" src="https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-xxxxxxxxxx&output=html&h=280&slotname=7139257958&adk=4289402179&adf=1131929206&pi=t.ma~as.7139257958&w=752&fwrn=4&fwrnh=100&lmt=1671441700&rafmt=1&format=752x280&url=https%3A%2F%2Ffilecr.com%2Fwindows%2Fadobe-indesign-2022-0002%2F%3Fid%3D937678064&fwr=0&fwrattr=true&rpe=1&resp_fmts=3&wgl=1&dt=1671441699033&bpp=5&bdt=1086&idt=828&shv=r20221207&mjsv=m202212050101&ptt=9&saldr=aa&abxe=1&cookie=ID%3D65a8c8bc760cb659-229ca8d322d90053%3AT%3D1671441677%3ART%3D1671441677%3AS%3DALNI_MYstdfFdvqDMbBT89kWi_GbmnW5Fw&gpic=UID%3D000008d9fc9b2725%3AT%3D1671441677%3ART%3D1671441677%3AS%3DALNI_MaA7dhdMS9LxBPtWwmg_Ho-5cQXWg&prev_fmts=0x0%2C1158x280&nras=1&correlator=536657398109&frm=20&pv=1&ga_vid=223145590.1671441677&ga_sid=1671441700&ga_hid=667781215&ga_fc=1&u_tz=0&u_his=1&u_h=1080&u_w=1920&u_ah=1080&u_aw=1920&u_cd=24&u_sd=1&adx=240&ady=1017&biw=1587&bih=1080&scr_x=0&scr_y=0&eid=44759875%2C44759926%2C44759837%2C44777508%2C31071219%2C31071259%2C44780792&oid=2&pvsid=4107435780668556&tmod=302213105&nvt=1&ref=https%3A%2F%2Ffilecr.com%2F%3Fs%3DAdobe&eae=0&fc=1920&brdim=%2C%2C0%2C0%2C1920%2C0%2C1920%2C1080%2C1600%2C1080&vis=1&rsz=%7C%7CeE%7C&abl=CS&pfx=0&fu=128&bc=29&ifi=3&uci=a!3&xpc=qnZUlMsEJP&p=https%3A//filecr.com&dtd=1078" data-google-container-id="a!3" data-google-query-id="CMm1s8athfwCFUrdhwodNQoNmA" data-load-complete="true" width="752" height="280" frameborder="0"></iframe></div>
<p><br>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
</p></ins></div>
<p><script type="text/javascript">;new advadsCfpAd( 69067 );</script> </p></div>
</body>';
$result = preg_replace( '#<div class="ads-wrapper">(.*?)</div>#', ' ', vh_html_minifier( $html ) );
echo '<pre>' . $result . '</pre>';
I want to display percent instead of an integer.
Now it simply shows the value as integer when hovering on the data point of the chart (the tooltip).
I think I need to set in the formatter formula like this:
let test = value / SUM(all_values)
return test.toFixed(0) + '%'
But, I could not find it in their documentation, the best I found is this one which always gives me 100%, per every data point:
tooltip: {
y: {
formatter: function(value, opts) {
let percent = opts.w.globals.seriesPercent[opts.seriesIndex][opts.dataPointIndex];
return percent.toFixed(0) + '%'
}
}
}
You're right that you'll need to use the tooltip formatter, but the array you're using to get the percentage values isn't correct.
If you log the values opts.w.globals.seriesPercent you'll find that it's all 100's:
[[100, 100, 100, ..., 100]]
(I suspect this might be because it's intended to be used with other chart types.)
You can still get the percentage though, it'll just need to be worked out.
Using your same method to format the tooltip, but getting the values from opts.series instead:
tooltip: {
y: {
formatter: function(value, opts) {
const sum = opts.series[0].reduce((a, b) => a + b, 0);
const percent = (value / sum) * 100;
return percent.toFixed(0) + '%'
},
},
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="app/app.js"></script>
<script>
let apiLabels = [];
let apiData = [];
let currentTimestamp = (Math.floor(Date.now() / 1000)).toString();
//use this URL for daily fetch
//let url = "https://aave-api-v2.aave.com/data/rates-history?reserveId=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480xb53c1a33016b2dc2ff3653530bff1848a515c8c5&resolutionInHours=24&from="+currentTimestamp;
let url = "https://aave-api-v2.aave.com/data/rates-history?reserveId=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480xb53c1a33016b2dc2ff3653530bff1848a515c8c5&resolutionInHours=24&from=1639813032";
// months list
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
// fetch from api
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
let myData = JSON.parse(this.responseText);
console.log(myData);
for (let i = 0; i < myData.length; i++) {
//let formedDate = (myData[i]['x']['year']+'-'+myData[i]['x']['month']+'-'+myData[i]['x']['date']).toString();
let formedDate = monthNames[myData[i]['x']['month']] + ' ' + myData[i]['x']['date'];
console.log(formedDate);
let formedLiquidData = (myData[i]['liquidityRate_avg'] * 100).toFixed(2);
console.log(formedLiquidData+"%");
apiLabels.push(formedDate);
apiData.push(formedLiquidData);
}
const data = {
labels: apiLabels,
datasets: [
{
label: "USDC",
borderColor: "rgb(180,11,107)",
data: apiData
}
]
};
const config = {
type: "line",
data: data,
options:{
scales: {
y: {
ticks: {
callback: function (value, index, values) {
return value + '%';
}
}
},
},
},
};
const myChart = new Chart(document.getElementById("myChart"), config);
}
});
xhr.open(
"GET",
url
);
xhr.send();
</script>
</div>
<div id="app"></div>
<title>brew</title>
<style>
body {
background-color: white;
}
.center-form {
width: 80%;
margin: auto;
}
#title {
color: teal;
text-align: center;
}
.waitlist {
position: relative;
z-index: 3;
width: 146px;
height: 30px;
margin-top: 60px;
border-style: solid;
border-width: 1px;
border-color: #081852;
background-color: transparent;
box-shadow: -10px 10px 0 0 #081852;
color: #081852;
font-size: 12px;
line-height: 30px;
font-weight: 400;
text-align: center;
letter-spacing: 0.21px;
position: fixed;
right: 3%;
top: -5%;
}
.waitlist-button {
display: inline-block;
padding: 9px 15px;
background-color: #3898EC;
color: white;
border: 0;
line-height: inherit;
text-decoration: none;
cursor: pointer;
border-radius: 0;
}
.box-prices {
padding: 20px;
width: 200px;
height: auto;
color: #000;
/* background-color: #fff; */
border: 4px solid #1c1c53;
border-radius: 2px;
}
.dropbtn {
background-color: navy;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #ddd;
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #0b95f1;
}
footer {
display: flex;
justify-content: space-between;
}
.myChart {
width: 50%;
height: 40px;
}
/* Decorative */
a {
text-decoration: none;
color: #555;
}
footer {
background-color: #82cdf8;
padding: 20px 40px;
}
.right {
float: left;
text-align: center;
}
.article {
color: white;
}
</style>
</head>
<body>
<img src="https://uploads-ssl.webflow.com/61768faf04d20bf3487b5a2a/6176a6363e64b8d84e32d0b7_brew-icon-256px-v2.png"
loading="eager" width="55" height="55" alt="Brew" class="img-logo" position="absolute" top="-3%" left="7;">
<!-------------- title------------------------>
<div class="container">
<div class="row">
<div class="col-md-12 mt-2">
<h1 style="color: #1c98">
Stablecoin Deposits on Aave
</h1>
<a data-w-id="14f1dfb2-926f-581f-7faa-3f62171b1db3" href="" class="waitlist waitlist-button">Join the
waitlist</a>
</div>
</div>
</div>
<!------------------------AAVE PRICE ------------>
<div class="container">
<div class="row mt-5">
<div class="col-md-6">
<div class="aave-prices">
<p>AAVE PRICE</p>
<p>$172.8</p>
<p>16%</p>
</div>
</div>
<!------------------------AAVE DESCRIPTION ------------>
<div class="col-md-6">
<h1>What is AAVE ?</h1>
<p>Aave is an open source and non-custodial liquidity protocol for earning
interest on deposits and borrowing assets.</p>
</div>
</div>
<!------------------------AAVe CHAIN ------------>
<div class="row">
<div class="col-md-12 mt-3">
<button class="dropbtn">CHAIN</button>
<div class="dropdown-content">
Polygon
Ethereum
Avalance
</div>
</div>
</div>
</div>
<!------graph----->
<div>
<canvas id="myChart" height="50" weidth="50"></canvas>
</div>
<!-- calculator -->
<div class="container mt-5" style="border: 1px solid black; border-radius: 5px;">
<div class="row">
<div class="col-md-12">
<h1 id="title">How Much You Can Earn ?</h1>
</div>
</div>
<br>
<div class="row">
<div class="col-md-6">
<form>
<div class="form-group mt-2">
<label class="form-group">Amount</label>
<input class="form-control mt-2" type="text" id="principal" placeholder="$">
</div>
<div class="form-group mt-2">
<label class="form-group">Interest rate: 4%</label>
</div>
<div class="form-group mt-2">
<label class="form-group">Compound Freequency: Daily</label>
</div>
<div class="form-group mt-2">
<label class="form-group">Payout Freequency: Monthly</label>
</div>
<button class="btn btn-block btn-info mt-3" type="button" onclick="calculate()">Calculate</button>
</form>
</div>
<div class="col-md-6">
<form style="padding-top: 70px;">
<div class="form-group mt-2">
<label class="form-group">Interest rate: 5%</label>
</div>
<div class="form-group mt-2">
<label class="form-group">Compound Freequency: Daily</label>
</div>
<div class="form-group mt-2">
<label class="form-group">Payout Freequency: Monthly</label>
</div>
</form>
</div>
</div>
<br>
<div class="row">
<div class="col-md-6">
<h5 class="total">Result USD</h5>
<h1 id="USD"></h1>
</div>
<div class="col-md-6">
<h5 class="total">Result USDT</h5>
<h1 id="USDC"></h1>
</div>
</div>
</div>
<!-- calculator end -->
<div>
<canvas id="myChart_subbagain" height="50" weidth="50" top="80%"></canvas>
</div>
<!----footer-->
<div class="col-md-12 mt-5">
<footer>
<div class="col-md-6">
<img src="/dawnload.png" alt="" width="150">
</div>
<div class="col-md-6">
<section class="right">
Join Brew Today
<article>USDC is not a legal tender recognised by US or any other government. Unlike a bank account, your
deposit is not insured. While Brew will make every effort to ensure that your deposit earn the best interest
rates in the most secure way possible, please note that any investment entails risk. Interest Rates are
subject to change anytime as per the market conditions.</article>
</section>
</div>
</footer>
</div>
</body>
<script type="text/javascript">
function calculate() {
var principle = 0;
var interest = 5 / 100;
var numberOfPeriod = 12;
var time = 10;
var CI = 0;
principle = document.getElementById("principal").value;
// CI = ((p * (1 + i) ^ n) - p);
CI = principle * (1 + interest / numberOfPeriod) ^ (numberOfPeriod * time);
document.getElementById("USD").innerHTML = CI;
document.getElementById("USDC").innerHTML = CI;
}
</script>
<!------cal graph-->
</html>
What I am trying to do is to create an invoice pdf file with several table rows. Table rows would be created using for loop in Django. The problem is data inside for loop tag is not visible on the pdf file.
You can check the screenshots below. Django properly renders invoice.html template so the code is valid, but the pdf file contains empty frame without any table rows. To render pdf from html I am using xhtml2pdf.
how django render the invoice.html template
how pdf file looks like
invoice.html
<html>
<head>
{% load static %}
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta charset="UTF-8">
<style>
#font-face {
font-family: Roboto;
src: url('{% static 'fonts/Roboto-Regular.ttf' %}');
}
#font-face {
font-family: Roboto-bold;
src: url('{% static 'fonts/Roboto-Bold.ttf' %}');
font-weight: bold;
}
#page {
size: a4 portrait;
#frame header_frame { /* Static Frame */
-pdf-frame-content: frame_header_left;
left: 50pt; width: 245pt; top: 30pt; height: 150pt;
}
#frame header_frame { /* Static Frame */
-pdf-frame-content: frame_header_right;
left: 300pt; width: 245pt; top: 50pt; height: 150pt;
}
#frame content_frame { /* Content Frame */
-pdf-frame-content: frame_invoice_number;
left: 50pt; width: 512pt; top: 170pt; height: 30pt;
}
#frame col1 {
-pdf-frame-content: frame_col1;
left: 50pt; width: 245pt; top: 220pt; height: 130pt;
}
#frame col2 {
-pdf-frame-content: frame_col2;
left: 300pt; width: 245pt; top: 220pt; height: 130pt;
}
#frame frame_services {
-pdf-frame-content: frame_services;
left: 50pt; width: 512pt; top: 380pt; height: 250pt;
-pdf-frame-border: 1;
}
#frame content_frame {
-pdf-frame-content: frame_summary;
left: 465pt; width: 100pt; top: 590pt; height: 50pt;
}
#frame content_frame {
-pdf-frame-content: frame_vat;
left: 50pt; width: 512pt; top: 590pt; height: 150pt;
}
#frame content_frame {
-pdf-frame-content: frame_signatures_left;
left: 50pt; width: 140pt; top: 725pt; height: 70pt;
}
#frame content_frame {
-pdf-frame-content: frame_signatures_right;
left: 400pt; width: 140pt; top: 725pt; height: 70pt;
left: 400pt; width: 140pt; top: 725pt; height: 70pt;
}
#frame content_frame {
-pdf-frame-content: footer_content;
left: 50pt; width: 512pt; top: 775pt; height: 50pt;
}
}
body {
background-color: white;
font-family: "Roboto", sans-serif;
}
.right{
font-size: 10px;
text-align: right;
}
.left{
text-align: left;
}
.invoice-number {
font-size: 18px;
font-family: "Roboto-bold", sans-serif;
}
.col-titles {
font-size: 16px;
text-decoration: underline;
font-family: "Roboto-bold", sans-serif;
}
.footer {
font-size: 8px;
text-align: center;
}
p{
font-size: 10px;
line-height: 0;
}
table {
border-bottom: 1px solid #ddd;
text-align: center;
}
td, td {
border-bottom: 1px solid #ddd;
vertical-align: middle;
}
.summary{
border-bottom: 1px solid #ddd;
}
.signatures {
border-top: 1px solid black;
font-size: 8px;
text-align: center;
}
th {
height: 36px;
}
td {
height: 25px;
}
</style>
</head>
<body>
<div>
<div>
<div id="frame_header_left" class="left">
<img src="{% static 'invoices/logo.png' %}" alt="logo" width="150" height="112">
</div>
<div id="frame_header_right" class="right">
<p>Miejsce wystawienia: Żabno</p>
<p>Data badania: {{ invoice.data_badania }}</p>
<p>Data wystawienia: {{ invoice.data_wystawienia_faktury }}</p>
</div>
</div>
<div id="frame_invoice_number">
<div class="invoice-number">
<h2>Faktura nr: {{ invoice.numer }}</h2>
</div>
</div>
<div id="frame_col1">
<p class="col-titles">Sprzedawca</p>
<div>
<p>MEDIKAP</p>
<p>ul. Plac Grunwaldzki 15B, 33-240 Żabno</p>
<p>NIP: 999999999</p>
<p>REGON: 9999999</p>
<p>Bank: ING Bank Śląski</p>
<p>Nr konta: 12 1234 1234 1243 1243 214 1244</p>
</div>
</div>
<div id="frame_col2">
<p class="col-titles">Nabywca</p>
<div>
<p> {{ invoice.firma}} </p>
<p> ul. {{ invoice.firma.ulica }} </p>
<p> {{ invoice.firma.kod_pocztowy }} {{ invoice.firma.miasto}}</p>
<p> NIP: {{ invoice.firma.nip }}</p>
<p> REGON: {{ invoice.firma.regon }}</p>
<p> forma płatności: {{ invoice.get_forma_platnosci_display}}</p>
</div>
</div>
<div id="frame_services">
<table>
<tr>
<th style="width: 50px;"> # </th>
<th style="width: 600px;"> Nazwa usługi</th>
<th style="width: 100px;"> Ilość</th>
<th style="width: 100px;"> Rabat[%]</th>
<th style="width: 100px;"> Cena usługi</th>
<th style="width: 100px;"> Wartość</th>
<th style="width: 100px;"> Wartość z rabatem:</th>
</tr>
{% for service in services_items %}
<tr>
<td> test </td>
<td> test </td>
</tr>
{% endfor %}
</table>
</div>
<div id="frame_summary" class="summary">
<p> : {{ service.get_total_value }} PLN</p>
<p> Wartość z uwzględnieniem {{ invoice.rabat}}% rabatu: {{ discounted_value|floatformat:"-2" }} PLN</p>
</div>
<div id="frame_vat">
<p> Podstawa zwolnienia z VAT: </p>
<p> Zwolnienie ze względu na zakres wykonywanych czynności (art. 43 ust.1) pkt 19 Ustawy o VAT</p>
</div>
<div id="frame_signatures_left">
<p class="signatures"> podpis osoby upoważnionej do odbioru faktury</p>
</div>
<div id="frame_signatures_right">
<p class="signatures"> podpis osoby upoważnionej do wystawienia faktury</p>
</div>
<div id="footer_content" >
<p class="footer">MEDIKAP Maria K.</p>
<p class="footer">Plac Grunwaldzki 15B, 33-240 Żabno</p>
<p class="footer">e-mail: gabinet.medikap#gmail.com tel: 539 993 332</p>
<p class="footer">NIP: 9930212793 REGON: 852441210</p>
</div>
</div>
</body>
</html>
views.py/DetailsInvoice
class DetailsInvoice(generic.View):
template_name = 'invoices/invoice_detail.html'
form_class = DetailInvoiceForm
success_url = reverse_lazy("invoices:list")
def get(self, request, invoice_id):
current_invoice = get_object_or_404(Invoice, id=invoice_id)
form = self.form_class(instance=current_invoice)
request.session['invoice_id'] = current_invoice.id
services = Service.objects.all()
all_service_items = ServiceItem.objects.all().filter(faktura = current_invoice).order_by('usluga')
context = {
'invoice': current_invoice,
'form' : form,
'services' : services,
'services_items' : all_service_items,
}
return render(request, self.template_name, context)
def post(self, request, invoice_id):
current_invoice = get_object_or_404(Invoice, id=invoice_id)
form = self.form_class(request.POST, instance=current_invoice)
all_service_items = ServiceItem.objects.all().filter(faktura=current_invoice)
context = {
'invoice' : current_invoice,
}
pdf = render_to_pdf('invoices/invoice.html', context)
services_assigned_to_invoice = current_invoice.uslugi.all()
if 'update-data' in request.POST and form.is_valid():
for service in all_service_items:
service_item = get_object_or_404(ServiceItem, id=service.id)
quantity_input = request.POST.get('quantity-' + str(service.id))
discount_input = request.POST.get('discount-' + str(service.id))
service_item.ilosc = int(quantity_input)
service_item.rabat = int(discount_input)
service_item.save()
form.save()
for service_item in all_service_items:
if service_item.usluga not in services_assigned_to_invoice:
service_item.delete()
for single_service in services_assigned_to_invoice:
new_service_item, created = ServiceItem.objects.get_or_create(usluga=single_service, faktura=current_invoice)
messages.success(request, 'Pomyślnie zaktualizowane dane')
return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
if 'view-pdf' in request.POST:
return HttpResponse(pdf, content_type='application/pdf')
if 'download-pdf' in request.POST:
response = HttpResponse(pdf, content_type='application/pdf')
filename = f"Faktura {current_invoice.numer}.pdf"
content = "attachment; filename={}".format(filename)
response['Content-Disposition'] = content
return response
else:
return redirect('invoices:list')
rendering function
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("utf-8")), result, link_callback=link_callback)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
You are not passing the same context variables to your PDF as the ones you are passing to your HTML template. To your HTML template you are passing:
context = {
'invoice': current_invoice,
'form' : form,
'services' : services,
'services_items' : all_service_items,
}
While to your PDF you are only passing:
context = {
'invoice' : current_invoice,
}
services_items is the one your PDF template seems to be missing. So because for service in services_items is an empty/non-existent list in your PDF template, it doesn't render any rows. In the future you can check this by adding an {% empty %} section to your for loop:
{% for service in services_items %}
<tr>
<td> test </td>
<td> test </td>
</tr>
{% empty %}
No items!
{% endfor %}
I'm really stuck in this subject and maybe someone can help me out. I can always generate a token with stripe successfully but somehow my charge function doesn't wan't to work. I'm using the stripe element from their official documentation.
How can I find out where I have to search for the mistake because I don't get any error from the code. In the stripe dashboard I can see the generated tokens, that's why I think until this point there is everything right but I guess my mistake is in the view function. More precise I think the view function doesn't get the generated token from the javascript. Many thanks for your help in advance!
stripe_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
{% load static %}
<link rel="stylesheet" href="{% static 'css/stripe.css' %}">
<title>Document</title>
</head>
<body>
<div id="collapseStripe" class="wrapper">
<script src="https://js.stripe.com/v3/"></script>
<form action="" method="post" id="payment-form">
{% csrf_token %}
<div class="form-row">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element" class="StripeElement StripeElement--empty">
<div class="__PrivateStripeElement" style="margin: 0px !important; padding: 0px !important; border: none !important; display: block !important; background: transparent !important; position: relative !important; opacity: 1 !important;"><iframe frameborder="0" allowtransparency="true" scrolling="no" name="__privateStripeFrame4" allowpaymentrequest="true" src="https://js.stripe.com/v3/elements-inner-card-bfbabea0af3ed365b5fe9ce78692fd3c.html#style[base][color]=%2332325d&style[base][fontFamily]=%22Helvetica+Neue%22%2C+Helvetica%2C+sans-serif&style[base][fontSmoothing]=antialiased&style[base][fontSize]=16px&style[base][::placeholder][color]=%23aab7c4&style[invalid][color]=%23fa755a&style[invalid][iconColor]=%23fa755a&componentName=card&wait=false&rtl=false&keyMode=test&origin=https%3A%2F%2Fstripe.com&referrer=https%3A%2F%2Fstripe.com%2Fdocs%2Fstripe-js%2Felements%2Fquickstart&controllerId=__privateStripeController1" title="Secure payment input frame" style="border: none !important; margin: 0px !important; padding: 0px !important; width: 1px !important; min-width: 100% !important; overflow: hidden !important; display: block !important; height: 19.2px;"></iframe><input class="__PrivateStripeElement-input" aria-hidden="true" aria-label=" " autocomplete="false" maxlength="1" style="border: none !important; display: block !important; position: absolute !important; height: 1px !important; top: 0px !important; left: 0px !important; padding: 0px !important; margin: 0px !important; width: 100% !important; opacity: 0 !important; background: transparent !important; pointer-events: none !important; font-size: 16px !important;"></div>
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<button>Submit Payment</button>
</form>
</div>
<div id="stripe-token-handler" class="is-hidden">Success! Got token: <span class="token"></span></div>
{% load static %}
<script src="{% static 'js/stripe.js' %}"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
function toggleDisplay() {
var x = document.getElementById("collapseStripe");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
};
</script>
</body>
</html>
views.py
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
def charge (request):
publishKey = settings.STRIPE_PUBLISHABLE_KEY
if request.method == 'POST':
try:
token = request.POST['stripeToken']
charge = stripe.Charge.create(
amount=999,
currency='usd',
description='Example charge',
source=token,
)
return redirect(request, 'registration/stripe_form.html')
except stripe.CardError as e:
message.info(request, "Your card has been declined.")
return render(request, 'registration/stripe_form.html')
stripe.js
var stripe = Stripe('pk_test_');
// Create an instance of Elements.
var elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
// (Note that this demo uses a wider set of styles than the guide below.)
var style = {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
// Create an instance of the card Element.
var card = elements.create('card', {style: style});
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// Handle real-time validation errors from the card Element.
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// Handle form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
// Inform the user if there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// Send the token to your server.
stripeTokenHandler(result.token);
}
});
});
// Submit the form with the token ID.
function stripeTokenHandler(token) {
// Insert the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// Submit the form
form.submit();
}
var successElement = document.getElementById('stripe-token-handler');
document.querySelector('.wrapper').addEventListener('click', function() {
successElement.className = 'is-hidden';
});
// Not in demo.
function stripeTokenHandler(token) {
successElement.className = '';
successElement.querySelector('.token').textContent = token.id;
}
I've been searching for a good trick to make a Hide/Show content or a list with only CSS and no javascript.
I've managed to make this action:
<!DOCTYPE html>
<head>
<style>
#cont {display: none; }
.show:focus + .hide {display: inline; }
.show:focus + .hide + #cont {display: block;}
</style>
</head>
<body>
<div>
[Show]
/ [Hide]
<div id="cont">Content</div>
</div>
</body>
</html>
Demo here: http://jsfiddle.net/6W7XD/
And it's working but not as it should. Here is the problem:
When the content is shown, you can hide it by clicking "anywhere on the page". How to disable that? how to hide content "only" by clicking hide?
Thank you in advance!
I wouldn't use checkboxes, i'd use the code you already have
DEMO http://jsfiddle.net/6W7XD/1/
CSS
body {
display: block;
}
.span3:focus ~ .alert {
display: none;
}
.span2:focus ~ .alert {
display: block;
}
.alert{display:none;}
HTML
<span class="span3">Hide Me</span>
<span class="span2">Show Me</span>
<p class="alert" >Some alarming information here</p>
This way the text is only hidden on click of the hide element
This is going to blow your mind: Hidden radio buttons.
input#show, input#hide {
display:none;
}
span#content {
display:none;
}
input#show:checked ~ span#content {
display:block;
}
input#hide:checked ~ span#content {
display:none;
}
<label for="show">
<span>[Show]</span>
</label>
<input type=radio id="show" name="group">
<label for="hide">
<span>[Hide]</span>
</label>
<input type=radio id="hide" name="group">
<span id="content">Content</span>
I used a hidden checkbox to persistent view of some message. The checkbox could be hidden (display:none) or not. This is a tiny code that I could write.
You can see and test the demo on JSFiddle
HTML:
<input type=checkbox id="show">
<label for="show">Help?</label>
<span id="content">Do you need some help?</span>
CSS:
#show,#content{display:none;}
#show:checked~#content{display:block;}
Run code snippet:
#show,#content{display:none;}
#show:checked~#content{display:block;}
<input id="show" type=checkbox>
<label for="show">Click for Help</label>
<span id="content">Do you need some help?</span>
http://jsfiddle.net/9s8scbL7/
There is 3 rapid examples with pure CSS and without javascript where the content appears "on click", with a "maintained click" and a third "onhover" (all only tested in Chrome). Sorry for the up of this post but this question are the first seo result and maybe my contribution can help beginner like me
I think (not tested) but the advantage of argument "content" that you can add great icon like from Font Awesome (its \f-Code) or an hexadecimal icon in place of the text "Hide" and "Show" to internationalize the trick.
example link http://jsfiddle.net/MonkeyTime/h3E9p/2/
<style>
label { position: absolute; top:0; left:0}
input#show, input#hide {
display:none;
}
span#content {
display: block;
-webkit-transition: opacity 1s ease-out;
transition: opacity 1s ease-out;
opacity: 0;
height: 0;
font-size: 0;
overflow: hidden;
}
input#show:checked ~ .show:before {
content: ""
}
input#show:checked ~ .hide:before {
content: "Hide"
}
input#hide:checked ~ .hide:before {
content: ""
}
input#hide:checked ~ .show:before {
content: "Show"
}
input#show:checked ~ span#content {
opacity: 1;
font-size: 100%;
height: auto;
}
input#hide:checked ~ span#content {
display: block;
-webkit-transition: opacity 1s ease-out;
transition: opacity 1s ease-out;
opacity: 0;
height: 0;
font-size: 0;
overflow: hidden;
}
</style>
<input type="radio" id="show" name="group">
<input type="radio" id="hide" name="group" checked>
<label for="hide" class="hide"></label>
<label for="show" class="show"></label>
<span id="content">Lorem iupsum dolor si amet</span>
<style>
#show1 { position: absolute; top:20px; left:0}
#content1 {
display: block;
-webkit-transition: opacity 1s ease-out;
transition: opacity 1s ease-out;
opacity: 0;
height: 0;
font-size: 0;
overflow: hidden;
}
#show1:before {
content: "Show"
}
#show1:active.show1:before {
content: "Hide"
}
#show1:active ~ span#content1 {
opacity: 1;
font-size: 100%;
height: auto;
}
</style>
<div id="show1" class="show1"></div>
<span id="content1">Ipsum Lorem</span>
<style>
#show2 { position: absolute; top:40px; left:0}
#content2 {
display: block;
-webkit-transition: opacity 1s ease-out;
transition: opacity 1s ease-out;
opacity: 0;
height: 0;
font-size: 0;
overflow: hidden;
}
#show2:before {
content: "Show"
}
#show2:hover.show2:before {
content: "Hide"
}
#show2:hover ~ span#content2 {
opacity: 1;
font-size: 100%;
height: auto;
}
/* extra */
#content, #content1, #content2 {
float: left;
margin: 100px auto;
}
</style>
<div id="show2" class="show2"></div>
<span id="content2">Lorem Ipsum</span>
This is what I've used recently.
CSS
div#tabs p{display:none;}
div#tabs p.tab1:target {display:block;}
div#tabs p.tab2:target {display:block;}
div#tabs p.tab3:target {display:block;}
HTML
<div id='tabs'>
<h2 class="nav-tab-wrapper">
Pages
Email
Support
</h2>
<p id='tab1' class='tab1'>Awesome tab1 stuff</p>
<p id='tab2' class='tab2'>Tab2 stuff</p>
<p id='tab3' class='tab3'>Tab3 stuff</p>
</div>
https://jsfiddle.net/hoq0djwc/1/
Hope it helps somewhere.
Nowadays (2020) you can do this with pure HTML5 and you don't need JavaScript or CSS3.
<details>
<summary>Put your summary here</summary>
<p>Put your content here!</p>
</details>
First, thanks to William.
Second - i needed a dynamic version. And it works!
An example:
CSS:
p[id^="detailView-"]
{
display: none;
}
p[id^="detailView-"]:target
{
display: block;
}
HTML:
Show View1
<p id="detailView-1">View1</p>
Show View2
<p id="detailView-2">View2</p>
The answer below includes changing text for "show/hide", and uses a single checkbox, two labels, a total of four lines of html and five lines of css. It also starts out with the content hidden.
Try it in JSFiddle
HTML
<input id="display-toggle" type=checkbox>
<label id="display-button" for="display-toggle"><span>Display Content</span></label>
<label id="hide-button" for="display-toggle"><span>Hide Content</span></label>
<div id="hidden-content"><br />Hidden Content</div>
CSS
label {
background-color: #ccc;
color: brown;
padding: 15px;
text-decoration: none;
font-size: 16px;
border: 2px solid brown;
border-radius: 5px;
display: block;
width: 200px;
text-align: center;
}
input,
label#hide-button,
#hidden-content {
display: none;
}
input#display-toggle:checked ~ label#display-button {
display: none;
}
input#display-toggle:checked ~ label#hide-button {
display: block;
background-color: #aaa;
color: #333
}
input#display-toggle:checked ~ #hidden-content {
display: block;
}
I've got another simple solution:
HTML:
Hide Me
Show Me
<p id="alert" class="alert" >Some alarming information here</p>
CSS:
body { display: block; }
p.alert:target { display: none; }
Source: http://css-tricks.com/off-canvas-menu-with-css-target/
I know it's an old post but what about this solution (I've made a JSFiddle to illustrate it)... Solution that uses the :after pseudo elements of <span> to show/hide the <span> switch link itself (in addition to the .alert message it must show/hide). When the pseudo element loses it's focus, the message is hidden.
The initial situation is a hidden message that appears when the <span> with the :after content : "Show Me"; is focused. When this <span> is focused, it's :after content becomes empty while the :after content of the second <span> (that was initially empty) turns to "Hide Me". So, when you click this second <span> the first one loses it's focus and the situation comes back to it's initial state.
I started on the solution offered by #Vector I kept the DOM'situation presented ky #Frederic Kizar
HTML:
<span class="span3" tabindex="0"></span>
<span class="span2" tabindex="0"></span>
<p class="alert" >Some message to show here</p>
CSS:
body {
display: inline-block;
}
.span3 ~ .span2:after{
content:"";
}
.span3:focus ~ .alert {
display:block;
}
.span3:focus ~ .span2:after {
content:"Hide Me";
}
.span3:after {
content: "Show Me";
}
.span3:focus:after {
content: "";
}
.alert {
display:none;
}
Just wanted to illustrate, in the context of nested lists, the usefulness of the hidden checkbox <input> approach #jeffmcneill recommends — a context where each shown/hidden element should hold its state independently of focus and the show/hide state of other elements on the page.
Giving values with a common set of beginning characters to the id attributes of all the checkboxes used for the shown/hidden elements on the page lets you use an economical [id^=""] selector scheme for the stylesheet rules that toggle your clickable element’s appearance and the related shown/hidden element’s display state back and forth. Here, my ids are ‘expanded-1,’ ‘expanded-2,’ ‘expanded-3.’
Note that I’ve also used #Diepen’s :after selector idea in order to keep the <label> element free of content in the html.
Note also that the <input> <label> <div class="collapsible"> sequence matters, and the corresponding CSS with + selector instead of ~.
jsfiddle here
.collapse-below {
display: inline;
}
p.collapse-below::after {
content: '\000A0\000A0';
}
p.collapse-below ~ label {
display: inline;
}
p.collapse-below ~ label:hover {
color: #ccc;
}
input.collapse-below,
ul.collapsible {
display: none;
}
input[id^="expanded"]:checked + label::after {
content: '\025BE';
}
input[id^="expanded"]:not(:checked) + label::after {
content: '\025B8';
}
input[id^="expanded"]:checked + label + ul.collapsible {
display: block;
}
input[id^="expanded"]:not(:checked) + label + ul.collapsible {
display: none;
}
<ul>
<li>single item a</li>
<li>single item b</li>
<li>
<p class="collapse-below" title="this expands">multiple item a</p>
<input type="checkbox" id="expanded-1" class="collapse-below" name="toggle">
<label for="expanded-1" title="click to expand"></label>
<ul class="collapsible">
<li>sub item a.1</li>
<li>sub item a.2</li>
</ul>
</li>
<li>single item c</li>
<li>
<p class="collapse-below" title="this expands">multiple item b</p>
<input type="checkbox" id="expanded-2" class="collapse-below" name="toggle">
<label for="expanded-2" title="click to expand"></label>
<ul class="collapsible">
<li>sub item b.1</li>
<li>sub item b.2</li>
</ul>
</li>
<li>single item d</li>
<li>single item e</li>
<li>
<p class="collapse-below" title="this expands">multiple item c</p>
<input type="checkbox" id="expanded-3" class="collapse-below" name="toggle">
<label for="expanded-3" title="click to expand"></label>
<ul class="collapsible">
<li>sub item c.1</li>
<li>sub item c.2</li>
</ul>
</li>
</ul>
A very easy solution from cssportal.com
If pressed [show], the text [show] will be hidden and other way around.
This example does not work in Chrome, I don't why...
.show {
display: none;
}
.hide:focus + .show {
display: inline;
}
.hide:focus {
display: none;
}
.hide:focus ~ #list { display:none; }
#media print {
.hide, .show {
display: none;
}
}
<div><a class="hide" href="#">[hide]</a> <a class="show" href="#">[show]</a>
<ol id="list">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
</ol>
</div>
There is a pure HTML solution! Try the <details> element.
Implementation details from MDN: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary
And a try it out example from W3: https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_details
Browser support info is here: https://caniuse.com/details
After reading all the answers, I made this for whoever may still be looking for the trick: https://jsfiddle.net/Junip/do5xbkr6.
You now have the four ways to interact with links with CSS:
No form elements, no summary-details html tags, zero scripting.
#btn1::before { content: "Hover"; }
#btn1:hover::before { content: "Move"; }
#btn1:hover ~ #content { display: block; }
#btn2::before { content: "Hold down"; }
#btn2:active::before { content: "Release"; }
#btn2:active ~ #content { display: block; }
#btn2:active { opacity: 0; }
#btn3 a::before { content: "Click"; }
#btn3 a:focus::before { content: "Click away"; }
#btn3:focus-within ~ #content { display: block; }
#content {
display: none;
position: absolute;
top: 30%;
}
[id^="btn"] a {
text-decoration: none;
color: black;
}
#btn4 a[href="#revert"] { display: none; }
#content:target { display: block; }
#content:target ~ #btn4 a[href="#content"] { display: none; }
#content:target ~ #btn4 a[href="#revert"] { display: block; }