Problems with create_row() function - javascript

All,
This javascript code dynamically adds input boxes based on a user's selection of a dropdown box. I have it almost where it needs to be, but right now, both the "msds_copy" and "cofa_copy" cases display the same data for "html2" when I test. The "msds_copy" selection should make the 2nd form box say "Region/Language" but instead it's saying "Batch Number".
Any ideas why this might be happening?
inquiry_type_onchange: function(e) {
var place_order = 1,
order_status = 2,
telalert_signup = 3,
invoice_questions = 4,
msds_copy = 5,
cofa_copy = 6,
html = null,
html2 = null,
inquiry = e.target,
id = "inquiry_type_addendum",
form_row = dojo.query("."+id);
//Clear any possible previous additions.
if (form_row != null)
form_row.forEach(dojo.destroy);
//Add the correct new field to the form.
switch (inquiry.selectedIndex) {
case place_order:
html = this.create_form_row(id, "Account Number:");
break;
case order_status:
html = this.create_form_row(id, "Order Number:");
break;
case telalert_signup:
html = this.create_form_row(id, "Account Number:");
break;
case invoice_questions:
html = this.create_form_row(id, "Invoice Number");
break;
case msds_copy:
html = this.create_form_row(id, "Product Name:");
html2 = this.create_form_row(id + "_2", "Region / Language:");
case cofa_copy:
html = this.create_form_row(id, "Product Name:");
html2 = this.create_form_row(id + "_2", "Batch Number:");
default:
}
if (html == null) return;
//Place the new element below the inquiry_type field.
var placeat = dojo.byId('buttons');
dojo.place(html, placeat, "before");
if(html2!=null)
dojo.place(html2, placeat, "before");
},
create_form_row: function(id, label) {
//Container
var a = dojo.create("div", { id: id, className: "question inquiry_type_addendum", style: "padding-top:4px;" });
//Label
var b = dojo.create("div", { className: "label", innerHTML: label, style: "margin-top:8px;" }, a);
//Field
var c = dojo.create("div", { className: "field" });
var d = dojo.create("span", { className: "full_number_span span" });
var e = dojo.create("input", { type: "text", className: "textbox full_number", name: label }, d);
dojo.place(d, c);
dojo.place(c, a);
return a;
}
});

You're missing your breaks and the switch case msds_copy is executing then falling through to the next case cofa_copy.
case msds_copy:
html = this.create_form_row(id, "Product Name:");
html2 = this.create_form_row(id + "_2", "Region / Language:");
break; // <----
case cofa_copy:
html = this.create_form_row(id, "Product Name:");
html2 = this.create_form_row(id + "_2", "Batch Number:");
break; // <----

Related

Multiple event listeners only update the last field that was setup

