jQuery to Select elements that does not contain a certain value - javascript

I am using the following jQuery code to count the number of text fields that have a value that is the same as its title attribute.
$(".textfield").val( $(".textfield").attr('title') ).size();
Problem: How do I count the number of text fields that do not have a value equal to its title attribute?

First of all, the code you post is not doing what you say it does. This:
$(".textfield").val( $(".textfield").attr('title') ).size();
Will set the value of all elements with class ".textfield" to the title of the first ".textfield" element's title attribute, and then return a count of all of them.
You need to compare the return of the .val() method (with no parameter it returns the current value) with the return of the .attr('title') method. You can do this with .filter() and then check the .length of the resulting jQuery object:
$('.textfield').filter(function() {
var $this = $(this);
return $this.val() == $this.attr('title');
}).length;
And then to get a count of those where the value is not equal just do the same thing except with != instead of ==. So:
$('.textfield').filter(function() {
var $this = $(this);
return $this.val() != $this.attr('title');
}).length;
(Note that .length will give you the same count as .size() but without the overhead of a function call.)

I would use filter() and then access the length property of the returned set.
var count = $('.textfield').filter(function() {
return $(this).val() != $(this).attr('title');
}).length;
You could also probably get away with the body of filter() as return this.value != this.title.

use the filter function.
use length property of the selector
var length = $('.textfield').filter(function() {
return this.value != this.title;
}).length;

Related

Removing json item causes error

I have a simple button that removes an item from a json object. This is currently working fine. The issue I have is that once it's clicked once it doesn't work again due to a js error. The error is reporting that an item is null.
I thought delete would remove the json item, not simply mark it as null.
See this JSFiddle
$("button").click(function() {
var jsonObj = $.parseJSON($('div').text());
var name;
if($(this).attr('id') == 'btn1') name = 'John2';
if($(this).attr('id') == 'btn2') name = 'Anna';
$.each(jsonObj, function(i, obj) {
if (obj.firstName == 'Anna') delete jsonObj[i];
});
$('div').text(JSON.stringify(jsonObj));
});
I need to get the json text from the div, remove an item from it, then save it as text back to the div. Any help would be appreciated.
you should be iterating over the .employees array element of the object
you can't delete an element from an array with delete - use .splice instead.
you should return false from the $.each callback once a match has been made, or you'll end up iterating over non-existent elements - you must always be careful when modifying the size of a collection whilst iterating over it.
See https://jsfiddle.net/alnitak/mjw4z7jL/1/
The reason is because you are removing items from the array while looping through the keys. When you remove an item, it will rearrange the other items depending on how the array is implemented internally, and you end up with a loop that doesn't iterate over the keys that you expect.
Use for loop instead of $.each or return false once you are inside the condition.
$("button").click(function() {
var jsonObj = $.parseJSON($('div').text());
var name;
if($(this).attr('id') == 'btn1') name = 'John2';
if($(this).attr('id') == 'btn2') name = 'Anna';
for(i=0; i < jsonObj.employees.length; i++){
if (jsonObj.employees[i].firstName == name){
jsonObj.employees.splice(i,1);
}
}
$('div').text(JSON.stringify(jsonObj));
});
https://jsfiddle.net/bipen/715qkhwo/4/
Remind you, this is not a proper solution and depends entirely on how your json object is. If there are two objects with same firstName, this might give you weird result. So make sure you add all of the needed condition before you delete it.
You were iterating through the root object, it has one single property, employees
You needed to loop through object.employees array
Far easier with native array filter function
Note: This will handle multiple Johns and Annas without issue
$("button").click(function() {
var jsonObj = $.parseJSON($('div').text());
var name;
if(this.id == 'btn1') name = 'John2';
else if(this.id == 'btn2') name = 'Anna';
else return;
jsonObj.employees = jsonObj.employees.filter(function(emp) {
return emp.firstName != name;
})
$('div').text(JSON.stringify(jsonObj));
});
https://jsfiddle.net/715qkhwo/5/

access elements in array of strings that contain certain strings

