Mustache flat array into nested elements - javascript

I'm isolating the problem and creating a simple case in here. It's basically an Image Accordion (CSS3 animation based) and in order to use this plugin my HTML structure has to be nested as shown below. In their samples the HTML was hardcoded - I need to use JSON data to generate the output.
Suppose an object like this,
[{imageurl:"link1"}, {imageurl: "link2"}, {imageurl: "link3"}]
I want the output to be
<figure>
<img src="link1" />
<figure>
<img src="link2" />
<figure>
<img src="link3 />
</figure>
</figure>
</figure>
I'm trying to think what kind of template can help to achieve this?

Because the Mustache language is "logic-less", views that require logic or complex nesting may need to be broken up into different views and included via partials or created outside of Mustache and then reinserted.
Anyhow, one way to produce the view that you desire is by reversing the array and working inside-out to nest the figures (jsfiddle):
<!-- If your desired output is so:
<figure>
<img src="link1">
<figure>
<img src="link2">
<figure>
<img src="link3">
</figure>
</figure>
</figure>
-->
<script id="entriesTemplate" type="text/x-mustache-template">
<figure>
<img src="{{{imageurl}}}">
{{{figure}}}
</figure>
</script>
You can then nest the above template via a small snippet of JS:
var figs = [
{url: "http://placehold.it/10x10"},
{url: "http://placehold.it/10x10"},
{url: "http://placehold.it/10x10"}
];
var ft = document.querySelector('#entriesTemplate').innerText.trim();
Mustache.parse(ft);
console.log(
figs.slice(0) // Make a copy of the array as the next call to `.reverse()` will work in situ
.reverse()
.reduce(function (previous, current, index, array) {
return fig = Mustache.render(ft, {
imageurl: current.url,
figure: previous
});
}, undefined)
);
When you pass undefined into the first template render, Mustache will produce no nested figure. Each subsequent render you are passing the output from the past to the outer figure etc. Instead of logging the value, you can then insert the chunk of HTML as need.

Related

How to put more than one image into an observable notebook cell?

I have several images attached to an observable notebook. I'd like to show them all in a cell because the user can toggle through them with a dropdown select. Using an HTML cell, I have:
<style>
figure.small-example-img {
width: 20%;
height: 100px;
display: inline-block;
}
</style>
<figure class="small-example-img">
<img src=`${await FileAttachment('Side.PNG').url()}` />
<figcaption>Side: method one</figcaption>
</figure>
<figure class="small-example-img">
<img src=`${img_urls.houseurl}` />
<figcaption>house: method 2</figcaption>
</figure>
...and so on
In the first, I call the img url explicitly, and in the second I make a variable earlier to hold it. Both ways I end up with:
<figure class="small-example-img">
<img src="\`https://static.observableusercontent.com/files/24_rest_of_url_7a9\`">
<figcaption>Side</figcaption>
</figure>
If I put the URL directly into the src then it works fine.
What is the correct way to template this url into the html?
I suspect it has something to do with strange interpretation of the backticks?
There's an example file for this topic here but it doesn't have an image example
Observable does seem to treat backticks as a special thing. If you take them out it seems to work just fine.
<figure class="small-example-img">
<img src="${await FileAttachment('Side.PNG').url()}" />
<figcaption>Side: method one</figcaption>
</figure>
This is one of those it works, but I don't know why answers, so if anyone knows the details, I'd love to know too!

React dynamic mapping image paths from json

I have a list of captions displayed from json. I would like to also map the location to local images / or urls in that same json data. So that each iteration of displayed item has its own images included.
The problem is with require js which seems to be working only when im passing into it actual string with location of image. If im trying to pass a reference to node in json that holds the location of that image it does not work.
note: some html tags are from materialize.
Does work:
const imgPath= require("../images/img1.jpg");
<img src={ imgPath } alt=""/>
Does not work:
const imgPath= require({row.img});
<img src={ imgPath } alt=""/>
{row.img} is key from json. Is there any way to map image locations like that in json and then use it to display it dynamicly rather than map entire list in static way?
{
"title":"title caption",
"note":"Lorem ipsum dolor sit amet....",
"img":"../images/img1.jpg",
"iconType":""
}
rendered component: this is how i would like it to work:
render() {
let rows = dataJson.map(function(row){
return <CollapsibleItem header={row.title} icon={row.iconType}>
<div>{row.note}</div>
<img src={ row.img } alt=""/>
</CollapsibleItem>
})
return (
<div className="container">
<div>
<Collapsible>
{rows}
</Collapsible>
</div>
</div>
);
}
If i import image to the component in static way it does work as well:
import img01 from "../images/img1.jpg";
and replace {row.img} with {img01}
<img src={ img01 } alt=""/>
is it possible? i found some examples of importing bunch of images from directory using webpack, but here the difference is that i want to have the paths to images mapped inside of my json, so that i can add images into specific list's item accordingly.
Thank You for any thoughts.

How to preload an image using jQuery

