I am using this JS code without any issues:
if(document.getElementById('add_calc_srt_gew').value.length != '' &&
document.getElementById('add_calc_dia_inner').value.length != '' &&
document.getElementById('add_calc_dia_out').value.length != '' &&
document.getElementById('add_breedte').value.length != '') {
// do something }
I need to add one more check. When add_calc_dia_out is larger then add_calc_dia_inner
So I have changed the JS to:
if(document.getElementById('add_calc_srt_gew').value.length != '' &&
document.getElementById('add_calc_dia_inner').value.length != '' &&
document.getElementById('add_calc_dia_out').value.length != '' &&
document.getElementById('add_breedte').value.length != '' &&
(document.getElementById('add_calc_dia_out').value > document.getElementById('add_calc_dia_inner').value)) {
// do something }
But the code that should be triggered is not triggered. Also no errors are shown. What is the correct way to be sure that add_calc_dia_out is larger then add_calc_dia_inner ?
Here is a DRY version
const num = str => isNaN(str) || str.trim() === "" ? 0 : +str;
const srt_gew = num(document.getElementById('add_calc_srt_gew').value),
dia_inner = num(document.getElementById('add_calc_dia_inner').value),
dia_out = num(document.getElementById('add_calc_dia_out').value),
breedte = num(document.getElementById('add_breedte').value);
if (srt_gew && dia_inner && dia_out && breedte && dia_out > dia_inner) { /* do something */ }
You are compare 2 number in string. It will cause unexpected behavior like '9' > '11'. You have to parseInt() them first. Try this:
... && parseInt(document.getElementById('add_calc_dia_out').value) > parseInt(document.getElementById('add_calc_dia_inner').value)) {
Also, you should check if it's a valid number or not before doing the compare:
!Number.isNaN(document.getElementById('add_calc_dia_out').value) && !Number.isNaN(document.getElementById('add_calc_dia_inner').value))
I need to filter my content with multiple parameters that I am taking from fields. The fields could also be empty, so I need to get all the values that are not empty. And filter by those.
What is the best way to achieve this without making a lot of if and else if conditions like this:
if (a !== '' && b !== '' && c !== '' && d !== '' && e !== ''){
// none is empty, filter by a & b & c & d & e
}
else if ( b !== '' && c !== '' && d !== '' && e !== ''){
// a is empty, filter by b & c & d & e
}
else if ( a !== '' && c !== '' && d !== '' && e !== ''){
// b is empty, filter by a & c & d & e
}
else if ( b !== '' && a !== '' && d !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && a !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && d !== '' && a !== ''){
}
else if ( c !== '' && d !== '' && e !== ''){
}
else if ( b !== '' && d !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && e !== ''){
}
else if ( b !== '' && c !== '' && d !== ''){
}
else if ( a !== '' && d !== '' && e !== ''){
}
and so on...
Alternatively, how can I get all the unique possible combination of these 5 letters?
Edit ::
The actual code would look something like this
//a/b/c take value of dropdown items, that match with data on an object
if (a != '' && b != '' && c != '') {
for (const i in ParticipationList.TaskMetadata) {
if (ParticipationList.TaskMetadata[i].attendance == a && ParticipationList.TaskMetadata[i].monitoring_status == b && ParticipationList.TaskMetadata[i].monitoring_status == c) {
filteredaudience[i] = { ['id']: i }
}
console.log(filteredaudience)
// get all the items that match with the object properties
}
}
So if a or b or c is empty, I can't still make the same call, as it would not match anything on the object.
The logic:
Since javascript has short-circuit evaluation, we'll just use a bunch of conditions in the format:
field === "" || (condition to filter using field)
Because of said "short-circuiting", the right side part will only be reached if the field is not empty (i.e. if the left side is false because field !== ""). However, if the field is empty then field === "" will be true and the right side part won't be reached and the whole condition will yield true resulting in the filtering for this field to be skipped.
Multiple conditions should be joined together by the logical && operator and each one of those conditions should be wrapped in parenthesis () because the operator && is higher in precedence than the || operator.
If the data to filter is an array:
For arrays, just use the conditions as the value returned from the callback of filter like so:
let filteredData = data.filter(item =>
(a === "" || (condition for field 'a' against 'item'))
&&
(b === "" || (condition for field 'b' against 'item'))
&&
(c === "" || (condition for field 'c' against 'item'))
&&
(d === "" || (condition for field 'd' against 'item'))
&&
(e === "" || (condition for field 'e' against 'item'))
);
If the data to filter is an object:
In case the data is an object and you can't use filter like above, you can still use the same logic, you just have to use the conditions inside if like so:
let filteredaudience = {};
for (const i in ParticipationList.TaskMetadata) {
if ((a === "" || ParticipationList.TaskMetadata[i].attendance === a)
&& (b === "" || ParticipationList.TaskMetadata[i].monitoring_status === b)
&& (c === "" || ParticipationList.TaskMetadata[i].monitoring_status === c)
&& (d === "" || ParticipationList.TaskMetadata[i].?????????? === d)
&& (e === "" || ParticipationList.TaskMetadata[i].?????????? === e)) {
filteredaudience[i] = { id: i };
}
}
Depending on how the actual filtering process works, it might be possible to incrementally filter your result instead of doing it simultaneously.
For example, if your data is an array, you might write:
let data = ...;
if (a != '') {
data = data.filter(elem => checkForA(a, elem));
}
if (b != '') {
data = data.filter(elem => checkForB(b, elem));
}
...
Maybe you can also incrementally augment the filter object itself and THEN apply the built filter.
Please enter more details ...
For now, what I understood was that you want to get all the
values that are not empty.
for this:
let allElements = [a, b, c, d, e]
let notEmpty = []
allElements.forEach(element => {
if (element !== '')
notEmpty.push(element)
});
console.log(notEmpty)
A common mistake for new developers is to create long, complicated and repetative if statements with tons of && and || symbols or long strings of if/else if
Instead of this, write a simple search predicate. This is a function which takes some parameters, and reduces them to either true or false.
Within said function, run each filter one at a time. As soon as one fails, return false.
var data = [
{ colour : "red", weight : 2, name : "Example 1"},
{ colour : "orange", weight : 15, name : "Example 2"},
{ colour : "yellow", weight : 10, name : "Test 1"},
{ colour : "green", weight : 24, name : "Test 2"}
];
console.log(search(data, "red", [], ""));
console.log(search(data, "", [5,20], ""));
console.log(search(data, "", [], "Test"));
function search(data, colour, weights, name) {
return data.filter(row=>testRow(colour, weights, name, row));
}
// much easier to read.
function testRow(colourFilter, weightFilter, nameSearchFilter, row) {
// run each filter one at a time. If any fail, "short circuit" out.
if (colourFilter != "" && row.colour == colourFilter) {
return false;
}
// sometimes, a double if statemnt is easier to read.
if (weightFilter.length > 0) {
if (row.weight < weightFilter[0] || row.weight > weightFilter[1]) {
return false;
}
}
// sometimes, the actual rule is a bit complex.
if (nameSearchFilter != "") {
if (row.name.indexOf(nameSearchFilter) < 0) {
return false;
}
}
// we survived all filters.
return true;
}
This might be a bit of a long shot but here we go. I've got 6 different variables that I need to create different url parameters. So for example:
var A
var B
var C
var D
var E
var F
Now I need to basically account for all options between those 6. So for example for var A I'd neeed something like:
if (A != '' && B == '' && C == '' && D == '' && E == '' && F == '') {
url += A ;
}
else if (A != '' && B != '' && C == '' && D == '' && E == '' && F == '') {
url += A + "+" + B;
}
else if (A != '' && B != '' && C != '' && D == '' && E == '' && F == '') {
url += A + "+" + B + "+" + C;
}
And so on. So basically I'd need to go through all the combinations like the above example, which I'm currently doing manually and which works fine, but there must be a better way of doing this?
You could filter the items, after taking them into an array and join with +.
result = [a, b, c, d, e, f].filter(Boolean).join('+');
I am trying to organize a observablearray that has inside 2 boolean values and a price. I need via knockout and 2 checkboxes, filter the elements by these two values. Also sort by price ( ascending and descending) the displayed values . I don't put any code because I'm new in knockout and I can't see the way to make these actions.
Appreciate someone who instructed me.
Simple answer, I tried with this, but making some changes on my personal viewModel to supply my needs. So, I make something like this:
self.elementsToShow = ko.pureComputed(function () {
// Represents a filtered and ordered list of elements
var recomend = self.showRecommended(); //chekbox 1
var special = self.showSpecial(); // checkbox2
var sorting = self.currentSortDirection(); //sort direction: price or rating //ascending or descending, represented by an observableArray with that conditions and the //selectedSortDirection
if (!recomend && !special) return self.myOservableArray().sort(function (a, b) {
//in case that no one of the checkboxes where selected but the sort direction was't by default
if (sorting.price != null) {
var fp = sorting.price ? -1 : 1;
ap = parseInt(a.price);
bp = parseInt(b.price);
return ap == bp ? 0 : (fp * (ap < bp ? -1 : 1));
}
else if (sorting.rate != null) {
var f = sorting.rate ? -1 : 1;
ar = parseFloat(a.rating);
br = parseFloat(b.rating);
return ar == br ? 0 : (f * (ar < br ? -1 : 1));
}
});
return ko.utils.arrayFilter(self.myOservableArray(), function (element) {
return (element.recommended != "0" && recomend) || (element.offer != "" && special); //some other conditions for the relection of the checkboxes in the observableArray
}).sort(function (a, b) {
if (sorting.price != null) {
var fs = sorting.price ? -1 : 1;
ap = a.price;
bp = b.price;
return ap == bp ? 0 : (fs * (ap < bp ? -1 : 1));
}
if (sorting.rate != null) {
var fu = sorting.rate ? -1 : 1;
ar = a.rating;
br = b.rating;
return ar == br ? 0 : (fu * (ar < br ? -1 : 1));
}
});
}, self);
I have radio buttons radioVisa, and radioMaster. If either one is checked, I need to first check to see which one is selected and then validate that the card number entered is valid. I also need to make sure that only numbers are entered.... I am not allowed to use any regular expression techniques.... If the radioVisa is checked, it seems to work but when I added the code for the radioMaster, if it is checked it does't work.... Can someone tell me what I am doing wrong please....
function isValidCardNumber(num, isVisa, isMaster){
var card = new Array();
if (document.getElementById('radioVisa').checked){
card = isVisa;
}
if (num[0] != '4' || num.length != 16 ){
return false;
} else {
return true;
} else if (document.getElementById('radioMaster').checked){
card = isMaster;
}
if (num[0] != '51' || num[0] != '52' || num[0] != '53' ||
num[0] != '54' || num[0] != '55' || num.length != 16 ){
return false;
} else {
return true;
}
if (num[0] != '51' || num[0] != '52' || num[0] != '53' ||
num[0] != '54' || num[0] != '55' || num.length != 16 )
You can not combine all those numbers.You need to specify individually.
or
var numbers= ["51", "52", "53", "54",55];
var index = numbers.indexOf(num[0]);
It will return -1 if that is not exist otherwise return the index