jQuery check if two values is blank - javascript

I have three values:
var tbb = $("#total1 span").text();
var tmb = $("#total2 span").text();
var tab = $("#total3 span").text();
Each of them could be blank.
What is the better way in javascript/jquery check if two of these values is blank?
UPDATE
here is what i mean, my a bit ugly and a "lot of lines" solution
var i = 0;
if (tab != "") {
i++;
}
if (tmb != "") {
i++;
}
if (tbb != "") {
i++;
}
if (i >= 2) {
//do something
}
Any better thoughts?

if(tbb == null || tbb == ''){...}
And the same for the rest.

var twoAreEmpty = $("#total1, #total2, #total3").find("span:empty").length === 2;

var twoblank =
$("#tota11 span, #total2 span, #total3 span")
.filter(function(index){
return !$(this).text().replace(/^\s+|\s+$/g, '');
})
.length === 2;
Also, you probably mean #total1, not #tota11 - just sayin.

if (tab == "") should be enough shouldn't it?
Does .text() ever return blank?

var filtered = [tmb, tbb, tab].filter(function( str ) {
return !str.length;
});
if( filtered.length === 2 ) {
console.log('yay, two empty values: ', filtered);
}

Just try it.
var i = 0;
if(tbb.length == 0 )
{
i++
}
if(tmb.length == 0 )
{
i++
}
if(tab.length == 0 )
{
i++
}
if(i >=2)
{
//perform operation
}

It's been a while, but this is going to be a single-line solution for what you want.
if (((tab == '' ? 1 : 0) + (tmb == '' ? 1 : 0) + (tbb == '' ? 1 : 0)) > 1){
// Do Something
}

All valid answers, but forgetting about undefined :)
if(tbb === '' || tbb === null || tbb === undefined){ // do stuff };
I'd recommend making it a function which could return true/false :)

Related

How to make multiple conditions inside single filter

I am trying to make a filter based on checkboxes.
The thing is js ignoring other conditions inside filter when one is active
filterData() {
return this.airlines.filter(x => {
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
return x.itineraries[0][0].stops == 0;
}
if (this.filters.options[i] == 1) {
return x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
}
} else {
return x;
}
})
}
I know that return will stop the current loop, but is there any way to do it correctly?
Update-1: (When to filter record for every case checked OR case)
Replace for loop and all conditions in a single return by && for if and || condition for data:
var chbox = this.filters.options;
return $.inArray(0, chbox) != -1 && x.itineraries[0][0].stops == 0
|| $.inArray(1, chbox) != -1 && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
Hope this helps !!
$.inArray(value, arr) method will check for each checkboxes and will work for every checked ones .
Update-2 (When to filter record for every case checked AND case)
As per comment below, you are trying to use checkbox on demand so use below code:
var chbox = this.filters.options;
boolean condition = true;
if ($.inArray(0, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].stops == 0;
}
if ($.inArray(1, chbox) != -1) {
conditon = conditon && x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
}
return condition;
Your filter function is returning an object, which ideally should be a boolean value. Please refactor the code as below.
filterData() {
return this.airlines.filter(x => {
let result = false;
if (this.filters.options.length != 0 || this.filters.airlines.length != 0) {
for (let i = 0; this.filters.options.length > i; i++) {
if (this.filters.options[i] == 0) {
result = x.itineraries[0][0].stops == 0;
break;
} else if (this.filters.options[i] == 1) {
result = x.itineraries[0][0].segments[0].baggage_options[0].value > 0;
break;
}
}
}
return result;
})
}

Sum with jquery not working

