I'm using Algolia instantsearch.js for search, and to display my result page, I'm using Bootstrap 3, and I'd like hits to be displayed in 3 columns:
qry | hit1 | hit2
| hit3 | hit4
| hit5 | hit6
(where qry = the search query input widget)
etc..
If it's mobile, it should display as:
qry
hit1
hit2
hit3
etc.
Can someone help me with the html/css I can use to implement this?
Thanks!
Basically, you want to use bootstrap rows and grid layout col-{xs,sm,md,lg}-X (More info about the grid layout here).
One interesting property with bootstrap is that if you declare a block as being col-YY-X, if the screen width is under the dimensions YY is associated with, it automatically expands to the full width.
instantsearch.js's widgets expose a cssClasses parameter that allows you to customize the classes of the underlying markup.
To easily do two columns, all you need to do is declare the root element of the cssClasses as being a .row, and each result as a .col-sm-6 (or .col-md-6 or .col-lg-6 depending on which screen size you want it to apply).
By combining them, you can have some really interesting layouts.
See this JSFiddle
Here, I've extended a bit the idea. Try to resize the view, and you'll see that it automatically picks a number of results to display per line depending on the width by combining multiple col-YY-X classes on the hit widget.
search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
templates: {
empty: 'No results',
item: '<div class="hit">{{title}}</div>'
},
hitsPerPage: 6,
cssClasses: {
root: 'row',
item: 'col-lg-3 col-md-4 col-sm-6'
}
})
);
As you can see, I've also added an inner class to the item template to be able to use the item as a wrapper with padding inside to avoid having the hits glued to each other. I apply the border to the inner element, because adding margins to bootstrap grid elements is not the right solution.
The layout itself is really simple, you can just nest rows together:
<div class="container-fluid">
<div id="search" class="row">
<div class="col-sm-4">
<div id="input"></div>
</div>
<div class="col-sm-8">
<div id="hits" class="row">
</div>
</div>
</div>
</div>
Related
vuehtml2pdf generating pdf but first page is blank only when my content is too much, it does break to second page but first page is left blank.
<client-only>
<vue-html2pdf
ref="html2pdf"
pdf-format="a4"
:show-layout="false"
:preview-modal="false"
:enable-download="false"
:manual-pagination="false"
#progress="onProgress($event)"
:pdf-quality="2"
:paginate-elements-by-height="10"
:filename="user.fullName + 'resume'"
#beforeDownload="beforeDownload($event)"
:html-to-pdf-options="{
filename: user.fullName + ' Resume',
jsPDF: {
format: 'a4',
unit: 'mm'
},
html2canvas: {
useCORS: true,
dpi: 192,
letterRendering: true,
scale: 4, // resolution
},
}">
<section slot="pdf-content">
<section>
<component :is="resumeComponent"></component>
</section>
</section>
</vue-html2pdf>
this is my code and my component is dynamic and it might have many pages of data or maybe one page. but when the data is too much an empty page is generated at first.
You have a very low value of paginate-elements-by-height
That number is in pixels.
Try 1000, instead of 10.
When that value is very low, it creates the behaviour you see:
It seems to eject one blank page, and then put one item on each subsequent page, with no limit on the size of that item (i.e. it doesn't break items).
Most likely its algorithm is:
For each item:
Does that item fit onto the current page without exceeding the paginate-elements-by-height?
If so, add it.
If not, eject page, and add it to the next page, irrespective of whether it is within the limit of paginate-elements-by-height.
(I suppose this is necessary, because if it applied that limit on the next page, then an outsize item would cause an infinite number of pages to be ejected.)
I think your code design puts all your elements inside a single super-element
That explains why it always ejects a page at the beginning. vue-html2pdf is not receiving a series of elements, but a single giant element:
<section slot="pdf-content">
<section>
<component :is="resumeComponent"></component>
</section>
</section>
Instead of putting all your individual elements inside , I suggest breaking it up into individual entries inside the <vue-html2pdf> tag.
That would allow the pagination function to work correctly.
<vue-html2pdf ....>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
<div>Item 4</div>
</vue-html2pdf>
Make sure each of the items that are direct children of <vue-html2pdf> has only a reasonable vertical height: no larger than the screen size.
If this works for you, remember to mark the answer as correct!
I'm trying to configure a nice footer on a pdf document I'm generating using Flying Saucer.
But I'm having problems getting the page number and page count in a nice position.
Consider this bit of css:
div#page-footer {
position : running(footer);
// .. more styling .. //
}
div.page-number:before {
content: counter(page);
}
Using this bit of html will not give me a page number:
<div id="page-footer">
<div class="page-number"></div>
</div>
The only way I manage to get a page number if I move the class a level up.
<div id="page-footer" class="page-number">
</div>
But this does not allow me to add additional content in the footer or makes it really difficult to apply styling. I could add a separate footer just for the page number, but it would be quite hard to get the position just right.
Is there a way to get page number + page count in a footer that also contains other elements and styling?
Extra notes:
I simplified the footer a bit, in the original there is more in there, but even this simple example it is giving problems.
using span or div for the element does not make a difference.
You should use the id instead of the class to identify the div containing the page number.
This will work:
div#page-number:before {
content: counter(page);
}
<div id="page-footer">
<div id="page-number"></div>
</div>
I am trying to have fields arranged in 2 columns within a horizontal form, but I cannot add a col-md-6 class to a form-group element.
The form should like something like this Fiddle.
I have checked the source code, and column size classes are explicitly removed from the form-group and applied to a new contained div element.
The net result is that the inner control is resized properly, but, as the form-group is still considered a 12 units sized element, the next control is placed in a different line.
I was able to achieve the layout I wanted using:
#Html.Bootstrap().Div().AddCss( Css.ColMd6 )
.AddChild( form.Input( "divChild", "Div Child" ) )
or
#Html.Bootstrap().Div().AddCss( Css.ColMd6 )
.AddContent( form.Input( "divContent", "Div Content" ) )
or
using (Html.Bootstrap().Div().AddCss( Css.ColMd6).Begin() )
{
#form.Input( "divusing", "Div Using" )
}
or
<div class="#Css.ColMd6" >
#form.Input( "htmldiv", "HTML Div" )
</div>
but I'd like a cleaner syntax like the following:
#form.Input( "name", "label" ).AddGroupCss( Css.ColMd6 )
but this would require adding a new extension AND not removing col sizing classes from form-group elements. Would this be possible?
Alternatively, can you suggest any other ways to get a multi columns layout in FluentBootstrap?
Wanted to use this 'item' example:
http://codepen.io/dimsemenov/pen/sHoxp
but instead of having one button, I'd like to have multiple buttons for each inline element (like a gallery).
For example, How would I create a second button that would open data array item 2 (paul irish)? Is there a way to specify from the button link? thanks!
I had to do something similar and had no idea how to do it so hopefully this helps someone later.
All my modals were inline but I also needed a list for each item on the page so you could click on the link and it would open at Item 2 or 3 etc..but still allow you to navigate through the gallery. I based my code off this http://codepen.io/dimsemenov/pen/zvLny and added the additional parts for the id's.
Basically you just have to put a data attribute e.g data-slideid on the individual links and pass that through when you open magnific. After you set everything you can specify which item it opens at by passing through the value from data-slideid. If anyone has a better solution i'd love to know!
Check out my below
<div id="gallery1" class="mfp-hide">
<div class="slide" data-slideid="0">slide 1</div>
<div class="slide" data-slideid="1">slide 2</div>
<div class="slide" data-slideid="2">slide 3</div>
</div>
// single link opens gallery starting at first slide
<p>view gallery</p>
// individual links opens gallery starting at relevant slide
Slide1
Slide2
Slide3
$('.open-gallery-link').click(function() {
var itemNum = $(this).data("slideid"); // get the id
var items = [];
$( $(this).attr('href') ).find('.slide').each(function() {
items.push( {
src: $(this)
} );
});
$.magnificPopup.open({
items:items,
gallery: {
enabled: true
}
},itemNum); // set it in here
});
I have, essentially, an unlimited number of containers with dynamic ids and a dynamic menu to load each containers content. I have done this with static id's (but still seems such a heavy use) but do not know where to go to use dynamic.
When a nav link (from .img_select) is clicked it shows the corresponding div and hides all others in the group. It also updates the class of the menu items so the clicked item becomes selected, and the remaining become unselected.
<div id="pf1_1">
My content for pf1_1 container goes here
</div>
<div id="pf1_2">
My content for pf1_2 container goes here
</div>
<!-- This could have a dozen+ or more divs, or only 1 //-->
<p class="img_select"><span class="pf_current" id="pfc1_1">1-1</span> <span class="pf_next" id="pfc1_2">1-2</span></p>
<div id="pf2_1">
My content for pf2_1 container goes here
</div>
<div id="pf2_2">
My content for pf2_2 container goes here
</div>
<div id="pf2_3">
My content for pf2_3 container goes here
</div>
<!-- This could have a dozen+ or more divs or only 1 //-->
<p class="img_select"><span class="pf_current" id="pfc2_1">2-1</span> <span class="pf_next" id="pfc2_2">2-2</span> <span class="pf_next" id="pfc2_3">2-3</span></p>
the jquery I would like to create dynamically something similar to this
<script>
$(document).ready(function(){
$("#pf1_2").hide();
$("#pf2_2").hide();
$("#pf2_3").hide();
$('#pfc1_1').click(function(){
$("#pf1_2").hide('fast');
$("#pf1_1").show('fast');
$("#pfc1_1").removeClass("pf_next").addClass("pf_current");
$("#pfc1_2").removeClass("pf_current").addClass("pf_next");
});
$('#pfc1_2').click(function(){
$("#pf1_1").hide('fast');
$("#pf1_2").show('fast');
$("#pfc1_2").removeClass("pf_next").addClass("pf_current");
$("#pfc1_1").removeClass("pf_current").addClass("pf_next");
});
$('#pfc2_1').click(function(){
$("#pf2_2").hide('fast');
$("#pf2_3").hide('fast');
$("#pf2_1").show('fast');
$("#pfc2_1").removeClass("pf_next").addClass("pf_current");
$("#pfc2_2").removeClass("pf_current").addClass("pf_next");
$("#pfc2_3").removeClass("pf_current").addClass("pf_next");
});
$('#pfc2_2').click(function(){
$("#pf2_1").hide('fast');
$("#pf2_3").hide('fast');
$("#pf2_2").show('fast');
$("#pfc2_2").removeClass("pf_next").addClass("pf_current");
$("#pfc2_1").removeClass("pf_current").addClass("pf_next");
$("#pfc2_3").removeClass("pf_current").addClass("pf_next");
});
$('#pfc2_3').click(function(){
$("#pf2_2").hide('fast');
$("#pf2_1").hide('fast');
$("#pf2_3").show('fast');
$("#pfc2_3").removeClass("pf_next").addClass("pf_current");
$("#pfc2_2").removeClass("pf_current").addClass("pf_next");
$("#pfc2_1").removeClass("pf_current").addClass("pf_next");
});
});
</script>
If you can point me in the right direction, be much appreciated, thank you.
Seeing as I found a way, not saying was right way, but it worked, I wanted to share it with you.
I would like to point out it didn't take 2 months to sort a solution, just 2 months to post it here.
To combat this;
$("#pf1_2").hide();
$("#pf2_2").hide();
$("#pf2_3").hide();
I used this;
$("div[id^=pf_]").hide();
$("div[id$=_1]").show();
first it hides all id's starting with pf_
then it shows only the first by matching id ending in _1
To combat this;
$('#pfc1_1').click(function(){
$("#pf1_2").hide('fast');
$("#pf1_1").show('fast');
$("#pfc1_1").removeClass("pf_next").addClass("pf_current");
$("#pfc1_2").removeClass("pf_current").addClass("pf_next");
});
// etc.....
I used this;
$('span[id^=pfc_]').live("click", function(e) {
e.preventDefault();
var id = $(this).attr('id').split('_');
var classname = $(this).attr('class');
var navwidth = $("div[id^=pf_"+id[1]+"_"+id[2]+"]").width();
if(classname != 'pf_current'){
$("span[id^=pfc_"+id[1]+"_]").removeClass("pf_current").addClass("pf_next");
$("span[id^=pfc_"+id[1]+"_"+id[2]+"]").removeClass("pf_next").addClass("pf_current");
// change portfolio item
$("div[id^=pf_"+id[1]+"_]").hide();
$("div[id^=pf_"+id[1]+"_"+id[2]+"]").delay('5').show();
}
});
Hope this helps someone else