I'm getting an image file as binary data in a controller action:
def show
#result = QrcodeService.call(id)
send_data #result.body, type: 'image/png', disposition: 'inline'
end
The QrCodeService is just calling an external API to get an image using httparty gem.
The corresponding view template is defines as follows:
<h2>Scan Me</h2>
<%= image_tag #result %>
The problem is that the fetched images is displayed bu there are no styles, - the background is just black:
<body style="margin: 0px; background: #0e0e0e; height: 100%" data-new-gr-c-s-check-loaded="14.991.0" data-gr-ext-installed=""><img style="-webkit-user-select: none;margin: auto;" src="http://localhost:3000/qrcode"></body>
Even if I remove the call to <%= image_tag #result %> the <h2>Scan Me</h2> is not displayed either. What's wrong with the use of send_data?
It seems like the method replace completely the body content? I have nothing at all on the page, just the image...
More of that, when looking at the logs in the console, there the same requests hit twice to get the image:
Started GET "/qrcode" for 127.0.0.1 at 2021-01-12 10:31:33 +0100
Processing by QrcodeController#show as HTML
Rendering text template
Rendered text template (Duration: 0.0ms | Allocations: 1)
Sent data (0.5ms)
Completed 200 OK in 374ms (Views: 0.3ms | ActiveRecord: 0.0ms | Allocations: 2116)
Started GET "/qrcode" for 127.0.0.1 at 2021-01-12 10:31:33 +0100
Processing by QrcodeController#show as HTML
Rendering text template
Rendered text template (Duration: 0.0ms | Allocations: 1)
Sent data (1.0ms)
Completed 200 OK in 319ms (Views: 0.8ms | ActiveRecord: 0.0ms | Allocations: 2126)
and when you try to navigate back in the browser with its navigation buttons, the URL in the URI field changes but not the page content.
How is it possible to display an image fetched as binary data and keep/apply the CSS styles?
I was inspired by the answer provided by Anna and replace the use of send_data in the controller with the instance variable as follows:
def show
#result = QrcodeService.call(server_id)
end
Then create a helper method in ApplicationHelper class:
def qrcode_preview(blob)
if blob.code == 200
('<img src="data:image/jpg;base64,%s">' % Base64.encode64(blob)).html_safe
else
'<b>Image not yet ready</b>'
end
end
Sure, it can be modified as you want (styles, text, etc.).
And, finally use the helper method in the show view template as follows:
<h2>Your QR Code to sign in</h2>
<%= qrcode_preview(#result) %>
Voilà.
How can I make sure that 50 characters are shown in block (width:100px;) with CSS if User posts 50 characters on one line.
Now, my view is below.
<div class='example-wrapper'>
<%= simple_format(#user.content , class:'example') %>
</div>
If User posts 50 characters on one line(without making a line break) in #user.content, it is sticking out from browser.I don't mean that I use overflow:hidden;.Although I use white-space:normal; , nothing changes. Please tell me how to do it.
Now, scss is below.
.example-wrapper{
background-color:red;
max-width:100px;
}
.example{
max-width:100px;
white-space:normal;
}
You can use the truncate method. An example:
truncate("Once upon a time in a world far far away", length: 17)
# => "Once upon a ti..."
Read more here: http://api.rubyonrails.org/classes/ActionView/Helpers/TextHelper.html#method-i-truncate
With your example it would be something like this:
<div class='example-wrapper'>
<div class='example'>
<%= trucate(simple_format(#user.content), length: 50) %>
</div>
</div>
Given the following embedding code:
<iframe src="https://www.google.com/calendar/embed?
title=2014 PLIDAM International Symposium (Paris)&
dates=20140611/20140615&
mode=WEEK&
showNav=1&
showDate=1&
showPrint=1&
showTabs=1&
showCalendars=0&
showTz=1;
height=600&
wkst=2&
bgcolor=%23666666&
src=vdfmfbp0msroletduigs2qtkoc%40group.calendar.google.com&
color=%232952A3&
ctz=Europe%2FParis"
style=" border:solid 1px #777 " width="800" height="600" frameborder="0" scrolling="no"></iframe>
Is there a parameter to set the hours to display/focus_on from 09:00 to 18:00 (6pm), aka the working hours ? Same for days, is there someways to just display/focus_on the rights 4 days only.
Fiddle here
There doesn't appear to be a way to do this through the API, currently. I would use javascript/jQuery to remove the elements you don't want to show in the DOM after the iframe has finished loading.
So, you could delete the Wednesday column, if you know the column index, by something like this:
$("tr").each(function() {
$(this).filter("td:eq(3)").remove();
});
You can also scroll a specific div into view:
https://stackoverflow.com/a/4884904/5129424
$("#myImage")[0].scrollIntoView();
As you probably know, if you will to use :before and/or :after pseudoelements without setting text in it, you still have to declare content: ''; on them to make them visible.
I just added the following to my base stylesheet :
*:before, *:after {
content: '';
}
...so I don't have to declare it anymore further.
Apart from the fact the * selector is counter-performant, which I'm aware of (let's say the above is an example and I can find a better way to declare this, such as listing the tags instead), is this going to really slow things down ? I don't notice anything visually on my current project, but I'd like to be sure this is safe to use before I stick it definitely into my base stylesheet I'm going to use for every project...
Has anyone tested this deeply ? What do you have to say about it ?
(BTW, I do know the correct CSS3 syntax uses double semicolons (::before, ::after) as these are pseudoelements and not pseudoclasses.)
So I ran some tests based on #SWilk's advice. Here's how I did it :
1) Set up a basic HTML page with an empty <style> tag in the <head> and the simple example he provided in a <script> tag at the bottom of the <body> :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Performance test</title>
<style>
/**/
</style>
</head>
<body onload="onLoad()">
<div class="container"></div>
<script>
function onLoad() {
var now = new Date().getTime();
var page_load_time = now - performance.timing.navigationStart;
console.log("User-perceived page loading time: " + page_load_time);
}
</script>
</body>
</html>
2) Fill up the div.container with loaaads of HTML. In my case, I went to html-ipsum.com (no advertising intended), copied each sample, minified it all together, and duplicated it a bunch of times. My final HTML file was 1.70 MB, and the div.container had 33264 descendants (direct or not ; I found out by calling console.log(document.querySelectorAll('.container *').length);).
3) I ran this page 10 times in the latest Firefox and Chrome, each time with an empty cache.
Here are the results without the dreaded CSS ruleset (in ms) :
Firefox :
1785
1503
1435
1551
1526
1429
1754
1526
2009
1486
Average : 1600
Chrome :
1102
1046
1073
1028
1038
1026
1011
1016
1035
985
Average : 1036
(If you're wondering why there's such a difference between those two, I have much more extensions on Firefox. I let them on because I thought it would be interesting to diversify the testing environments even more.)
4) Add the CSS we want to test in the empty <style> tag :
html:before, html:after,
body:before, body:after,
div:before, div:after,
p:before, p:after,
ul:before, ul:after,
li:before, li:after,
h1:before, div:after,
strong:before, strong:after,
em:before, em:after,
code:before, code:after,
h2:before, div:after,
ol:before, ol:after,
blockquote:before, blockquote:after,
h3:before, div:after,
pre:before, pre:after,
form:before, form:after,
label:before, label:after,
input:before, input:after,
table:before, table:after,
thead:before, thead:after,
tbody:before, tbody:after,
tr:before, tr:after,
th:before, th:after,
td:before, td:after,
dl:before, dl:after,
dt:before, dt:after,
dd:before, dd:after,
nav:before, nav:after {
content: '';
}
...and start again. Here I'm specifying every tag used in the page, instead of * (since it is counter-performant in itself, and we want to monitor the pseudo-element triggering only).
So, here are the results with all pseudo-elements triggered (still in ms) :
Firefox :
1608
1885
1882
2035
2046
1987
2049
2376
1959
2160
Average : 1999
Chrome :
1517
1594
1582
1556
1548
1545
1553
1525
1542
1537
Average : 1550
According to these numbers, we can conclude the page load is indeed slower (of about 400-500 ms) when declaring content: '' on every pseudo-element.
Now, the remaining question now is : is the extra load time we can see here significative, given the relatively big test page that was used ? I guess it depends on the size of the website/project, but I'll let more web-performance-knowledgeable people give their opinion here, if they want to.
If you run your own tests, feel free to post your conclusions here as well, as I'm very interested in reading them - and I think I won't be the only one.
My answer is: I don't know, but one can test that.
Read about Navigation Timing and check out this example page
The most simple example of usage:
function onLoad() {
var now = new Date().getTime();
var page_load_time = now - performance.timing.navigationStart;
console.log("User-perceived page loading time: " + page_load_time);
}
So, go generate a few MB of html full of random tags, and test.
I am creating quite simple form for my model. I have generated scaffolded "Edit" view for it with validation. One validation is for "URL" type and it is causing me problems.
I have this in view:
<div class="editor-label">
#Html.LabelFor(model => model.Server)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Server)
#Html.ValidationMessageFor(model => model.Server)
</div>
This is css for #content section that contains everything rendered by View:
#content
{
border:solid;
border-width:thin;
position:relative;
margin-left: auto ;
margin-right: auto ;
text-align:center;
margin-top: 50px;
min-width:480px;
max-width:800px;
display:table;
padding: 30px;
}
When page is loaded, #content is 480px wide and elements inside take up as much space as possible (editor-field elements and element with submit buttons are set to 100%, nothing else has width set in css).
When "required" validation message is displayed on fields, everything works ok (width doesnt change).
When I enter invalid URL, message is longer (localized version of default mesage says "Pole Server neobsahuje plně kvalifikovanou adresu URL protokolu http, https nebo ftp.") and the whole #content width changes to 657px;
Is there a way how I can keep the width as it was before validation message got displayed and wrap validation message in case it is too long into more than one line with css settings?
I would like to avoid fixed width settings (on main section and all elements including validation message divs) and still keep the layout template and its css universal so I can keep using it repeatedly without need for tailoring it to particular scenario where it is used.
Thanks in advance
I have included screenshot that shows how it looks like