I am trying to setup an order form where the user can enter a quantity into an input field and the total for that particular product will update. There will be dozens of products in the end.
At the moment, I have the product data stored into a javascript object that is turned into an array to work with. Using this array, I have the products and all fields set up. The price is setup based on a products size. Certain products will have multiple sizes and some only one size.
The problem I am having is that when I loop over the products to setup their event listeners, it only seems to work on the last element of the array. Here is just the sections I think are the culprits:
//Set the listener for each products input box
function SetListeners(_prodList) {
for(var p in _prodList)
{
//We need a listener for each size
for(var s in _prodList[p].sizes)
{
//Get the html of the element in question and add a listener with the product details
var inputID = 'input-' + _prodList[p].sizes[s].sku;
document.getElementById(inputID).addEventListener('input', function() {
UpdatePrice(inputID, _prodList[p].sizes[s].price, 'total-' + _prodList[p].id);
UpdateTotal();
});
}
}
}
//Updates our total for each product
function UpdatePrice(_id, _price, _total)
{
var prodQty = document.getElementById(_id).value;
var prodTotal = (prodQty * _price).toFixed(2);
document.getElementById(_total).innerHTML = '$' + prodTotal;
}
How can I get it so that every input box registers to a specific total innerHTML based on the products sku?
Here is a fiddle with the whole code running and with formatting:
https://jsfiddle.net/BlueVolcano/cx70veh3/1/
Here is the full javascript only:
//The total for the order
var orderTotal = 0;
//The data object containing all the products
const products = {
"shirts":
[
{
"name": "Product 1",
"id": "Prod-1",
"img": "https://i.imgur.com/Ycfi8RS.png",
"details": "These are the details for the product.",
"sizes": [
{"size": "Large", "sku": "Prod-1-1", "price": 10.99}
]
},
{
"name": "Product 2",
"id": "Prod-2",
"img": "https://i.imgur.com/Ycfi8RS.png",
"details": "These are the details for the product.",
"sizes": [
{"size": "Large", "sku": "Prod-2-1", "price": 20.99}
]
},
{
"name": "Product 3",
"id": "Prod-3",
"img": "https://i.imgur.com/Ycfi8RS.png",
"details": "These are the details for the product.",
"sizes": [
{"size": "Large", "sku": "Prod-3-1", "price": 30.99},
{"size": "Medium", "sku": "Prod-3-2", "price": 26.99},
{"size": "Small", "sku": "Prod-3-3", "price": 22.99}
]
}
]
};
//Sort all products from data object into array and flatten it
var thisProductList = [];
for(var v in products)
thisProductList.push(products[v]);
thisProductList = thisProductList.flat();
//Category specific lists from the all products
SetProducts(thisProductList, 'shirts');
//Creates our products and adds them as new html elements
function SetProducts(_products, _category)
{
//Create the section header
var sectionDiv = document.createElement('section');
sectionDiv.setAttribute("class", _category);
sectionDiv.innerHTML = '<h2 class="section-header">' + _category.toUpperCase() + '</h2>';
document.getElementById('container').append(sectionDiv);
//Loop through the list and create the products
for(var p in _products)
{
var rowDiv = document.createElement('div');
rowDiv.setAttribute("class","row");
var productDiv = document.createElement('div');
productDiv.setAttribute("class","product");
var productImage = document.createElement('div');
productImage.setAttribute("class","product-image padding");
productImage.innerHTML = '<img src="'+ _products[p].img + '" />';
productDiv.append(productImage);
var productName = document.createElement('div');
productName.setAttribute("class","product-name padding");
productName.innerHTML = '<h2 class="product-header">' + _products[p].name + '</h2>';
productDiv.append(productName);
var productDetails = document.createElement('div');
productDetails.setAttribute("class","product-details");
productDetails.innerHTML = _products[p].details;
productName.append(productDetails);
var productSizes = document.createElement('div');
productSizes.setAttribute("class","product-sizes padding");
for(var s in _products[p].sizes)
{
var temp = document.createElement('div');
var size = _products[p].sizes[s];
temp.setAttribute("id","size-"+size.sku);
_products[p].sizes.length > 1 ? temp.setAttribute("class","flex underline") : temp.setAttribute("class","flex");
var price= document.createElement('div');
price.innerHTML = (size.size == '' ? '' : size.size + ': ') + '<strong>$' + size.price.toFixed(2) + '</strong><br/><span class="sku"><i>' + size.sku + '</i></span>';
price.setAttribute("class","half");
temp.append(price);
var input = document.createElement("input");
input.type = "number";
input.setAttribute("id", "input-" + size.sku);
input.setAttribute("class", "quantity-input half");
temp.append(input);
productSizes.append(temp);
}
productDiv.append(productSizes);
var productTotal = document.createElement('div');
productTotal.setAttribute("id","total-" + _products[p].id);
productTotal.setAttribute("class","product-total padding");
productTotal.innerHTML = '$0.00';
productDiv.append(productTotal);
sectionDiv.append(rowDiv);
rowDiv.append(productDiv);
}
SetListeners(_products);
}
//Set the listener for each products input box
function SetListeners(_prodList) {
for(var p in _prodList)
{
//We need a listener for each size
for(var s in _prodList[p].sizes)
{
//Get the html of the element in question and add a listener with the product details
var inputID = 'input-' + _prodList[p].sizes[s].sku;
document.getElementById(inputID).addEventListener('input', function() {
UpdatePrice(inputID, _prodList[p].sizes[s].price, 'total-' + _prodList[p].id);
UpdateTotal();
});
}
}
}
//Updates our total for each product
function UpdatePrice(_id, _price, _total)
{
var prodQty = document.getElementById(_id).value;
var prodTotal = (prodQty * _price).toFixed(2);
document.getElementById(_total).innerHTML = '$' + prodTotal;
}
//Updates the order total field
function UpdateTotal()
{
orderTotal = 0;
var totals = document.getElementsByClassName('product-total');
for(var i = 0; i < totals.length; i++)
{
var temp = totals[i].innerHTML;
temp = temp.replace('$','');
var t = parseFloat(temp);
orderTotal += t;
}
document.getElementById('top-order-total-val').innerHTML = '$' + orderTotal.toFixed(2);
}
Your issue is caused by using outside variables (inputID, p, s) inside your input handler function. The values of these 3 variables are the values of last product in your loop.
To solve this issue, when generation HTML elements for the products, you could add some more attributes, for storing pricing and its corresponding total's id.
var input = document.createElement("input");
input.type = "number";
input.setAttribute("id", "input-" + size.sku);
input.setAttribute("class", "quantity-input half");
// set additional attribute for calculation
input.setAttribute("price", size.price);
input.setAttribute("total", "total-" + _products[p].id);
input.setAttribute("last-value", "0");
Then in your input handler function, reference these additional attributes for pricing and corresponding total element.
//Get the html of the element in question and add a listener with the product details
var inputID = 'input-' + _prodList[p].sizes[s].sku;
document.getElementById(inputID).addEventListener('input', function() {
var input = event.target;
UpdatePrice(input.id, input.getAttribute("price"), input.getAttribute("total"));
UpdateTotal();
});
In your UpdatePrice function, update formula for total calculation
{New Total} = {Last Total} - {Last Value Of Current Size} + {New Value Of Current Size}
Updated UpdatePrice function:
function UpdatePrice(_id, _price, _total) {
var inputElement = document.getElementById(_id);
var totalElement = document.getElementById(_total);
var prodQty = inputElement.value;
var lastTotal = parseInt(totalElement.getAttribute("last-total"));
var lastValue = parseInt(inputElement.getAttribute("last-value"));
var newValue = prodQty * _price;
var prodTotal = lastTotal - lastValue + newValue;
inputElement.setAttribute("last-value", newValue);
totalElement.setAttribute("last-total", prodTotal);
totalElement.innerHTML = '$' + prodTotal.toFixed(2);
}
You could reference it here: https://jsfiddle.net/bt9dz63a/

