Why is my .empty() not emptying the parent element? - javascript

I cannot get the jQuery empty method to work on my appended HTML elements.
It's quite a simple problem seemingly, but it has me beat.
I've tried moving the empty method around in the code but I still cannot get it to empty.
Edit: It will not let me edit this unless there is more text so here is some more text.
My jQuery/JavaScript:
// Declares blank arrays
let monthHolidayName = [];
let monthHolidayDescription = [];
let monthHolidayDay = [];
let monthHolidayMonth = [];
let monthHolidayIsoDate = [];
// On change pushes the arrays with the current months data
$('#monthSelect').change(function(){
var selectedMonth = $('#monthSelect').val();
var numSelectedMonth = parseInt(selectedMonth) + 1;
for(i = 0; i < result['data']['holidays'].length; i++){
var holidayMonth = result['data']['holidays'][i]['date']['datetime']['month'];
if(holidayMonth === numSelectedMonth){
// console.log((result['data']['holidays'][i]));
monthHolidayName.push(result['data']['holidays'][i]['name']);
monthHolidayDescription.push(result['data']['holidays'][i]['description']);
monthHolidayDay.push(result['data']['holidays'][i]['date']['datetime']['day']);
monthHolidayMonth.push(result['data']['holidays'][i]['date']['datetime']['month']);
monthHolidayIsoDate.push(result['data']['holidays'][i]['date']['iso']);
}
}
// Empties the #holidays element <--------------------
$("#holidays").empty();
// Appends the data to the modal
for(i = 0; i < monthHolidayName.length; i++){
var holidayName = monthHolidayName[i];
var holidayDescription = monthHolidayDescription[i];
var holidayDay = monthHolidayDay[i];
var holidayDayMonth = monthHolidayMonth[i];
var holidayIsoDate = monthHolidayIsoDate[i];
var dateParsed = Date.parse(`${holidayDay} ${holidayDayMonth}`).toString("MMMM dS");
// Appends elements to #holidays with the data
$("#holidays").append(`<div class="list-group-item list-group-item-action"><div style="text-decoration: underline; text-align: center;">${holidayName}</div><div style="text-align: center">${holidayDescription}</div><small class="text-muted">${holidayIsoDate}</small></div>`);
}
});
My HTML code:
<!-- Calendar Modal -->
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="modal fade " id="calendar-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 id="modalTitle">Holidays</h1>
<button type="button" class="close btn btn-secondary" data-bs-dismiss="modal" >×</button>
</div>
<!-- This is the body section of our modal overlay -->
<div class="modal-body" id="modalBody">
<div class="btn-group dropright">
<select class="form-select form-select-sm mb-3" id="monthSelect">
</select>
</div>
<div class="list-group">
<button type="button" class="list-group-item list-group-item-action active" id="holidayTitle">
Holidays in <span id="currentMonth"></span>
</button>
<span id="holidays">
</span>
</div>
</div>
<!-- This is the footer section of our modal overlay -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" >Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

It seems that you want to both append new data to your existing data while also deleting the old data. Your code is constantly referencing append, which implies that you want to keep the previous data, but your question asks about how to clear the holidays div, and then add the new holiday.
Answering your question, we don't need an array if we're always deleting the previous holiday information, instead we can use a JavaScript Object to hold the information. The other portion that you'll notice I changed is I took out the for loop you had. Since we have a single holiday, we don't need to iterate through an array. The following code should show how to work with a single holiday in an Object. Note that I did not change the HTML
// Declare an object with our empty parameters:
let holiday = {
name: "",
description: "",
day: "",
month: "",
isoDate: ""
};
// On change pushes the arrays with the current months data
$('#monthSelect').change(function(){
var selectedMonth = $('#monthSelect').val();
var numSelectedMonth = parseInt(selectedMonth) + 1;
for(i = 0; i < result['data']['holidays'].length; i++){
var holidayMonth = result['data']['holidays'][i]['date']['datetime']['month'];
if(holidayMonth === numSelectedMonth){
// console.log((result['data']['holidays'][i]));
// Using object setter notation to change each key:
holiday.name = result['data']['holidays'][i]['name'];
holiday.description = result['data']['holidays'][i]['description'];
holiday.day = result['data']['holidays'][i]['date']['datetime']['day'];
holiday.month = result['data']['holidays'][i]['date']['datetime']['month'];
holiday.isoDate = result['data']['holidays'][i]['date']['iso'];
}
}
// Empties the #holidays element <--------------------
$("#holidays").empty();
var dateParsed = Date.parse(`${holiday.day} ${holiday.month}`).toString("MMMM dS");
// Appends elements to #holidays with the data
$("#holidays").append(`<div class="list-group-item list-group-item-action"><div style="text-decoration: underline; text-align: center;">${holiday.name}</div><div style="text-align: center">${holiday.description}</div><small class="text-muted">${holiday.isoDate}</small></div>`);
});

