jquery each() and js array not working as expected - javascript

I have this code in html:
<div class="box-content">
<span>
<h4 id="title">title1</h4>
<h5 id="texto"></h5>
</span>
<span>
<h4 id="title">title2</h4>
<h5 id="texto"></h5>
</span>
<span>
<h4 id="title">title3</h4>
<h5 id="texto"></h5>
</span>
....
</div>
and I need to populate that structure using an array as follows
$(".pluscontrol").click(function(){
var itemBoxValues1 = ["text1", "text2", "text3"];
var i = 0;
$('.box-content').children().each(function(){
var tmp = itemBoxValues1[i];
$('.box-content').children().children("h5").text(" id: "+i+" val "+tmp);
i++;
});
});
but it doesn't work as I expected because in all <h5> elements print this:
<span>
<h4 id="title">title n </h4>
<h5 id="texto">id: 35 val 23</h5>
</span>
I don't understand why it's happen. Thanks.

Make your selector tighter so you don't need .children() methods. With .each() you don't need to increment i because it's built in and the this is also established as well.
Also, you need to use class instead of id, because id must be unique per document (i.e. the webpage). With classes (which you'll need to change to or HTML is not valid), you could use $('.texto') instead of $(.box-content h5').
$(".pluscontrol").click(function() {
var tmp = ["text1", "text2", "text3"];
$('.box-content h5').each(function(i) {
$(this).text(" id: " + i + " val: " + tmp[i]);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box-content">
<span>
<h4 class="title">title1</h4>
<h5 class="texto"></h5>
</span>
<span>
<h4 class="title">title2</h4>
<h5 class="texto"></h5>
</span>
<span>
<h4 class="title">title3</h4>
<h5 class="texto"></h5>
</span>
<button class='pluscontrol'>GO</button>

Try this:
$(".pluscontrol").click(function(){
var itemBoxValues1 = ["text1", "text2", "text3"];
var i = 0;
$('.box-content').children().each(function(){
var tmp = itemBoxValues1[i];
$(this).children("h5").text(" id: "+ i +" val "+ tmp);
i++;
});
});
Update
Inside each, you need to find children of current span, so you need to use $(this), this $('.box-content').children().children("h5") will return all h5 tags
Also you can use following to save some lines of your code:
var itemBoxValues1 = ["text1", "text2", "text3"];
$('.box-content > span').each(function(i, span){
$(span).children("h5").text(" id: "+ i +" val "+ itemBoxValues1[i]);
});

try this :
<html>
<head></head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<style type="text/css">
[class^="B_class"]:first-child{
display: none;
}
</style>
<body>
<div class="box-content">
<span>
<h4 id="title">title1</h4>
<h5 id="text0"></h5>
</span>
<span>
<h4 id="title">title2</h4>
<h5 id="text1"></h5>
</span>
<span>
<h4 id="title">title3</h4>
<h5 id="text2"></h5>
</span>
<input type="button" value="plus+" id="plus">
</div>
</body>
<script type="text/javascript">
$(document).ready(function(){
var items = $(".box-content span").length;
var itemBoxValues1 = ["text1", "text2", "text3"];
$("#plus").click(function(){
for(var i=0;i<items;i++)
{
var tmp = itemBoxValues1[i];
var theid = "#text"+i;
$(theid).text("id :"+i+" val "+tmp);
}
});
});
</script>
</html>
note : don't use same id name for elements.

You are getting id: 35 val 23 in each iteration because the reference to each of the span elements is getting overwritten every time the loop runs (more explanation below).
I would write it like this:
$(".pluscontrol").click(function(){
var itemBoxValues1 = ["text1", "text2", "text3"];
$('.box-content').children().each(function(i){
var tmp = itemBoxValues1[i];
$(this).children("h5").text(" id: " + i + " val: " + tmp);
});
});
You don't need variable "i", nor do you need to increment it inside the loop. jQuery.each() gives you an index variable and automatically increments it inside the loop.
You don't need to re-query the DOM for the children of your span elements. Just call $(this) to get the spans, 'this' is a reference to each object being iterated inside the loop.

An id by definition is unique. You can use data- attributes or a class instead.
Here's how you may re-write your code to take advantage of all the available data:
$('.box-content > span').each(function(i,v) {
$(v).find('h5').text(' id: ' + (i+1) + '; val: ' + $(v).find('h4').text() );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box-content">
<span>
<h4 data-id="title">title1</h4>
<h5 data-id="texto"></h5>
</span>
<span>
<h4 data-id="title">title2</h4>
<h5 data-id="texto"></h5>
</span>
<span>
<h4 data-id="title">title3</h4>
<h5 data-id="texto"></h5>
</span>
....
</div>

Related

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

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

Trying to get multiple <span> elements by classname and change their value to true or false

I've just about tried this every possible way, I'm super new at this.
I'm trying to get the element using class name, and then I'm trying to change it's value to true so that I can run a function I made that uses .push and an if/else statement to build a new array based off of the values in the spans (I'll post that function at the bottom)
Any help anyone can provide would be awesome, I've been at this for the last 3 evenings and I'm just stuck and I have to have this solved by tomorrow.. :(
A billion thanks in advance!
JavaScript
// Function Declaration to check the user's character choice.
function userChoiceCheck(uChoice, low) {
for (var j = 0; j < low.length; j++) {
if (uChoice == low[j]) {
var element = document.getElementsByClassName(low[j]);
element.setAttribute = "true";
console.log(element);
console.log("The value of " + low[j] + " should now be true!");
} else {
document.getElementsByClassName(low[j].class).value = "false";
console.log("The value of " + low[j] + " should now be false!");
}
}
}
HTML
<div class="text-center pt-5">
<h1 id="wordGuessArea">
<span class="m" value="false">__ </span>
<span class="o" value="false">__ </span>
<span class="o" value="false">__ </span>
<span class="s" value="false">__ </span>
<span class="e" value="false">__ </span>
</h1>
</div>
function mentioned above:
// Function Declaration to merge censoredWord Array and upper Array into a
new array called displayArr. Depending on the boolean value of the span that
contains the character.
function mergeArr(low, up, wSplit, cWord) {
for (var m = 0; m < wSplit.length; m++) {
var targetCharSpan = document.getElementsByClassName(low[m]);
var charSpanVal = targetCharSpan.value;
if (charSpanVal == true) {
displayArr.push(up[m]);
} else if (charSpanVal == false) {
displayArr.push(cWord[m]);
}
}
}
I assume that you are having trouble on get all element by class,
if so, you need a loop
getElementsByClassName return a array HTMCollection, instead of using element.setAttribute, you should loop through every element inside your element variable
Like this:
for(let i=0;i<element.length;i++)
{
element[i].setAttribute = "true";
}
You can solve your problem this way using jQuery
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div class="text-center pt-5">
<h1 id="wordGuessArea">
<span class="m" value="false">__ </span>
<span class="o" value="false">__ </span>
<span class="o" value="false">__ </span>
<span class="s" value="false">__ </span>
<span class="e" value="false">__ </span>
</h1>
</div>
<script>
for(var i=0;i<$('#wordGuessArea span').length;i++){
//Applying for all span elements inside wordGuessArea id
$('#wordGuessArea span').html('Bla');
}
</script>
</body>

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>

Load More Button JS - Load new content on page

I'm trying to develop a Load-More button using Javascript calling an API done with PHP.
So far, so good. I can load the new objects in a range i += i + 4 (I load three new comments everytime I press the button).
This is my load-more button:
$(document).ready(function () {
$(".load-more").on('click', function () {
var tab = $(this).data('tab');
var next_page = $(this).data('next-page');
console.log(next_page);
console.log(tab);
$.get($(this).data('url') + '?tab=' + tab + '&page=' + next_page, function (data) {
addNewQuestions($.parseJSON(data));
});
});
});
And for every object loaded I want to print each of these html blocks.
<div class="question-summary narrow">
<div class="col-md-12">
<div class="votes">
<div class="mini-counts"><span title="7 votes">
{if $question['votes_count']}
{$question['votes_count']}
{else}
0
{/if}
</span></div>
<div>votes</div>
</div>
<div {if $question['solved_date']}
class="status answered-accepted"
{else}
class="status answer-selected"
{/if}
title="one of the answers was accepted as the correct answer">
<div class="mini-counts"><span title="1 answer">{$question['answers_count']}</span></div>
<div>answer</div>
</div>
<div class="views">
<div class="mini-counts"><span title="140 views">{$question['views_counter']}</span></div>
<div>views</div>
</div>
<div class="summary">
<h3>
<a href="{questionUrl($question['publicationid'])}" class="question-title" style="font-size: 15px; line-height: 1.4; margin-bottom: .5em;">
{$question['title']}
</a>
</h3>
</div>
<div class = "statistics col-sm-12 text-right" style="padding-top: 8px">
<span>
<i class = "glyphicon glyphicon-time"></i>
<span class="question-updated-at">{$question['creation_date']}</span>
</span>
<span>
<i class = "glyphicon glyphicon-comment"></i>
<span class="question-answers">{$question['answers_count']}</span>
</span>
</div>
</div>
</div>
The problem is that I have several conditions, as {if$question['votes_count']} and I'm struggling because I don't know how get those variables when rendering the html.
Then I found something but I can't figure out how to adapt to my case
On that addNewQuestions I think that a good approach would be:
function addNewQuestions(objects) {
$.each(objects, function (i, object) {
console.log(object);
var lastItem = $('div.active[role="tabpanel"] .question-line:last');
var newLine = lastItem.clone(true);
var newObject = newLine.find('.question-col:eq(' + i + ')');
newObject.find('.question-info-container').attr('data-id', object.publicationid);
newObject.find('.vote-count').html(object.votes);
updateTitleAndLink(newObject.find('.question-title'), object);
lastItem.after(newLine);
});
}
function updateTitleAndLink(questionTitle, object) {
questionTitle.attr('href', questionTitle.data('base-question-url') + object.publicationid);
questionTitle.html(object.title);
}
But nothing happens and I can't figure out why.
Any idea or suggestion?
Kind regards

Display user data inside div - blocks

I am trying to display user data in div blocks depending upon the number of users. I will get the number of users and data from server using ajax. I want to display the user data in a separate div block. If the number of users is 2, I want to display two blocks , 3 users in three blocks...I defined a div
<div class = "users> </div>.
Inside this div, I want to append the users details like
<div class=" user1"> <p><span class="name"></span></p>
<p><span class="age"></span></p>
<p><span class="address"></span></p>
</div>
using jQuery. If there are two users, I have to display the blocks in the center. Depending upon the number of users , I have to align the blocks.(For ex : 6 users - 3 in one row)
How to display the data inside the div?
code:
<div class="users">
<div class="user1">
<p> <span class="name"> </span> </p>
<p> <span class="age"> </span> </p>
<p> <span class="address"> </span> </p>
<p> <span class="phone"> </span> </p>
</div>
<div class="user2">
<p> <span class="name"> </span> </p>
<p> <span class="age"> </span> </p>
<p> <span class="address"> </span> </p>
<p> <span class="phone"> </span> </p>
</div>
</div>
for(var user_name in res) {
$.ajax({
type: 'GET',
timeout: 10000,
dataType: 'json',
url: multidashboard_info_url + '?client=' + user_name,
async: true,
})
.done(function(data) {
console.log(" success and data is ",data);
var dashboard_info = data["dashboard_info"];
var name = dashboard_info["details"]["name"],
age = dashboard_info["details"]["age"],
address = dashboard_info["details"]["address"],
})
.fail(function() {
console.log("error");
})
}
You can use append() method to add content inside html and for multiple solution, you need to create a dynamic function like this:
Here is working jsFiddle.
function addUserData($selector,name,age,address) {
$selector.append('<p><span class="name">'+ name +'</span></p>' +
'<p><span class="age">'+ age +'</span></p>' +
'<p><span class="address">'+ address +'</span></p>');
}
var name1 = 'John',
age1 = 23,
address1 = 'New York';
addUserData($('.user1'),name1,age1,address1);
var name2 = 'Wall',
age2 = 32,
address2 = 'Istanbul';
addUserData($('.user2'),name2,age2,address2);
You may wanna try something like this:
//this object you should be returned as a json_encoded(USERS_ARRAY) at your php controller
var jsonEncodedObject = '[{"name":"Gonsalo Sousa","age":23,"address":"Some Address"},{"name":"Jonh Doe","age":40,"address":"Some Address"}]';
//parseJSON to use with jscript
var users = $.parseJSON(jsonEncodedObject);
//now run the object using $.each()
$(users).each(function(index) {
//appends each user to the #users <div>
$('#users').append('<div class="user' + index + '"><p><span class="name">' + this.name + '</span></p>' + '<p><span class="age">' + this.age + '</span></p>' + '<p><span class="address">' + this.address + '</span></p></div>');
});
[class*="user"] {
border: 1px solid black;
margin-bottom: 5px;
padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="users"></div>
UPDATE
Maybe this can help you
var i = 0;
jQuery(dashboard_info["details"]).each(function(){
var className = "user"+i;
jQuery('#users').append('<div class="'+className+'">/*rest of your html*/</div>')
i++;
});

Categories

Resources