Hi I have a project in which one of the pages has a gallery. Something like that:
<div id="gallery" class="sections">
<img src="Images/Image1.jpg" class="thumbnails">
<img src="Images/Image2.jpg" class="thumbnails">
<img src="Images/Image3.jpg" class="thumbnails">
etc...
</div>
I would like to preload these images so that when you access the gallery page they are already loaded. I know you can do this by using javascript. Something along the lines of:
var myImage = new Image();
myImage1.src = "Images/Image1.jpg";
etc...
What I am unsure about is the next step. Do I remove the src from the html and add an id, like so:
<div id="gallery" class="sections">
<img id="image1" class="thumbnails">
<img id="image2" class="thumbnails">
<img id="image3" class="thumbnails">
etc...
</div>
and then do something like that:
$('#image1').append(myImage1);
This hasn't worked... I have also tried:
$('#image1').attr('src','Images/Image1.jpg');
And that hasn't worked either.
I have had a look around and there are plenty of tutorials about how to make a function that preloads your images etc... but I am not quite there yet. I just would like to know how to do it on a one by one basis for now and then maybe create a function. Thanks.
They are many function to do that
Images are loaded in the DOM when the page is open, but not visibles. Then, when you want show them (On click, on a slider, ...), no load time !
function preload(arrayOfImages) {
$(arrayOfImages).each(function(){
$('<img/>')[0].src = this;
// Alternatively you could use:
// (new Image()).src = this;
});
}
// Use your function with all your image path
preload([
'img/imageName.jpg',
'img/anotherOne.jpg',
'img/blahblahblah.jpg'
]);

Jquery get index of same type

I'm wondering how to get the index of a figure tag inside a particular wrapper relative to that wrapper. I've prepared an exemple here: http://jsfiddle.net/vhyfwbjm/ (or see below)
The wrapper #wrapper contains three figure tags differently nested. I would like to get the index() relative to #wrapper.
Any ideas ?
<div id="wrapper">
<p>
<figure>
<img src="#" />
</figure>
<div class="another-wrapper">
<figure>
<img src="#" />
</figure>
<div class="another-wrapper">
<figure>
<img src="#" />
</figure>
</div>
</div>
</p>
</div>
You can simply ask for the index inside #wrapper:
$('figure').on('click', function() {
console.log( $('#wrapper').find('figure').index( this ) );
});
You select the collection of elements you want to look through (.find('figure')) then ask for the index of a specific element (this refers to the clicked figure, here).
You can also pass in another jQuery selector as your index-element:
<figure id="myFigure"></figure>
...
console.log( $('#wrapper').find('figure').index( $('#myFigure') ) );
Try this : Find all the figure tag inside wrapper and iterate them.
$(function(){
$('#wrapper').find('figure').each(function(index){
alert(index);
});
});
Demo
You can use .index() with parameter. Read here
$("figure").click(function(){
var figureElements=$("#wrapper").find("figure");
alert(figureElements.index(this));
});
Demo

jQuery inside each loop meteor not works

i everyone,
i have a problem that has already happened to me in another case, but I present this hoping that we can solve it:
The jquery (called on "rendered") works well when it is not generated by eachloop ... why not work in generated html?
i click on an image generated by eachloop and nothing happens
gallery.html
{{#each gallery}}
<div class="superbox-list">
<img src="images/superbox/superbox-thumb-1.jpg" data-img="images/superbox/superbox-full-1.jpg" alt="My first photoshop layer mask on a high end PSD template theme" title="Miller Cine" class="superbox-img">
</div>
{{/each}}
<div class="superbox-list">
<img src="images/superbox/superbox-thumb-1.jpg" data-img="images/superbox/superbox-full-1.jpg" alt="My first photoshop layer mask on a high end PSD template theme" title="Miller Cine" class="superbox-img">
</div>
<div class="superbox-list">
<img src="images/superbox/superbox-thumb-2.jpg" data-img="images/superbox/superbox-full-2.jpg" alt="My first photoshop layer mask on a high end PSD template theme" title="Bridge of Edgen" class="superbox-img">
</div>
gallery.js
Template.gallery.rendered = function(){
$('.superbox').SuperBox();
}
Template.gallery.helpers({
gallery: function(){
return Gallery.find();
}
});
Example,
Image 1 Image 2
best regards,
ty
EDIT:
I used this way and it worked, although not find the method defer in meteor docs!
_.defer(function () {
$('.superbox').SuperBox();
});
I used this way and it worked, although not find the method defer in meteor docs!
_.defer(function () {
$('.superbox').SuperBox();
});
Your issue is probably that the data isn't there when your gallery is first rendered. You can fix that by waiting on the subscription using iron-router's waitOn (if you're using iron-router) but that only solves the problem of the documents that are in the database on page load. Any new documents wouldn't be "superBox'd" either. So the way around that is to have a specific template for each Gallery row.
Your each becomes:
{{#each gallery}}
{{> galley_row }}
{{/each}}
You add a new template:
<template name="gallery_row">
<div class="superbox-list">
<img src="images/superbox/superbox-thumb-1.jpg" data-img="images/superbox/superbox-full-1.jpg" alt="My first photoshop layer mask on a high end PSD template theme" title="Miller Cine" class="superbox-img">
</div>
</template>
Then whenever your new template is rendered (each iteration of the #each loop):
Template.galley_row.rendered = function () {
$('.superbox').SuperBox();
});

Categories