Using the jQuery lightGallery plugin: http://sachinchoolur.github.io/lightGallery/
So I have the following code:
JSON (array):
var gallery_json = '[{"src":"/assets/Images/Gallery-Images/img-1.jpg","thumb":"/assets/Images/Gallery-Images/img-2.jpg"},{"src":"/assets/Images/Gallery-Images/img-3.jpg","thumb":"/assets/Images/Gallery-Images/img-4.jpg"},{"src":"/assets/Images/Gallery-Images/img-5.jpg","thumb":"/assets/Images/Gallery-Images/img-wool-2015-hero-crop-sheep-river.jpg"},{"src":"/assets/Images/Gallery-Images/img-6.jpg","thumb":"/assets/Images/Gallery-Images/img-7.jpg"},{"src":"/assets/Images/Gallery-Images/img-8.jpg","thumb":"/assets/Images/Gallery-Images/img-9.jpg"}]';
JS:
$(document).ready(function () {
var $gallery = $('[data-hook="gallery"]');
if ($gallery && typeof gallery_json !== 'undefined') {
$gallery.on('click', 'img', function () {
$gallery.lightGallery({
dynamic: true,
dynamicEl: JSON.parse(gallery_json)
});
$gallery.data('lightGallery').slide($(this).parent().index());
});
}
});
MarkUp:
<div class="row" data-hook="gallery">
<div class="col-sm-3">
<img src="/assets/Images/Gallery-Images/img-1.jpg" class="img-responsive">
</div>
<div class="col-sm-3">
<img src="/assets/Images/Gallery-Images/img-2.jpg" class="img-responsive">
</div>
<div class="col-sm-3">
<img src="/assets/Images/Gallery-Images/img-3.jpg" class="img-responsive">
</div>
<div class="col-sm-3">
<img src="/assets/Images/Gallery-Images/img-4.jpg" class="img-responsive">
</div>
</div>
So basically what I am after is whichever image in the [data-hook="gallery"] is selected the dynamic light gallery will load up showing this image as the index, bear in mind my JS skills are really limited so please walk my through any solutions.
Related
im trying to display images that are uploaded into a modal shown below:
<template iterator:thefield={images}>
<template if:true={imagesAttached}>
<div class="slds-file slds-file_card slds-float_right" key={thefield.value.apiName} style="width: 15rem">
<div class="slds-grid slds-gutters">
<div class="slds-col slds-p-horizontal_medium">
<span>
<div class="slds-file slds-file_card slds-float_right" style="width: 15rem">
<figure>
<img src={images} alt="Description of the image" />
</figure>
</div>
</span>
</div>
</div>
</div>
</template>
</template>
I have a function that takes the image and put it in an array.
getImages(string) {
const imgRex = /<img .*?>/g // /<img [^>]*src=['"]([^'"]+)[^>]*>/gi
const images = [];
let img;
while ((img = imgRex.exec(string))) {
images.push(img);
if(images.length > 0){
this.imagesAttached = true;
}
}
return images;
}
I would appreciate the help.
Thank you.
I have 32 items in my array, all of them have these properties: id, word, image. User has to guess what's in all the images and write their guess in inputs (so 32 inputs in total). I need to check if the input equals my arrays property "word" and then when clicked a button (type submit, all my pic's and inputs are in a form) display some text for example "Oops! Guess again" if wrong and "Yay! You got it correctly" if right. The text should appear below every input. I displayed all the pictures and inputs with a forEach, and i'm using bulma framework for this page:
const wordBox = info.forEach((words) => {
mainColumns.innerHTML += `
<div class="column is-one-quarter">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src=${words.image} alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<input class="input" id="text" type="text" placeholder="Įvesk žodį">
</div>
</div>
<div class="content">
Content
</div>
</div>
</div>
</div>`;
});
Any ideas?
This is how it should look like (the result should appear in content place)
Something like this
I use change instead of a button click
const info = [
{word:"flower",image:"flower.gif"},
{word:"boat",image:"boat.gif"}
];
const mainColumns = document.getElementById("mainColumns");
mainColumns.innerHTML = info.map(({image,word}) =>
`<div class="column is-one-quarter">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src=${image} alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<input class="input" data-word="${word}" type="text" placeholder="Įvesk žodį">
<span class="correct hide">Yay</span>
<span class="wrong hide">NOO</span>
</div>
</div>
<div class="content">
Content
</div>
</div>
</div>
</div>`).join("");
mainColumns.addEventListener("change",function(e) {
const correct = [...mainColumns.querySelectorAll("[data-word]")].map(input => {
if (input.value) {
const correct = input.value === input.dataset.word;
parent = input.closest("div");
parent.querySelector(".correct").classList.toggle("hide",!correct)
parent.querySelector(".wrong").classList.toggle("hide",correct);
return correct ? 1 : 0;
}
else return 0;
}).reduce((a,b)=>a+b);
document.getElementById("correct").innerText = correct;
})
#mainColumns { display:flex; }
.hide { display: none; }
<div id="mainColumns"></div>
Correct: <span id="correct"></span>
What you can do is to filter the word array with word from the input value. Then check if the length is equal zero, No match, if the length is greater than one, then there is a match.
const status = wordBox.filter(item => item.word === inputWord)
I'd move towards keeping the objects and the HTML separate, binding the HTML to the object and vice versa. This means including a couple more properties to your array elements.
let info = [{
image: 'flower.png',
word: 'flower',
content: '',
guess: ''
}];
function bindWords() {
info.forEach((words) => {
mainColumns.innerHTML = `
<div class="column is-one-quarter">
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src=${words.image} alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-content">
<input class="input" data-word="${words.word}" type="text" placeholder="Įvesk žodį" value="${words.guess}">
</div>
</div>
<div class="content">
${words.content}
</div>
</div>
</div>
</div>`;
});
}
bindWords();
check.addEventListener('click', () => {
info = Array.from(document.querySelectorAll('.card')).map(el => ({
image: el.querySelector('img').src,
word: el.querySelector('.input').dataset.word,
guess: el.querySelector('.input').value,
content: el.querySelector('.input').value === el.querySelector('.input').dataset.word ?
'Correct' : 'Incorrect'
}));
bindWords();
});
<div id="mainColumns"></div>
<button id="check">Check Answers</button>
I want to list my products from database by clicking on category in html/view.
Firstly I created it in HTML (static) just to check how this is going to look, and it looks lik this:
Here is my html:
<div class="col-md-8" style="margin-top: -15px;">
<div class="products row">
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/coke.png">
<p class="product-title">
Product no1
</p>
</div>
</div>
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/pepsi.png">
<p class="product-title">
Product no2
</p>
</div>
</div>
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/coffe.png">
<p class="product-title">
Product no3
</p>
</div>
</div>
</div>
</div>
And now I want to create this block dynamically:
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/coffe.png">
<p class="product-title">
Product no N
</p>
</div>
</div>
Here is what I've tried so far:
<script>
function onSelectGroup(Id) {
$.ajax({
method: "GET",
url: "Products/GetProductsByCategoryId",
data: { categoryId: Id }
})
.done(function (response) {
//In response I am getting my products, looping through them to create divs like in code above
for (var i = 0; i < response.length; i++) {
//<div class="col-md-3">
// <div class="article-holder">
// <img class="img-responsive" src="images/picture_not_available_400-300.png">
// <p class="product-title">
// Product no 1
// </p>
// </div>
// </div>
//Trying to append it to my .product class because it's parent of this divs above
$(".products").append('<div class="col-md-3"></div>');
$(".products).appendChild('<div class="article-holder"></div>');
}
})};
</script>
But this is not working unfortunatelly... I tried few another things, but this appendings are not working as expected :/
Thanks guys for any help
Cheers
There are many answers posted for the question which might solve the issue with the javascript code. I am posting a different approach as OP specifically requested for it in the comments.
At times, i do not like to build complex HTML markup in javascript with jQuery ( i afraid i might make typos (missing "" or ' etc..). In that case, i would like to have my action method return a view result (the HTML markup) as the response of my ajax call and i can simply update the DOM with that as needed.
public ActionResult GetProductsByCategoryId(int categoryId)
{
var p = db.Products.Where(a=>a.CategoryId==categoryId).ToList();
return PartialView("ProductList",p);
}
Now i will have a partial view called ProductList.cshtml, which is strongly typed to a list of products and i can loop through the items passed to it and render whatever markup i want.
Here is a simple example where i am rendering a div with css class col-md-3 for each item in the collection passed to it. You can update it to render whatever markup you want to render.
#model List<Product>
#foreach (var item in Model)
{
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="#item.ImageUrl">
<p class="product-title">
#item.Name
</p>
</div>
</div>
}
Now all i have to do is, call this action method, and use the response to update my DOM. Let's give an Id to the container div which we will update
<div class="col-md-8" >
<div id="product-list" class="products row">
</div>
</div>
Now when the ajax call receives a response from server, update the inner html of the DOM element with Id product-list
$.ajax({
method: "GET",
url: "#Url.Action("GetProductsByCategoryId","Products")",
data: { categoryId: 2345 }
})
.done(function(response) {
$("#product-list").html(response);
}).fail(function(a, a, e) {
alert(e);
});
Keep in mind that, now you are getting a bigger payload (the resulting HTML)
from the server compared to the JSON data. So use this approach as you feel appropriate to do so. With this approach, i can use the C# methods in my partial view (For example, to build the path to an image in a location/ use Html helper methods etc)
I you create the dom element like any string, and append it to the container
function onSelectGroup(Id) {
//In response I am getting my products, looping through them to create divs like in code above
for (var i = 0; i <10; i++) {
let item = `<div class="col-md-3">
<div class="article-holder">
<img class="img-responsive" src="images/picture_not_available_400-300.png">
<p class="product-title">
Product no ${i}
</p>
</div>
</div>`
//Trying to append it to my .product class because it's parent of this divs above
$(".products").append(item);
}
};
onSelectGroup();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-8" style="margin-top: -15px;">
<div class="products row">
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/coke.png">
<p class="product-title">
Product no1
</p>
</div>
</div>
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/pepsi.png">
<p class="product-title">
Product no2
</p>
</div>
</div>
<div class="col-md-3">
<div class="product-holder">
<img class="img-responsive" src="images/coffe.png">
<p class="product-title">
Product no3
</p>
</div>
</div>
</div>
</div>
You can create a new element with jquery and fill it properly
for (var i = 0; i < response.length; i++) {
//<div class="col-md-3">
// <div class="article-holder">
// <img class="img-responsive" src="images/picture_not_available_400-300.png">
// <p class="product-title">
// Product no 1
// </p>
// </div>
// </div>
//Trying to append it to my .product class because it's parent of this divs above
var newelem = $('<div class="col-md-3"></div>');
var artholder = $('<div class="article-holder"></div>');
newelem.append(artholder);
artholder.append(<your-image><your article title>);
}
You was close; all you needed to do was create an element for each item in the results object. I've used test data in the example.
https://jsfiddle.net/tw0vrpyy/
var response = {
item1: {
id: "id1",
title: "title1",
img: "img_src1.jpg"
},
item2: {
id: "id2",
title: "title2",
img: "img_src2.jpg"
}
};
var product = document.getElementsByClassName('response')[0];
Object.keys(response).forEach(function(key) {
var el = '<div class="col-md-3">' +
'<div class="article-holder">' +
'<img class="img-responsive" src="'+ response[key].img +'">' +
'<p class="product-title">' +
response[key].title +
'</p>' +
'</div>' +
'</div>';
product.innerHTML += el;
});
I'm making slider with Angularjs using modal. I'm trying to accomplish when clicking on picture modal pops up displaying image that I have clicked.
.html
<div class="float" ng-repeat="a in $ctrl.f">
<div class="column is-narrow topIcons">
<div class="photo topIconsHover" ng-click="$ctrl.togglePicture()">
<figure class="image is-128x128">
<img ng-src="{{a.imageSrc}}">
</figure>
</div>
</div>
</div>
<div class="modal" id="myModal">
<div class="modal-background" ng-repeat="a in $ctrl.f"></div>
<div class="modal-content">
<p class="image is-4by3">
<img ng-src="{{togglePicture(a.id)}}">
</p>
</div>
<button class="modal-close" ng-click="$ctrl.closeModal()"></button>
</div>
component.js
function PhotoController($scope){
var vm = this;
vm.f = [{
albumName: "Name",
imageSrc: 'app/images/bio.jpg',
owner: "OwnerName",
id: 1
},
{ albumName: "Name",
imageSrc: 'app/images/bio.jpg',
owner: "OwnerName",
id: 2
}];
vm.togglePicture = function(id) {
$('#myModal').addClass('is-active');
};
I'm trying to get imageSrc by passing id of an image as a function parameter but is not working. What should I do in my function to select correct imageSrc using id and then to display it and how my imageSrc should look like?
Was thinking something like this <img ng-src="{{togglePicture(a.id)}}">?
Pass Selected image in funnction.
<div class="photo topIconsHover" ng-click="$ctrl.togglePicture(a)">
Then set selcted image in controller
vm.selectedImgsrc='';
vm.togglePicture = function(a) {
$('#myModal').addClass('is-active');
vm.selectedImgsrc=a.imageSrc;
};
Then modify modal to view selected image
<p class="image is-4by3">
<img ng-src="{{$ctrl.selectedImgsrc}}">
</p>
I'm having problem accessing the index returned by Collection.find(). In HTML, I'm creating a carousel and I want to make the images dynamic. Before making it dynamic, here's what it looks like:
<div class="carousel-inner">
<div class="item active">
<img src="img/homepage/sliders/1.jpg">
</div>
<div class="item">
<img src="img/homepage/sliders/2.jpg">
</div>
</div>
After implementation, here's the new code:
<div class="carousel-inner">
{{#each sliders}}
<div class="item active">
<img src="{{this.url}}">
</div>
{{/each}}
</div>
Here's what my JS looks like:
Template.homepageSlider.helpers({
sliders: function() {
return HomepageSliders.find({}, {fields: {url:1}}).fetch();
}
});
This sort of works fine, but I wanted to add the class 'active' only on first index. How should I do this?
Thanks a lot!
Something like this should work.
JS:
Template.homepageSlider.helpers({
sliders: function() {
return _.map(HomepageSliders.find({}, {fields: {url:1}}).fetch(),
function(val, index) {
return {value: val,
class: (index == 0 ? "item active" : "item")}
});
}
});
HTML:
<div class="carousel-inner">
{{#each sliders}}
<div class="{{this.class}}">
<img src="{{this.value.url}}">
</div>
{{/each}}
</div>