This question already has answers here:
Use magnificPopup with dynamic elements
(3 answers)
Closed 4 years ago.
my problem is when i append to the div from jquery after ajax post the popup magnifier does not work at all
i am using jquery.magnific-popup
$(document).ready(function () {
$('.image-popup').magnificPopup({
type: 'image',
closeOnContentClick: true,
mainClass: 'mfp-fade',
gallery: {
enabled: true,
navigateByImgClick: true,
preload: [0, 1] // Will preload 0 - before current, and 1 after the current image
}
});
});
and this is my div
<div id="officialDiv" class="row m-b-15">
<%
for (int i = 0; i < officialDocsList.Count; i++)
{
%>
<div class="col-sm-6 col-lg-3 col-md-4 mobiles" style="flex: 0 0 15%; max-width: 15%;">
<div class="product-list-box thumb">
<a href="<%= officialDocsList[i] %>" class="image-popup" title="Screenshot-1">
<img style="width:100px;height:100px;" src="<%= officialDocsList[i] %>" class="thumb-img" alt="work-thumbnail">
</a>
<div class="product-action">
<i class="md md-close"></i>
</div>
</div>
</div>
<%} %>
but i need to append to the div on file input upload so i did the below :
$('#officialDoc').on('change', function (event) {
var files = $("#officialDoc").prop("files");
for (var i = 0; i < files.length; i++) {
(function (file) {
var fileReader = new FileReader();
fileReader.onload = function (f) {
var d = f.target.result;
var img = d.split("base64,").pop();
var byteArray = _base64ToArrayBuffer(img);
$.ajax({
type: "POST",
url: "BusinessLogic/SaveTempFiles.ashx",
data: {
'file': img,
'name': file.name
},
success: function (result) {
$("#OfficialDocsPath").val($("#OfficialDocsPath").val() + ',' + result);
$("#officialDiv").append("<div class='col-sm-6 col-lg-3 col-md-4 mobiles' style='flex: 0 0 15%; max-width: 15%;'><div class='product-list-box thumb'><a href='" + result + "' class='image-popup' title='Screenshot-1'><img src='" + result + "' class='thumb-img' style='width:100px;height:100px;' alt='work-thumbnail'></a><div class='product-action'> <a href='#' class='btn btn-danger btn-sm'><i class='md md-close'></i></a> </div></div> </div>");
}
});
};
fileReader.readAsDataURL(file);
})(files[i]);
}});
When you call
$('.image-popup')
(with anything after the .) it will only apply to the elements that exist at that time. eg $('.image-popup').click(function() { alert("click"); }); will only put an event handler for those that exist so appending any new elements will not have that click handler (which is why we need to use event delegation for dynamically added elements).
The same applies here.
$('.image-popup').magnificPopup({
will tell magnificPopup only about the image-popups that exist at that time. When you add new ones later, it doesn't know about them.
So you need to recall your magnificPopup initialisation after you add the new elements.
Related
I have this unslider which display tweets polled from some sources via Ajax which refreshes every 8 sec. The Unslider works fine for the first time but subsequently when new ajax queries are fired, it is supposed to clear the first tags and repopulate with new one. For some reason, it doesn't clear out the old tags and instead appends the new tags to the old.
Here are the screenshots:
var flag = false;
(function setTweets() {
$.ajax({
type: "GET",
url: "../tweets/get_latest_tweets",
success: function(data) {
//clear all children first
$('#tweets-list').children().remove();
for (var i = 0; i < data.length; i++) {
$('<li>' + data[i].text + '<div class="card-footer bg-twitter"><div class="card-profile-image"><img src="' + data[i].pic + '" class="rounded-circle img-border box-shadow-1" alt="Card Image"></div>' +
'<footer class="blockquote-footer bg-twitter white"><strong>#' + data[i].screen_name + '</strong></footer></div></li>').appendTo($('#tweets-list'))
}
if (!flag) {
$('#tweet-slider').unslider({ //initialize unslider only once
autoplay: true,
arrows: true,
speed: 1000,
delay: 7000,
});
flag = true;
}
},
error: function(err) {
console.log(err);
}
}).then(function() {
setTimeout(setTweets, 8000); //Todo: Check how to do this async (dynamic adding of points)
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="card bg-twitter white">
<div class="card-content p-2">
<div class="card-body">
<div class="text-center mb-1">
<i class="ft-twitter font-large-3"></i>
</div>
<div class="tweet-slider" id="tweet-slider">
<ul id='tweets-list' class="text-center">
</ul>
</div>
</div>
</div>
Similar to .empty(), the .remove() method takes elements out of the DOM. Use .remove() when you want to remove the element itself, as well as everything inside it. In addition to the elements themselves, all bound events and jQuery data associated with the elements are removed. To remove the elements without removing data and events, use .detach() instead.
According to this, you are removing # tweets-list as an element, I think if you use .empty () you will clean it
uses $('#tweets-list').empty();
I was reading the unslider website and it says that if you delete or add slides you should use the method slider.unslider('calculateSlides');
var flag = false;
(function setTweets() {
$.ajax({
type: "GET",
url: "../tweets/get_latest_tweets",
success: function(data) {
//clear all children first
$('#tweets-list').children().remove();
for (var i = 0; i < data.length; i++) {
$('<li>' + data[i].text + '<div class="card-footer bg-twitter"><div class="card-profile-image"><img src="' + data[i].pic + '" class="rounded-circle img-border box-shadow-1" alt="Card Image"></div>' +
'<footer class="blockquote-footer bg-twitter white"><strong>#' + data[i].screen_name + '</strong></footer></div></li>').appendTo($('#tweets-list'))
}
if (!flag) {
$('#tweet-slider').unslider('calculateSlides');
flag = true;
}
},
error: function(err) {
console.log(err);
}
}).then(function() {
setTimeout(setTweets, 8000); //Todo: Check how to do this async (dynamic adding of points)
});
})();
apparently there is no need to reinitialize the unslider, try it but, you restart it
<div class="page-content">
<div class="content-block">
<div id="tab-holder" class="buttons-row">
Tab 1
Tab 2
Tab 3
</div>
</div>
</div>
how should i add tabs dynamically?
Tab 1
I made a function like this but not working:
function createTabButton(_holder, _text, _isActive) {
var thm = $(`<a class="tab-link button ${_isActive ? 'active' : ''}">${_text}</a>`);
_holder.append(thm);
console.log(_text);
}
did i miss something ?
I did that using only Dom7(framework7 own dom manipulator), using almost the same code that you.
Used https://jsonplaceholder.typicode.com/ as example
<div class="page-content">
<div class="content-block">
<div id="tab-holder" class="buttons-row">
Tab 1
Tab 2
Tab 3
</div>
</div>
<button class="button">add</button>
</div>
Javascript - [Updated with template String]
var myApp = new Framework7();
// Export selectors engine
var $$ = Dom7;
$$("#btnLoad").on('click', function() {
$$.ajax({
url: "https://jsonplaceholder.typicode.com/todos",
data: {
'userId': 1
},
type: 'GET',
beforeSend: function(){
$$("#btnLoad").text("Loading...");
},
success: function(data) {
var list = JSON.parse(data);
for (var i = 0; i < 5; i++) {
createTabButton($$("#tab-holder"), list[i].id, list[i].completed);
}
$$("#btnLoad").text("Tabs Added");
}
});
});
function createTabButton(_holder, _text, _isActive) {
//var thm = $$('<a class="tab-link button ' + (_isActive ? 'active' : '') + '">' + _text + '</a>');
var thm = `<a class="tab-link button ${_isActive ? 'active' : ''}">${_text}</a>`;
_holder.append(thm);
}
http://jsfiddle.net/alexprazeres11/0cwvejcx/76/
Tested in Framework7 v1.4.2 and 1.6.4, it may work also on v2.0+.
I have a coffeescript based code which has all the definitions (IDs and Classes) are called locally. Now I want it to refactor it based on a dynamic view i.e, on click by the user in the site, that should send the corresponding ID to the function. How do I deal with this?
HTML -
<div id="dl1">
<div class="dl_div">
<div id="target1" data-key="<%= #aws_url1[:key] if !#aws_url1.nil? %>">
<% if !#aws_url1.nil? %>
<img id="user_dl1" src="<%= #aws_url1[:url] %>">
<% end %>
</div>
<div id="close1" style="display: none;">
<button id="closebtn1" class="closebtn">X</button>
</div>
<div id="closemsg1" style="display: none; position: relative;">
<button id="deletebtn1" class="deletebtn">
<p class="deletebtnstyle">Delete</p>
</button>
<button id="cancelbtn1" class="cancelbtn">
<p class="cancelbtnstyle">Cancel</p>
</button>
</div>
<div class="file_browser1" id="file_browser1">
<label for="file_upload1" class="custom-file_upload z-depth-1">
<i class="material-icons"></i>
<p class="button-text"> Upload Here</p>
</label>
<form id="user_id1_form" action="">
<input type="hidden" name="user_id1_key" value="<%= #aws_urls[0][:key] %>"/>
<input id="file_upload1" type="file" accept="image/*" name="user_id1"/>
</form>
</div>
</div>
</div>
CoffeeScript -
if $('#target1 img').length == 1
$('#file_browser1').addClass 'none'
$('#close1').addClass 'delete'
$('#closebtn1').on 'click', (e) ->
$('#closemsg1').addClass 'msg'
$('#cancelbtn1').click ->
$('#closemsg1').removeClass 'msg'
$('#deletebtn1').click ->
$('#close1').removeClass 'delete'
$('#closemsg1').removeClass 'msg'
$('#target1 > img').hide()
$('#file_browser1').removeClass 'none'
$('#file-upload1').val('')
return
$('#file_upload1').on 'change', (event) ->
files = event.target.files
image = files[0]
old_key = $("#target1").data("key");
new_key = null
$user_id1 = $('#file_upload1')[0].files[0];
console.log image.size
reader = new FileReader
$.ajax({
type: "GET",
url: "http://localhost:3000/users/get_url/13",
success :(data) ->
new_key = data[0].key
processfile $user_id1,(result)->
console.log data[0].url
$user_id1 = dataURItoBlob(result)
reader1 = new FileReader()
reader1.readAsArrayBuffer($user_id1)
reader1.onload = (e) ->
rawData1 = reader1.result;
$.ajax({
url: data[0].url,
type: 'PUT',
xhr: ->
myXhr = $.ajaxSettings.xhr();
if (myXhr.upload)
myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
return myXhr;
,
success: completeHandler,
error: errorHandler,
data: rawData1,
cache: $.param(false),
contentType: "binary/octet-stream",
processData: $.param(false)
}, 'json');
})
completeHandler = (data) ->
$.ajax({
type: "POST",
url: "http://localhost:3000/users/user_documents/13",
data: {
aws_key_new: new_key,
aws_key_old: old_key,
dl_id: "dl",
},
success: ->
a = $('#target1')
console.log a.data("key")
console.log new_key
a.attr('data-key', new_key);
})
success :(data) ->
alert "complete"
return
error :(data) ->
alert "failed"
return
errorHandler = (data) ->
console.log data
alert "failed"
progressHandlingFunction = (data) ->
reader.onload = (file) ->
img = new Image
img.src = file.target.result
$('#target1').html img
$('#file_browser1').addClass 'none'
$('#close1').addClass 'delete'
$('#closebtn1').on 'click', (e) ->
$('#closemsg1').addClass 'msg'
$('#cancelbtn1').click ->
$('#closemsg1').removeClass 'msg'
$('#deletebtn1').click ->
$('#close1').removeClass 'delete'
$('#closemsg1').removeClass 'msg'
$('#target1 > img').hide()
$('#file_browser1').removeClass 'none'
$('#file-upload1').val('')
return
return
reader.readAsDataURL image
console.log files
return
How to pass the IDs to the coffeescript on click?
If I understood from your question, you want to adding click events to a group of elements and be able to get their respective values when trigged.
One way to do it would be to adding click event to the attribute class:
For example (using jquery):
// Add click event to the class .drill_cursor
$(".drill_cursor").click(function(){
console.log(this.id);
});
// Used to display console.log
var consoleLine = "<p class=\"console-line\"></p>";
console = {
log: function (text) {
$("#console-log").append($(consoleLine).html(text));
}
};
.console-line {
font-family: monospace;
color: red;
margin: 2px;
}
.drill_cursor {
margin: 50px;
color: blue;
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<div id="console-log"></div>
<div id="id-div-1" class="drill_cursor" >div-1-click-on-me</div>
<div id="id-div-2" class="drill_cursor" >div-2-click-on-me</div>
<div id="id-div-3" class="drill_cursor" >div-3-click-on-me</div>
<div id="id-div-4" class="drill_cursor" >div-4-click-on-me</div>
</body>
Another way to do it would be delegating the event to another element tag:
You can find more information about delegate events here:
api.jquery.com/delegate
For some cases, delegate events is a better way to add events dynamically!
I hope it helps you!
Good luck!
This question already has answers here:
jQuery ID selector works only for the first element
(7 answers)
Closed 6 years ago.
I've implemented a program something like a shopping cart where you would add products to the cart. I'm using ajax make the page dynamic so multiple products can be added to the cart without a page reload. For some reason, the first product in the list can be added correctly while the rest of products alway redirects to the controller url when it isn't supposed to.
View Code
<section class="grid grid--loading" id="portfoliolist">
<!-- Loader -->
<img class="grid__loader" src="~/Images/grid.svg" width="60" alt="Loader image" />
<!-- Grid sizer for a fluid Isotope (Masonry) layout -->
<div class="grid__sizer"></div>
<!-- Grid items -->
#foreach (var item in Model.ProductsList)
{
var pricetag = "pricegroup3";
if (item.Price <= 300)
{
pricetag = "pricegroup1";
}
else if (item.Price > 300 && item.Price <= 500)
{
pricetag = "pricegroup2";
}
<div class="grid__item #item.Type #pricetag">
<div class="slider">
#foreach (var image in Model.ProductImagesList.Where(m=>m.ProductID == item.Id))
{
<div class="slider__item"><img src="~/Images/Products/#image.Image" /></div>
}
</div>
<div class="meta">
<h3 class="meta__title">#item.Name</h3>
<span class="meta__brand">#item.Brand</span>
<span class="meta__price">R #item.Price</span>
</div>
<a class="action action--button action--buy" href="#Url.Action("AddToPlatform", "ProductPlatforms", new { ProdID = item.Id })" id="platformAdd" data-value="#item.Id"><i class="fa fa-shopping-cart"></i><span class="text-hidden">Add to Platform</span></a>
</div>
}
</section>
The last tag is what will be clicked on to add the product to the cart.
Script -Ajax
$("#platformAdd").click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: $(this).attr("href"),
success: toastr["success"]("Product added to Platform")
});
});
Controller function
public void AddToPlatform(int ProdID)
{
var currUser = User.Identity.GetUserId();
DateTime now = DateTime.Now;
var exists = ProductExists(ProdID);
if (exists == false)
{
ProductPlatform prodPlatform = new ProductPlatform()
{
ProductID = ProdID,
UserID = currUser,
ViewedStatus = false,
DateAdded = now
};
db.ProductPlatforms.Add(prodPlatform);
db.SaveChanges();
}
}
The ajax script function would call the controller function which will add the product to the cart. Since there are no redirects I can't seem to figure out why the ajax call redirects to the tag "href".
Thanks for any help!
You need to use class instead of id because ids are always unique.
$(".lnkAddProduct").click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: $(this).attr("href"),
success: function(){alert("ADDED");}
});
});
so I have an array as response when i upload images with dropzone:
{50: "/media/50/twitter cover photos for new year 2016.png", 51: "/media/51/174920-1280.png",…}
50: "/media/50/twitter cover photos for new year 2016.png"
51: "/media/51/174920-1280.png"
52: "/media/52/buy-instagram-followers.jpg"
Now i want to append this:
<div class="col-lg-2 col-md-4 col-xs-6 thumb">
<img class="img-responsive" src=" // the values of the response array //" alt="">
<div class="galleryremovebutton">
Izbrisi sliku
</div>
</div>
as a loop to this:
<div id="galleryimgs" class="row">
After the complete event of dropzone, that means i would need this code here somewhere:
Dropzone.options.myGalleryDropzone = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 1, // MB
parallelUploads: 8,
complete: function () {
HERE
}
};
Using only jQuery, you have a choice between building the DOM through a string or programmatically. Either way, it should be a DOM element wrapped in jQuery:
function makeThumb() {
// $('html_for_one_thumbnail');
// $('<div />').append('<div />')...etc;
return elementForThumb;
}
Then another function to populate the element:
function configureThumb($element, thumb, thumbId) {
$element.find('img').attr('src', thumb);
$element.find('a').attr('href', '/delete/' + thumbId);
}
And one more to put it together:
function buildThumbnails($element, thumbs) {
thumbs.forEach(function(thumb, thumbId) {
var $thumb = makeThumb();
$element.append($thumb);
configureThumb($thumb, thumb, thumbId);
});
}
Called at the complete, assuming the container is empty:
complete: function(data) {
buildThumbnails($('#galleryimgs'), data);
}