Unable to read a true when using array value - javascript

UPDATE(11 Aug 22): Per request from Ruben - The checkboxes are placed next to a column of items using .insertCheckboxes(). They are checked when onEdit(e) is invoked by any entry in the checkbox column. Temporarily the checkbox status is listed next to each item to ensure that the checkbox value is changing. The desired outcome is to capture which checkbox is true so that item can be edited on the associated data entry form. The non-working code is part of a if/else statement. The if works fine, which indicates to me that the logic is OK:
if (newAssetBox === true) {
gatherAsset();
}
But the else statement does NOT work. As you can see below, it is using a counter thru an array to get and list the checkbox value. I have removed the // lines from the original posting for clarity.
Hope this helps better understand the problem.
ORIGINAL POST:
In this function the first if for newAssetBoxs() works just fine.
But if (theCheckedBoxs[count] === true) does not work (the block of code is temporary for trouble shooting purposes). The function is called by an OnEdit(). I have tried many ways and am totally frustrated.
You can see in the second block of code below that I can display the value of the checked box as true just fine (the boxs are between the TRUE/FALSE and the descriptive text) . Please offer some suggestions. Thanks
function checkTheBoxs() {
assetEntryForm.getRange("F2").clearContent();
if (newAssetBox === true) {
gatherAsset();
} else {
for (count = 0; count < 20; count++) {
assetEntryForm.getRange(count + 3, 10, 1, 1).setValue(theCheckedBoxs[count]);
if (theCheckedBoxs[count] === true) {
assetEntryForm.getRange("F2").setValue('Found a True');
} else {
editAsset();
}
}
}
The following block is a partial from the form page. The checkbox, not shown, but there on the form between TRUE and XLR is the only one checked.
FALSE AC / Power cables
TRUE XLR type cable
FALSE Multi Pair cables
FALSE NL4 cable
FALSE NL8 speaker cables
FALSE L14-30 10/4 cable
FALSE Behringer S16 Digital Snake with 100 Foot DuraCat6 Cable

I finally returned to this problem and logger.logged the theCheckedBoxs[count] to discover that it is actually a 2d array (why I am not sure). I was getting [true} instead of true, so I searched around and found that flat() will convert 2D to 1D and bingo, now I find my true with theCheckedBoxs.flat()[count] and life is good again...

Related

If statement in a switch

I am working on a question for a course for learning javascript. I am running into trouble trying to add an if statement inside of a switch. I currently have:
var user = prompt("Are you ready for battle?!").toUpperCase();
switch(user) {
case'YES':
if(YES && NO) {
console.log("Great, let's do it.");
} else {
console.log("Bye");
}
console.log("Great! It will be a long exciting battle.");
break;
case'NO':
console.log("Come back when you are ready.");
break;
case'MAYBE':
console.log("Go away. This is only for the brave");
break;
default:
console.log("You obviously do not belong here. It was a simple yes/no question.")
}
The question is this:
Add some if/else statements to your cases that check to see whether one
condition and another condition are true, as well as whether one condition
or another condition are true. Use && and || at least one time each.
The error I am getting is this: ReferenceError: YES is not defined
What can I put in the if's condition to make this work or how do I define YES?
It would appear that you have two problems working against you here.
First is the issue pointed out in comments that you're treating YES and NO like variables, and they aren't. To avoid robbing you of the opportunity to learn by providing a corrected version of your code, I'll only give relevant examples.
var word = "test";
// If we compare against the string literally, it will have an error
// because it's looking for a variable with that name.
if (word === test) { } // ReferenceError: test is not defined
// we fix this by quoting what we're comparing against
if (word === "test") { } // Code inside the block would be executed :)
// But what about checking the value of "test" by itself?
// A string is "truthy", meaning that it passes the conditional test always.
if ("test") { } // Code would be executed always regardless of the content of var word
// Stringing multiple constants together doesn't make sense
if ("test" && "word") { } // This is equivalent...
if (true && true) { } // ... to this, which doesn't make sense
This brings us to the second problem you're trying to solve. The requirements for your problem specify checking if one condition AND another are true, as well as one condition OR another. The problem is that you only have one conditional to check: the status of the variable user.
It only makes sense to test the condition of something if you don't know what it is. Input received from a user is a perfect example. So I'd recommend that you take more inputs from the user such as name, age, gender, shoe size, or anything else. You can then check conditions as follows:
// You would need to store user input in variables username and age previously...
if (username === "vastlysuperiorman" && age < 13) { console.log("You're awfully young!"); }
// Or to only allow people within an age range...
if (age < 13 || age > 31) { console.log("You must be between 13 and 31 years old to play this game!"); }
Once you have multiple conditions to check, you can check them anywhere--inside a function, inside a case statement, inside another if. It doesn't matter. Just add an if block and test the conditions. :)

Acrobat PDF calculation with checkbox

I've created a PDF form to help create an estimate for plumbing work. There are various lines that the contractor fills in for quanity, cost of the item and then automatically calculates the price for that line; this works fine.
But now I want to add a checkbox to the line that the customer would check if they actually want that work to be done. If they check the box then the price would appear in the final field, otherwise it would display 0.
My fields are:
QtyRow2 ItemCostRow2 CheckboxRow2 PriceRow2
I've tried this Javascript code in the Calculation tab for the PriceRow2 field, but it displays "0" in the price field whether the checkbox is checked or not.
var oFldQty = this.getField("QtyRow2");
var oFldItem = this.getField("ItemCostRow2");
if (this.getField("CheckboxRow2").isBoxChecked(0)) {
nSubTotal = oFldQty.value * oFldItem.value;
} else {
nSubTotal = 0;
}
event.value = nSubTotal;
How should I modify this to get it to work?
If this is the whole code in the calculation, it would be way safer to define nSubTotal; otherwise, it gets defined as a global variable, and can behave strangely.
Also, whenever this calculation runs, and the test results to false, nSubTotal is set to 0. That means, you have to define nSubTotal, and then add to it while you work through the form.
If you want to simply have a result in the field, there is no need to do the detour via a variable; you can set event.value in the true and the false path.
For a single checkbox, it is IMHO easier to use its value (or its "unchecked" value for portability of the code reasons). This leads to the following code snippet:
if (this.getField("CheckboxRow").value != "Off") {
// box is checked
event.value = oFldQtyty.value * oFldItem.value ;
} else {
// box is unchecked
event.value = 0 ;
}
And that should do it.
However, as you have a table, it is best practice to consolidate all calculations into one single script, which can be attached to a hidden read-only field which is not even involved in the calculation itself. This gives you much better overview and control over the calculation, and prevents calculation order errors.

Generate multiple checkboxes from Javascript array?

My jsfiddle will help explain things better than I ever can >< http://jsfiddle.net/L65QD/17/
I've got two select boxes, when you select something from the first select it enables the second. I have quite a few arrays that I'm using as sort of a fake database.
What I need to happen is that depending on what is selected in profile_select it needs to generate checkboxes for every PRIVILEGE_CODE it has, however the checkboxes must be generated with SEC_PRIVILEGES.Name next to them instead of the actual PRIVILEGE_CODE and they must be generated in the correct DIV. Since it's so hard to explain I made a JSFiddle which just about summarizes it http://jsfiddle.net/L65QD/17/
If my instructions aren't clear:
Depending on what profile is selected in the PROFILE_SELECTION
Needs to generate some checkboxes based on what PRIVILEGE_PROFILES.PRIVILEGE_CODES it has
However the checkboxes must have the name from SEC_PRIVILEGES next to them instead of the code, so PRIVILEGE_CODES = Unique_Code
Checkboxes are generated in either the DA div or the MR div based on what Group_Code they have in SEC_PRIVILEGES (this bit really confuses me, can you make it so a DIV ID can be equal to something from an array?) However to generate them in DA or MR it can't really be an IF because my fiddle is just an example and I'd actually have about 30 different codes so I couldn't do 30 IF statements.
This is the method I was experimenting with but it doesn't really make sense and is probably not even close to being on the right lines:
$(document).on('change', '#select_profile', function () {
var Select = $("#select_profile option:selected").text();
$("#apps").html;
for (var i = 0; i < SEC_Privileges.length; i++) {
if (SEC_Privileges[i].Unique_Code == //something?) {
$('#DA').html("<b>lol</b>");
}
}
});
So that's pretty simple:
Correct this fatal error: Array literals are written in square bracket notation ([], not ()). When you log the PRIVILEGE_PROFILE[0].PRIVILEGE_CODE you'll see only the first code is logged as the key's value.
Building the function: Consider what you need:
When a user changes company, all checkboxes must be reset
When a user changes profile, all checkboxes must be reset, then changed accordingly
When 'None' is selected in either dropdown, all checkboxes must be reset
Result: http://jsfiddle.net/kevinvanlierde/L65QD/19/
Some conventions:
Please choose one naming convention and stick with it. The more common ones are lowercase_underscore or CamelCase. You can opt for uppercase, but don't mix them (easier readability). I've had several errors just because I wrote the names incorrectly.
Declare your variables at the start of your function, assign them further on.
Also want to add that if I were to have control over the object's structure, I would probably opt for a more hierarchical tree/ JSON-like structure, eg instead of your current object, do:
var SEC_Privileges = {
'DA': {
'name': 'Dispatch App',
'accesses': {
'DAAccess': 'Access',
'DASuper': 'Supervisor'
}
},
'MR': {
'name': 'MyRoster',
'accesses': {
'MRAccess': 'Access',
'MRSuper': 'Supervisor'
}
}
}
Because the object keys are themselves values, you can use them to build your UI, eg to get the full name of your MRAccess you could do something like SEC_Privileges.MR.name + SEC_Privileges.MR.accesses.MRAccess to get MyRoster Access
There is different ways to approach this but the amount of Privileges would always be the same?. Depending on what your SEC_privileges is if its JSON array then you could loop through that array and access the code and the description. You would then want to validate the selected privileges again the whole set and say something like:
var array = ('one','two','three');
if($.inArray(SEC_privileges[i].Unique_code, array))
{
$('#DA').html("<input type='checkbox' id='"+i+"' value='"+SEC_privileges[i].Unique_code+"' checked/>"+SEC_privileges[i].Unique_desc);
}
else
{
$('#DA').html("<input type='checkbox' id='"+i+"' value='"+SEC_privileges[i].Unique_code+"'/>"+SEC_privileges[i].Unique_desc);
}
A ticked value is done by adding the word checked as part of the html input object. Like illustrated above

How can I remove blank lines in an array generated that show in a dropdown

I have a dropdown that is generated using javascript and html. I have some code which I will post below that loops through this list and should potentially remove any blank lines found but is not working. "$maxfield1rows" has a value of 7, what I am saying is that if the value is a blank (=='') then remove it. I used removeChild but this doesn't seem to work, I also tried splice, I think filter can work but am not sure. I tried the disabled=true but that just makes them disabled and unselectable. Can someone please help?
for(index=1; index<$maxfield1rows; index++) {
if(document.pickDivision.field1.options[index].value=='') {
document.pickDivision.field1.removeChild(document.pickDivision.field1.options[index]);
}
}
Updated below, I'm using $maxfield1rows since that is the amount of maximum number of rows the the loop goes through, also by change I meant that there is an onchange event that gets triggered when the user selects a different option in the dropdown menu, so depending on the option selected the output for field1 changes, sometimes there are 5 values that show and sometimes just 1:
for(index=$maxfield1rows-1; index>=0; index--) {
alert(document.pickDivision.field1.options[index]);
if(document.pickDivision.field1.options[index].value==''){
document.pickDivision.field1.removeChild(document.pickDivision.field1.options[index]);
document.pickDivision.field1.options[index].disabled=true;
}
else{
document.pickDivision.field1.options[index].disabled=false;
}
}
To expand upon my comment, I think the issue is that you are looping forwards through the options array. I am surprised that no error is being thrown when you try to do this. You should loop backwards through the collection to keep from skipping an item.
JS Fiddle demonstrating the error. In the example, items 1 and 2 are blank and item 3 is not.
These built in collections are changed each time your add/remove an item. Using the example in the fiddle, my array changes from [1,2,3] to [2,3] to error no item at index 2.
Looping backwards, my collection takes this change: [1,2,3] to [1,3] to [3].
Here is the code with comments explaining what each part of the for loop is used for and why. You can use a while loop if you prefer too.
//options.length - 1 because arrays are 0 based
//i >= 0 because you don't want to use a negative index on an array
//i-- to loop backwards
for(var i = document.pickDivision.field1.options.length - 1; i >= 0; i--) {
//Is this an empty item
if(document.pickDivision.field1.options[i].value == '') {
//Remove the empty item
document.pickDivision.field1.removeChild(document.pickDivision.field1.options[i]);
}
}
UPDATE
With the newly updated code you posted, you are attempting to access an option element after it has been removed. From the looks of the line, you don't need it anymore as you are already removing the element. If you do still want to disable the element before removing it, move that line above the other line (see comment in code).
for(index=$maxfield1rows-1; index>=0; index--) {
alert(document.pickDivision.field1.options[index]);
if(document.pickDivision.field1.options[index].value==''){
document.pickDivision.field1.removeChild(document.pickDivision.field1.options[index]);
//This line is causing the issue; move it above the previous line or remove it
document.pickDivision.field1.options[index].disabled=true;
}
else{
document.pickDivision.field1.options[index].disabled=false;
}
}
UPDATE 2
Per the question in the comments, when you change the number of options to 6, your code breaks. This is because you are using the hard coded PHP value $maxfield1rows. Since you already know the name of the form and the name of the field in the form, I would recommend you use the length of the options collection in your for loop rather than this variable. This will make sure that no matter how many option elements there are (1, 10, 1000), you will always loop through the entire collection.
for(var i = document.pickDivision.field1.options.length - 1; i >= 0; i--) {

Knockout Can I get around this computed loop?

I have the following structure for a bunch of objects in my viewmodel
I have an underlying array filled with objects that have ko.observable items in.
Ex: selections = [{Legs:{'0':ko.observable(12)}}, {Legs:{'0':ko.observable(0)}}]
What I am trying to achieve is that when a user clicks on a checkbox, that should toggle the Selected value of that Runner. Now when that happens I would also like to update the Cache value to reflect the Runners selected state
Cache is used as binary storage 12 == 1100 == Checkboxes 3 and 4 are checked
Now all of that I can get to work no problem, I obviously don't need to even make Cache observable.
But, I also have a need to programatically change the Cache values, and I would like the checkboxes to reflect these changes automatically.
What is below sorta works, but creates a Loop, which knockout gracefully handles, but its results are unreliable and this slows things down.
How can I create this binding setup?
function Runner(name, odds, race, leg, post) {
var runner = {
Name: name,
Odds: odds,
Post: post,
Race: race,
Leg: leg,
Cache: selections[race].Legs[leg],
Selected: ko.observable(false),
Enabled: ko.observable(true),
Valid: true
};
runner.Check = ko.computed(function() {
if (!this.Enabled.peek() || !this.Valid ) return;
var checked = this.Selected();
var cache = this.Cache();
if (checked) {
this.Cache(cache | 1 << this.Post);
} else {
this.Cache(cache & ~(1 << this.Post));
}
}, runner);
return runner;
}
Edit
<input type="checkbox" data-bind="checked: Selected, enable: Enabled"/>
I had a moment of clarity after writing my question. But I think its a good question none the less so rather than changing or removing my question ill just post my newest solution and get some critique hopefully.
So in the end I forgo the Selected value entirely
Note The this.Post + 1 is specific to my needs, its not needed normally, I simply wish to leave the first bit unused for future use.
runner.Check = ko.computed({
read: function() {
var cache = ko.utils.unwrapObservable(this.Cache); //Edit 1
return cache & 1 << (this.Post + 1);
},
write:function(value) {
var cache = this.Cache();
if (!this.Enabled.peek() || !this.Valid || this.Post === -1) return;
var mask = 1 << (this.Post+1);
if(value === !(cache & mask)){ //Edit 2
this.Cache(value ? cache | mask : cache & ~mask);
}
}
}, runner);
One bad thing about doing things this way is that if I have 20 runners who all use the same Cache, then when a user selects 1 of them all 20 will re-check themselves...
For my specific case a future change may be removing the Peek on Enabled, and performing a check that says if !Enabled then turn that bit off by default rather than possibly allowing a Disabled Checked checkbox.
Edit
Changed 'read' function to use unwrapObservable() in case the Cache is cleared by ways of the observable being deleted/removed elsewhere.
Edit 2
While answering a comment in the original question I realized that to help prevent some redundant calls I could add a check to see if the bit's value is already equal to value and if so do nothing, so if programatically I try to turn on a bit that is already on then it won't fire the computed since nothing has actually changed.

Categories

Resources