Unable to get dynamically created checkboxes to work - javascript

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.

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/

how to disable selectlistitem in kendogrid conditionally

I've kendogrid which has a field that allow user to choose the status of the apartment, I'd like to check if value =3 at grid data bound then disable cell from editing.
#(Html.Kendo().Grid<ApartmentModel>()
.Name("UnitsGrid")
.Columns(columns =>
{
columns.ForeignKey(o => o.Status,
new List<SelectListItem>() {
new SelectListItem() { Text = "Not Reserved", Value = "1", Selected = true },
new SelectListItem() { Text = "Reserved", Value = "2" },
new SelectListItem() { Text = "Contracted", Value = "3" } }, "Value", "Text")
At grid databound event
function GridDataBound(data) {
var grid = $("#UnitsGrid").data("kendoGrid");
debugger;
var gridData = grid.dataSource.view();
for (var i = 0; i < gridData.length; i++) {
var gridItem = gridData[i];
if (gridItem.Status == 3) { //Condition
grid.table.find("[name=Status_input]").hide();
}
}
}
I think a column template is a better choice for this scenario. Something like:
columns.Bound(p => p.Status).Template( #<text>
#if(#item.Status == 3){
// Display editable dropdown list
} else {
// Just show the value or a message
"Contracted"
}
</text>
);

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.

dynamically create div element using javascript

I am trying to create html elements dynamically using javascript. For example, when creating a paragraph in my "finalXML" file, I use the syntax below:
function paragraph (finalXML, value)
{
var code1 = 'var para = document.createElement("p");
var t = document.createTextNode("This is the paragraph that should be displayed");
para.appendChild(t);
document.body.appendChild(para);'
return String(finalXML).replace(/add_paragraph_here/g,code1);
}
How would I go about creating a div with radio buttons, for example, using the same process? Can anyone help me with that syntax?
see this example: http://jsfiddle.net/kevalbhatt18/owuqm8j8/
var radio_home = document.getElementById("radio_home");
function makeRadioButton(options) {
var div = document.createElement("div");
for (var i = 0; i < options.length; i++) {
var label = document.createElement("label");
var radio = document.createElement("input");
radio.type = "radio";
radio.name = options[i].name;
radio.value = options[i].value;
label.appendChild(radio);
label.appendChild(document.createTextNode(options[i].text));
div.appendChild(label);
}
radio_home.appendChild(div);
}
var options = [{
name: "first",
value: "yes",
text: "yes"
}, {
name: "first",
value: "no",
text: "no"
}]
var options2 = [{
name: "second",
value: "ohhh yes",
text: "ohhh yes"
}, {
name: "second",
value: "ohhh no",
text: "ohhh no"
}]
makeRadioButton(options);
makeRadioButton(options2);

Problems with create_row() function

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; // <----

Categories