Pass Text Value of cascading dropdown list item web controller

I have a MVC web form that contains a couple textbox fields and two dropdown lists. I am trying to pass the text values of my dropdown list back to my controller to use within a method. The first dropdown list is for a location, is dependent on the second dropdown list (for security groups).
The only problem I am having is with the variable (var) value for userDn, I am trying to pass in the Location Name or "Text" value of the first dropdown list item but it is setting the location value to the switch case number of the associated with the dropdown list item instead:
Example:
Firstname: Some
Lastname: Name
Location : Temecula (switch case number 7)
currently returning: "CN=Some Name,OU=7,OU=Some OU,DC=xxx,DC=com
should return : "CN=Some Name,OU=Location Name,OU=Some OU,DC=xxx,DC=com
Am I missing a function in my javascript that would return the Text value of my first dropdown list instead of the switch case number? Any suggestions would be greatly appreciated!
public ActionResult AddUserToGroup()
{
var model = new CreateUser();
List<SelectListItem> li = new List<SelectListItem>();
li.Add(new SelectListItem { Text = "Select", Value = "0" });
li.Add(new SelectListItem { Text = "Des Moines", Value = "1" });
li.Add(new SelectListItem { Text = "Fort Worth", Value = "2" });
li.Add(new SelectListItem { Text = "Kansas City", Value = "3" });
li.Add(new SelectListItem { Text = "Marysville", Value = "4" });
li.Add(new SelectListItem { Text = "South Hack", Value = "5" });
li.Add(new SelectListItem { Text = "St Clair", Value = "6" });
li.Add(new SelectListItem { Text = "Temecula", Value = "7" });
ViewData["location"] = li;
return View(model);
}
public JsonResult GetGroups(string id)
{
List<SelectListItem> groups = new List<SelectListItem>();
switch (id)
{
case "1":
groups.Add(new SelectListItem { Text = "Select", Value = "0" });
groups.Add(new SelectListItem { Text = "DM Genetec 24-7 No Act", Value = "1" });
groups.Add(new SelectListItem { Text = "DM Genetec Admin", Value = "2" });
groups.Add(new SelectListItem { Text = "DM Genetec ExtAct-Front", Value = "3" });
groups.Add(new SelectListItem { Text = "DM Genetec ExtAct-Ship", Value = "4" });
groups.Add(new SelectListItem { Text = "DM Genetec ExtAct-Ship", Value = "5" });
groups.Add(new SelectListItem { Text = "DM Genetec Front Door Inner", Value = "6" });
break;
}
return Json(new SelectList(groups, "Value", "Text"));
}
[HttpPost]
public ActionResult AddUserToGroup(CreateUser model)
{
var group = model.Group;
var location = model.Location;
var groupDn = "CN=" + group + ",OU=Groups,DC=xxx,DC=com";
var user = model.FirstName + " " + model.LastName;
var userDn = "CN=" + user + ",OU=" + location + ",OU=Some OU,DC=xxx,DC=com";
try
{
DirectoryEntry entry = new DirectoryEntry("LDAP://" + groupDn);
entry.Properties["member"].Add(userDn);
entry.CommitChanges();
entry.Close();
}
catch(System.DirectoryServices.DirectoryServicesCOMException E)
{
ModelState.AddModelError("", "Exception adding cool user to additional group" + E);
}
var newUserAddition = model.FirstName + " " + model.LastName;
var newGroupAddition = model.Group;
return RedirectToAction("CompletedUserToGroup", "Users", new { someNewUserAddition = newUserAddition, someNewGroupAddition = newGroupAddition });
}
--Below is the javascript in my view--
<script type="text/javascript">
$(document).ready(function () {
$("#Location").change(function () {
$("#Group").empty();
$.ajax({
type: 'POST',
url: '#Url.Action("GetGroups")',
dataType: 'json',
data: { id: $("#Location").val(), Text: $("#Location").val() },
success: function (groups) {
$.each(groups, function (i, group) {
// $("#Group").append('<option value="' + group.Value + '">' + group.Text + '</option>');
$("#Group").append('<option value="' + group.Text + '">' + group.Text + '</option>');
});
},
error: function (ex) {
alert('Failed to retrieve states.' + ex);
}
});
return false;
})
});
I figured out how to pass in the value, it seems janky but it works, in my POST ActionResult I added the following (var locationValue) after initializing var location, then I changed var userDn to: "CN=" + user + ",OU=" + locationValue + ",OU=Some OU,DC=xxx,DC=com":
var locationValue = "";
if (location == "1")
{
locationValue = "Des Moines";
}
else if (location == "2")
{
locationValue = "Fort Worth";
}
else if (location == "3")
{
locationValue = "Kansas City";
}
else if (location == "4")
{
locationValue = "Marysville";
}
else if (location == "5")
{
locationValue = "South Hack";
}
else if (location == "6")
{
locationValue = "St Clair";
}
else if (location == "7")
{
locationValue = "Temecula";
}
If you don't care about the integer value, then change Value to be the same as Text.
new SelectListItem { Text = "Des Moines", Value = "Des Moines" }
If you don't want to change the Value, then you can obtain the text label from the selected child <option>.
$("#Location option:selected").text()
The value from $("#Location").val() is automatic but the text requires finding the right child option.