I have a lot of labels as shown on a page. I want to sum the values and store them in final_cpa.
HTML :
<label class="tmpcpa">32.1</label>
JS :
function calculate_final_cpa() {
var final_cpa = 0;
var allfilled = false;
$('.tmpcpa').each(function () {
if ($(this).val() != 0) {
final_cpa += parseInt($(this).text()) || 0;
allfilled = true;
} else {
allfilled = false;
}
});
console.log(final_cpa);
console.log(allfilled);
}
var run = setInterval(calculate_final_cpa, 500);
However final_cpa is always 0 and allfilled remains false.
That because label don't have a value attribute so the .val() function will always return an empty string, you have to use .text() instead to get the text content inside the label element :
if ($(this).val() != 0) {
Should be :
if ($(this).text() != 0) {
NOTE : as Rayon mentioned in the comment below text() will always return string so better to change the zero in condition to string '0'.
Hope this helps.
function calculate_final_cpa() {
var final_cpa = 0;
var allfilled = false;
$('.tmpcpa').each(function () {
if ($(this).text() != '0') {
final_cpa += parseInt($(this).text()) || 0;
allfilled = true;
} else {
allfilled = false;
}
});
console.log(final_cpa);
console.log(allfilled);
}
calculate_final_cpa();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label class="tmpcpa">32.1</label>
Check $(this).text() != "" instead of $(this).val() != 0 as You can not use .val() for getting label text. .text() will give you text of label
if ($(this).text() != "" && $(this).text() != "0") {
....
}
First thing, you need to use .text() instead of .val() to get the text inside a label. Also, if you are expecting your result to contain decimal digits, you need to use parseFloat():
function calculate_final_cpa() {
var final_cpa = 0;
var allfilled = false;
$('.tmpcpa').each(function () {
if ($(this).text() != 0) {
final_cpa += parseFloat($(this).text()) || 0;
allfilled = true;
} else {
allfilled = false;
}
});
console.log(final_cpa);
console.log(allfilled);
}
calculate_final_cpa();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<label class="tmpcpa">32.1</label>
<br />
<label class="tmpcpa">32.1</label>
Change
if ($(this).val() != 0)
to
if (parseInt($(this).text()) != 0)
Beside your code had an error, you should check the content of the table before parsing them. And because you use decimals in your example, you should switch from parseInt to parseFloat too.
And your allfilled varibale makes no sense, because if the last element of .tmpcpa was empty, it will be false again. So i removed it.
function calculate_final_cpa() {
var final_cpa = 0;
$('.tmpcpa').each(function () {
var content = $(this).text();
final_cpa += IsNumeric(content) ? parseFloat(content) : 0;
});
console.log(final_cpa);
}
Test it with .text instead of val() as label has no value property
Use Unary plus(+)/Number operator instead of parseInt as parseInt will ignore floating point
Use length of lable-elements to test whether all the label has values !== 0
function calculate_final_cpa() {
var final_cpa = 0;
var countOfFilled = 0;
$('.tmpcpa').each(function() {
if ($(this).text() !== '0') {
final_cpa += +($(this).text()) || 0;
++countOfFilled;
}
});
console.log('Total: ' + final_cpa);
console.log('All filled ' + $('.tmpcpa').length === countOfFilled);
}
calculate_final_cpa();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<label class="tmpcpa">32.1</label>
<label class="tmpcpa">32.1</label>
<label class="tmpcpa">0</label>

String comparison not as expected

I have written the following code looking for a string token in an array.
var parseCSVLines = function(lines) {
var valueObj = {};
var delim = ',';
var isLayer = false;
var isGroup = false;
for(var i = 0; i < lines.length; i++){
//skips CR/CF lines
if(!lines[i]) continue;
//only data lines reach this loop
var data = lines[i].split(delim);
/*********looks for tag*************/
if(data[0] == '#L' || data[0] == '#l'){
//on occasions, data[0] is '#L' or '#G' still execution reaches here
isLayer = true;
}else if(data[0] == '#G' || data[0] == '#g'){
isGroup = true;
}else{
if(isLayer){
valueObj[data[0]] = {
layerInfo: data[1] == 'on' ? true : false
};
}
else if(isGroup){
valueObj[data[0]] = {
GroupInfo: data[1] == 'on' ? true : false
};
}
}
}
return valueObj;
};
I loop through lines and mark next line to get data. Weirdly when data[0] is '#L' and '#G', first if statement is executed. What have I done wrong?
The if statement is fine, even if you have data[0]='#G#L'...it will never go into data[0]=='#L'||data[0]=='#l'
On my mind you are stuck in the logic-
if (data[0] == '#L' || data[0] == '#l') {
isLayer = true;
//isGroup=false; you should toggle isGroup
} else if (data[0] == '#G' || data[0] == '#g') {
isGroup = true;
//isLayer=false; you should toggle isLayer
} else { //do you want else here??? This would pick the value of isLayer or isGroup according to previous line processed but not the value according to current line being processed.
if (isLayer) {
valueObj[data[0]] = {
layerInfo: data[1] == 'on' ? true : false
};
} else if (isGroup) {
valueObj[data[0]] = {
GroupInfo: data[1] == 'on' ? true : false
};
}
}
Example:
line1: '#L,hi'
line2:'#G,hi'
line3:'hi'
processing first line will set isLayer=true;
processing second line will set isGroup=true;//remember isLayer is still true - you haven't set it to false;
processing third line will trigger your else part...and get into first condition where if(isLayer) will be true
To make it work:
//update isLayer and isGroup for every iteration to keep the logic inline
isLayer=(data[0] == '#L' || data[0] == '#l');
isGroup=(data[0] == '#G' || data[0] == '#g');
if(!isLayer && !isGroup) {
if (isLayer) {
valueObj[data[0]] = {
layerInfo: data[1] == 'on' ? true : false
};
} else if (isGroup) {
valueObj[data[0]] = {
GroupInfo: data[1] == 'on' ? true : false
};
}
}
Try this:
if(data[0] == "#l" || data[0] == "#L") {
if(data[0].search("#g") != -1 || data[0].search("#G") != -1){
}else{
isLayer = true;
}
}else if(data[0] == "#g" || data[0] == "#G"){
if(data[0].search("#l") != 0 || data[0].search("#L") != 0){
}else{
is group = true;
}
}
You see, what you weren't doing was checking if both were present. What my code does is checks that
The item is #g or #l
The item is not the opposite as well.
This ensures that one, and only one option is chosen.
Good day, And good luck.

How to fire an event after a kendo comboBox has finished a filter

I need to fire an event after my combo box finishes its filter
I have extended the widget and have tried to chuck a .done on the end of the call.
search: function(word) {
word = typeof word === "string" ? word : this.text();
var that = this,
length = word.length,
options = that.options,
ignoreCase = options.ignoreCase,
filter = options.filter,
field = options.dataTextField;
clearTimeout(that._typing);
if (length >= options.minLength) {
that._state = STATE_FILTER;
if (filter === "none") {
that._filter(word);
} else {
that._open = true;
that._filterSource({
value: ignoreCase ? word.toLowerCase() : word,
field: field,
operator: filter,
ignoreCase: ignoreCase
}); // .done here does not work :(
}
}
},
I need to know when a value is returned so that I can do some other stuff on my page once i know that the input matches a value server side.
Can anybody think of a way to achieve this? :)
Is there a way to fire an event once the datasource has changed?
I solved the issue by using the _busy state on the widget.
The following code is in the select function on the widget so whenever someone losses focus this fires.
If the widget is not busy it will have finished the ajax call.
Hope this is usefull to someone :)
if (data && data.length != 0)
{
for (var i = 0; i < data.length; i++)
{
li = $(that.ul).find('li:nth-child(' + (i + 1) + ')');
if (li.length != 0 && data[i].ProductCode == that.input.val())
{
that._select(li);
return;
}
}
}
if (that._busy && that._busy != null)
{
that.busyCheck = setInterval(function () {
if (!that._busy || that._busy == null) {
clearInterval(that.busyCheck);
if (data && data.length != 0){
for (var i = 0; i < data.length; i++){
li = $(that.ul).find('li:nth-child(' + (i + 1) + ')');
if (li.length != 0 && data[i].ProductCode == that.input.val()){
that._select(li);
return;
}
}
}
}
}, 50);
}
that._AddcodeIsServerValid(false);

