I've got this button in which I'd like to insert an icon with JavaScript:
<button id="chat5" onclick="actualizarIdChat('{{ elemento.pk }}')" class="btn btn-secondary" style="background-color: maroon; border-color: transparent;border-radius: 15px;height: 60px;margin: 10px 0px 10px 0px;width: 90%;" type="button">
<img class="border rounded-circle" style="width: 50px;height: 50px;border-color: transparent;" src="{{ elemento.producto.info_producto.contenido_multimedia.0.contenido_url }}">
{{ elemento.producto.info_producto.nombre }}
</button>
This is the code I've defined to make it work, but it does nothing.
var idChat = 'chat5';
var icon = document.createElement("div");
icon.innerHTML = '<i class="fa fa-envelope"></i>';
document.getElementById(idChat).appendChild(icon);
How could I do it?
Update javascript part, it looks like:
var buttonElement = document.getElementById("chat5");
buttonElement.innerHTML = buttonElement.innerHTML + '<i class="fa fa-envelope"></i>';
It will work
Related
I am currently working on a webshop, and I'm trying to create a product quantity button. I have three increments and three decrement buttons with the same classes. I'm trying to make them each target their own input field. But what happens to me is that no matter which of the three buttons I click, it only works on the third input field.
I am fairly new to javascript and could use any help. Thank you.
My work so far:
Javascript:
var elem = [].slice.call(document.querySelectorAll('input[type="number"]')).pop()
document.querySelectorAll(".product-quantity-button-up").forEach(function(button){
button.addEventListener("click",function(){
elem.value =Number(elem.value) + 1;
})
})
document.querySelectorAll(".product-quantity-button-down").forEach(function(button){
button.addEventListener("click",function(){
elem.value =Number(elem.value) - 1;
if(elem.value<=0){
elem.value=0
}
})
})
html
(same code x 3)
<div class="product-quantity-button-container">
<div>
<input type="number" min="1">
</div>
<div class="product-quantity-arrow-container">
<button class="product-quantity-button-up">
<img class="product-quantity-arrow" src="arrow-up.svg">
</button>
<button class="product-quantity-button-down">
<img class="product-quantity-arrow" src="arrow-down.svg">
</button>
</div>
</div>
I changed the classes to something less verbose and removed unnecessary <div>s. The original layout of OP will still function properly with the example, just be mindful of the classes -- they must be changed either in OP or in the example if keep the original HTML.
Details are commented in example
/**
Collect all <button> into a NodeList
On each <button> register the "click" event
Event handler incDec() is called
*/
document.querySelectorAll('button').forEach(btn => btn.onclick = incDec);
/**
Event handler passes the Event object by default
Find the closest <section> then find and reference <input>
Reference <input> value and coherce it into a real number
If the clicked <button> has the class ".up"...
...increment >val<...
...otherwise decrement >val<
If >val< is less than 0...
...assign it as 0...
...otherwise keep it's value
Assign the value of <input> as >val<
*/
function incDec(e) {
const num = this.closest(".quantity").querySelector("input");
let val = +num.value;
if (this.matches(".up")) {
val++;
} else {
val--;
}
val = val < 0 ? 0 : val;
num.value = val;
}
html {
font: 300 2ch/1.2 Consolas
}
input,
button {
font: inherit
}
input {
display: block;
width: 77px;
border: 0;
outline: 0;
font-size: 1.5rem;
text-align: center;
}
button {
border: 0;
padding: 5px 3px 0;
background: transparent;
cursor: pointer
}
button:hover,
button:active {
background: rgba(193, 211, 233, 0.6);
}
<section class="quantity">
<input value="0" readonly>
<button class="up">
<img src="https://upload.wikimedia.org/wikipedia/commons/7/76/Arrow_%2880554%29_-_The_Noun_Project.svg" width="32" height="32">
</button>
<button class="down">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/63/Arrow_%2880557%29_-_The_Noun_Project.svg" width="32" height="32">
</button>
</section>
<section class="quantity">
<input value="0" readonly>
<button class="up">
<img src="https://upload.wikimedia.org/wikipedia/commons/7/76/Arrow_%2880554%29_-_The_Noun_Project.svg" width="32" height="32">
</button>
<button class="down">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/63/Arrow_%2880557%29_-_The_Noun_Project.svg" width="32" height="32">
</button>
</section>
<section class="quantity">
<input value="0" readonly>
<button class="up">
<img src="https://upload.wikimedia.org/wikipedia/commons/7/76/Arrow_%2880554%29_-_The_Noun_Project.svg" width="32" height="32">
</button>
<button class="down">
<img src="https://upload.wikimedia.org/wikipedia/commons/6/63/Arrow_%2880557%29_-_The_Noun_Project.svg" width="32" height="32">
</button>
</section>
use this code instead for the same
$('.product-quantity-button-container').each(function(input){
var elem = $(this).find('input[type="number"]')[0];
var button_up =$(this).find(".product-quantity-arrow-container .button-up")[0];
$(button_up).on("click",function(){
elem.value =Number(elem.value) + 1;
});
var button_down =$(this).find(".product-quantity-arrow-container .button-down")[0];
$(button_down).on("click",function(){
elem.value =Number(elem.value) - 1;
if(elem.value<=0){
elem.value=0
}
});
});
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<div class="product-quantity-button-container">
<div>
<input type="number" min="1">
</div>
<div class="product-quantity-arrow-container">
<button class="button-up">
<img class="product-quantity-arrow" src="arrow-up.svg">
</button>
<button class="button-down">
<img class="product-quantity-arrow" src="arrow-down.svg">
</button>
</div>
</div>
<div class="product-quantity-button-container">
<div>
<input type="number" min="1">
</div>
<div class="product-quantity-arrow-container">
<button class="button-up">
<img class="product-quantity-arrow" src="arrow-up.svg">
</button>
<button class="button-down">
<img class="product-quantity-arrow" src="arrow-down.svg">
</button>
</div>
</div>
<div class="product-quantity-button-container">
<div>
<input type="number" min="1">
</div>
<div class="product-quantity-arrow-container">
<button class="button-up">
<img class="product-quantity-arrow" src="arrow-up.svg">
</button>
<button class="button-down">
<img class="product-quantity-arrow" src="arrow-down.svg">
</button>
</div>
</div>
const renderNote = data => {
const postListRef = ref(db, 'Notes/' +data.key);
console.log(data.key)
const newPostRef = push(postListRef);
var status = 'Pending'
var title = 'new note'
var date = '29-4-2022'
var note = 'newly added note'
let card =
`<div id="single-card" class="col-lg-4 col-md-3" data-id=${data.key} ><!--outer layer of single card-->
<div class="card card-body"><!--card body-->
<p class="badge" id="status" style="background-color: rgb(0, 81, 81);">${status}</p>
<span class="side-stick"></span> <!--side-stick color-->
<!-- note title -->
<h5 class="note-title text-truncate w-75 mb-0" >${title}<i class="point fa fa-circle ml-1 font-10"></i></h5><!--fa fa-circle is for the dot dot dot(continuity)-->
<p class="note-date font-12 text-muted mt-0">${date}</p>
<!--note description-->
<div class="note-content">
<p class="note-inner-content text-muted" >${note}<i class="point fa fa-circle ml-1 font-10"></i></p>
</div>
<button class="btn btn-del">Delete${data.key}</button>
<div id="actions" >
</div>
</div>
</div>`
prod.innerHTML += card;
const btnDelete = document.querySelector(`[data-id='${data.key}'] .btn-del`);
console.log(btnDelete);
btnDelete.addEventListener("click",()=>{
console.log('deleting');
});
}
EventListener is not working. But when I print the btnDelete(console.log(btnDelete);) it is printing correctly. But the eventlistener is not workingDoes anybody know what is wrong with the code?
Why donĀ“t you use onclick in HTML?
<button onclick="console.log('deleting');" class="btn btn-del">Delete${data.key}</button>
You can even call a delete Function like that:
HTML:
<button onclick="deleteCard(${data.key})" class="btn btn-del">Delete${data.key}</button>
JavaScript:
function deleteCard(key) {
console.log(`Delete Card with key: ${key}`)
}
I want to zoom the image inside the div but when I am trying to zoom the image the size of the div is also increasing.
<img src="" alt="Image Preview" id="zoom" class="image-preview__image">
<div class="btn-group mt-2" role="group" aria-label="">
<button ng-click="Size=100" class="btn btn-sm btn-group btn-outline-info" onclick="zoomout()" >100%</button>
<button ng-click="Size=200" class="btn btn-sm btn-group btn-outline-info" onclick="zoomin()" >200%</button>
<button ng-click="Size=300" class="btn btn-sm btn-group btn-outline-info">300%</button>
<button ng-click="Size=400" class="btn btn-sm btn-group btn-outline-info">400%</button>
</div>
<script type="text/javascript">
function zoomin() {
var GFG = document.getElementById("zoom");
var currHeight = GFG.clientHeight;
GFG.style.height = (currHeight + 40) + "px";
}
function zoomout() {
var GFG = document.getElementById("zoom");
var currHeight = GFG.clientHeight;
GFG.style.height = (currHeight - 40) + "px";
}
Instead of using the width/height, you can use the transform property to scale the image. If you place that image inside a container with overflow:hidden, you can resize the image to any size you like without it overflowing the container and the image will retain its original size for layout purposes.
With that said, you don't need a container with overflow hidden, but without one, the image will visually grow to whatever size you specify, though it will still maintain the intrinsic layout size.
document.querySelectorAll("button").forEach(e => {
e.addEventListener("click", function(){
let size = this.getAttribute("ng-click").split("=")[1];
let image = document.getElementById("zoom");
image.style.transform = `scale(${size}%)`;
});
});
.image-container
{
width: 200px;
height: 200px;
overflow: hidden;
}
.image-container img
{
transition-duration: 1s;
}
<div class="btn-group mt-2" role="group" aria-label="">
<button ng-click="Size=100" class="btn btn-sm btn-group btn-outline-info">100%</button>
<button ng-click="Size=200" class="btn btn-sm btn-group btn-outline-info">200%</button>
<button ng-click="Size=300" class="btn btn-sm btn-group btn-outline-info">300%</button>
<button ng-click="Size=400" class="btn btn-sm btn-group btn-outline-info">400%</button>
</div>
<div class="image-container">
<img alt="Image Preview" id="zoom" class="image-preview__image" src="https://via.placeholder.com/200x200">
</div>
I'm using flask for my application and I want a div to appear when the user presses on one of the selected buttons. While this works for every button, the "liking feature" only works for the div in the first button. There is an unfilled heart favicon that I swap for a filled in one when the user presses the heart. However, this only works for the first div and not the rest and I can't seem to know why.
function like(status) {
console.log("here");
if (status == 'True') {
console.log(status);
document.getElementById('nofill').style.display = "none";
document.getElementById('fill').style.display = "inline-block";
} else if (status == 'False') {
console.log(status);
document.getElementById('fill').style.display = "none";
document.getElementById('nofill').style.display = "inline-block";
}
}
function showInfo(tag, button_id) {
console.log("Got to the actions.js file");
console.log(button_id);
var selected_tag_div = document.getElementById(tag);
var button = document.getElementById(button_id);
if (selected_tag_div.style.display === "none") {
selected_tag_div.style.display = "block";
selected_tag_div.style.textAlign = "left";
// selected_tag_div.style.backgroundColor = "#5BC0DE";
button.style.opacity = .7;
selected_tag_div.style.height = "100px";
} else {
selected_tag_div.style.display = "none";
button.style.backgroundColor = "#5BC0DE";
button.style.opacity = 1;
}
}
{% if output %}
<p class="section-title">Top #'s to use</p>
<div class="output-container text-center">
{% for tag in output %} {% set button_id = tag[1:] + "-btn" %}
<button type="button" onclick="showInfo('{{tag[1:]}}', '{{button_id}}')" id={{button_id}} class="btn btn-info tag_buttons">{{tag}}
</button>
<div class="selected-container row" id={{tag[1:]}} style="display: none">
<div class="col-sm-12">
<div class="like-button">
<span style="float: right;" onclick="like('True')"><i id='nofill' class="far fa-heart" style="color: #000000; font-size:1.5em; display: inline-block"></i></span>
<span style="float: right;" onclick="like('False')"><i id='fill' class="fas fa-heart" style="color: #FF0000; font-size:1.5em;"></i></span>
</div>
</div>
</div>
{% endfor %}
</div>
{% endif %}
HTML tag id attribute must be unique so you are not supposed to have elements with the same id in the DOM.
<span style="float: right;" onclick="like('True')"><i id='nofill' class="far fa-heart" style="color: #000000; font-size:1.5em; display: inline-block"></i></span>
<span style="float: right;" onclick="like('False')"><i id='fill' class="fas fa-heart" style="color: #FF0000; font-size:1.5em;"></i></span>
One option is to use class attribute instead of id:
<span style="float: right;" onclick="like('True')"><i class='nofill' class="far fa-heart" style="color: #000000; font-size:1.5em; display: inline-block"></i></span>
<span style="float: right;" onclick="like('False')"><i class='fill' class="fas fa-heart" style="color: #FF0000; font-size:1.5em;"></i></span>
Also look at how to use this keyword and learn more about JS events.
There is a table which displays files (one tr one file) there is a dropzonejs created on table so I can drag file and drop on table. I would like to add a "preview" as TR element of a table but I can't do this. This is how my preview template looks like:
<tr class="dz-preview">
<td><span class="name" data-dz-name></span></td>
<td><span class="size" data-dz-size></span></td>
<td colspan="5">
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress> </div>
</div>
</td>
</tr>
Problem is that Dropzone.js does this:
Dropzone.createElement = function(string) {
var div;
div = document.createElement("div");
div.innerHTML = string;
return div.childNodes[0];
};
TR or TBODY is not valid child of DIV so it will be created as TEXT, TEXT doesn't have property querySelectorAll, and there is an error.
Is there a solution to use TR or TBODY as preview template?
Just redefine Dropzone.createElement function in your code.
In my case I use jQuery:
$(function() {
Dropzone.createElement = function(string) {
var el = $(string);
return el[0];
};
var dropzone = new Dropzone(document.body, options);
});
So here's a little fix in Dropzone.createElement function that fixes the problem:
Replace this:
div = document.createElement("div");
With this:
if (string.substr(0, 3) == '<tr'){
// Table elements can not be wrapped into a div
div = document.createElement("tbody");
} else {
div = document.createElement("div");
}
While I recommend #strikes answer as the most suitable answer. I'm attaching this code of a complete implementation using a tabular format which is a extension of #strikes answer and DropzoneJS bootstrap template
PS: Run snippet is functional, so you can try running the snippet here to see if it is properly working.
$('#allselect').change(function () {
var selections = document.getElementsByName('selection');
for( var i=0; i<selections.length; i++){
if(selections[i].checked == false) {
selections[i].checked = true;
}
else {
if(selections[i].checked == true) {
selections[i].checked = false;
}
}
};
});
</script>
<script>
// Get the template HTML and remove it from the doument
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
Dropzone.createElement = function(string) {
var el = $(string);
return el[0];
};
var myDropzone = new Dropzone(document.body, { // Make the whole body a dropzone
url: "{{ route('user.warehouse_images.store') }}", // Set the url
thumbnailWidth: 80,
paramName: "warehouse_image",
thumbnailHeight: 80,
parallelUploads: 20,
previewTemplate: previewTemplate,
autoQueue: false, // Make sure the files aren't queued until manually added
previewsContainer: "#previews", // Define the container to display the previews
clickable: ".fileinput-button", // Define the element that should be used as click trigger to select files.
renameFile: function(file) {
var dt = new Date();
var time = dt.getTime();
return time+file.name;
},
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
});
myDropzone.on("addedfile", function (file) {
// Hookup the start button
file.previewElement.querySelector(".start").onclick = function () {
myDropzone.enqueueFile(file);
};
});
// Update the total progress bar
myDropzone.on("totaluploadprogress", function (progress) {
document.querySelector("#total-progress .progress-bar").style.width = progress + "%";
});
myDropzone.on("sending", function (file) {
// Show the total progress bar when upload starts
document.querySelector("#total-progress").style.opacity = "1";
// And disable the start button
file.previewElement.querySelector(".start").setAttribute("disabled", "disabled");
});
// Hide the total progress bar when nothing's uploading anymore
myDropzone.on("queuecomplete", function (progress) {
document.querySelector("#total-progress").style.opacity = "0";
});
myDropzone.on("sending", function(file, xhr, formData){
formData.append("camera_id", "loremipsum");
console.log(file);
console.log(file.upload.filename);
console.log(xhr);
});
// Setup the buttons for all transfers
// The "add files" button doesn't need to be setup because the config
// `clickable` has already been specified.
document.querySelector("#actions .start").onclick = function () {
myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED));
};
document.querySelector("#actions .cancel").onclick = function () {
myDropzone.removeAllFiles(true);
};
html, body {
height: 100%;
}
#actions {
margin: 2em 0;
}
/* Mimic table appearance */
div.table {
display: table;
}
div.table .file-row {
display: table-row;
}
div.table .file-row > div {
display: table-cell;
vertical-align: top;
border-top: 1px solid #ddd;
padding: 8px;
}
div.table .file-row:nth-child(odd) {
background: #f9f9f9;
}
/* The total progress gets shown by event listeners */
#total-progress {
opacity: 0;
transition: opacity 0.3s linear;
}
/* Hide the progress bar when finished */
#previews .file-row.dz-success .progress {
opacity: 0;
transition: opacity 0.3s linear;
}
/* Hide the delete button initially */
#previews .file-row .delete {
display: none;
}
/* Hide the start and cancel buttons and show the delete button */
#previews .file-row.dz-success .start,
#previews .file-row.dz-success .cancel {
display: none;
}
#previews .file-row.dz-success .delete {
display: block;
}
.custom-control {
position: relative;
display: block;
min-height: 1.5rem;
padding-left: 2.5rem;
}
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/dropzone.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/basic.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src='https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.7.0/dropzone.js'></script>
</head>
<body>
<!--File Dropzone-- -->
<div id="actions" class="row">
<div class="col-lg-1">
<div class="custom-control custom-checkbox">
<input class="custom-control-input" type="checkbox" id="allselect">
<label for="allselect" class="custom-control-label"></label>
</div>
</div>
<div class="col-lg-7">
<!-- The fileinput-button span is used to style the file input field as button -->
<span class="btn btn-success fileinput-button dz-clickable">
<i class="fa fa-plus"></i>
<span>Add files...</span>
</span>
<button type="submit" class="btn btn-primary start">
<i class="fa fa-upload"></i>
<span>Start upload</span>
</button>
<button type="reset" class="btn btn-warning cancel">
<i class="fa fa-ban"></i>
<span>Cancel upload</span>
</button>
</div>
<div class="col-lg-4">
<!-- The global file processing state -->
<span class="fileupload-process">
<div id="total-progress" class="progress progress-striped active" role="progressbar" aria-valuemin="0"
aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;" data-dz-uploadprogress=""></div>
</div>
</span>
</div>
</div>
<div class="row">
<table class="table table-striped">
<thead>
<tr>
<th>Select</th>
<th>Image Preview</th>
<th>Image Name</th>
<th>Camera</th>
<th>Date</th>
<th>Progress</th>
<th>Actions</th>
</tr>
</thead>
<tbody class="table table-striped files" id="previews">
<tr id="template" class="file-row">
<td>
<input type="checkbox" name="selection">
</td>
<td>
<span class="preview"><img data-dz-thumbnail/></span>
</td>
<td>
<p class="name" data-dz-name></p>
<strong class="error text-danger" data-dz-errormessage></strong>
</td>
<td>
<p class="cameraText"> Camera Not set</p>
</td>
<td>
<p class="timestamp">Date Not Set</p>
</td>
<td>
<p class="size" data-dz-size></p>
<div class="progress progress-striped active" role="progressbar" aria-valuemin="0"
aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-success" style="width:0%;"
data-dz-uploadprogress></div>
</div>
</td>
<td>
<button class="btn btn-primary start">
<i class="fa fa-upload"></i>
<span>Start</span>
</button>
<button data-dz-remove class="btn btn-warning cancel">
<i class="fa fa-ban"></i>
<span>Cancel</span>
</button>
<button data-dz-remove class="btn btn-danger delete">
<i class="fa fa-trash"></i>
<span>Delete</span>
</button>
</td>
<td>
<p class="camera" style="visibility: hidden"></p>
</td>
</tr>
</tbody>
</table>
</div>
</body>