I'm really trying to avoid nesting in this code snippet...
deal_trade_in_model_1 = document.getElementById('deal_trade_in_model_1').value;
deal_trade_in_amount_1 = document.getElementById('deal_trade_in_amount_1').value;
if (typeof deal_trade_in_model_1 !== 'undefined' && deal_trade_in_model_1 !== null) {
console.log(deal_trade_in_amount_1);
console.log(deal_trade_in_model_1);
if (deal_trade_in_model_1 !== null || deal_trade_in_model_1 !== "") {
if (deal_trade_in_amount_1 == null || deal_trade_in_amount_1 == "") {
console.log('entered into function');
document.getElementById("deal_trade_in_model_1").value = "";
document.getElementById("deal_trade_in_amount_1").value = "";
}
}
}
Basically, what this function does is take the value of two fields... things to know about them and what I want to do to them:
1) They're NOT required
2) If one of them is filled out, the other must be
3) If ONLY one of them is filled out, the user clicks submit, and this part of the function is called upon, I want to delete the value of both of them.
I've tried doing a compound of
&& (and)
and
|| (or)
buttttt it odiously it didn't work.
Primary question: What's the best way to get rid of the nesting (I planned on doing this twice and just swapping the code) that will be the most efficient? This, I want, to be done preferably in the smallest amount of IF statements possible.
Please note: If you change the code a lot, I might not know what you're talking about.. please be prepared to teach me or help me learn!
It sounds like you only want to do something if either of the fields are empty, but not both. Assuming both of the elements are text fields, .value will always return a string. Converting a string to boolean results in false if the string is empty, otherwise true.
So
Boolean(deal_trade_in_model_1) === Boolean(deal_trade_in_amount_1)
will be true if either both fields have a value (both will convert to true) or both fields are empty (both convert to false).
Thus your code can be reduced to
var model_1 = document.getElementById('deal_trade_in_model_1');
var amount_1 = document.getElementById('deal_trade_in_amount_1');
if (Boolean(model_1.value) !== Boolean(amount_1.value)) {
model_1.value = "";
amount_1.value = "";
}
Related
I want to know why my function always returns false, and how I can fix it.
At first I thought it had something to do with my syntax at check = ("stairway to heaven"===value || "Stairway to heaven"===value);. But no matter how I put it, it's always false.
I tried reading into this, but as far as I could understand, it doesn't help me.
I've created this in JavaScript to do different things depending on if the result of check is true or false.
else if (textNodes[15].id === 16 && nextTextNodeId === 16) {
showSongContainer();
if(check) {
showTextNode(17);
}
if (!check) {
textElement.innerText = 'That’s superwrong! Maybe if you would use that small brain of yours you’d figure it out!';
showTextNode(11);
}
The above code runs this function first, to determine if a text input returns true (stairway to heaven) or false (anything other than stairway to heaven):
function showSongContainer() {
songContainer.style.display = 'unset';
const songInput = document.getElementById('songInput');
const songButton = document.getElementById('songButton');
songButton.addEventListener('click', (e) => {
e.preventDefault();
let value = songInput.value;
check = ("stairway to heaven"===value || "Stairway to heaven"===value);
});
}
However, when the first else ifstarts (in the first codeblock), it always goes to the if(!check), before the text input has even been entered. Why is this? And how do I make it so that it returns the first if (in the first code block) if the text input is correct, and the other if, if incorrect?
I also have let check = ''; in a global scope at the beginning of my code, if that has anything to do with it.
Here in the below code, some rows has this nested field with value present and some doesn't. So I am trying to declare it with the value if the field is present, if not I want to assign 'false' in it. I tried using the double pipe operator to handle this situation, but the below code doesn't run at all.
let penetration = result[i].address_stats[1].penetration || false;
Please help!
Use optional chaining:
let penetration = result[i]?.address_stats[1]?.penetration || false;
You could also do something like this:
let penetration = false;
if ( result
&& result[i]
&& result[i].address_stats
&& result[i].address_stats[1]
&& result[i].address_stats[1].penetration ) {
penetration = result[i].address_stats[1].penetration;
}
Not all of those checks may be necessary, I just included them all since I'm not sure what result looks like.
let penetration =false
if(!result[i].address_stats[1].penetration)
{
penetration = result[i].address_stats[1].penetration
}
//Optionally
penetration=result[i].address_stats[1].penetration?result[i].address_stats[1].penetration:false
In a form (named createform) many inputs are created dynamically by clicking on add button (from 0 to any number for each kind of input).
The problem I'm having is the validation of the inputs that were created dynamically, because there is a complex logic behind it.
THE SCENARIO
I can have several different inputs:
brand
model
country
region
The first of them is called brand1, model1, country1 and region1, then adding others they will be called for instance brand2... brand50
In the starting scenario there will be only brand1 and model1. The country and region inputs are added only by clicking on a button.
THE VALIDATION CONDITION
I have to submit the form only in two cases:
If there is at least one brand + one model where both of them are not empty (any brand and any model, so it can also be brand5 and model12)
If there is at least one brand + country + region not empty (all of them not empty, same logic than before)
I made the following validation function which works good if I assume that I just have the first brand,model,country and region (so brand1,model1,country1 and region1).
THE CODE
function validateForm() {
var brand = document.forms["createform"]["brand1"].value;
var model = document.forms["createform"]["model1"].value;
if (document.forms["createform"]["country1"] === undefined) {
var country = "";
} else {
var country = document.forms["createform"]["country1"].value;
}
if (document.forms["createform"]["country1"] === undefined) {
var region = "";
} else {
var region = document.forms["createform"]["region1"].value;
}
if ((brand != "") && (model != "")) {
alert("Send");
return true;
} else if ((brand != "") && (country != "") && (region != "")) {
alert("Send");
return true;
} else {
alert("Impossible to send");
return false;
}
}
For better reading of the code I added return true even if it is not necessary.
The main problem is that it is impossible to know how many inputs there will be of every different kind. I was thinking about trying by checking if the inputs are starting with brand,model,country or region but I don't know how to cross my controls in my validation function with all the possible results.
Do you guys have any idea of how to solve this?
What you need is a way to access all your brand and model elements by the start of their name.
var elements = document.querySelectorAll("form[id='createform']>input[id^='brand']");
This will give you an array (instead of your single valued variable) which you can loop through looking for your values.
The nifty querySelectorAll accepts selectors which can narrow your search to all matching elements. In the example, it gets all input elements within a form named "createform" which start with (^=) "brand".
var brandelements = document.querySelectorAll("#createform select[name^='brand'] option:checked:not([value=''])");
This is the best way to get all the values of a select (you can easily change with a normal input) that are not empty.
if($('#this').val().indexOf('4289')){
Do something
else
Do something.
This works only with that 4289,
When I try to add other numbers to be indexed next to it using 'or', it doesn't work. How should I put other number. E.g
IndexOf('4289||78843')
I want this to check this numbers and if the number in the input field is not one of this, to echo error.
Here's more which happens to die when one revisits the field.
$('#Zip').blur(function(){
if (($(this).val().indexOf('0860') > -1)||($(this).val().indexOf('0850') > -1)){
$('#Status_Zip').html("No way.")
$(this).alterClass('*_*', 'Success')
return false;
}else{$('#Status_Code').hide()
$(this).alterClass('*_*', 'Error')
$(this).css('border-color', '#F00').css('background-color', '#FFC').effect("pulsate",{times:4},2)
return true;
}
})
That's because it would be looking for the string '4289||78843', which doesn't exist in the target I'm assuming. Logical operators can't just be tossed in anywhere, only where there are actual values to logically operate on. Something like this:
if(($('#this').val().indexOf('4289') > -1) ||
($('#this').val().indexOf('78843') > -1))
The return value of the indexOf() function is the numeric index of that value in the target value, or -1 if it's not found. So for each value that you're looking for, you'd want to check if it's index is > -1 (which means it's found in the string). Take that whole condition and || it with another condition, and that's a logical operation.
Edit: Regarding your comment, if you want to abstract this into something a little cleaner and more generic you might extract it into its own function which iterates over a collection of strings and returns true if any of them are in the target string. Maybe something like this:
function isAnyValueIn(target, values) {
for (var i = 0; i < values.length; i++) {
if (target.indexOf(values[i]) > -1) {
return true;
}
}
return false;
}
There may even be a more elegant way to do that with .forEach() on the array, but this at least demonstrates the idea. Then elsewhere in the code you'd build the array of values and call the function:
var values = ['4289', '78843'];
var target = $('#this').val();
if (isAnyValueIn(target, values)) {
// At least one value is in the target string
}
Is there a better way for checking an attribute for:
it exist. so value must be false if attribute doesn't exist
Value is correct (boolean)
var isOwner = false;
if ($(selectedItem).is('[data-isOwner="True"]') || $(selectedItem).is('[data-isOwner="true"]')) {
isOwner = true;
} else {
isOwner = false;
}
Now I need to check for 'True' and 'true'...
Thanks
You can convert the value stored in data-isOwner to lower case and only compare the value to 'true'.
if (($(selectedItem).attr ('data-isOwner') || '').toLowerCase () == 'true')
The above use of <wanted-value> || '' will make it so that if the selectedItem doesn't have the attribute data-isOwner the expression will result in an empty string, on which you can call toLowerCase without errors.
Without this little hack you'd have to manually check so that the attribute is indeed present, otherwise you'd run into a runtime-error when trying to call toLowerCase on an undefined object.
If you find the previously mentioned solution confusing you could use something as
var attr_value = $(selectedItem).attr ('data-isOwner');
if (typeof(attr_value) == 'string' && attr_value.toLowerCase () == 'true') {
...
}