Unable to get dynamically created checkboxes to work

I've been searching the site for a solution however, ive had no luck getting this to work. The desired end result for this piece of code will be to hide and show rows on a table with the checkboxes - the checkboxes are default set to checked as the tables by default are all shown, at the end of the code is my current method of trying to get the checkboxes to activate.
function searchContents(table, noRows) {
document.getElementById('dynamicSearchContents').innerHTML = "";
//locals declarations
var i;
var checkboxes = [];
//labels
var lables = [];
var bikesTableRows = ["Bike ID", "Bike Status", "Bike Cost", "Bike type", "Last Maintainance", "Lock Code", "Depot"];
var staffTableRows = ["Staff ID", "Fullname", "Role", "DOB", "Full Address", "Mobile", "Landline", "Email", "Notes"];
var repairTableRows = ["Repair ID", "Bike ID", "Fault", "Reported Data", "Repair Started", "Reapir Completed", "Parts Required", "Assigned Mechanic", "Repair Notes"];
var customerTableRows = ["Customer ID", "Fullname", "DOB", "Full Address", "Mobile", "Landline", "Email", "Notes"];
var collectionsTableRows = ["Job ID", "Collection Depot", "Delivery Depot", "Time and Date Started", "Time and Date Completed", "Assigned Driver"];
for (i = 0; i < noRows; i++) {
//creation
var br = document.createElement("br");
checkboxes[i] = document.createElement('input');
lables[i] = document.createElement('label');
//setting
checkboxes[i].type = "checkbox";
checkboxes[i].name = "checkbox" + i;
checkboxes[i].value = "value";
checkboxes[i].checked = "true";
checkboxes[i].class = "checkboxClass"
checkboxes[i].id = "checkbox" + i;
lables[i].htmlFor = "checkbox" + i;
//what lables
if (table === "bikeInnerTable") {
console.log("Bikes Lables")
lables[i].appendChild(document.createTextNode(bikesTableRows[i]));
}else if (table === "staffInnerTable") {
console.log("Staff Lables")
lables[i].appendChild(document.createTextNode(staffTableRows[i]));
}else if (table === "repairInnerTable") {
console.log("Repair Lables")
lables[i].appendChild(document.createTextNode(repairTableRows[i]));
}else if (table === "customerInnerTable") {
console.log("Customer Lables")
lables[i].appendChild(document.createTextNode(customerTableRows[i]));
}else if (table === "collectionsInnerTable") {
console.log("Collections Lables")
lables[i].appendChild(document.createTextNode(collectionsTableRows[i]));
}
//appending
document.getElementById('dynamicSearchContents').appendChild(lables[i]);
document.getElementById('dynamicSearchContents').appendChild(checkboxes[i]);
document.getElementById('dynamicSearchContents').appendChild(br);
}
$('.checkboxClass').on('change', function(){ // on change of state
if(this.checked) // if changed state is "CHECKED"
{
console.log("blahahaha");
}
});
}
Edit:
A button is pressed which is located on each of the tables, it calls a function to show the search/filter div, and also the below code to populate it's contents
Pass the third argument in the jquery on function like so:
$('body').on('change', '.checkboxClass', function(){ // on change of state
if(this.checked) // if changed state is "CHECKED"
{
console.log("blahahaha");
}
});
}
This will bind any future elements with '.checkboxClass' that are created to this same function.

