I know this topic has been asked a lot before but I read a lot of stackoverflow posts and can't figure it out. Either I'm doing a silly mistake or using the code wrong. In any case I'd appreciate other sets of eyes.
My code is actually simple. Elements are being dragged into boxes and I want the user to be able to close the dragged boxes so they can redo the dragging.
<div id="questionContainer">
<div class='row-fluid'>
<div class='span3 box-content'>
<div class="box span12">
<input type="text" placeholder="Column 1" />
</div>
<div class="box span12 groupBoxes">
</div>
</div>
<div class='span3 box-content'>
<div class="box span12">
<input type="text" placeholder="Column 2" />
</div>
<div class="box span12 groupBoxes">
</div>
</div>
<div class='span3 box-content'>
<div class="box span12">
<input type="text" placeholder="Column 3" />
</div>
<div class="box span12 groupBoxes">
</div>
</div>
<div class='span3 box-content'>
<div class="box span12">
<input type="text" placeholder="Column 4" />
</div>
<div class="box span12 groupBoxes">
</div>
</div>
</div>
Then there is the javascript which appends the dragged element. And I have an .on() function there that doesn't work at all.
$( ".groupBoxes" ).droppable({
accept: ".sDrag",
drop: function( event, ui ) {
var studentID = $(ui.draggable).attr('Uid');
var studentName = $(ui.draggable).find(".sName").text();
console.log(studentID + ' ' + studentName);
var dropbox = "<div class='box questionBox' Uid='"+studentID+"' ><div class='box-content box-statistic'><h3 class='title text-error'>"+studentName+"</h3><div class='icon-remove align-right card-remove' style='font-size:12px'></div></div> </div>";
$(this).append(dropbox);
}
});
$("#questionContainer").on('click', '.card-remove', function () {
console.log('hi');
var student = $(this).parent('.questionBox').attr('Uid'); // get user number
var box = $(".studentBox[value='"+student+"']")// find the original object through user
box.removeClass('muted-background').addClass('sDrag');// back in the original object, add class sDrag and remove class muted-background
// remove the object clicked
});
Any ideas about what's going wrong here?
try to define dropbox outside the function
var dropbox;
$( ".groupBoxes" ).droppable({
accept: ".sDrag",
drop: function( event, ui ) {
var studentID = $(ui.draggable).attr('Uid');
var studentName = $(ui.draggable).find(".sName").text();
console.log(studentID + ' ' + studentName);
dropbox = "<div class='box questionBox' Uid='"+studentID+"' ><div class='box-content box-statistic'><h3 class='title text-error'>"+studentName+"</h3><div class='icon-remove align-right card-remove' style='font-size:12px'></div></div> </div>";
$(this).append(dropbox);
}
});
$("#questionContainer").on('click', '.card-remove', function () {
console.log('hi');
var student = $(this).parent('.questionBox').attr('Uid'); // get user number
var box = $(".studentBox[value='"+student+"']")// find the original object through user
box.removeClass('muted-background').addClass('sDrag');// back in the original object, add class sDrag and remove class muted-background
// remove the object clicked
});
Related
The following code allows me to append new content to the div "users". However, I want to be able remove the appended content if the user clicks button.
The current code removes only the "remove" button when its clicked. However, I need to remove the entire appended code with the class "removeuser", in the beginning of the appended code.
Any help will be appreciated!
<div id="users"></div>
<script>
function adduser() {
count += 1;
$('#users').append('<div id="field'+ count +'" class="removeuser[]"><div
id="left"><div id="fieldname">user #'+ count +' Name:</div><div
id="field"><input id="user_name'+ count +'" name="user_name[]"' + '"
type="text" /></input></div><div id="clear"></div></div><div id="leftleft">
<div id="fieldname">user #'+ count +' Age</div><div id="field"><input
type="number" id="user_age'+ count +'" name="user_age[]"
style="width:50px;" min="0"></input></div><div id="clear"></div><br></div>
<div id="leftleft"><a href="javascript: void(0)" onclick="adduser(); return
false;"><div id="field" class="add"><div
style="position:relative;left:-4px;top:1px;">add another user +</div></div>
</a><br></div> <div id="leftleft"><a href="javascript: void(0)"
onclick="$(this).remove();" ><div id="deluser[]" class="add"><div
style="position:relative;left:-4px;top:1px;">-</div></div></a><br></div>
<div id="clear"></div></div>');
var no = document.getElementById("deluser");
no.onclick = function(){
$('#users .removeuser').$(this).remove();
};
</script>
From what I can tell this is might be the solution you're looking for (note not supported in all browser. See below for transpiled version)...
var count = 0;
adduser();
function adduser() {
$('#users').append(newUser(count))
count++;
}
function deluser(e) {
$(e.target).closest('.user-container').remove();
}
function newUser(count) {
var deleteButton = `
<div>
<a href="javascript: void(0)" onclick="deluser(event); return false;">
<div class="add delete-user" data>
<div style="position:relative;left:-4px;top:1px;">-</div>
</div>
</a>
<br>
</div>
`;
return `
<div class="user-container">
<div id="left">
<div class="fieldname">
user #${count} Name:
</div>
<div class="field">
<input id="user_name${count}" name="user_name[]" type="text" /></input>
</div>
<div id="clear"></div>
</div>
<div>
<div class="fieldname">
user #${count} Age
</div>
<div class="field">
<input type="number" id="user_age${count}" name="user_age[]" style="width:50px;" min="0"></input>
</div>
<div id="clear"></div><br>
</div>
<div>
<a href="javascript: void(0)" onclick="adduser(); return false;">
<div class="field" class="add">
<div style="position:relative;left:-4px;top:1px;">add another user +</div>
</div>
</a>
<br>
</div>
${count > 0 ? deleteButton : ""}
<div class="clear">
</div>
</div>
`;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users"></div>
There area quite a few things wrong with your initial attempt though and I don't mean to be rude, but you should probably do more work learning the basics of HTML, JS and in this case jQuery. Treehouse is where I started out many years ago and think it is a great introduction to web development (Treehouse - front-end web development). That being said here are the most glaring issues...
Unique ids
id attributes must be unique per HTML document. As in, having id="leftleft" and then on another element in same document having id="leftleft" is invalid.
Missing closing bracket of function block }
HTML template strings
Honestly I don't know how you're able to read that HTML template string, but this is one of the issues front-end frameworks like React and Angular are meant to solve. Writing HTML templates like this will definitely introduce bugs and also drive you insane.
Instead or rewriting your whole program in React or Angular I would suggest using Template Literals and either using Webpack + babel to transpile your code to achieve browser support or for now just visit Babel repl and manually drop in your JS (with template literals) then replace with output code.
This is how the code would look after being transpiled through Babel, which would be supported in all browsers..
var count = 0;
adduser();
function adduser() {
$('#users').append(newUser(count));
count++;
}
function deluser(e) {
$(e.target).closest('.user-container').remove();
}
function newUser(count) {
var deleteButton = "\n <div>\n \n <div class=\"add delete-user\" data>\n <div style=\"position:relative;left:-4px;top:1px;\">-</div>\n </div>\n \n <br>\n </div>\n ";
return "\n <div class=\"user-container\">\n <div id=\"left\">\n <div class=\"fieldname\">\n user #".concat(count, " Name:\n </div>\n <div class=\"field\">\n <input id=\"user_name").concat(count, "\" name=\"user_name[]\" type=\"text\" /></input>\n </div>\n <div id=\"clear\"></div>\n </div>\n <div>\n <div class=\"fieldname\">\n user #").concat(count, " Age\n </div>\n <div class=\"field\">\n <input type=\"number\" id=\"user_age").concat(count, "\" name=\"user_age[]\" style=\"width:50px;\" min=\"0\"></input>\n </div>\n <div id=\"clear\"></div><br>\n </div>\n <div>\n \n <div class=\"field\" class=\"add\">\n <div style=\"position:relative;left:-4px;top:1px;\">add another user +</div>\n </div> \n \n <br>\n </div> \n ").concat(count > 0 ? deleteButton : "", "\n <div class=\"clear\">\n </div>\n </div>\n ");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="users"></div>
use something like this
$( '#users' ).empty();
You need to use following code
var no = $(".deluser"); // add class 'deluser' to each div
no.onclick = function(){
$('#users').empty();
};
I tried to illustrate your approach in another way, I hope it will help you.
var count = 0;
function addUser(i) {
var userBloc = '<li class="list-group-item" id="user'+i+'"> I am the user'+ i +
' <br><button class="btn btn-danger remove" data-count="'+i+'">Remove me</button><hr></li>';
return userBloc;
}
$('#add').click(function(){
$('#blocs').append(addUser(count));
$('#user'+count).fadeIn(activeRemove); //important to active remove event
count++;
});
function activeRemove(){
$.each($('button.remove'), function(i,item){
$(item).click(function(){
$('#user'+$(item).attr('data-count')).remove();
});
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="blocs" class="list-group"></div>
<button id="add">Add a another user</button>
Hello I have this html code:
<div class="row newrow">
<div class="col-10"><b>this</b></div>
<div class="col-2">
<img src="close.png" id="exit"/>
</div>
</div>
When I click on img with id exit using this code
$('body').on('click','#exit',function(e){
})
I need to get the text of the <b>behind it which would be "this"
I have tried this but it does not work:
$('body').on('click','#exit',function(e){
$q = $(e.target).prev('b')
var word = $q.text()
)}
It only gives me the that I clicked from the beginning
try this:
$('body').on('click','#exit',function(e){
var this_b = $(this).parent().prev().children(0).html();// get the text
alert(this_b);
});
You can use $(this).closest('.row').find('b'):
$('#exit').click(function(e){
$q = $(this).closest('.row').find('b');
var word = $q.text();
console.log(word);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row newrow">
<div class="col-10"><b>this</b></div>
<div class="col-2">
<img src="close.png" id="exit"/>
</div>
</div>
You need to select the parent of the clicked img to get the the .col-2, and then get the col-2's prev() to get to the .col-10, and then you can access its children() to get the children (the single <b>). Also, there's no need for e.target if you use this:
$('body').on('click', '#exit', function() {
$q = $(this).parent().prev().children();
var word = $q.text()
console.log(word);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row newrow">
<div class="col-10"><b>this</b></div>
<div class="col-2">
<img src="close.png" id="exit" />
</div>
</div>
Try this
$('body').on('click','#exit',function(e){
var word = $(this).closest('.newrow').find('b').text();
});
I ask a question about my function Javascript.
I recover a data list after an a ajax call.
In the list i have a field with a picture and i want show this in a modal bootstrap.
In my code the picture is displayed below the column.
Thanks in advance guys :)
$.when(promiseListeRubriqueDocument).then(function(result) {
var data = JSON.parse(result);
$(".listRubrique").html("");
$.each(data, function(index, item) {
console.log(item);
var rubTemplate = $(".template");
var modal = (".img");
var rub = $(rubTemplate).clone().removeClass("template").removeClass("hide");
$(rub).find(".labelRubrique").text(item.codeRubrique);
$(rub).find(".inputRubrique").val(item.libelleRubrique);
$(rub).find("div.rubrique-image").attr("data-rubrique-id", item.idRub);
$(rub).find("div.rubrique-image[data-rubrique-id=" + item.idRub + "]").click(function(i, element) {
if (item.imageRubrique) {
if ($("" + "[data-rubrique-id=" + item.idRub + "]").find('img.rubrique-exemple').length < 1) {
$("" + "[data-rubrique-id=" + item.idRub + "]").append("<div><img class='rubrique-exemple' src=" + item.imageRubrique + " width='100px' /></div>");
}
}
});
$(".listRubrique").append(rub);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="list-group-item template hide">
<label class="labelRubrique" style="font-weight:bold"></label>
<div class="row rubrique-image" data-rubrique-id="">
<div class="col-md-8">
<input name="enteteRubrique" id="enteteRubrique" maxlength="255" type="text" class="form-control aveo-icon aveo-magnifier inputRubrique" disabled/>
</div>
<div class="col-md-3">
<a class="seeImage" href="javascript:void(0);" role='button' aria-expanded='false' aria-controls='collapseExample'><span class='glyphicon glyphicon-eye-open fa-lg'></span></a>
</div>
</div>
</li>
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
<liferay-ui: messagekey="admin.gestion.documents.rubriques.disponibles" />
</div>
<div class="panel-body">
<ul class="list-group listRubrique">
</ul>
</div>
</div>
</div>
</div>
"Lightbox" is the common name for what you've described. Since you mentioned a modal bootstrap, something like http://jbutz.github.io/bootstrap-lightbox/ is likely to be aligned with your goals.
simply clone your "field" div, give it id then append to a bootstrap modal body. Or to avoid appending new clone everytime: use .html() instead.
from https://www.w3schools.com/bootstrap/bootstrap_modal.asp with modification, using bootstrap 3.3.7, jquery 3.3.1
<body>
<div class="container">
<button type="button" class="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<div id='myColumn'>
<img src="https://via.placeholder.com/350x150"/>
<p>Some text in the modal.</p>
</div>
</div>
<script>
$(document).ready(function(){
// var field = $("" + "[data-rubrique-id=" + item.idRub + "]").clone();
var fieldtest= $('#myColumn').clone();
var modal = $("<div id='myModal' class='modal'>\
<div class='modal-dialog'>\
<div class='modal-content'>\
<div id='myBody' class='modal-body'>\
</div>\
</div>\
</div>\
</div>").appendTo('body');
// $('#myBody').html(field);
$('#myBody').html(fieldtest);
});
</script>
</body>
`
I'm trying to pass data from a function to a specific div, but I can't seem to be able to get this to work. I'm making a gallery viewer and I just want to pass the counter that I use to show the pictures and the total number of files for each gallery in the page.
Here is the code:
jQuery
$(document).ready(function () {
$('.photoset').each(function () {
$(this).data('counter', 0);
$items = $(this).find('img')
$(this).data('numItems', $items.length);
});
var showCurrent = function (photoset) {
$items = photoset.find('img');
var counter = photoset.data('counter');
var numItems = $items.length;
var itemToShow = Math.abs(counter % numItems);
$items.fadeOut();
$items.eq(itemToShow).fadeIn();
};
$('.photoset').on('click', function (e) {
e.stopPropagation();
var photoset = $(this);
var pWidth = photoset.innerWidth();
var pOffset = photoset.offset();
var x = e.pageX - pOffset.left;
if (pWidth / 2 > x) {
photoset.data('counter', photoset.data('counter') - 1);
if (photoset.data('counter') < 0)
photoset.data('counter', photoset.data('numItems') - 1);
showCurrent(photoset);
} else {
photoset.data('counter', photoset.data('counter') + 1);
if (photoset.data('counter') > photoset.data('numItems') - 1)
photoset.data('counter', 0);
showCurrent(photoset);
}
$(this).text(photoset.data('counter') + 1 + " de " + photoset.data('numItems'))
});
});
Html Razor
<div class="container">
#{ var i = 10; }
#foreach (var item in Model)
{
<div class="row">
<div class="col-md-4 col-md-offset-4 text-center">
<br />
#Html.DisplayFor(modelitem => item.NomeGaleria)
<br />
</div>
</div>
<div class="row"><div class="col-md-4 col-md-offset-4 text-center"><div class="nav-informer"></div></div></div>
<div class="row">
<div class="photoset center-block">
#{ var item2 = item.FilePaths;}
#for (var k = 0; k < Enumerable.Count(item2); k++)
{
<br />
<img src="~/images/#Html.DisplayFor(modelItem2 => item2[k].FileName)" style="#(k != 0 ? "display: none" : "" ) " />
<br />
}
</div>
</div>
}
</div>
So I'm trying to use this code
$(this).text(photoset.data('counter') + 1 + " de " + photoset.data('numItems'))
to pass the data to the "nav-informer" div, but it just won't work. Does anyone knows what to do in this case? Sorry if this is a dumb question, I'm very new to jQuery.
UPDATE
Here is the rendered HTML page:
<div class="container">
<div class="row">
<div class="col-md-4 col-md-offset-4 text-center">
<br />
Galeria Um
<br />
</div>
</div>
<div class="row"><div class="col-md-4 col-md-offset-4 text-center"><div class="nav-informer"></div></div></div>
<div class="row">
<div class="photoset center-block">
<br />
<img src="/images/572fdd6b-13eb-48d2-8940-23da73e056c0.JPG" style=" " />
<br />
<br />
<img src="/images/018a55be-a8a7-4412-8415-1678d01eb6a2.JPG" style="display: none " />
<br />
<br />
<img src="/images/e5b0bdcb-d517-49a5-818b-245d46c0a0d9.JPG" style="display: none " />
<br />
</div>
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4 text-center">
<br />
Galeria Dois
<br />
</div>
</div>
<div class="row"><div class="col-md-4 col-md-offset-4 text-center"><div class="nav-informer"></div></div></div>
<div class="row">
<div class="photoset center-block">
<br />
<img src="/images/fdc2e9fd-978a-4150-87af-483e34f68798.JPG" style=" " />
<br />
<br />
<img src="/images/b17d169d-e5ed-45cd-9901-1d9dc294c873.JPG" style="display: none " />
<br />
<br />
<img src="/images/3ad1ae20-7102-4d69-b658-7b3d8cbfb9e8.JPG" style="display: none " />
<br />
<br />
<img src="/images/4ef03a84-da00-4f93-b3a2-839ac2ec9ac2.JPG" style="display: none " />
<br />
</div>
</div>
So, since you're new to jQuery, the use of $(this) basically means "the element that I've started the process with" which in your case is .photoset. So $(this) = $('.photoset')
If you want to make that line of text go into your .nav-informer div, you need to change $(this) to $('.nav-informer')
$('.nav-informer').text(photoset.data('counter') + 1 + " de " + photoset.data('numItems'));
UPDATE
So it seems you need to traverse through the hierarchy. Is each 'gallery' a .container? If so, try this:
$(this).closest('.container').find('.nav-informer').text(photoset.data('counter') + 1 + " de " + photoset.data('numItems'));
.closest() traverses up through the hierarchy trying to find the closest parent of the element you start with. (in our case $(this)).
'.find()' does the opposite, it goes down through the hierarchy to find the first instance of the element in question from the point before.
Add them together and what I like to do is .closest() to the parent of the element you're trying to find and .find() the element after that. I feel like doing .parents(), .children() and .siblings() gets messy.
UPDATE 2
Alright, I see now - The way you're exporting each gallery may get a bit dicey eventually, and if possible, I would suggest containing your gallery and informer into the same container, but if you're going to leave it like this, try this:
$(this).closest('.row').prev('.row').find('.nav-informer').text(photoset.data('counter') + 1 + " de " + photoset.data('numItems'));
So, using .parent() will traverse only a single parent, where if you needed to go farther up, you can use .parents() (with an S) or my favorite .closest(). Then, once you reach the level you need to go, you can use .siblings(), or in our case, since your .nav-informer is always in the .row before your .photoset, you need to use .prev(). This will select the div written directly before the div you are currently, at the same level.
Check This Fiddle to see a quick example.
I am trying to create a comparison overlay that shows items selected by users when they 'add to compare' link.(like one in flipkart that appears on top when you hit add to compare). Here is my code:
<div class="college-list-container">
<div class = "individual-college-container" id="text1">
<div class="image-header"><h3>text1</h3>
</div>
<div class="dark-overlay">
<div class="overlay-links" style=" float:left;"> <div class="absolute-center ">Details</div></div>
<a href=""> <div class="overlay-links" style=" float:right; border-right:none;"> <div class="absolute-center comparison" id="comparison">Add to compare</div>
</div></a>
</div>
</div>
<div class = "individual-college-container">
<div class="image-header"><h3>text2</h3>
</div>
<div class="dark-overlay">
<div class="overlay-links" style=" float:left;"> <div class="absolute-center ">Details</div></div>
<a href=""> <div class="overlay-links" style=" float:right; border-right:none;"> <div class="absolute-center comparison">Add to compare</div>
</div></a>
</div>
</div>
<div class = "individual-college-container" id="itm">
<div class="image-header" ><h3>text3</h3>
</div>
<div class="dark-overlay">
<div class="overlay-links" style=" float:left;"> <div class="absolute-center ">Details</div></div>
<a href=""> <div class="overlay-links" style=" float:right; border-right:none;"> <div class="absolute-center comparison">Add to compare</div>
</div></a>
</div>
Javascript
/show overlay when one checkbox is checked and add its name/image to the empty space
$('.comparison').click(function(e){
var clgId = $(this).parentsUntil('.individual-clg-container').find('.image-header').text();
e.preventDefault();
var clg = $("<li></li>")
clg.text(clgId);
var removeLink = $("<a href=''>(Remove)</a>");
clg.append(removeLink)
$('.comparison-colleges').append(clg);
$('.add-to-compare-overlay').show("slide", { direction: "up" }, 300);
});
I want the text in the div containing class 'image-header' to be assigned to the variable clgId. The problem that i am facing with my code is that it is adding the text of all the divs containing class 'image-header'. Ex i want the value text1 to be assigned on clicking add to compare of the div with id text1. However it assigns 'text1 text2 text3' to clgId.
Please help
I've created a JSFiddle with what I think is your desired functionality (I included a console log output in the script of the clgId variable):
http://jsfiddle.net/py38kuvv/
I replaced the parentsUntil function with the closest function (and replaced the individual-clg-container class selector):
var clgId = $(e.target).closest('.individual-college-container').find('.image-header').text();
and also updated your click handler:
$('.comparison').on( "click", function(e) {
In order to get a quicker response in future, posting a JSFiddle of what you have so far makes it easier for others to help :)
It is adding all of them because
var clgId = $(this).parentsUntil('.individual-clg-container').find('.image-header').text();
should be
var clgId = $(this).parentsUntil('.individual-college-container').find('.image-header').text();