Bootstrap on mobile: two column on horizontal view - mobile

is there a way on bootstrap, in mobile view, to have one column listing on vertical view and, on phone rotation, two column on horizontal view, using the usual col-xs-xx methodology?
I'm not able to find a way.
Thank you.

The column breakpoints are based on your device viewport in pixels. You could modify this breakpoints with bootstraps generator, less, scss or harder with hacking the bootstrap core css. You could also generate additional breakpoints with less/scss.
You could also do some magic with jquery "on orientationchange" and toggle some classes when viewport width is greater as viewport height. ;)

Thanks to cakebake suggestion, this is a working example
https://jsfiddle.net/mud16c60/
<div class="container">
<div class="row" id="extra">
<div id="switch1" class="col-xs-12">
left
</div>
<div id="switch2" class="col-xs-12">
right
</div>
</div>
</div>
<div id="orientation"></div>
$(window).on("orientationchange",function(event){
$( "#orientation" ).text( "This device is in " + event.orientation + " mode!" );
if(event.orientation=="landscape")
{
$("#extra [id^='switch']").removeClass( "col-xs-12" );
$("#extra [id^='switch']").addClass( "col-xs-6" );
}
else if(event.orientation=="portrait")
{
$("#extra [id^='switch']").removeClass( "col-xs-6" );
$("#extra [id^='switch']").addClass( "col-xs-12" );
}
});
$( window ).orientationchange();

By default Bootrap has this configuration:
< 768px = -xs- prefix
>= 768px = -sm- prefix
>= 992px = -md- prefix
>= 1200px = -lg- prefix
Using this standards, Bootstrap considers mobile portrait and landscape both as -xs- devices.
You could override (using less or sass/scss) this variables:
#screen-sm-min
#screen-md-min
#screen-lg-min
to achieve what you are looking.
For example you could change #screen-sm-min to 480px to target vertical device with -xs- prefix and horizontal device with -sm- prefix.
Mind you that in this way you lose the possibility to target portrait tablet.

Related

Leaflet map not properly displayed in ionic react app [duplicate]

I am using tabs to display clear content, but one of them stopped downloading well since it is in the data-toggle tab. It is a Leaflet map.
Here is the code :
Navbar code :
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#home">Données principales</a></li>
<li><a data-toggle="tab" href="#carte">Carte</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">Lorem ipsum</div>
<div id="carte" class="tab-pane fade"> **//see script below\\** </div>
</div>
Script :
<div id="carteBenef"></div>
<script type="text/javascript">
$(document).ready(function () {
var map = new L.Map('carteBenef');
var cloudmadeUrl = 'http://{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png',
subDomains = ['otile1', 'otile2', 'otile3', 'otile4'],
cloudmadeAttrib = 'Data, imagery and map information provided by MapQuest, OpenStreetMap and contributors, CC-BY-SA';
var cloudmade = new L.TileLayer(cloudmadeUrl, {maxZoom: 18, attribution: cloudmadeAttrib, subdomains: subDomains});
var iades = new L.LatLng(<?php echo $beneficiaire->latitude . ', ' . $beneficiaire->longitude; ?>)
map.addLayer(cloudmade).setView(iades, 15);
var benefLocation = new L.LatLng(<?php echo $beneficiaire->latitude . ', ' . $beneficiaire->longitude; ?>);
var benef = new L.Marker(benefLocation);
map.addLayer(benef);
benef.bindPopup("<?php echo htmlspecialchars($beneficiaire->nom) . ' ' . htmlspecialchars($beneficiaire->prenom); ?>").openPopup();
});
</script>
The map was appearing well before I put it in the tab, does someone have an idea why it does not work now? Thank you =)
Welcome to SO!
If your Leaflet map suddenly works correctly after you resize your browser window, then you experience the classic "map container size not valid at map initialization": in order to work correctly, Leaflet reads the map container size when you initialize the map (L.map("mapContainerId")).
If your application hides that container (typically through CSS display: none;, or some framework tab / modal / whatever…) or later changes its dimensions, Leaflet will not be aware of the new size. Hence it will not render correctly. Typically, it downloads tiles only for the fraction of the container it thinks is shown. This can be a single tile in the top left corner in the case of a container that was entirely hidden at map initialization time.
This mistake often arises when embedding the map container in a "tab" or "modal" panel, possibly using popular frameworks (Bootstrap, Angular, Ionic, etc.).
Leaflet listens to browser window resize event, and reads again the container size when it happens. This explains why the map suddenly works on window resizing.
You can also manually trigger this update by calling map.invalidateSize() when the tab panel is displayed (e.g. add a listener on the tab button click), at least the first time the container is rendered with its correct dimensions.
As for implementing the tab button click listener, perform a new search on SO on that topic: you should have plenty resources available for that matter, for most of the popular frameworks.
First, thank you #ghybs for your good explanation on why the Leaflet maps are not shown properly in these cases.
For those who tried unsuccessfully the #ghybs's answer, you should try to resize your browser instead of calling a method of the map object :
window.dispatchEvent(new Event('resize'));
As #MarsAndBack said, this fix may cause issues on pan/animation/etc features that Leaflet's invalidateSize provides.
I have this problem because i used modal bootstarp. and it not solved anyway. i tried map.invalidateSize() and window.dispatchEvent(new Event('resize')); but not fixed.
finaly it fixed by this:
$('#map-modal').on('shown.bs.modal', function(event) {});
'shown.bs.modal' event means when modal is completely load and not any confuse on size, now inside that write your codes.
For those like me weren't able to solve the challenge with the precious #ghybs explanation (map.invalidateSize()) and were able to do it with #gangai-johann one, there's still a chance you may do it the right way. Put your invalidate instruction inside a setTimeout, as it may be too early to dispatch that instruction.
setTimeout(() => {
this.$refs.mymap.mapObject.invalidateSize()
}, 100)
Refer to https://stackoverflow.com/a/56364130/4537054 answer for detailed instructions.