JS Push Array Not Working

Any idea why this will not push the TFW to the list. TFW is input from a text box that does work, but it will just not push it to the list.
I could not put the code in becuase StackOverflow was mad about how much code it was.
function tfw() {
var goodTrump = [
"america",
"americans",
"white people",
"african americans",
"black people",
"blacks",
"whites",
"latinos",
"latinas",
"mexicans",
"church",
"christianity",
"god",
"jesus",
"church and state",
"trump",
"money"
];
var badTrump = [
"mexico",
"immigration",
"muslims",
"islamic terrorist",
"terrorist",
"islam",
"democrats",
"dexter"
];
var sadTrump = [
"death",
"no money",
"abortion",
"public school system",
"public schools"
];
var done = [
];
var TFW = document.getElementById("TFW").value
for (i = 0; i < done.length; i++) {
console.log(done[i]);
}
if (TFW == "") {
document.getElementById("image").innerHTML = "<img src='http://inthesetimes.com/images/articles/trump_flicker_face_yess.jpg'><br> Cant react to something not there.";
} else if (badTrump.indexOf(TFW) !== -1) {
document.getElementById("image").innerHTML = "<img src='http://inthesetimes.com/images/articles/trump_flicker_face_yess.jpg'>";
} else if (goodTrump.indexOf(TFW) !== -1) {
document.getElementById("image").innerHTML = "<img src='http://noiimages.s3.amazonaws.com/images/redstate/20160614-1525871659.jpg'>";
} else if (sadTrump.indexOf(TFW) !== -1) {
document.getElementById("image").innerHTML = "<img src='http://www.mintpressnews.com/wp-content/uploads/2016/08/1033209603.jpg'>";
} else {
var failsafe = Math.floor(Math.random() * 3);
if (failsafe === 0) {
document.getElementById("image").innerHTML = "<img src='http://inthesetimes.com/images/articles/trump_flicker_face_yess.jpg'>";
goodTrump.push(TFW);
} else if (failsafe === 1) {
document.getElementById("image").innerHTML = "<img src='http://noiimages.s3.amazonaws.com/images/redstate/20160614-1525871659.jpg'>";
badTrump.push(TFW);
} else {
document.getElementById("image").innerHTML = "<img src='http://www.mintpressnews.com/wp-content/uploads/2016/08/1033209603.jpg'>";
sadTrump.push(TFW);
}
}
}
Any one know what the problem is?
You defined TFW with this code, but .value is not a function. If you log your value for TFW, it's probably undefined right now, which would be why you aren't able to push it to an array
You may be thinking of the jQuery function .val() which would return the content of the div with id TFW
var TFW = $("#TFW").val();
Alternatively, there is a pure javascript solution. If #TFW has no nested elements, you could use .innerHTML
var TFW = document.getElementById("TFW").innerHTML