I have an array that can look like this: ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"]
I want to access the element containing IN, if it exists and the next elements(s) until I reach and including an element with NN in it. and join those elements together into a string.
When I try to access the element containing IN like so, I get -1 that there is no element containing IN.
Here's how I am trying to do it:
strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
strARR[strARR.indexOf('IN')];
but then I get undefined because nothing at -1 exists.
How can I access the element of this array of strings if it contains IN and every element after until it matches an element containing NN, including that element? And joining those as a string?
You need a for loop for that:
var strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
var foundStr = null;
for (var i = 0, cString; i < strARR.length; ++i) {
cString = strARR[i];
if (cString.indexOf("IN") !== -1) {
foundStr = cString;
break;
}
}
if (foundStr !== null) {
/* do someting with found string */
}
strARR[strARR.indexOf('IN')] was returning a weird value because:
strARR.indexOf('IN') // returns -1 (no string "IN" in the array)
strArr[-1] // undefined
There is no "IN" element in that array. Just an "inIN" element, which is not precisely equal. (Keep in mind, this could be an array of ANYTHING, not just strings, so it's not assumed they can check the string contents)
You'll have to loop through the strARR, using a standard for(var i = 0; i < strARR.length; i++) loop. The i variable will help you find the correct indexes.
Then, for combining the results, use the Array.splice and Array.join methods. Splice can take a start index and length of items to take as arguments, and Join can take an intermediate character as an argument, like a comma, to put between them.
You need to evaluate each element in the array individually, not evaluate the array as a whole. Using jQuery each, you can do:
var containsIN = '';
$.each(strARR, function(){
if($(this).indexOf('IN') !== -1){
containsIN = $(this);
}
});
To achieve appending or joining string until you find a string that contains 'NN'
you need to modify the original if condition to:
if(containsIN === '' && $(this).indexOf('IN') !== -1)
then add another condition afterwards
if(containsIN !== ''){
final += $(this);
}
Then, to terminate the each:
if($(this).indexOf('NN') !== -1){
return false;
}
So, the final code should look like:
var containsIN = '';
var final = '';
$.each(strARR, function(){
if(containsIN === '' && $(this).indexOf('IN') !== -1){
containsIN = $(this);
}
if(containsIN !== ''){
final += $(this);
}
if($(this).indexOf('NN') !== -1){
return false;
}
});
You can use the Array's filter() function for this. There is a polyfill available on the linked page if you need to target browsers that do not support filter() natively.
You can create any filter condition that you like and filter() will return the array elements that match your condition.
var strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
var strARRFiltered = strARR.filter(function(element){
return element.indexOf("IN") !== -1;
});
alert(strARRFiltered);
Here is an example of this concept expanded a bit to include accessing multple matches and a variable filter.
To do what you're currently trying to do, the code would need to be like this:
strARR = ["whatWP", "isVBZ", "theDT", "temperatureNN", "inIN", "bostonNN"];
strARR[strARR.indexOf('inIN')];
You need to loop through each element in the array calling indexOf, rather than trying to access it as an array.

Replacing a substring of an element's text with another string

The Problem
I'm trying to use the JavaScript string replace method to replace some text in a div if it contains a certain string. However, my code does not replace the string inside that div.
The Javascript
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
val.replace(NAME, '');
}
}
It doesn't work because .replace() is a String function and not a jQuery function; Strings in JavaScript are immutable, so .replac() returns the modified String which you then have to reassign to your element.
That said, you can use .text(fn) to perform the replacement in a single step:
$("div#like-list-").text(function(i, val) {
return val.replace(NAME, '');
});
Btw, I've removed the .indexOf() condition as well, because if NAME doesn't occur inside your string, the .replace() function will just return the original string.
You're editing the string, then simply throwing it away. Take the edited val and put it's contents back into the HTML element using a parameterized call to the text method.
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
$("div#like-list-").text(val.replace(NAME, ''));
}
}
replace() is javascript not jQuery and you need to reset the value to variable after replace as replace() returns the updated text;
ie;
val = val.replace(NAME, '');
so try:
function john(){
var NAME = "Johnny Buffet,";
var val = $("div#like-list-").text();
if ( val.indexOf(NAME) !== -1 ){
val = val.replace(NAME, '');
}
}

Get jQuery element by stored data

Using .data() function we can store data in jQuery objects:
From documentation:
Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.
Example:
// sets "string" value to "test"
$(".myClass").data("test", "string");
$(".myClass").data("test"); // returns "string"
This is simple.
Now I want to get all jQuery elements from page that have "string" value associated with "test".
Is this possible? Is there any function that would do this?
You can use .filter() to filter the elements
var $filtered = $('<target-elements>').filter(function(){
return $(this).data('test') == 'test'
})
Demo: Fiddle
I'm affraid .data() doesn't actually add a data- attribute to your html element.
A possible workaround would be to iterate over the elements:
$('.myClass').each(function(){
var el = $(this);
if(el.data("test") === "string") {
console.log("found !");
}
});
Here is a fiddle:
http://jsfiddle.net/5p9LX/1/
Try using jQuery.grep() to filter all elements
Get all elements with 'test' data key:
var arrElements = $.grep($("*"), function (a) { return $(a).data("test") != undefined; });
var $filteredElements = $(arrElements);
Get all elements with 'test' data value equals to 'string':
var arrElements = $.grep($("*"), function (a) { return $(a).data("test") == "string"; });
var $filteredElements = $(arrElements);

jQuery $.inArray() always return -1 with an array of object

I have an array of object, that contain key value pair of columnNames.
when i check if a particular columnName exists it alwayz returns -1
Here is an sample http://jsfiddle.net/trLkt/6/, Help will b appriciated
You're searching for string values in the columnModel array, but you're storing objects in it (columnModel.push({'colName': $(this).text()});). $.inArray() cannot decide by itself to compare against the colName property of each array element, it simply compares the value you're searching for against each array element.
Two things you can do:
Add strings to the array instead of objects using .push (as suggested by #lanzz), then $.inArray will work as you expect.
Alternatively, if you do need to store objects within the array (if for example you need to have multiple properties within each object) you would need to iterate over each object and see if the colName already exists:
var colExists = false;
var text = $(this).text();
$.each(columnModel, function(k, v) {
if(text == v['colName']) {
colExists = true;
}
});
Then change your check from if(colExists === -1) to if(!colExists).
Example
$(function () {
$('#ddlMain').change(function (event) {
$('option:selected', $(this)).each(function () {
var colExists = false;
var text = $(this).text();
$.each(columnModel, function(k, v) {
if(text == v['colName']) {
colExists = true;
}
});
if(!colExists) {
columnModel.push({'colName': $(this).text()});
alert($(this).text() + ' added to columnModel');
}
});
});
});

Categories