You can manage this
$("#yourDiv").html(""); // jQuery

Related

add to cart button is not responding

my add to cart button is not responding. I have applied javascript on my add to cart button, In the cart button, I have assigned attribute i.e data-product the value that is {{product.id}}.
var updateBtns = document.getElementsByClassName('update-cart')
for (var i = 0; i < updateBtns.length; i++) {
updateBtns[i].addEventListener('click', function() {
var productId = this.dataset.product
var action = this.dataset.action
console.log('productId:', productId, 'action:', action)
})
}
<div class="card-body">
<h5 class="card-title fw-bold text-uppercase">{{product.name}}</h5>
<p class="card-text">
<h4 style="font-size: 1rem; padding: 0.3rem;
opacity: 0.8;">$ {{product.price}} </h4>
</p>
<button data-product={{product.id}} data-action="add" class="btn btn-outline-secondary add-btn update-cart">ADD TO CART</button>
</div>
</div>
The console is not showing anything even though I click on Add to Cart button several times
Instead of getElementsByClassName use querySelectorAll beacuse as #tacoshy stated getElementsByClassName returns an object of HTML Collection not an array. Also length would return the amount of elements within an array but not an object.
const updateBtns = document.querySelectorAll('.update-cart')
updateBtns.forEach((updateBtn) => {
updateBtn.addEventListener('click', (event) => {
var productId = updateBtn.dataset.product
var action = updateBtn.dataset.action
console.log('productId:', productId, 'action:', action)
})
})

Display entire dictionary in modal from grid-table in Razor view with Jquery

I have a pop-up modal (in a partial) that I need to display the contents of a dictionary in a grid-table. It currently works fine, but only if the dictionary is being returned with one {key, val} pair. I cannot seem to make it work for more than one key/val pairs properly. If there is more than one, it is concatenating them all together in the same cols. I also need the function to remove the previous vals when the modal is re-opened. It does this part fine, but I think the Jquery manipulations to add & remove them may be hindering my attempt to add the values.
To clarify, this works with a returned Dictionary that has one {key, value} pair, but I need for it to work with more than one as well without concatenating them together. For example if returned:
{valName1, val1}
{valName2, val2}
{valName3, val3}
Below is my Modal and the Jquery I am using:
<div class="modal fade" id="paramsModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header modal-header-primary">
<a class="btn btn-xs btn-primary pull-right" data-dismiss="modal" aria-label="Close"><span class="glyphicon glyphicon-remove"></span></a>
<h4 class="modal-title" id="modalTitleText">Job Parameters</h4>
</div>
<div class="modal-body">
<div class="list-group">
<div class="row list-group-item list-group-item-heading container divTableHeading" style="width:inherit; margin-bottom:0px;" id="modalGridHeader">
<div class="col-md-6 font-weight-bold"> Parameter: </div>
<div class="col-md-6 font-weight-bold"> Value: </div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
$("button[name='paramsBtn']").click(function () {
/* Grabs ID from col selected */
var $col = $(this).closest('.row').find('.requestId');
var jobRequestId = $col.data('id');
var nameType = $col.data('name');
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId, "name" : nameType},
success: function (results) {
$modal = $('#paramsModal');
$modal.modal("show");
var name = "";
var value = "";
var arr = results;
//loop through arr created from dictionary to grab key(s) and value(s)
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
name += key;
value += results[key];
//Remove previous rows
$("div[name='params']").remove();
//Adding parameters as rows
$('<div class="col-md-6 text-break" name="params"> ' + name + '</div>' + '<div class="col-md-6 text-break" name="params">' + value + '</div>').insertAfter($('#modalGridHeader'));
}
}
}
});
});
</script>
Here is a screenshot of the modal pop-up. In this screen shot, a dictionary with 3 key/val pairs was returned, however you can see that they are all concatenated together.
I was able to achieve what was needed by changing name and value from strings to arrays, and looping through them with another nested for loop:
//loop through arr created from dictionary to grab key(s) and value(s)
for (var key in arr) {
if (arr.hasOwnProperty(key)) {
//name += key;
//value += results[key];
name.push(key);
value.push(results[key])
//Remove previous rows
$("div[name='params']").remove();
for (var i in name) {
//Adding parameters as rows
$('<div class="col-md-6 text-break" name="params"> ' + name[i] + '</div>' + '<div class="col-md-6 text-break" name="params">' + value[i] + '</div>').insertAfter($('#modalGridHeader'));
}
}
}

Push HTML Elements into an array to appendChild them later to a div which is also dynamically created

