Toggling the status of an object from a dynamically generated DIV - javascript

I am having trouble with a checkbox, that when clicked toggles an attribute of my "contact" object from 0 to 1.
The checkbox is part of a DIV that is generated containing all the object details.
The attribute i want to toggle is called "toggled".
What I was trying to achieve, was that when the checkbox is clicked, it executes the UpdateStatus() method with the "ID" of the object passed in as a parameter. Then loop through all the objects in the array to match the "ID" of the object.
The problem is it toggles every objects "toggled" attribute, not just the one im trying to target.
The Code that generates the div with the checkbox
Contact.prototype.generateDiv = function(){
divid = divid + 1;
buttonid = buttonid + 1;
var control = [];
control[0] = divid;
control[1] = buttonid;
var mapLocation = " ";
myControls.push(control);
if(this.daysUntil<=14){ //This checks to see if the contacts birthday is within 7 days or less,and creates a warning flag variable so we can display a warning flag
birthdayFlag = "<img src=resources/birthday.png>"
}else{
birthdayFlag = " "
};
if(this.post){ // this checks to see if there is a value in the Postcode attribute, if not it will set the map location to the address entered
mapLocation = this.post;
}else{
mapLocation = this.address;
}
var childDiv =
"<div class='parentDiv'>" +
this.firstName + " " + this.surname + " " + birthdayFlag + "<input type='checkbox' onclick='updateStatus(this.ID)'>" + " " + "<button class='btnForDiv' id='" + buttonid + "'" + " > Click to Expand </button>" +
"<div class='childDiv' id='" + divid + "' " + ">" + "<img class=map src='http://maps.google.com/maps/api/staticmap?scale=1&center=" + mapLocation + "&zoom=14&size=500x350&maptype=hybrid&markers=size:normal|color:RED|label:C|" + mapLocation + "&sensor=false' style='float: right;border-style:groove'>" +
"&nbsp" + "<span style='color:#5f9ea0';> Surname: </span>" + "<br> &nbsp&nbsp&nbsp&nbsp" + this.surname +
"<BR> &nbsp" + "<span style='color:#5f9ea0';> First Name:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.firstName +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Date Of Birth:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.days + "/" + this.months + "/" + this.years +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Telephone Number:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.phone +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Address:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.address + " " + this.post +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Email Address:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.email +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Group:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.group +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Days Until Birthday:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.daysUntil +
"</div>" + "</div>" + "<HR width=1000px>" + "<BR> ";
return childDiv;
The code that is supposed to toggle the "toggled" attribute
var updateStatus = function(thisID){
alert("firing");
for (i = 0; i < contacts.length; i += 1) {
if (thisID = contacts[i].ID){
if (contacts[i].toggled = "0"){
contacts[i].toggled = "1";
}else{
if (contacts[i].toggled = "1"){
contacts[i].toggled = "0";
}
}
}
}
}
And the entire code incase it is required
var surnameField,firstNameField,birthdayField, phoneField, addressField, postField, emailField, groupField ; //Declaring variables for the fields
var Contact = function(surname,firstName,date, phone , address , post, email, group, imglink){
this.surname = surname ;
this.firstName = firstName ;
this.birthdayDate = new Date (date) ;
this.phone = phone;
this.address= address;
this.email = email;
this.post = post;
this.group = group;
this.toggled = "0" ;
this.ID = "";
}
var contacts = [];
upcomingBirthdays = [];
divid = 0;
buttonid = 1000;
mapid = 100;
myControls = [];
var getDate = function() {
for (var i= 0, j=contacts.length;i<j;i++){
var y = contacts[i].birthdayDate.getFullYear();
var m = contacts[i].birthdayDate.getMonth();
var d = contacts[i].birthdayDate.getDate();
contacts[i].days = d;
contacts[i].months = m + 1;
contacts[i].years = y ;
var today = new Date() ;
var ty = today.getFullYear();
contacts[i].bdThisYear = new Date(ty,m,d, 0 , 0 , 0);
}
}
var daysUntilBirthday = function(){
for (var i= 0, j=contacts.length;i<j;i++){
var today = new Date() ;
contacts[i].daysUntil = Math.round((contacts[i].bdThisYear - today ) /1000/60/60/24+1);
if (contacts[i].daysUntil <= 0){
contacts[i].daysUntil = contacts[i].daysUntil + 365 ;
}
}
}
var birthdayCheck = function(){
for (var i= 0, j=contacts.length;i<j;i++){
birth = "\n" + contacts[i].firstName + " " + contacts[i].surname + " has a birthday in " + contacts[i].daysUntil + " days" ;
if(contacts[i].daysUntil <= 14){
upcomingBirthdays.push (birth);
}
}
if(upcomingBirthdays.length > 0){
alert(upcomingBirthdays);
}
}
Contact.prototype.generateDiv = function(){
divid = divid + 1;
buttonid = buttonid + 1;
var control = [];
control[0] = divid;
control[1] = buttonid;
var mapLocation = " ";
myControls.push(control);
if(this.daysUntil<=14){ //This checks to see if the contacts birthday is within 7 days or less,and creates a warning flag variable so we can display a warning flag
birthdayFlag = "<img src=resources/birthday.png>"
}else{
birthdayFlag = " "
};
if(this.post){ // this checks to see if there is a value in the Postcode attribute, if not it will set the map location to the address entered
mapLocation = this.post;
}else{
mapLocation = this.address;
}
var childDiv =
"<div class='parentDiv'>" +
this.firstName + " " + this.surname + " " + birthdayFlag + "<input type='checkbox' onclick='updateStatus(this.ID)'>" + " " + "<button class='btnForDiv' id='" + buttonid + "'" + " > Click to Expand </button>" +
"<div class='childDiv' id='" + divid + "' " + ">" + "<img class=map src='http://maps.google.com/maps/api/staticmap?scale=1&center=" + mapLocation + "&zoom=14&size=500x350&maptype=hybrid&markers=size:normal|color:RED|label:C|" + mapLocation + "&sensor=false' style='float: right;border-style:groove'>" +
"&nbsp" + "<span style='color:#5f9ea0';> Surname: </span>" + "<br> &nbsp&nbsp&nbsp&nbsp" + this.surname +
"<BR> &nbsp" + "<span style='color:#5f9ea0';> First Name:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.firstName +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Date Of Birth:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.days + "/" + this.months + "/" + this.years +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Telephone Number:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.phone +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Address:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.address + " " + this.post +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Email Address:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.email +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Group:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.group +
"<br> &nbsp" + "<span style='color:#5f9ea0';> Days Until Birthday:</span> " +"<br> &nbsp&nbsp&nbsp&nbsp" + this.daysUntil +
"</div>" + "</div>" + "<HR width=1000px>" + "<BR> ";
return childDiv;
}
var updateStatus = function(thisID){
alert("firing");
for (i = 0; i < contacts.length; i += 1) {
if (thisID = contacts[i].ID){
if (contacts[i].toggled = "0"){
contacts[i].toggled = "1";
}else{
if (contacts[i].toggled = "1"){
contacts[i].toggled = "0";
}
}
}
}
}
var assignID = function(){
for (i = 0; i < contacts.length; i += 1) {
contacts[i].ID = "" + i + "" ;
}
}
var removeContacts = function () {
for (i = 0; i < contacts.length; i += 1) {
if (contacts[i].toggled = "1"){
contacts.splice(i,1);
}
}
updateList();
}
var addContact = function(surnameField,firstNameField,birthdayField, phoneField, addressField, postField, emailField, groupField ){
if(surnameField.value){
a = new Contact(surnameField.value, firstNameField.value,birthdayField.value, phoneField.value, addressField.value, postField.value, emailField.value, groupField.value);
contacts.push(a);
}else{ alert("Please complete all fields")}
}
var clearUI = function(){
var white = "#fff";
surnameField.value = "";
surnameField.style.backgroundColor = white;
firstNameField.value = "";
firstNameField.style.backgroundColor = white;
birthdayField.value="";
birthdayField.style.backgroundColor = white;
phoneField.value = "";
phoneField.style.backgroundcolor = white;
addressField.value = "";
addressField.style.backgroundcolor = white;
postField.value = "";
postField.style.backgroundcolor = white;
emailField.value = "";
emailField.style.backgroundcolor = white;
groupField.value="";
groupField.style.backgroundcolor = white;
}
var updateList = function(elements){
assignID();
myControls = []
var tableDiv = document.getElementById("parentDiv"),
cDiv = "<BR>" ;
for (var i= 0, j=elements.length;i<j;i++){
var cntct = elements[i];
cDiv += cntct.generateDiv();
}
tableDiv.innerHTML = cDiv;
getDate();
daysUntilBirthday();
saveContacts();
}
var add = function(){
;
addContact(surnameField,firstNameField,birthdayField, phoneField, addressField, postField, emailField, groupField, imgField);
clearUI();
daysUntilBirthday();
getDate();
updateList(contacts);
updateList(contacts);
};
var saveContacts = function(){
var cntcts = JSON.stringify(contacts);
if (cntcts !==""){
localStorage.contacts = cntcts;
}else{
alert("Could not save contacts");
}
}
var loadContacts = function(){
var cntcts = "";
if(localStorage.contacts !== undefined){
cntcts = localStorage.contacts;
contacts = JSON.parse(cntcts);
var proto = new Contact();
for (var i=0; i<contacts.length; i++){
var cntct = contacts[i]
cntct.__proto__ = proto;
cntct.birthdayDate = new Date(cntct.birthdayDate);
}
}
}
var clearContacts = function(){
contacts = [];
updateList(contacts);
}
var sort_by = function(field, reverse, primer){
var key = function (x) {return primer ? primer(x[field]) : x[field]};
return function (a,b) {
var A = key(a), B = key(b);
return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse];
}
}
var sortBySurname = function(){
contacts.sort(sort_by('surname', false, function(a){return a.toUpperCase()}));
updateList(contacts)
}
var sortByFirstname = function(){
contacts.sort(sort_by('firstName', false, function(a){return a.toUpperCase()}));
updateList(contacts)
}
var sortByGroup= function(){
contacts.sort(sort_by('group', false, function(a){return a.toUpperCase()}));
updateList(contacts)
}
var sortByBirthday= function(){
contacts.sort(sort_by('daysUntil', false, parseInt));
updateList(contacts)
}
window.onload = function(){
loadContacts();
updateList(contacts);
surnameField = document.getElementById("surname");
firstNameField = document.getElementById("firstName")
birthdayField = document.getElementById("birthday");
phoneField = document.getElementById("phone");
addressField = document.getElementById("address");
postField = document.getElementById("post");
emailField = document.getElementById("email");
groupField = document.getElementById("group");
imgField = document.getElementById("image");
addButton = document.getElementById("addButton");
addButton.onclick = add;
delButton = document.getElementById("delButton");
searchField = document.getElementById("searchField");
searchButton = document.getElementById("searchButton");
//searchButton.onclick = doSearch();
//delButton.onclick = removeContacts();
sortSurnameButton = document.getElementById("surnameSort");
sortSurnameButton.onclick = sortBySurname;
sortFirstNameButton = document.getElementById("firstNameSort");
sortFirstNameButton.onclick = sortByFirstname;
sortGroupButton = document.getElementById("groupSort");
sortGroupButton.onclick = sortByGroup;
birthSortButton = document.getElementById("birthSort");
birthSortButton.onclick = sortByBirthday;
clearUI();
birthdayCheck();
}

