I have a list of items. I can create some items. The problem is that when I push the delete button I want all values to refresh and change. How can I do that?
For example when I delete the third number, then the fourth tag will be third.
$(document).on("click", ".addnew", function() {
id = this.id;
var idsh = parseInt(id.substr(3));
var ids = parseInt(id.substr(3)) + 1;
document.getElementById("ad_" + idsh).style.display = "none";
kanban = document.getElementById("kanban");
var btn = document.createElement("p");
btn.id = "main_" + ids;
btn.innerHTML =
'<span type="text" id="co_' + ids + '" class="counter text-center bg-success text-white" >' + ids + ' </span>' +
'<span id="mo_' + ids + '" class="formulbitti text-center bg-success text-white" > inner </span>' +
'<button id="de_' + ids + '" class="delete text-center bg-success text-white" >delete</button> ' +
'<button type="text" id="ad_' + ids + '" class="addnew text-center bg-success text-white" >add</button>';
kanban.appendChild(btn);
});
$("body").on("click", ".delete", function() {
id = this.id;
var ids = id.substr(3);
$('#main_' + ids).remove();
});
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<div id="kanban">
<span type="text" id="co_1" class="counter text-center bg-success text-white">1</span>
<span type="text" id="mo_1" class="formulbitti text-center bg-success text-white">inner</span>
<button type="text" id="de_1" class="delete text-center bg-success text-white">delete</button>
<button type="text" id="ad_1" class="addnew text-center bg-success text-white">add</button>
</div>
Do not use incremental id attributes. As you can see in your code they add needless complication and have absolutely no benefit.
The best method to do what you require is to use DOM traversal to relate elements to each other. The only tweak you need to make to your HTML is to add a new div to group the span and button elements. From there when a button is clicked you can use closest() to retrieve the nearest .row container and clone/remove it.
The benefit of this is that the HTML becomes standardised and the JS to work with it is the same, regardless of the content or position.
To solve the issue of the counters being updated when an action is performed, create a function which iterates through all the .counter elements and updates their text based on their index in the DOM.
Finally note that button elements have a type of button or submit, never text.
With all that said, try this:
let $kanban = $('#kanban');
let updateCounters = () => $kanban.find('.counter').text(i => i + 1);
$(document).on("click", ".addnew", e => {
$(e.target).closest('.row').clone().appendTo($kanban);
updateCounters();
});
$(document).on("click", ".delete", e => {
$(e.target).closest('.row').remove();
updateCounters();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<div id="kanban">
<div class="row">
<span type="text" class="counter text-center bg-success text-white">1</span>
<span type="text" class="formulbitti text-center bg-success text-white">inner</span>
<button type="button" class="delete text-center bg-success text-white">delete</button>
<button type="button" class="addnew text-center bg-success text-white">add</button>
</div>
</div>
One last thing to note is that it's a litte odd to have a table-level 'add' button on each row. It would make more sense to have a single add button at the top or bottom of the content.
Related
I'm building a website that will have a file upload. It should be possible to both upload picture, and also to drag and drop.
I have a droparea, that opens a file input once clicked.
Thereafter, it adds a new li where it is possible to delete the file.
However, I am not getting this to work with the drag and drop, no matter what I try.
In this fiddle you can see what my challange is.. pressing the field opens up correctly, and I can add and delete files.
It does not work when I drag and drop though.
https://jsfiddle.net/k14fgo0a/
<div class="upload-area text-center ml-4 py-4" id="dropContainer">
<i class="fa fa-upload mt-4 mb-2" style="font-size:50px"></i>
<p class=" mt-1" id="uploadText" style="font-size:18px">Upload file / drag file
here</p>
</div>
<ul class="list-group ml-4" id="attList">
<li class="border-0 bg-transparent" style="list-style-type: none;">
<input id="fileInput" value="%attachments%" type="file" name="attachment_0" class="attachment" />
</li>
</ul>
window.addEventListener("drop", function (e) {
e = e || event;
$(".upload-area").removeClass("onHover");
$("#uploadText").text("Upload file / drag file here");
e.stopPropagation();
e.preventDefault();
}, false);
$(document).ready(function () {
$('#attList').on('change', '.attachment', function () {
var currentInput = $(this);
var inputName = currentInput.attr('name');
var filename = currentInput.val().replace(/C:\\fakepath\\/i, '');
currentInput.css('display', 'none');
$('<li>' + filename + '<button type="button" class="remove ml-2 remove btn btn-danger btn-sm">Delete</button></li>').insertBefore(currentInput);
var idsInput = $('#attachment_ids');
var ids = idsInput.val();
if (ids != '')
idsInput.val(ids + ',' + inputName);
else
idsInput.val(inputName);
var number;
var arr = inputName.split('_');
if (arr.length > 1)
number = parseInt(arr[1]);
number += 1;
$('<li class="mb-1" style="list-style-type: none;"><input id=\"fileInput\" class=\"' + currentInput.attr('class') + '\" type=\"file\" name=\"' + arr[0] + '_' + number + '\" /></li>').insertBefore(currentInput.closest('li'));
});
any help would be appreciated!
I am trying to use .hide() from jQuery to hide some the parents of the li's that has the same class. No success so far. I see the other things like .addClass works fine, but .hide() is not working on this one?
Can someone give me a hand?
This is my code:
add()
function add() {
var element = document.getElementById("tasks");
var name = "acb"
$(element).append(
'<div class="d-flex mt-4">' +
'<span class="col-1">' +
'<li class="not-done" onclick="done(this)">' + name + '</li>' +
'</span>' +
'<span class="col-3">' +
'<button type="button" class="btn-edit">Edit</button>' +
'</span>' +
'</div>'
)
}
$("#show-done").click(function() {
$("li.not-done").parent().parent().hide();
// $("li.done").show();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="tasks">
<div class="d-flex mt-4">
<span class="col-1">
<li class="done" onclick="done(this)">xys</li>
</span>
<span class="col-3">
<button type="button" class="btn-edit">Edit</button>
</span>
</div>
</div>
<button id="show-done">show</button>
I am trying to add an integer to the card id so that I can delete it when pressing the delete button. Any help?
var variable = '' +
'<div id="card+$num.toString(cnt);" class="card col-3" style="width: 18rem;" style="margin-right=3%; margin-right=3%">' +
' <img src="..." class="card-img-top" alt="..." id="image"+String(cnt)>' +
' <div class="card-body">' +
' <h5 class="card-title" id="title"+String(cnt) contentEditable="true"; >Card title</h5>' +
' <p class="card-text" id="desc"+String(cnt) contentEditable="true">Some quick example text to build on the card title and make up the' +
' bulk of the' +
' card\'s content.</p>' +
' <a href="#" class="btn btn-primary" id="button"+ String(cnt) >Go somewhere</a>' +
' <a href="#" id="btn"+String(cnt) class="close"+String(cnt)>Delete</a>' +
' </div>' +
' </div>' +
'';
$(".create").click(function(){
document.getElementById("lastRow").innerHTML+=variable;
});
$(".close"+String(cnt)).click(function(){
console.log("Doulevw!");
document.getElementById("card"+String(cnt)).hidden=true;
});
There are a few concepts that you have to know when rendering dynamic elements with js.
you have a click listener for your .close button. This listener will never fire because this listener is relevant only for your initial DOM. But your closing button is rendered dynamically, which means that listener not relevant for your button.
Easily solving that by attaching onclick to the button, and creating a function. (example follows)
I inspected your code, you DON'T have to use id mechanism to delete/hide your card element (unless you need to fire POST request), you can use parentNode (example follows)
I made some simple changes to your code:
$(".create").click(function(){
let element = `
<div id="card" class="card col- 3" style="width:18rem;style="margin-right=3%; margin-right=3%"><img src="..." class="card-img-top" alt="..." id="image"+String(cnt)><div class="card-body"><h5 class="card-title" id="title" contentEditable="true">Card title</h5><p class="card-text" id="desc" contentEditable="true">Some quick example text to build on the card title and make up the bulk of the' card\'s content.</p><a href="#" class="btn btn-primary" id="button"+ String(cnt) >Go somewhere</a><a href="#" class="close" onclick='deleteCard(this)'>Delete</a></div></div>`;
document.getElementById("lastRow").innerHTML+=element;
});
function deleteCard(delBtn){
delBtn.parentNode.parentNode.hidden = true
}
Notice for the function I added and the onclick that enables the hiding action.
Here is a codeped link for you to test by your self what I did.
Hope this was helpful, any other questions will be great :)
I am trying to write some code that updates a header tag and a button tag. However, when I use the method .text(); it does not work. So I looked up the proper way to do it via other stack overflow questions, and I see basically the same thing. Everyone is telling me to use .text() or .html(). So I am really confused on why it is not working. I am not sure if it has anything to do with values already in the tag.
HTML:
<div class="contents">
<div class="card text-center myCard">
<div class="card-header"></div>
<div class="card-body">
<h5 class="card-title"></h5>
<p class="card-text"></p>
<button type="button" class="btn btn-primary ttBtn"></button>
</div>
<div class="card-footer text-muted"></div>
</div>
</div>
jQuery:
$(".eBtn").on(
"click",
function(event) {
event.preventDefault();
var href = $(this).attr('href');
console.log(href);
$.get(href, function(ary2, status) {
$("#displayAppName").val(ary2.appname);
$("#appcode").val(ary2.appcode);
$("#editStatus").val(ary2.status);
if (ary2.mapstatus == "" || ary2.mapstatus == null) {
mapBool = true;
$("#mapStatus").val("");
$("#createBtn").val('Create');
$('#modalCreateBtn').attr(
'href',
'/create?currentAppcode='
+ ary2.appcode
+ "¤tAcro="
+ ary2.acronym
+ "¤tAppname="
+ ary2.appname);
console.log("Card Create: " + $(".card-title").val());
} else {
$("#mapStatus").val("Mapped");
$("#createBtn").val('Edit');
$('#modalCreateBtn').attr(
'href',
'/edit?currentAppcode='
+ ary2.appcode
+ "¤tAcro="
+ ary2.acronym);
mapBool = true;
console.log("Card Edit: " + $(".card-title").val());
}
});
console.log("Main Boolean : " + this.mapBool)
console.log("Main Boolean : " + mapBool)
if(mapBool){
$(".card-title").text("Application Mapped!");
$(".card-text").text("Continue to view application");
$(".ttBtn").text("New Mapping after");
}
$("#exampleModal").modal();
});
jQuery Change HTML:
$(".card-title").text("Application Mapped!");
$(".card-text").text("Continue to view application");
$(".ttBtn").text("Continue");
Created variable ary2. Hope this help you.
var ary2 = [];
if (ary2.mapstatus == "" || ary2.mapstatus == null) {
$("#mapStatus").val("");
$("#createBtn").val('Create');
$('#modalCreateBtn').attr(
'href',
'/create?currentAppcode=' +
ary2.code +
"¤tAcro=" +
ary2.acro +
"¤tAppname=" +
ary2.name);
$(".card-title").text("Application Mapped!");
$(".card-text").text("Continue to view application");
$(".ttBtn").html("Continue");
} else {
$("#mapStatus").val("Mapped");
$("#createBtn").val('Edit');
$('#modalCreateBtn').attr(
'href',
'/edit?currentAppcode=' +
ary2.code +
"¤tAcro=" +
ary2.acro);
}
$(document).ready(function() {
$(".card-title").text("Application Mapped!");
$(".card-text").text("Continue to view application");
$(".ttBtn").html("Continue");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="contents">
<div class="card text-center myCard">
<div class="card-header"></div>
<div class="card-body">
<h5 class="card-title">Application not mapped!</h5>
<p class="card-text">Click the "New Tier" button to begin mapping.
</p>
<button type="button" class="btn btn-primary ttBtn">New
Mapping</button>
</div>
<div class="card-footer text-muted"></div>
</div>
</div>
I have an issue where hiding a bootstrap popover just resets the text content of my textarea within the popover. There are many of these in my page and they are created dynamically in a loop (with int i being the counter). Here is my html:
<button class="btn btn-sm" data-toggle="popover" data-container="body" data-title="FOR EVALUATOR'S ATTENTION" type="button" data-html="true" #*id="commentPopOver-#i"*# #*onclick="getAttention(#i)"*#>
<span class="glyphicon glyphicon-pencil"></span>
</button>
<div class="popoverContent" style="display: none !important">
<div class="form-group">
<input name="values[#i].AttentionComment" id="comment-#i" hidden />
<textarea class="form-control" onchange="updateText(#i)" id="commentText-#i" rows="3">someText</textarea>
</div>
</div>
and my JS:
$(function () {
$("[data-toggle=popover]").popover({
html: true,
content: function () {
return $('.popoverContent').html();
}
});
})
Now I understand that it's just recreating the popover with it's default text on load, but it should at least be keeping the changes and the value of the textarea after it is closed/hidden. I wrote this JS to try and make it populate a separate hidden input to contain the value even after reset but it didn't work:
function updateText(id) {
var newtext = $('#commentText-' + id).val();
$('#comment-' + id).val(newtext);
}
Any ideas?
When you use content: function () {return $('.popoverContent').html();} the set the content of your tooltips, the tooltips content a copy of the HTML code return by $('.popoverContent').html(); The textarea is also a copy and not reference to the original textarea in your DOM.
When a tooltips opens the plugin inserts its HTML (including the copy mentioned above) in the DOM with a random unique ID. The plugin also insert a aria-describedby attribute to the elements that trigger the tooltip (the button in your case). The aria-describedby holds the same unique ID set for the tooltip.
Now you can use the 'hide.bs.popover` event. When the tooltips close you should copy the content of the textarea inside your tooltip to the (hidden) textarea in your DOM
Example
HTML:
<button type="button" id="po1" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="right" data-html="true">
Popover on right
</button>
<div class="popoverContent" style="display: none !important">
<div class="form-group">
<textarea class="form-control" rows="3">someText 1</textarea>
</div>
</div>
<br>
<button type="button" id="po2" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="right" data-html="true">
Popover on right
</button>
<div class="popoverContent" style="display: none !important">
<div class="form-group">
<textarea class="form-control" rows="3">someText 2</textarea>
</div>
</div>
javascript:
$("[data-toggle=popover]").each(function( index ) {
var that = $(this);
$(this).popover({
html: true,
content: function () {
return $('#' + $(this).attr('id') + ' + .popoverContent').html();
}
});
});
$('[data-toggle=popover]').on('hide.bs.popover', function () {
$('#' + $(this).attr('id') + ' + .popoverContent textarea').html( $('#' + $(this).attr('aria-describedby') + ' .popover-content textarea').val());
});
Demo: http://www.bootply.com/DvOYV12bHg