Can't get JavaScript to check for null objects

I really don't know what the issue is here. As far as I can see, the code is simple and should work fine.
var Prices="";
for (var PriceCount = 1; PriceCount <= 120; PriceCount++) {
var CurrentPrice = "Price" + PriceCount;
if (prevDoc.getElementById(CurrentPrice).value != null) {
if (Prices == "") {
Prices = prevDoc.getElementById(CurrentPrice).value;
} else {
Prices += "," + prevDoc.getElementById(CurrentPrice).value;
}
} else {
break;
}
}
There could be up to 120 hidden inputs on the form. The moment we check for an input that doesn't exist the loop should break. My test page has two input elements that get pulled. On the third (the null) I get this error in firebug:
prevDoc.getElementById(CurrentPrice) is null
if (prevDoc.getElementById(CurrentPrice).value != null) {
Yes it is null...that's what the check is for ಠ_ಠ
Does any one know what I'm doing wrong? This seems like it should be really straight forward.
EDIT:
for clarity's sake, prevDoc=window.opener.document
if (prevDoc.getElementById(CurrentPrice).value != null) {
can be expanded to:
var element = prevDoc.getElementById(CurrentPrice);
var value = element.value; /* element is null, but you're accessing .value */
if (value != null) {
value is never null.
If it is not filled in, the value would be "" or a length of zero.
If the element does not exist, you would check for the existence of the element.
var CurrentPrice = "Price" + PriceCount;
var elem = prevDoc.getElementById(CurrentPrice);
if (elem && elem.value != null) {
I think it should be:
var Prices="";
for (var PriceCount = 1; PriceCount <= 120; PriceCount++) {
var CurrentPriceId = "Price" + PriceCount,
CurrentPrice = prevDoc.getElementById(CurrentPriceId);
if (CurrentPrice != null) {
Prices = (Prices == "") ? CurrentPrice.value : (Prices + "," + CurrentPrice.value);
}
else break;
}
Try
if (prevDoc.getElementById(CurrentPrice) !== null)

Categories

Resources