Remove Object from "Object of Objects"

I have a Object that contain objetcs like this.Object {MAILING ADDRESS: "P O BOX 59", APN: "066-102-11-1"} . Now I need data without empty Object. Like I get output like this Output
Object {MAILING ADDRESS: "P O BOX 59", APN: "066-102-11-1"}
Object {MAILING ADDRESS: "", APN: ""}
Object {MAILING ADDRESS: "P O BOX 3", APN: "066-105-11-1"}
Object {MAILING ADDRESS: "", APN: ""}
So in this case I dont want to get 2nd and 4th object. And in case of 100 I dont want to get 2,4,6,8..100 index . Because output after one time is repeating and I have to remove this. ScreenShot of output I getting
//Code How I am creating this
ExportTool.prototype.click = function(value) {
var lidtest = mapport.panels.info.current.selection.features.mem;
if (value != undefined) {
var lid = lidtest[value].attributes.layer_id;
} else {
var lid = lidtest[0].attributes.layer_id;
}
if (!lid) return;
var tbody;
var thead;
tbody = $('<tbody></tbody>');
thead = $('<thead></thead>');
self = this;
// Reset
this.tblHeader = [];
this.tblData = [];
this.labelData = [];
// thead.children().remove();
// tbody.children().remove();
//var tbody;
var layer = mapport.layer(lid);
var tr = $('<tr></tr>');
layer.fields.each(function(field) {
tr.append($('<th ></th>').text(field.name));
// Table heading for the PDF
if (self.availableForTable.indexOf(field.name.toUpperCase()) != -1)
self.tblHeader.push(field.name);
});
tbody.append(tr);
var features = mapport.panels.info.current.features();
for (var i = 0; i < features.length; ++i) {
if (features[i].geometry != null) {
var data = features[i].attributes.data,
row_data = [],
row_field, obj_field = {};
tr = $('<tr></tr>');
layer.fields.each(function(field) {
var field_name = field.name.toUpperCase();
var td = $('<td></td>');
if (data[field.id] != null) td.text(data[field.id]);
tr.append(td);
if (self.availableForTable.indexOf(field_name) != -1) {
row_field = (data[field.id] != null) ? data[field.id] : '';
row_data.push(row_field);
obj_field[field_name] = row_field;
}
});
row_data = row_data.filter(function(entry) {
return /\S/.test(entry);
});
obj_field = JSON.parse(obj_field);
console.log(obj_field);
// Table Data for the PDF
this.tblData.push(row_data);
// Table Data for the PDF
this.labelData.push(obj_field);
tbody.append(tr);
$('#table_multi_layers').append(tbody);
}
}
}
You can use filter option like this. You can change your object to array and apply filter.
var someArray = $.map(obj_field, function(value, index) {
return [value];
});
someArray = [{
MAILINGADDRESS: "P O BOX 59",
APN: "066-102-11-1"
},
{
MAILINGADDRESS: "",
APN: ""
},
{
MAILINGADDRESS: "P O BOX 59",
APN: "066-102-11-1"
}, {
MAILINGADDRESS: "",
APN: ""
}
];
result = someArray.filter(function(el) {
return el.APN !== "";
});
console.log(JSON.stringify(result, null, ' '));

Categories