Why are images duplicated with append()? - javascript

When a "project" is clicked, I want multiple images to be appended to a container element.
Projects and their image URLs are defined in a JavaScript object.
If I click a project, its images are correctly appended. But if I close the project viewer and click that project again, the images are all duplicated. I think this has something to do with append().
What am I doing wrong?
I made a demonstration below:
$(function() {
var projects = {
'project_1': {
'title': 'EduTravel For Credit',
'description': 'Innovative travel for credit.',
'images': [
'http://lorempixel.com/400/30/abstract/1/',
'http://lorempixel.com/400/30/abstract/2/'
]
}
}
var projectData = projects["project_1"];
jQuery('button').on('click', function() {
$.each(projectData.images, function(item) {
$('#project-images').append('<span class="image_holder" style="background-image:url(' + projectData.images[item] + ');"></span>')
});
$('#project_images').html('');
});
});
.image_holder {
display: block;
height: 30px;
background-size: cover;
margin: 0 0 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>CLICK ME</button>
<div id="project-images"></div>
View the live website

From the source code on your website, it seems that you might be attempting to remove images from the container before appending new images:
$('#project_images').html('');
However, that selector uses an underscore while the actual element uses a hyphen:
<div id="project-images">
Also, you are clearing the contents after appending images rather than before.
I suggest using jQuery's empty() on the container before appending new images:
$(function() {
var projects = {
'project_1': {
'images': [
'http://lorempixel.com/400/30/abstract/1/',
'http://lorempixel.com/400/30/abstract/2/'
]
},
'project_2': {
'images': [
'http://lorempixel.com/400/30/abstract/3/',
'http://lorempixel.com/400/30/abstract/4/'
]
},
'project_3': {
'images': [
'http://lorempixel.com/400/30/abstract/5/',
'http://lorempixel.com/400/30/abstract/6/'
]
}
}
var projectData = projects["project_1"];
jQuery('button').on('click', function() {
var id=jQuery(this).data('id'),
projectData=projects["project_"+id];
$('#project-images').empty();
$.each(projectData.images, function(item) {
$('#project-images').append('<span class="image_holder" style="background-image:url(' + projectData.images[item] + ');"></span>')
});
});
});
.image_holder {
display: block;
height: 30px;
background-size: cover;
margin: 0 0 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-id="1">LOAD #1</button>
<button data-id="2">LOAD #2</button>
<button data-id="3">LOAD #3</button>
<div id="project-images"></div>
An alternate method is to concatenate a string of new images, and then set the HTML of the container without using append():
$(function() {
var projects = {
'project_1': {
'images': [
'http://lorempixel.com/400/30/abstract/1/',
'http://lorempixel.com/400/30/abstract/2/'
]
},
'project_2': {
'images': [
'http://lorempixel.com/400/30/abstract/3/',
'http://lorempixel.com/400/30/abstract/4/'
]
},
'project_3': {
'images': [
'http://lorempixel.com/400/30/abstract/5/',
'http://lorempixel.com/400/30/abstract/6/'
]
}
}
var projectData = projects["project_1"];
jQuery('button').on('click', function() {
var id=jQuery(this).data('id'),
projectData=projects["project_"+id],
html_string='';
$.each(projectData.images, function(item) {
html_string+='<span class="image_holder" style="background-image:url(' + projectData.images[item] + ');"></span>';
});
$('#project-images').html(html_string);
});
});
.image_holder {
display: block;
height: 30px;
background-size: cover;
margin: 0 0 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button data-id="1">LOAD #1</button>
<button data-id="2">LOAD #2</button>
<button data-id="3">LOAD #3</button>
<div id="project-images"></div>

Related

How to add closeable text tags to Textarea Kendo | jQuery

I need to use Text area like this image.
I should able to click Text A, Text B, Text C, Text D buttons and, once I click any of this button it should add to the Text area and also able remove added text field from the Text area. Can I do it using jQuery UI , jQuery or JavaScript .Kendo UI is also okay. but I'm unable to found my requirement support Kendo component to do this.
I researched and found this http://skfox.com/jqExamples/insertAtCaret.html , but it's not support added text fields removable function,
As was mentioned in my previous comments on your previous post, this cannot be done with a <textarea> element. These elements can only contain text, they cannot contain other elements like <button> or <span> which would be required to make a remove button.
The following is a very lightweight example and it has many pitfalls. It does give you some ideas of how you might look at proceeding.
$(function() {
function calcWordWidth(str, fontfamily, fontsize) {
var word = $("<span>").css({
display: "none",
"font-family": fontfamily,
"font-size": fontsize
}).html(str).appendTo("body");
var width = word.width();
word.remove();
return width;
}
function addCloseButton(pos, st, en, trg) {
var btn = $("<span>", {
class: "closeBtn"
}).html("x");
btn.css({
position: "absolute",
left: pos + "px",
top: "1px"
});
trg.parent().append(btn);
btn.click(function() {
removeText(st, en, trg);
$(this).remove();
});
}
function addText(str, trg) {
var cur = trg.val();
var start = cur.length;
if (start) {
trg.val(cur + " " + str);
} else {
trg.val(str);
}
cur = trg.val();
var end = cur.length;
var width = calcWordWidth(cur, trg.css("font-family"), trg.css("font-size"));
console.log(width);
addCloseButton(width, start, end, $("#txtMessage"));
}
function removeText(start, end, trg) {
var cur = trg.val();
var upd = cur.slice(0, start) + " " + cur.slice(end);
trg.val(upd);
}
$("button").click(function() {
addText($(this).val(), $("#txtMessage"));
});
});
.closeBtn {
font-family: Arial;
font-size: 12px;
cursor: pointer;
padding: 1px;
background: #ccc;
border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="maincontainer">
<div id="navtoplistline"> </div>
<div id="contentwrapper">
<div><button id="btn-1" value="Hello World!">Hello World!</button></div>
<div id="maincolumn">
<div class="text" style="position: relative;">
<textarea name="txtMessage" id="txtMessage" class="txtDropTarget ui-droppable" cols="80" rows="15"></textarea>
</div>
</div>
</div>
</div>
You can also look at using a <div> element with the contenteditable attribute enabled. Again, pretty complex and would not advise it.
As I suggested, you may be better off using something like TinyMCE. TinyMCE is a JavaScript based Rich Text editor that is highly customizable.
Example: https://jsfiddle.net/Twisty/fngjcse3/
JavaScript
tinymce.init({
selector: 'textarea',
menubar: false,
statusbar: false,
plugins: "code",
toolbar: 'helloWorld allBase code',
setup: function(editor) {
var makeSpan = function(str) {
return '<span class="word"> ' + str + ' <em>x</em><span> ';
}
editor.ui.registry.addButton('helloWorld', {
text: 'Hello World!',
onAction: function(_) {
editor.insertContent(makeSpan("Hello World!"));
}
});
editor.ui.registry.addButton('allBase', {
text: 'All your Base',
onAction: function(_) {
editor.insertContent(makeSpan("All your base"));
}
});
},
content_style: 'span.word em { font-style: normal; font-size: 12px; background: #ccc; cursor: pointer; padding: 1px; border-radius: 3px; }',
init_instance_callback: function(editor) {
editor.on('click', function(e) {
if (e.target.nodeName == "EM") {
console.log("Remove Word.");
e.target.parentElement.remove();
}
});
}
});
This initializes TinyMCE with custom buttons. These buttons add the HTML that would be needed. You can also initialize it with custom callbacks, this can handle the close or remove options you are looking for.

Adding buttons for previous and next slide in Vegas slider

I have very simple slider created with Vegas Slideshow. Now I'm trying to add simple Prev/Next buttons. This is the slider
<div class="slide-caption"></div>
<script src="/assets/js/jquery-3.4.0.min.js"></script>
<script src="/assets/js/vegas.min.js"></script>
<script>
$(".slider-wrapper").vegas({
slides: [
{ src: "/assets/images/slide-1.jpg", text: "Deployment" },
{ src: "/assets/images/slide-1.jpg", text: "Deployment" },
],
walk: function (index, slideSettings) {
$('.slide-caption').html(slideSettings.text);
}
});
</script>
This works perfectly. It is showing the image and the caption bellow.
Now I've tried to add this for the buttons but nothing is appeared on page. There is no errors in console. I'm not sure also if I need to add the HTML for the buttons or it is pull them from the JS and CSS of the Vegas
<script>
$(".slider-wrapper").vegas({
slides: [
{ src: "/assets/images/slide-1.jpg", text: "Deployment" },
{ src: "/assets/images/slide-1.jpg", text: "Deployment" },
],
walk: function (index, slideSettings) {
$('.slide-caption').html(slideSettings.text);
}
});
// buttons
$('a#previous').on('click', function () {
$elmt.vegas('options', 'transition', 'slideRight2').vegas('previous');
});
$('a#next').on('click', function () {
$elmt.vegas('options', 'transition', 'slideLeft2').vegas('next');
});
</script>
Anyone know how exactly I can add the buttons?
I haven't tested this, but it may get you heading in the right direction...
HTML...
<div id="previous" class="button"></div>
<div id="next" class="button"></div>
JQUERY...
<script>
$("#previous").click( function() {
$elmt.vegas('options', 'transition', 'slideRight2').vegas('previous');
});
$("#next").click( function() {
$elmt.vegas('options', 'transition', 'slideRight2').vegas('next');
});
</script>
CSS...
.button {
display: block;
height: 100px;
width: 100px;
background-color: purple;
}

Function only working once

I am working on a map based project and have been using this library to pull info from Google about locations on the map - https://github.com/peledies/google-places
I have created the bellow test to make sure that none of the map based code was causing issues and to show you what is wrong.
The idea is that you can click a button which will pass a Google Place ID to the getInfo() function which will use the library and pull info from Google and display it on the page.
The problem is that this only works once. If you click the other location button nothing appears to happen. The information isn't being updated with info from the new location.
I have even added a clear button which will remove anything in the google related divs on the page.
I have put a console.log in the function and can see that when a button is clicked the ID is being passed to it.
I don't know what could be causing this and Google Dev Console does not show any errors.
function getInfo(p) {
console.log(p);
$("#google-reviews").googlePlaces({
placeId: p,
render: ['reviews', 'address', 'phone', 'hours'],
min_rating: 1,
max_rows: 3,
//rotateTime:5000,
schema: {
displayElement: '#schema', // optional, will use "#schema" by default
beforeText: 'Googlers rated',
middleText: 'based on',
afterText: 'awesome reviewers.',
type: 'Hostel',
},
address: {
displayElement: "#google-address" // optional, will use "#google-address" by default
},
phone: {
displayElement: "#google-phone" // optional, will use "#google-phone" by default
},
hours: {
displayElement: "#google-hours" // optional, will use "#google-hours" by default
}
});
}
function clearInfo() {
document.getElementById('schema').innerHTML = "";
document.getElementById('google-reviews').innerHTML = "";
document.getElementById('google-address').innerHTML = "";
document.getElementById('google-phone').innerHTML = "";
document.getElementById('google-hours').innerHTML = "";
}
.review-stars ul {
display: inline-block;
list-style: none;
}
.review-stars ul li {
float: left;
margin-right: 5px;
}
.review-stars ul li i {
color: #E4B248;
font-size: 12px;
}
/*color: #E4B248;*/
.review-stars ul li i.inactive {
color: #c6c6c6;
}
.star:after {
content: "\2605";
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<button onclick="getInfo('ChIJ7aUBOtBqdkgRMzcGmyqWyxM')">Location 1 (Watford)</button>
<button onclick="getInfo('ChIJ3xiQIe6g2EcRdkyT0iS5GNU')">Location 2 (Buckhurst Hill)</button>
<button onclick="clearInfo()">Clear</button>
<br>
<div id="schema">
<b>Schema - </b>
</div>
<div id="google-reviews"></div>
<div id="google-address"></div>
<div id="google-phone"></div>
<div id="google-hours"></div>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" crossorigin="anonymous"></script>
<script src="https://rawgit.com/peledies/google-places/master/google-places.js"></script>
By looking at the plugin's code, it seems that it can only be initialised once. Beside the plugin, it also adds a googlePlaces function directly to the jQuery object. You can use that function instead, here is an example:
function getInfo(p) {
clearInfo();
$.googlePlaces($("#google-reviews"), {
placeId: p,
render: ['reviews', 'address', 'phone', 'hours'],
min_rating: 1,
max_rows: 3,
//rotateTime:5000,
schema: {
displayElement: '#schema', // optional, will use "#schema" by default
beforeText: 'Googlers rated',
middleText: 'based on',
afterText: 'awesome reviewers.',
type: 'Hostel',
},
address: {
displayElement: "#google-address" // optional, will use "#google-address" by default
},
phone: {
displayElement: "#google-phone" // optional, will use "#google-phone" by default
},
hours: {
displayElement: "#google-hours" // optional, will use "#google-hours" by default
}
});
}
function clearInfo() {
document.getElementById('schema').innerHTML = "";
document.getElementById('google-reviews').innerHTML = "";
document.getElementById('google-address').innerHTML = "";
document.getElementById('google-phone').innerHTML = "";
document.getElementById('google-hours').innerHTML = "";
}
.review-stars ul {
display: inline-block;
list-style: none;
}
.review-stars ul li {
float: left;
margin-right: 5px;
}
.review-stars ul li i {
color: #E4B248;
font-size: 12px;
}
/*color: #E4B248;*/
.review-stars ul li i.inactive {
color: #c6c6c6;
}
.star:after {
content: "\2605";
}
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<button onclick="getInfo('ChIJ7aUBOtBqdkgRMzcGmyqWyxM')">Location 1 (Watford)</button>
<button onclick="getInfo('ChIJ3xiQIe6g2EcRdkyT0iS5GNU')">Location 2 (Buckhurst Hill)</button>
<br>
<div id="schema">
<b>Schema - </b>
</div>
<div id="google-reviews"></div>
<div id="google-address"></div>
<div id="google-phone"></div>
<div id="google-hours"></div>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" crossorigin="anonymous"></script>
<script src="https://rawgit.com/peledies/google-places/master/google-places.js"></script>

I created a sorting tool with Angular.js. How can I animate ng-click to create animated transitions when the items are sorted?

I am building a personal portfolio site with Angular and decided to build my project sorter using pure Angular, instead of doing it with jQuery. I utilized the filter feature of Angular, and am able to get the projects to sort correctly. However, when I'm going through the ng-animate section, there's no support for ng-click and filters that I can see. I was also not able to get the ng-animate to work on the ng-repeat (when the projects are all displayed.) I basically want cool transitions whenever a new filter is selected. The same type of reactions to clicking a button as what happens here.
https://mixitup.kunkalabs.com/
What would be the best course of action to handle animating those types of things? Also, does my code look properly done the 'Angular' way?
jsfiddle-
http://jsfiddle.net/jtbitt/tg6oh0g1/6/
HTML -
<div id="portfolio" ng-controller="mainController as main">
<div class="container">
<div class="row">
<div>Portfolio</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="">
<ul ng-repeat="language in main.languages">
<li><button ng-click="main.projectSort(language)">{{ language.name }}</button></li>
</ul>
</div>
</div>
</div>
<div class="row">
<div ng-repeat="project in main.projectsToShow">
<div class="portfolio-projects language-{{ project.reference }}">{{ project.name }}</div>
</div>
</div>
</div>
</div>
CSS -
#portfolio {
height: 100%;
width: 100%;
font-color: black;
}
#portfolio .container, #portfolio .container .row {
height: 100%;
width: 100%;
}
#portfolio .container .row {
height: 33.3%;
}
.portfolio-projects{
border-style: solid;
border-color: #000000;
padding: 10px;
margin: 10px;
}
.language-angular {
color: blue;
}
.language-ruby {
color: red;
}
.language-node {
color: green;
}
JS -
var app = angular.module('portfolioSorter', []);
app.controller('mainController', ['filterFilter', function(filterFilter) {
var vm = this;
vm.languages = [
{
name: 'ALL',
reference: 'all'
},
{
name: 'ANGULAR',
reference: 'angular'
},
{
name: 'NODE',
reference: 'node'
},
{
name: 'RUBY ON RAILS',
reference: 'ruby'
}
];
vm.projects = [
{
name: 'Tic-Tac-Toe',
language: 'ANGULAR.JS',
reference: 'angular'
},
{
name: 'Escrow',
language: 'RUBY ON RAILS',
reference: 'ruby'
},
{
name: 'Feed.Me',
language: 'RUBY ON RAILS',
reference: 'ruby'
},
{
name: 'Gone-In',
language: 'NODE.JS',
reference: 'node'
}
];
vm.projectsToShow = vm.projects;
vm.projectSort = function(language) {
vm.projectsToShow = vm.projects;
switch (language.reference) {
case 'all':
vm.projectsToShow;
break;
case 'angular':
vm.projectsToShow = filterFilter(vm.projectsToShow, 'angular');
break;
case 'node':
vm.projectsToShow = filterFilter(vm.projectsToShow, 'node');
break;
case 'ruby':
vm.projectsToShow = filterFilter(vm.projectsToShow, 'ruby');
break;
default:
vm.projectsToShow;
};
};
}]);

create an array with values of selected images

Im trying to gather the images selected, take their values, put them into an array, and then push them to a mysql database.
Here is my current code
$(document).ready(function() {
var startfind = $("body").find('.on').val();
var awnsers = $('.on').map(function() {
return $(startfind).text();
}).get().join(',');
$("img").click(function() {
$(this).toggleClass("on");
});
$('button').click(function() {
alert(awnsers);
});
});
#seasoning {
margin: 8px;
font-size: 16px;
height: 100px;
width: 100px;
}
.on {
padding: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://i.imgur.com/7HyU4yh.jpg" id="seasoning" value="0">
<br>
<img src="https://i.imgur.com/OEHCjCK.jpg" id="seasoning" value="1">
<br>
<button>Submit</button>
I can't get the alert to show the values of the items selected.
You can trigger an event when you click on an image
Then listen on that event, an update the answer
use answer when you need it
an I change a little in your html code, that change img's value attr to data-value
============Here is the code and jsFiddle=======================
$(function(){
//catch this values, because you will use these for more than one time
var answers = [];
function getAnswers(){
answers = []; //empty old answers so you can update it
$.map($('.on'), function(item){
answers.push($(item).data('value'));
});
}
//init the answers in case you use it before click
getAnswers();
$(document).on('click', 'img', function(e){
e.preventDefault();
$(this).toggleClass('on');
//trigger the state change when you click on an image
$(document).trigger('state-change');
});
//get answers when event was triggered
$(document).on('state-change', function(e){
getAnswers();
});
$('#btn-show').click(function(){
alert(answers.join(',') || 'nothing was selected');
});
});
#seasoning {
margin: 8px;
font-size: 16px;
height: 100px;
width: 100px;
}
.on {
padding: 10px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img src="https://i.imgur.com/7HyU4yh.jpg" id="seasoning" data-value="0">
<br>
<img src="https://i.imgur.com/OEHCjCK.jpg" id="seasoning" data-value="1">
<br>
<button id="btn-show">Submit</button>
Please check this code.
$("img").on('click',function() {
$(this).toggleClass("on");
});
$(document).on('click', 'button', function() {
var awnsers = $('.on').map(function() {
return $(this).attr('value');
}).get().join(',');
alert(awnsers);
});
Working fiddle - http://jsfiddle.net/Ashish_developer/6ezf363a/

Categories

Resources