Colorbox maxWidth, maxHeight not working - colorbox

I have problems to set colorbox using only the available viewport. As soon as I set the maxHeight or maxWidth attribute, no images will be displayed. The colorbox opens, but stays at the "spinning wheel".
function showImage(e) {
$.colorbox({href:$(e.currentTarget).attr("src")}); }
jQuery(document).ready(function () {
$('.popout').on("click", showImage);
$('.popout').colorbox({rel:'popout', maxWidth:'95%', maxHeight:'95%'}); });
<img class="popout" src="my.jpg" alt="" width="500" height="373" />
so, what's wrong with my code ? Or do i need to set other attributes as well to get maxWidth/height working ?

Sounds like you are causing an JS error (check your browser's development console).
However, your approach has problems. Try this instead:
jQuery(document).ready(function () {
$('.popout').colorbox({rel:'popout', maxWidth:'95%', maxHeight:'95%', href:function(){
return this.src;
}});
});
<img class="popout" src="my.jpg" alt="" width="500" height="373" />

While I know this is an old question. I just wish to add an answer for reference purposes that I have found useful, with this question.
In order to set a maxWidth or maxHeight on the colorbox one should also define the width and height first. The maxWidth and maxHeight should only be set as limit to how big the image should load.
For mobile viewports I generally set my function as follows, which ensures the colorbox never loads an image larger than 800px for larger screens. Smaller screens show the colorbox in a 90% width.
Code example below only using the width and maxWidth attributes:
$(document).ready(function(){
$(".popout").colorbox({rel:'popout', width:"90%", maxWidth:"800px"});
});
I hope this helps anyone still stumbling on this question.

Related

How to set height of WebView according to the length of content in Nativescript-Vue?

Update: I used HtmlView and yes, the height is dynamic with the content,
but it seems like not support <img />
I'm currently using WebView to render the markdown content as below
<WebView :src="marked_content" height="1200px" margin="20dp" />
The result is fixed at 1200px with scrollBar as expected, but what I actually want to do is to render the whole markdown content with various height and without scrollBar.
Anyone may help, please?
PS: Any other methods which may render markdown content is welcome! Thank you!
Do you have control over the website, if Yes you can do this
https://discourse.nativescript.org/t/dynamic-webview-height/4215/2?u=manojdcoder
I have worked out how to do this without plugins.
There is a solution above which appends the URL with a hash containing the page height. It didn't work for me because I'm adding HTML code directly.
For example
src="<p>blah blah</p>"
This is a plain JS solution, so you'll have to rework it to get it working in Vue / Typescript.
Give your WebView an id, do not set the height, and add the "loaded" and "loadFinished" handlers.
For the loaded handler.
platformModule = require("tns-core-modules/platform");
var webViewSrcObj = {};
exports.webViewLoaded = function(webargs){
if(platformModule.isAndroid){console.log("IS ANDROID!!!"); return false;}
webview = webargs.object;
if(webview.height == "auto"){
webViewSrcObj[webview.id] = webview.src;
webview.src += '<script>function getPageHeight(){if(document.documentElement.clientHeight>document.body.clientHeight){height = document.documentElement.clientHeight}else{height = document.body.clientHeight}; ph = document.getElementById("pageHeight"); window.location = "pageHeight.html?height="+height;} setTimeout(getPageHeight, 1);</script>';
}
}
It checks the platform, and returns false if it is Android (Android works fine already).
Then it checks if the height is set to "auto" (which is default).
if it is set to auto, it will copy the HTML content. I'll explain more about this later. It then appends the html with some JavaScript code that calculates the view height, and then redirects to an empty page. It does this in order to use the query string for the page height. Make sure that page exists in your app folder to avoid any page not found errors!
Then for the onLoadeFinished handler...
exports.webViewLoadFinished = function(webargs){
if(platformModule.isAndroid){
console.log("IS ANDROID!!!"); return false;
}
webview = webargs.object;
if(webargs.url.indexOf("?height") > -1){
height = (webargs.url).split("?height=");
height = height[1].substr(0, height[1].length)/1;
webview.height = height; webview.src = webViewSrcObj[webview.id];
}
}
This will check to see if the query string height value exists.
If so it uses the height value to set the height of the webview.
And finally it adds the HTML content that was copied in the onLoaded handler.
My initial testing works well even with multiple webviews in a page.
I haven’t done extensive testing, but it might help to increase the setTimeout time if you experience any problems.
If anyone is able to improve this solution, please share your results.

Positioning based on size of rendered component

I have a Vue component which generates a part of an SVG.
Since text handling in SVG is a pain, I decided to use a foreignObject tag inside it in order to let the HTML and CSS inside it handle the layout.
The template part basically looks like this:
<template>
<g class="port">
<foreignObject ref="html">
<div class="port__wrapper" ref="wrapper">
<div class="port__label">{{ label }}</div>
<div class="port__content">{{ content }}</div>
</div>
</foreignObject>
</g>
</template>
Everything works fine until I try to position the part, based on its computed size. The size of my foreignObject has to be set manually. In order to do that, I need the computed size of my port__wrapper element.
Here is my current approach:
export default {
methods: {
calculateAndSetSize() {
const frame = this.$refs.html;
const wrapper = this.$refs.wrapper;
frame.setAttribute('width', `${wrapper.clientWidth}px`);
frame.setAttribute('height', `${wrapper.clientHeight}px`);
}
},
created() {
window.setTimeout(() => {
this.calculateAndSetSize();
// also some positioning stuff
}, 0);
}
}
I use the created lifecycle hook to ensure the component is created and use the setTimeout to move the calculation to the end of the render queue.
This works fine when I just move around inside my app, but if I refresh the page it only works 5/6 of the time. The calculation seems to be done just before the final render.
An example from Safari (even though it happens in all browsers):
I captured this, while my system was super slow. This usually happens in a fraction of a second
Before the component is fully rendered, this part is visible:
The component takes up a little bit less than double the size of the end-result. The calculation and positioning have happened and everything is aligned as expected (right side and vertically centered to the cross in the middle).
Almost correct, but then there is the final paint, which looks like this:
As you can see the positioning is totally off, since the element is way smaller and the calculations already happened.
The foreignObject sill has the wrong size:
(the last screenshot is from another build and looks a little different, but the problem stays the same)
I figured the problem might be the font loading and tried the execute the calculations after the document.fonts.ready promise, but that is even less consistent than the setTimeout approach.
Any hint what could cause this and how to work around it would be greatly appreciated.

image as tooltip using dojo

I'm trying to display an image on mouseover of another image. I'm using dijit/Tooltip for that. Problem is, the image is not displaying on the first mouseover, it always appears on the second time onwards. The images are dynamically displayed and have given a dynamic id.
<c:forEach items="${model.images}" var="image" varStatus="status">
<img src="${image.url}" height="50" onmouseover="showImage('${image.id}')" id="image${image.id}" />
<c:forEach>
<script>
function showImage(name) {
require(["dijit/Tooltip", "dojo/domReady!"], function(Tooltip){
new Tooltip({
connectId: ["image"+name],
label: "<img src='/images/"+name+"'/>"
});
});
};
</script>
With dijit/Tooltip there is no need for an onmouseover function. With your code the first mouseover only sets up the Tooltip. The second time the Tooltip is attached and so it is displayed (and showImage() runs again, which isn't optimal).
You need to create the Tooltip when the image is added to the dom. You can refer to the dijit/Tooltip guide for an example on how to set up a Tooltip declaratively. Alternatively you can convert your code to add the images and their tooltips programmatically.

Dynamically setting max-height of Bootstrap modal body

I'm trying to dynamically set the max-height of Bootstraps modal-body elements for all modal dialog boxes. I've written the following, which seems to work when the dialog is opened. I'm depending on the enforceFocus method to exist and to be called once the dialog is rendered. I realize there may be moment before the CSS property is set where the dialog will not be rendered exactly right, but I'm okay with that. Is there anything wrong with this solution? I know I have yet to account for resizing the screen with a modal open, but that seems the easier problem to solve.
(function ($) {
$.fn.modal.Constructor.DEFAULTS.backdrop = 'static';
$.fn.modal.Constructor.DEFAULTS.keyword = false;
var oldEnforceFocus = $.fn.modal.Constructor.prototype.enforceFocus;
$.fn.modal.Constructor.prototype.enforceFocus = function () {
oldEnforceFocus.call(this);
var $element = this.$element;
var maxHeight =
$("body").height() // full page
- $element.find(".modal-header").outerHeight(true) // modal header
- $element.find(".modal-footer").outerHeight(true) // modal footer
- ($element.find(".modal-dialog").outerHeight(true) - $element.find(".modal-dialog").height()) // dialog margins
- 5; // fudge factor
$element.find(".modal-body").css("max-height", maxHeight);
}
})(jQuery);
Thanks!
edit: To give credit where credit is due, this is based on
Correct way to extend Bootstrap Modal - lock, unlock.
If you don't want to use javascript, you can use CSS media queries and get close-ish to the height you need by using min-height. For example, define a media query on min-height: 540px, and set the max-height of the modal to something like max-height: 500px. Then define a media query at say min-height: 680px and set the modal to max-height: 640px. It's not fluid, and it requires several media queries to inch up to the largest size you want to plan for, but it will get you there.
#Josh solution is good with CSS and media queries but writing so many media queries where small devices has different screen heights e.g Iphone and SamSung G and N series, required alot of media queries to even calculate close-ish modal height on different screen sizes.
so setting height of modal (modal-body) dynamically according to media screen size and on small devices where there will be 2 types of media screen landscape and portrait, following few lines of code will put you very close-ish to your goal
Rendering modal HTML according to screen size with-in sec and later if screen size changes adjust it's height according to screen size
$(document).ready(function () {
setInterval(Dimension, 100);
function Dimension() {
var doc = $(document).height(); // document height
var head = $(".modal-header").height(); // modal header height
var footer = $(".modal-footer").height(); // modal footer height
var modheight = doc - head - footer - 65; // 65 is extra margins and it will not effect the height of modal any way if not changed.
$('.modal-body').css('height', modheight);
}
});
Note
Few Changes required in Modal CSS
CSS
.modal-dialog {
margin: 0px auto !important;
}
.modal-body {
overflow-y: scroll; // In-case the content in modal-body overflow so it will have scrolling.
}
Fiddle
You can check the modal height adjust itself by increasing and decreasing the fiddle result window's height and width.

How to keep bootstrap carousel paused until it enters in the viewport?

EDIT: reason for this request. This edit has been added when the solution has been found for the sake of describing my needs. I had a Carousel that showed a logical sequence step 1, step 2, step 3.. That carousel is not a top of page, so I want it to stay stopped / paused until the user sees it and when it will see it, as first, I want the user to see the first slide, step 1. Nevertheless, some users (and they are not few, believe me) don't know about carousels and sliders, so I don't wanna miss their view on the subsequent slides. This is the reason for what follow.
I'm wondering about this
I have a bootstrap 3.1 carousel that is not at top of the home page.
Instead you "reach it" when scrolling down some "bootstrap' rows".
Well I'd like it to keep the carousel stopped / paused until the user will scroll the page down to where the carousel is placed (let's say the carousel height is 500 pixel, when at least the first top 150 pixels are entered in the viewable area)
when those 150 pixel have been scrolled in, the pause / stop should turn to "play" and so, if the pause between each slide is 5000 msec, after 5000 msec the next slide should turn.
According with this solution it is matter of javascript but it is not what I'm seeking for also excuse me but currently I'm not so strong with javascript and jquery, so thank you for any hint with some explanation.
EDIT 01
This script looks to be the correct and also a great solution :-), especially reading the comments at bottom of that page, but as stated above, I miss the knowledge to properly take advantage of it, thank you for any hint.
Here's a method using Intersection Observer API; it will fail silently for IE and other unsupported browsers.
setTimeout(function() {
if (IntersectionObserver === undefined) return;
const carousels = $(".carousel");
if (carousels.length === 0) return;
const RATIO = 0;
// You can set a intersection percentage, such as 0.25 for 25% visible, but
// if you want pixels, I'm using `rootMargin` in the options below
var observer = new IntersectionObserver(function (entries, observer) {
entries.forEach(function(entry) {
jQuery(entry.target).carousel(entry.intersectionRatio < RATIO ? 'pause' : 'cycle');
});
}, {
root: null,
rootMargin: '-150px 0px', // 150px visible on top or bottom of viewport
threshold: RATIO
});
carousels.each(function () {
observer.observe(this);
});
}
});
I went for the long path, self answered myself.
I've tried several plugins, but they were not effective or either they were breaking the Carousel engine.
Researching so much, finally I've landed on this jQuery plugin
http://www.jqueryscript.net/other/jQuery-Plugin-To-Determine-If-An-Element-Is-In-the-Viewport-Viewport-Checker.html
It works pretty fine, straight and as expected and there is a bonus included: the offset I was seeking for!!! (yeeeh!)
Pretty easy to implement
<script src="viewportchecker.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.carousel').carousel('pause'); /** load page with carousel paused
$('.carousel').viewportChecker({
offset: 200, /** wait for the first 200 pixel of the element
to enter in the viewport
callbackFunction: function(elem){
setTimeout(function(){
$('.carousel').carousel(''); /** remove pause
},500);
}
});
});
</script>
"thank you" to myself :-)
I suppose this would also help the problem when the viewport cuts the carousel in half. ie: With a carousel at the top of the page and you scroll down, forcing the top of browser window to show only the bottom half of carousel.
Currently, when the carousel cycles, the carousel images load to the top of the viewport, not the top of the carousel container.
When you scroll back up, the carousel only displays half the image and the top half is grey. This is very annoying. Will try this to see if it fixes.