Angularjs material one row with 2 columns

i am trying to achieve that, and can't figure how:
|-------------80%---------------------|----20%---|
one row with 2 columns with specific width.
i don't understand something, columns (usage in Material) are look to me like rows > in rows
|-------------------------------------|----//---|
|-------------------------------------|----//---|
|-------------------------------------|----//---|
and not like my example.
How can i achieve it?
After you have imported AngularJS and Angular Material (including the css file), you need to import Angular Material in your AngularJS app. To do this, you need to add the "ngMaterial" provider in your AngularJS module, like this:
var app = angular.module("myApp", ["ngMaterial"]);
(if you skip this part, it won't work).
Then you can write your HTML code as follows
<div layout="row" layout-wrap>
<div flex="80">80%</div>
<div flex="20">20%</div>
</div>
This will create a div that will act as a container. It will contain the elements you want to show and they will be aligned in a row and, if necessary, they will be displayed in a second row. In the flex property you can specify the width (as a percentage) of the element compared to the width of the container.
Obviously you can change the name of your Angular module and the number/ width of your html elements as you want.
And there you can see some examples and a bit of documentation
First you need to declare:
md-cols Number of columns in the grid.
In your case (8+2=10):
<md-grid-list md-cols="10" ...
Then your items:
<md-grid-tile md-colspan="8">...</md-grid-tile>
<md-grid-tile md-colspan="2">...</md-grid-tile>
Codepen Sample - Angular Material Docs

Is there a way to create a dialog in material design lite?

I have created dialogs using Angular Material, but so far haven't found a way to create one using Material Design Lite. Is there a workaround for it?
MDL has support for styling HTML5 dialogs but does not include any polyfills for them. So you must have a browser that supports them (like Chromium). Else use a polyfill like https://github.com/GoogleChrome/dialog-polyfill as pointed out by #manuel-84
<dialog id="dialog" class="mdl-dialog">
<h4 class="mdl-dialog__title">Hello User</h4>
<div class="mdl-dialog__content">
<p>Hello world from dialog!<p>
</div>
<div class="mdl-dialog__actions">
<button type="button" class="mdl-button close">Disagree</button>
</div>
</dialog>
And using a button somewhere call
document.getElementById('dialog').showModal();
See Material Design Lite Components : Dialogs
I'm just a user of MDL, not an insider. But, as I understand it, Dialog support isn't there, but it's being worked on. Tagged for V1.1, but no idea what the schedule for that might be.
https://github.com/google/material-design-lite/pull/1762
Not a dialog per se, but what I am doing in one project is to have a form slide down, using jQuery you get some nice animation
Basically define the form in a card, set the height to zero and opacity to 0. Then execute the following script to reveal the dialog
$('#objects_card_holder').animate({
height: 400
},500,function(){
$('#objects_card_holder').animate({
opacity: 1
},100,function(){
$('#projectName').val('');
});
});
Then when the form is not required run another script to hide it.
$('#objects_card_holder').animate({
opacity:0
},
100,
function(){
$('#objects_card_holder').animate({
height:0
},
500,
function(){
});
});
Assuming that your card has the id objects_card_holder
Of course if you really need a dialog jQuery has it's own dialog.
see https://jqueryui.com/dialog/

how to crop-area with different height/width size? with ngImgCrop

I'm trying to crop not same height/width crop-area can I use rectangle crop-area.
<div>Select an image file: <input type="file" id="fileInput" /></div>
<div class="cropArea">
<img-crop image="myImage" result-image="myCroppedImage" area-type="square" area-min-size="20" result-image-size="150"></img-crop>
</div>
<div>Cropped Image:</div>
<div><img ng-src="{{myCroppedImage}}" /></div>
I need set height/width like area-min-size="{100, 150}" result-image-size="{100, 150}"
As far as I can see - it is not possible, as it involves a more complex manipulation of the selector area (e.g., it will need to resize in two dimensions independently).
There is an alternative however. Though it might be not as much of an eye candy as ngImgCrop, but it achieves what you need. [ http://grab.by/Cbpq ]
It is called: angular-image-crop.
Here is a JSBin sample.
You may need to play around with the following parameters data-width="", data-height="", dat-shape="square" before the result is satisfying:
<image-crop
data-width="500"
data-height="300"
data-shape="square"
data-step="imageCropStep"
data-result="imageCropResult"
ng-show="showImageCropper"
></image-crop>
#Bilegsaikhan, I found a modified version of ngImgCrop which supports rectangular crop as well as a fixed aspect ratio. Here I created a JsFiddle.
One could fiddle with the result-image-size="400" parameter to tailor the intermediate/resulting image size (this parameter defines the canvas size of an intermediate step). For the size of the final img, normal height and width of the image node can be changed.
Enjoy :)
have you tried this library https://github.com/vogloblinsky/ngImgCropExtended ? It probably extends the feature from ngImgCrop and supports area type like circle, square and rectangle

Fluid like box?

I'm making a responsive site and need to include a Facebook Like-Box for the client's Facebook fanpage. The developer page for the like-box has a widget for customization, but it doesn't allow you to set a width in percentages.
I've searched around and the closest I've got was this page from 2010, which refers to a fb:fan widget that allows you to link custom CSS. I tried to get this tutorial to work but it fails with this error:
<fb:fan> requires one of the "id" or "name" attributes.
So, to recap, I need a Facebook Like Box that I can either set up to be fluid, or which allows me to pass custom CSS to the iFrame it generates. Anyone able to point me in the right direction?
I found this Gist today and it works perfectly: https://gist.github.com/2571173
/* Make the Facebook Like box responsive (fluid width)
https://developers.facebook.com/docs/reference/plugins/like-box/ */
/* This element holds injected scripts inside iframes that in
some cases may stretch layouts. So, we're just hiding it. */
#fb-root {
display: none;
}
/* To fill the container and nothing else */
.fb_iframe_widget, .fb_iframe_widget span, .fb_iframe_widget span iframe[style] {
width: 100% !important;
}
You thought it couldn't be done? AHA! Have at you, Facebook and your wicked fixed-width ways: I wrote a JQuery script to undo all your evil!
$(document).ready(function(){
var fbWidth;
function attachFluidLikeBox(){
// the FBML markup: WIDTH is a placeholder where we'll insert our calculated width
var fbml = '<fb:like-box href="http://www.facebook.com/YOURFANPAGEORWHATEVS" width="WIDTH" show_faces="false" stream="true"></fb:like-box>';//$('#likeBoxTemplate').text().toString();
// the containing element in which the Likebox resides
var container = $('#likebox');
// we should only redraw if the width of the container has changed
if(fbWidth != container.width()){
container.empty(); // we remove any previously generated markup
fbWidth = container.width(); // store the width for later comparison
fbml = fbml.split('WIDTH').join(fbWidth.toString()); // insert correct width in pixels
container.html(fbml); // insert the FBML inside the container
try{
FB.XFBML.parse(); // parses all FBML in the DOM.
}catch(err){
// should Facebook's API crap out - wouldn't be the first time
}
}
}
var resizeTimeout;
// Resize event handler
function onResize(){
if(resizeTimeout){
clearTimeout(resizeTimeout);
}
resizeTimeout = setTimeout(attachFluidLikeBox, 200); // performance: we don't want to redraw/recalculate as the user is dragging the window
}
// Resize listener
$(window).resize(onResize);
// first time we trigger the event manually
onResize();
});
What is does is it adds a listener to the window's resize event. When it resizes, we check the width of the Likebox' containing element, generates new XFBML code with the correct width, replaces the containing element's children with said XFBML and then trigger the Facebook API to parse the XFBML again. I added some timeouts and checks to make sure it doesn't do anything stupid and only runs when it needs to.
Much has changed since the OP.
By simply choosing iFrame and setting your width to 100%, your FB Like Box should be responsive.
Basically FB adds this to the iFrame:
style="border:none; overflow:hidden; width:100%; height:300px;".
Been struggling with the exact same problem. A quick & simple solution is to use the iframe based Facebook Like box.
<iframe class="fb-like-box" src="//www.facebook.com/plugins/likebox.php?href=http%3A%2F%2Fwww.facebook.com%2Fplatform&width=292&height=500&colorscheme=light&show_faces=true&border_color&stream=true&header=true" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
Note the assigned 'fb-like-box' class and all the removed inline styles. The class for the iframe could look something like this:
.fb-like-box {
width: 100% !important;
height:500px;
border:none;
overflow:hidden;
}
Looks like it doesn't matter what the height and width are that are defined in the iframe's src tag. Just place the iframe into some fluid element like a cell in a CSS grid layout.
(includes ideas from: http://updateox.com/web-design/make-facebook-comment-and-like-box-fluid-width/)
I used the HTML5 version of Facebook Like Box and here is what worked for me:
.fb-like-box,
.fb_iframe_widget span,
.fb_iframe_widget iframe {
width:100% !important;
}
You cannot set the like-box to anything other than a pixel width. My suggestion is to place it in a DIV or SPAN that is fluid with overflow set to hidden. Sure, it's going to crop off part of the like-box, but by having the requirement of fluid, this is your best bet.
Here's a small work around that appends the HTML5 Facebook LikeBox Plugin into the DOM with a response height or width.
$(document).ready(function(){
var height = $(window).height();
var width = $(window).width();
var widget_height = parseInt((height)*0.9);
var widget_width = parseInt((height)*0.3);
var page_url = "http://www.facebook.com/Facebook";
$(".fb-plugin").append("<div class='fb-like-box'
data-href='"+page_url+"'
data-width='"+widget_width+"'
data-height='"+widget_height+"'
data-colorscheme='dark'
data-show-faces='true'
data-border-color='#222'
data-stream='true'
data-header='true'>
</div></div>");
});
The comment above from Ed and Matthias about using 100% for the iframe worked great for me. Here is my iframe code
ORIGINAL WITHOUT FIX:
<iframe src="//www.facebook.com/plugins/likebox.php?
href=https%3A%2F%2Fwww.facebook.com%2FXXXXXXXXXX&
width&height=290&colorscheme=dark&
show_faces=true&header=true&stream=false&
show_border=true&appId=XXXXXXXXXX"
scrolling="no" frameborder="0"
style="border:none; overflow:hidden; height:290px;"
allowTransparency="true"></iframe>
UPDATED WITH 100% FIX:
<iframe src="//www.facebook.com/plugins/likebox.php?
href=https%3A%2F%2Fwww.facebook.com%2FXXXXXXXXXX&
width&height=290&colorscheme=dark&
show_faces=true&header=true&stream=false&
show_border=true&appId=XXXXXXXXXX"
scrolling="no" frameborder="0"
style="border:none; overflow:hidden; height:290px;width:100%"
allowTransparency="true"></iframe>
The only change is adding "width:100%" to the style attribute of the iframe
note that the code above has "XXXXXXXXXX" in place of the unique references

Resources