I have some dynamically created elements.
I want to push these elements to an array to be able to for loop all of them and assign an attribute to each.
The problem is that if I declare an array like this var Array = []; I can't push an HTML element to it. Console log says that:
Cannot read property 'push' of undefined
If I declare the array like this var Array; then I can't push elements to it.
Here is how I wanted to.
var listgroupdiv = document.createElement("div");
var listgroupdiv1 = document.createElement("div");
var listgroupdiv2 = document.createElement("div");
var ListGroupClass = document.createAttribute("class");
ListGroupClass.value = "row";
listgroupdiv.setAttributeNode(ListGroupClass);
var ListGroupClass1 = document.createAttribute("class");
ListGroupClass1.value = "col-4";
listgroupdiv1.setAttributeNode(ListGroupClass1);
var ListGroupClass2 = document.createAttribute("class");
ListGroupClass2.value = "list-group";
listgroupdiv2.setAttributeNode(ListGroupClass2);
var ListGroupID = document.createAttribute("id");
var ListGroupRole = document.createAttribute("role");
ListGroupID.value = "list-tab";
ListGroupRole.value = "tablist";
listgroupdiv2.setAttributeNode(ListGroupID);
listgroupdiv2.setAttributeNode(ListGroupRole);
var id_href = 0;
var Array_A_Group = [];
for(var b = 0; b < CommentArray.length; b++){
if(CommentArray[b].indexOf("Parts:") > -1){
var listgroupa = document.createElement("a");
var listgroupaClass = document.createAttribute("class");
var listgroupaID = document.createAttribute("id");
var listgroupaToggle = document.createAttribute("data-toggle");
var listgroupaHref = document.createAttribute("href");
var listgroupaRole = document.createAttribute("role");
var listgroupaAria = document.createAttribute("aria-controls");
listgroupaClass.value = "list-group-item list-group-item-action";
listgroupaID.value = String(id_href);
listgroupaToggle.value = "list";
listgroupaHref.value = String(id_href);
listgroupaRole.value = "tab";
listgroupaAria.value = "home";
listgroupa.setAttributeNode(listgroupaClass);
listgroupa.setAttributeNode(listgroupaID);
listgroupa.setAttributeNode(listgroupaToggle);
listgroupa.setAttributeNode(listgroupaHref);
listgroupa.setAttributeNode(listgroupaRole);
listgroupa.setAttributeNode(listgroupaAria);
var CommentText = document.createTextNode(CommentArray[b]);
listgroupa.appendChild(CommentText);
Array_A_Group[id_href].push(listgroupa); // <<-- Problem is in this line!
id_href++;
}
}
My goal is to create a div like this:
<div class="row">
<div class="col-4">
<div class="list-group" id="list-tab" role="tablist">
<a class="list-group-item list-group-item-action active" id="list-home-list" data-toggle="list" href="#list-home" role="tab" aria-controls="home">Home</a>
<a class="list-group-item list-group-item-action" id="list-profile-list" data-toggle="list" href="#list-profile" role="tab" aria-controls="profile">Profile</a>
<a class="list-group-item list-group-item-action" id="list-messages-list" data-toggle="list" href="#list-messages" role="tab" aria-controls="messages">Messages</a>
<a class="list-group-item list-group-item-action" id="list-settings-list" data-toggle="list" href="#list-settings" role="tab" aria-controls="settings">Settings</a>
</div>
</div>
<div class="col-8">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="list-home" role="tabpanel" aria-labelledby="list-home-list">...</div>
<div class="tab-pane fade" id="list-profile" role="tabpanel" aria-labelledby="list-profile-list">...</div>
<div class="tab-pane fade" id="list-messages" role="tabpanel" aria-labelledby="list-messages-list">...</div>
<div class="tab-pane fade" id="list-settings" role="tabpanel" aria-labelledby="list-settings-list">...</div>
</div>
</div>
</div>
With unique IDs and unique hrefs, and later add a TextNode to each <a>.
The problem indeed is this line:
Array_A_Group[id_href].push(listgroupa);
The push method of the array object is called on the array itself.
e.g.
Array_A_Group.push(listgroupa);
The way you did, it tries to push the object to an array inside Array_A_Group
at the index id_href. Since this element doesn't exist you correctly get the error Cannot read property 'push' of undefined
Furthermore you don't need to keep an additional variable to keep track of the array's index. After pushing something to an array it's index will increment automatically.

I can´t remove the last item of array