The mistake in overcomplex toggler:
try this:
if (thisID === contacts[i].ID){ //<- HERE WAS MISTAKE - single =
contacts[i].toggled=contacts[i].toggled==="1"? "0": "1"
}
Best to index your contacts by id in Object to avoid loops by id... or just use id when accessing array, you can use this function to generate like UUIDs.
you can acheive that using:
var addContact = function(surnameField,firstNameField,birthdayField, phoneField, addressField, postField, emailField, groupField ){
if(surnameField.value){
a = new Contact(surnameField.value, firstNameField.value,birthdayField.value, phoneField.value, addressField.value, postField.value, emailField.value, groupField.value);
contacts[GUID()]=a;
}else{ alert("Please complete all fields")}
}
the objects will look than like:
{ef9cffdc-9132-af78-6147-6bfc2cb247dc: {object data}, 405e61ae-881e-4b11-eab6-2f2355ca54ae : {object data},}
and will be easy accessed with objects[ID];
single object delete will look like: delete(objects[ID]);
loop will look:
for (var id in objects) {
var object=objects[id];
}
easy enough ?

Related

Toggle function problem, What am I doing wrong?

I've created a comment system that posts comments in an ordered list. My requirememnts were to add hide/show toggle function to each comment.
Currently, the toggle function only works on the first comment (even when you try to click on 2nd, 3rd, etc.)
I've tried to use querySelectAll, but it didn't work for me. What am I doing wrong?
<div class="textbox">
<h3>Leave comments</h3>
<label for=msg>Name</label><br>
<input type=text id=fname> <br>
<label for=msg>Content</label><br>
<textarea id=msg> </textarea>
<br>
<input type=button onclick="postcomments()" value="Send" />
<input type="reset" value="Reset" />
<ol id="showcomments" style="max-width:200px; font-size:12px; padding-left:10px;">
</ol>
</div>
<script>
var ans = [];
function postcomments() {
var fname = document.getElementById("fname").value;
var msg = document.getElementById("msg").value;
var lastpos = ans.length;
var current = new Date();
console.log(current);
var time = current.getHours() + ":" + (current.getMinutes() < 10 ? '0' : '') + current.getMinutes();
var date = current.getDate() + "." + (current.getMonth() + 1) + "." + current.getFullYear();
var i = 0;
ans[lastpos] = '<img src="Media/minusicon.png" alt="minusicon" onclick="toggle(document.getElementById("txt&quot))" style="width:8%;" id="plusminusicon">' + " " + "Sent By" + " " + '' + fname + '' + " " + " In" + " " + date + " " + "At" + " " + time + '<br>' + '<span id="txt" class="toggle_panel">' + msg + '</span>' + '<br>' + '-------------------------------';
var ol = document.getElementById("showcomments");
ol.innerHTML = "";
for (var i = 0; i < ans.length; i++) {
ol.innerHTML += "<li id=" + (i + 1) + ">" + ans[i] + "</li>";
}
}
function toggle(x) {
if (x.style.display === "none") {
x.style.display = "block";
document.getElementById("plusminusicon").src = "Media/minusicon.png";
} else {
x.style.display = "none";
document.getElementById("plusminusicon").src = "Media/plusicon.png";
}
}
</script>
You have always the same id for all "txt" span, so the browser change always the first.
If you don't want change much of your code the simpliest solution is add the lastpost variable to the span id and to the parameter of toggle function.
Here the changes to do:
ans[lastpos] = '<img src="Media/minusicon.png" alt="minusicon" onclick="toggle(' + lastpos + ')" style="width:8%;" id="plusminusicon' + lastpos + '">' + " " + "Sent By" + " " + '' + fname + '' + " " + " In" + " " + date + " " + "At" + " " + time + '<br>' + '<span id="txt' + lastpos + '" class="toggle_panel">' + msg + '</span>' + '<br>' + '-------------------------------';
function toggle(x) {
let comment = document.getElementById("txt" + x);
let icon = document.getElementById("plusminusicon" + x);
if (comment.style.display === "none") {
comment.style.display = "block";
icon.src = "Media/minusicon.png";
} else {
comment.style.display = "none";
icon.src = "Media/plusicon.png";
}
}
To bind click listeners to dynamically added elements, you can use event delegation.
document.addEventListener('click', function(e) {
if (e.target && e.target.classList.contains('comment')) {
// do something
}
})
jQuery makes it even easier.
$(document).on('click','.comment',function(){ //do something })
And here's a jsfiddle link to the complete code example. https://jsfiddle.net/ep2bnu0g/

how can the if (){}else{} statement execute both outcomes

I want to create a basic search engine that searches students already existing in an array of objects by first name and last name and if it finds a student named that way enlist it on the page, and if it doesn't write on the page it doesn't exist. but when I have 2 people with the same first name, it gives me both outcome of the if statement. can someone help, please
searchButton.addEventListener("click", function () {
userSearch = searchInput.value;
for (i = 0; i < allStudents.length; i++) {
student = allStudents[i];
if(userSearch.toLowerCase() === student.firstName.toLowerCase() ||
userSearch.toLowerCase() === student.lastName.toLowerCase() ||
userSearch.toLowerCase() === student.firstName.toLowerCase() + " " + student.lastName.toLowerCase() ||
userSearch.toLowerCase() === student.lastName.toLowerCase() + " " + student.firstName.toLowerCase()) {
outputDiv.innerHTML += "<h2> Student: " + student.firstName + " " + student.lastName + "</h2><br>" +
"Age: " + student.age + "<br>" +
"Eye Color: " + student.eyeColor + "<br>" +
"Hair Color: " + student.hairColor + "<br>" +
"Programming Skills: " + student.programmingSkills
searchInput.value = "";
} else {
searchInput.value = "";
outputDiv.innerHTML += "<h2>The student you searched for is not in out database</h2>"
}
}
});
You might want to change your logic as you have two tasks:
Find if the student exists
Display students if available else show message
You can use a variable (found) to keep track of whether any students were found in allStudents, that way you won't have to worry about the else condition executing more than once
let allStudents = [{
firstName: "George",
lastName: "A"
}, {
firstName: "George",
lastName: "B"
}]
searchButton.addEventListener("click", function() {
outputDiv.innerHTML = "";
userSearch = searchInput.value;
var found = false;
for (i = 0; i < allStudents.length; i++) {
student = allStudents[i];
if (userSearch.toLowerCase() === student.firstName.toLowerCase() ||
userSearch.toLowerCase() === student.lastName.toLowerCase() ||
userSearch.toLowerCase() === student.firstName.toLowerCase() + " " + student.lastName.toLowerCase() ||
userSearch.toLowerCase() === student.lastName.toLowerCase() + " " + student.firstName.toLowerCase()) {
outputDiv.innerHTML += "<h2> Student: " + student.firstName + " " + student.lastName + "</h2><br>" +
"Age: " + student.age + "<br>" +
"Eye Color: " + student.eyeColor + "<br>" +
"Hair Color: " + student.hairColor + "<br>" +
"Programming Skills: " + student.programmingSkills
found = true;
}
}
if (!found)
outputDiv.innerHTML = "<h2>The student you searched for is not in out database</h2>";
searchInput.value = "";
});
<input id="searchInput" value="George" />
<button id="searchButton">search</button>
<div id="outputDiv"></div>
You need to rearrange the check to see if it's found or not. You are outputting "that student was not found in our database" INSIDE the loop of students, so it's outputting that text even if another result (in the loop) WAS found. I have corrected that issue by moving the check (for if a student was found) outside of the loop and using a variable to track that. I also changed some things so that you aren't reformatting names toLowerCase() in every loop or having to locate a DOM element.
searchInput = document.getElementById("search_text"),
searchButton = document.getElementById("SearchButton"),
outputDiv = document.getElementById("outputdiv");
searchButton.addEventListener("click", function () {
var userFound = false;
userSearch = searchInput.value;
studentLen = allStudents.length;
outputDiv.innerHTML = "";
for (i = 0; i < studentLen; i++) {
student = allStudents[i];
userSearch = userSearch.toLowerCase();
var fn = student.firstName.toLowerCase(),
ln = student.lastName.toLowerCase();
if(userSearch === fn || userSearch === ln || userSearch === fn + " " + ln || userSearch === ln + " " + fn) {
outputDiv.innerHTML += "<h2> Student: " + student.firstName + " " + student.lastName + "</h2><br>" +
"Age: " + student.age + "<br>" +
"Eye Color: " + student.eyeColor + "<br>" +
"Hair Color: " + student.hairColor + "<br>" +
"Programming Skills: " + student.programmingSkills
searchInput.value = "";
userFound = true;
}
}
if(!userFound){
outputDiv.innerHTML += "<h2>The student you searched for is not in out database</h2>";
}
});
Working fiddle with HTML/JS both included:
https://jsfiddle.net/Ltkacgn4/

jquery not returning the string correctly which consists of 's

I am storing "Uncle Bob's Organic" in data-Iname attribute while retrieving the same value it is retrieving up to "Uncle Bob"
Below is the process I used to retrieve the value from data-Iname
var iname = $(this).attr("data-Iname");
This is what i did so far !!
$(function () {
var ItemId = 0;
$("#AddItems").change(function () {
var SelectedUserId = $("#AddItems").val();
var SelectedItem = $("#AddItems option:selected").text();
//alert(SelectedItem);
var ItemName = "Uncle Bob's Organic";
items.push(SelectedItem + '|' + SelectedUserId);
ItemId++;
//$("#tblItems").append("<tr id=" + ItemId + "><td id=" + ItemId + ">" + SelectedItem + ' ' + "<span class= 'glyphicon glyphicon-trash' title='Delete'></span><br></td></tr>");
$("#AddedItems").append("<div id=div_" + ItemId + ">" + SelectedItem + ' ' + "<span class= 'remove glyphicon glyphicon-trash' id=remove_" + ItemId + " title='Delete' data-Iname='" + ItemName.toString() + "'></span><br></div>");
});
});
$('.container').on('click', '.remove', function () {
var iname = $(this).attr("data-Iname");
var id = this.id;
var split_id = id.split("_");
var deleteindex = split_id[1];
for (var i = 0; i < items.length; i++)
{
if (iname == items[i])
{
alert(items[i])
items.splice(i, 1);
}
}
alert(items);
$("#div_" + deleteindex).remove();
});
try this instead
var ItemName = "Uncle Bob's Organic";
$("#AddedItems").append(
"<div id=div_" +
ItemId +
">" +
SelectedItem +
" " +
"<span class= 'remove glyphicon glyphicon-trash' id=remove_" +
ItemId +
" title='Delete' data-Iname=\"" +
ItemName.toString() +
"\"></span><br></div>"
);
so your output was something like data-Iname = 'Uncle Bob's Organic' .. i just replaced the outer quotes with double quotes

Click on the x in the SelectPicker element

var selectedTags = [];
var selectedTags2 = [];
if (d && d.length) {
d.forEach(function(value, index, array) {
if (index < 5) {
var color = $('option[value="' + value + '"]').data('color');
var tagSpan = '<span class="label label-' + color + '" style="margin-right:1px;"><span class="icon icon-times">' + value + '</span></span>';
selectedTags.push(tagSpan);
list = [];
c = 1;
} else {
var color2 = $('option[value="' + value + '"]').data('color');
var tagSpan2 = '<span class="label label-' + color2 + '" style="margin-right:1px;"><span class="icon icon-times">' + value + '</span></span>';
selectedTags2.push(tagSpan2);
list.push(tagSpan2);
}
});
}
var allTagsElement = selectedTags.join('');
if (a <= 0) {
return "<div class='col-md-11 col-xs-10' style='padding-left:0px;'> " + allTagsElement + " </div><div class='col-md-1 col-xs-2'id='eSecim'></div>";
}
return "<div class='col-md-10 col-xs-10' style='padding-left:0px;'> " + allTagsElement + " </div><div class='col-md-1 col-xs-2'id='eSecim'>+" + (-a) + "</div>";
I want to get out of here.
I use the bootstrap selectpicker. I will select it by clicking on the x next to the elements.

Hide/show dynamic generated div based on select option

I have some divs which are generated by jquery. Inside there is showing up the price, the title and the selected option value.
I've tried a lot of things to hide each div class "result" if no option is select, but with no luck.
Is there a way to hide each div without rewriting the whole code?
JS:
function pcc_calc_forms() {
jQuery(".calcolare").each(function (e) {
var t = jQuery(this).attr("id");
var n = pcc_form_data(t);
jQuery("#" + t + "-mostra").html('<h3 class="pcc-total">Totale : ' + n[0] + "" + "€" + '</h3><div class="content">' + n[1] + '<br /><br /></div>')
})
}
function pcc_form_data(e) {
var t = new Array(0, "");
var n = new Array;
var r = new Array;
$("#" + e + " select").each(function (e) {
var title = $(this).attr("data-title");
var inside = $(this).find("option:selected").attr("data-title");
var i = $(this).find("option:selected").html();
if (inside === undefined) {
inside = " ( " + i + " ) "
} else {
inside = " ( " + inside + " ) "
}
var i = $(this).find("option:selected").attr("data-price");
var s = parseFloat($(this).attr("data-mult"));
if (isNaN(s)) {
s = 1
}
var o = parseFloat($(this).find("option:selected").text());
if (isNaN(o)) {
o = 0
}
if (i !== undefined) {
if (i == "this") {
i = o
} else {
i = parseFloat(i)
}
t[0] = t[0] + parseFloat(i) * s;
if (s == 1) {
t[1] = t[1] + "<div class=\"result\"><b>" + title + "" + inside + "</b> : " + parseFloat(i) + "" + " € " + "</div>"
} else {
t[1] = t[1] + "<div class=\"result\"><b>" + title + "" + inside + "</b> : " + parseFloat(i) + " X " + s + " = " + parseFloat(i) * s + "" + " € " + "</div>"
}
}
});
n = [];
r = [];
return t
}
$(document).ready(function () {
pcc_calc_forms();
$(document).on("change", ".calcolare select", function () {
pcc_calc_forms()
});
});
THIS is the link to the fiddle
Thanks in advance for any hint.
$(document).on("change", ".calcolare select", function () {
var i = $(this).find('option:selected').index();
alert(i);
//if(i>0) ppc_calc_forms();
//else $('.results').hide();
})
This will find the index of the selected option... as you can see, it works, just not with your function...
I would simplify that script as much as possible..
I understand not wanting to rewrite the code substantially at this point. However, for comparison, here is the way I would do it while still holding to your general pattern:
function pcc_calc_forms() {
jQuery(".calcolare").each(function (e) {
var t = jQuery(this).attr("id");
var items = pcc_item_data(t);
var totalPrice = $.makeArray(items).reduce(function(total,item,i,a) {
return total+item.price;
},0);
text = '<h3 class="pcc-total">Totale : ' + totalPrice + "" + "€" + '</h3>';
text += '</h3><div class="content">';
items.each(function(i,item) {
if (item.mult > 1)
text += "<div class=\"result\"><b>" + item.title + " ( " + item.name + " )</b> : " + item.price + " X " + item.mult + " = " + item.price * item.mult + "" + " € " + "</div>";
else
text += "<div class=\"result\"><b>" + item.title + " ( " + item.name + " )</b> : " + item.price + "" + " € " + "</div>";
});
text += '<br /><br /></div>';
jQuery("#" + t + "-mostra").html(text);
});
}
function pcc_item_data(e) {
return $("#" + e + " select").map(function (e) {
if (this.selectedIndex > 0) {
var item = {};
item.title = $(this).attr("data-title");
var inside = $(this).find("option:selected").attr("data-title");
var i = $(this).find("option:selected").html();
item.name = inside ? inside : i;
item.price = parseFloat($(this).find("option:selected").attr("data-price"));
var mult = parseFloat($(this).attr("data-mult"));
item.mult = isNaN(mult) ? 1 : mult;
return item;
}
});
}
$(document).ready(function () {
pcc_calc_forms();
$(document).on("change", ".calcolare select", function () {
pcc_calc_forms();
});
});
What I've done:
Separate data collection (pcc_item_data) from data presentation;
this makes the code more readable and easier to maintain later.
Used map (http://api.jquery.com/jQuery.map/) and reduce (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) to transform / aggregate arrays; they're concise
and expressive once you're familiar with them.

Categories