I can remove any item of array unless the last one. I also use angularjs to show information in the view. I don´t know what is happening with the last item of this array. Please, anyone can help me?
Here is HTML:
<div class="row">
<div class="col-md-12">
<h4><strong>Documento {{index + 1}} de {{documentos.length}}:</strong> {{documentos[index].nome}}</h4>
<iframe style="background: #ccc;" ng-show="exibirPreview" frameborder="0" ng-src="{{versaoLink}}" width="100%" height="300px"></iframe>
<div class="alert alert-warning" ng-hide="exibirPreview">
#Html.Raw(Resources.Dialog.SignDocuments.TypeDocumentCanNotPreDisplayed)
</div>
<hr />
<div class="pull-right btn-row" ng-show="documentos.length > 1">
<button class="btn btn-default" type="button" ng-click="RemoveDoc(index)"><i class="fa fa-fw fa-times"></i> #Resources.Common.RemoveDocList</button>
</div>
</div>
</div>
Here is js/angularjs
$scope.documentos = [
{nome:"document1", chave: "8F65579E3737706F", extensao:".pdf"},
{nome:"document2", chave: "8F65579E3730007F", extensao:".pdf"},
{nome:"document3", chave: "8545579E3737706F", extensao:".pdf"},
{nome:"document4", chave: "8555579E3730007F", extensao:".pdf"}
]
$scope.ViewLink = function () {
var versao = $scope.documentos[$scope.index];
$scope.exibirPreview = versao.extensao == ".pdf" || versao.extensao == ".txt";
if (!$scope.exibirPreview) {
$scope.versaoLink = '';
} else {
$scope.versaoLink = '/Documento/VersaoView?chave=' + versao.chave;
}
};
$scope.ViewLink();
$scope.RemoveDoc = function (index) {
$scope.documentos.splice(index, 1);
$scope.ViewLink();
};
Or Plunker
In your HTML you are preventing the deletion of the last element:
<div class="pull-right btn-row" ng-show="documentos.length > 1">
<!-- -->
</div>
documentos.length > 1 means "hide when it reaches one item in the array".
It should be documentos.length == 0.
It's either this or your index value starts from 1 and not from 0.
The simplest solution would be to change your remove function to take in the document instead of the index. Try this:
$scope.RemoveDoc = function(document) {
var index = $scope.documents.indexOf(document);
$scope.documents.splice(index, 1);
}
in view:
<button class="btn" type="button" ng-click="RemoveDoc(document)">Delete</button>

Bind paired data in object to another element outside ng-repeat - angular

I have this array of objects that I need to work with:
$scope.pdfs = [
{ "pdf_title": "Corporate Hire", "attached_file": "http://file1.jpg"},
{ "pdf_title": "Wedding Hire", "attached_file": "http://file2.jpg"},
{ "pdf_title": "Filming Hire", "attached_file": "http://file3.jpg"}
];
The pdf_file value is ng-repeated in li's.
What I want to do is if that li is clicked, to push its paired to another div, say the src for an href.
Here are my workings, but not quite correct:
Controller function:
$scope.bindWithFile = function(value) {
var currentValue = $scope.corpResult = value;
// pdfs support
var pdfs = $scope.pdfs;
for (var i = pdfs.length - 1; i >= 0; i--) {
if (currentValue == hasOwnProperty(key[pdfs])) {
value[pdfs] = $scope.corpLinkHref;
}
};
Markup:
<div class="w-12" ng-controller="corpHireController">
<div class="c-6-set">
<ul>
<li ng-repeat="pdf in pdfs" class="col-7 link link-inherit" ng-click="bindWithFile(pdf.pdf_title)">{{::pdf.pdf_title}}</li>
</ul>
</div>
<div class="c-6-set">
<div class="w-12">
<i class="fs-4 col-7 icon icon-pdf"></i>
</div>
<span class="col-7 h4" ng-bind="corpResult"></span>
<button ng-href="{{::corpLinkHref}}" class="button green2-button smaller-letters full-width">Download</button>
</div>
</div>
What is needed:
Clicking on the titles on the left, binds the pdf_title under the pdf icon and binds the attached_file to the button's href
Instead of passing the title of the selected pdf, why not passing the whole object. This way you don't have to performance any find or search function.
Markup:
<div class="w-12" ng-controller="corpHireController">
<div class="c-6-set">
<ul>
<li ng-repeat="pdf in pdfs" class="col-7 link link-inherit"
ng-click="bindWithFile(pdf)">
{{::pdf.pdf_title}}
</li>
</ul>
</div>
<div class="c-6-set">
<div class="w-12">
<i class="fs-4 col-7 icon icon-pdf"></i>
</div>
<span class="col-7 h4" ng-bind="corpResult"></span>
<button ng-href="{{::corpLinkHref}}"
class="button green2-button smaller-letters full-width">
Download
</button>
</div>
</div>
Controller
$scope.bindWithFile = function(selectedPdf) {
$scope.corpResult = selectedPdf.pdf_title;
$scope.corpLinkHref = selectedPdf.attached_file;
}

Categories

Resources