How to determine if $(this) is in array on click event - javascript

I have a set of id values in 4 arrays. Each array will be assigned a text value for an h1 and a p that I haven't put in yet. Right now I'm just trying to get it to alert if one of the images in array graphicDesign is clicked. I tried using $.inArray
DEMO
var graphicDesign = [$('#design'), $('#DD'), $('#SElogo')];
var webDesign = [$('#bootstrap'), $('#farm'), $('#pong'), $('#SE'), $('#dung')];
var programming = [$('#SE'), $('#dung'), $('#sacar')];
var other = [$('#firm')];
function categories() {
if ($.inArray(this, graphicDesign) > -1) {
alert('hello');
}
}

You should not store DOM objects in an array and try to match them with $.inArray.
Using ids or another attribute would be a better solution.
For example :
https://jsfiddle.net/1f9xd3t0/
var graphicDesign = ['design', 'DD', 'SElogo'];
function categories(id) {
if ($.inArray(id, graphicDesign) > -1) {
alert('hello');
}
}
categories('design');

You need to pass the event object to categories().
$('.portPic').click(function(e) {
// ...
categories(e);
});
function categories(e) {
console.log(e.target);
if ($.inArray(e.target, graphicDesign) > -1) {
alert('hello');
}
}
UPDATE
And maybe use id's rather than jQuery objects in your arrays.
var graphicDesign = ['design', 'DD', 'SElogo'];
Then use e.target.id in categories().

You can use typeof , here is an example.
// Objects
typeof {a:1} === 'object';
// use Array.isArray or Object.prototype.toString.call
// to differentiate regular objects from arrays
typeof [1, 2, 4] === 'object';

Array.indexOf() is a native function that does the same thing.
graphicDesign.indexOf(this) > -1 would be the equivalent of what you wrote.
In your usage, this is going to refer to the global object, unless you elsewhere assign this function to an object and call it as a method... But then you're trying to tell if the object you're calling it on is inside the graphicDesign array?
Here's an example of a usage that would fire the alert:
var graphicDesign = [ {} ]
graphicDesign[0].categories = function() {
if (graphicDesign.indexOf(this) > -1) {
alert('the object this method was called on is inside the graphicDesign array')
}
}
graphicDesign[0].categories()
It's unclear exactly what you're trying to accomplish, however (you mention a click detection, but there's no click handler here, etc.)... I hope this helps?

This block of $.inArray is working, but you put them in wrong place, it always returned -1, so you cannot get the alert('hello'). Please fix the overall logic.
if ($.inArray(this, graphicDesign) > -1) {
alert('hello'); }

Related

Find texbox value match in an array

I am trying to look for texbox values matching an array I have provided a code snippet below:
$('#message').on('keyup', function () {
suggest_array_sample = [
{ array_val: "#{person1}" },
{ array_val: "#{person2}" },
{ array_val: "#{person3}" }
];
found_variable_array = [];
$.each(suggest_array_sample, function (key, value) {
console.log(value);
if ($.inArray(value, textbox_value)) {
console.log('found');
found_variable_array.push(value);
} else {
console.log('not found');
}
})
console.log(found_variable_array);
});
<textarea id="message"></textarea>
The problem is it always return the whole array instead of just the matches the ouput should be when I type #{person1} on the textbox the output should be
[{array_val:"#{person1}"}] //expected output
[{array_val:"#{person1}"},{array_val:"#person2"}]// expected output when two or more matches are found on the textbox
instead of
[{array_val:"#{person1}"},]{array_val:"#{person2}",{array_val:"#{person3}"}] //current output
is this possible using the inArray() or do I need to change the code.
use filter method of Array.
yourArray.filter ( yourArrayModel => yourArrayModel.fieldValue === yourSearchValue )
In your case yourSearchValue can be “{#person1}”
For more information, look for filter method documentation, i hope this is what you want.
$.inArray return a position, if not found return -1 else return >= 0
The $.inArray() method is similar to JavaScript's native .indexOf()
method in that it returns -1 when it doesn't find a match. If the
first element within the array matches value, $.inArray() returns 0
Try this code
$('#message').on('keyup', function () {
textbox_value = $(this).val();
suggest_array_sample = ["#{person1}", "#{person2}", "#{person3}"];
console.log($.inArray(textbox_value, suggest_array_sample));
});
It's not entirely clear what you're trying to achieve. I've written something using $.inArray that tells you the array index of the found value. You need to use .map() on the array to extract the val you want.
EDIT:
From what I understood of your comment, I've now had the value be added to found_value_array each time the value is found.
Or is it that you want an array to be returned because the same value might appear multiple times?
let found_variable_array = [];
$('#message').on('keyup',function(){
suggest_array_sample = [
{array_val:"#{person1}"},
{array_val:"#{person2}"},
{array_val:"#{person3}"}
]
let index = $.inArray($(this).val(), suggest_array_sample.map(o => o.array_val));
if (index >= 0) found_variable_array.push(suggest_array_sample[index]);
console.log(found_variable_array);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="message"></textarea>
After combining ideas presented here this method work for me
match_value = suggest_array.filter(function(result){
if(textbox_value){
return textbox_value.search(result)>-1
}
else{
return false
}
})
console.log(match_value);

How to check if an Object already exists in an Array before adding it?

I have this algorithme issue, I would like to check if an Object is already present in my Array before adding it.
I tried many different approaches (indexOf, filter...), and my last attempt is with an angular.foreach.
The problem is my $scope.newJoin remains always empty. I understood why, it's because the if is never read, because of the 0 size of my $scope.newJoin, but I don't know how to figure this out...
$scope.newJoinTMP is composed by : 6 Objects, within each a timePosted attribute (used for compare these different array Objects).
$scope.newJoin is an empty Array. I want to fill it with the Objects inside $scope.newJoinTMP but with the certainty to have once each Objects, and not twice the same ($scope.newJoinTMP can have duplicates Objects inside, but $scope.newJoin mustn't).
angular.forEach($scope.newJoinTMP, function(item)
{
angular.forEach($scope.newJoin, function(item2)
{
if (item.timePosted === item2.timePosted)
{
//snap.val().splice(snap.val().pop(item));
console.log("pop");
}
else
{
$scope.newJoin.push(item);
console.log("newJoin :", $scope.newJoin);
}
});
});
if(!$scope.newJoin.find(el=>item.timePosted===el.timePosted){
$scope.newJoin.push(item);
console.log("newJoin :", $scope.newJoin);
}
You dont want to push inside an forEach, as it will push multiple times...
There might be better ways to handle your particular situation but here's a fix for your particular code.
Replaced your inner for each with some which returns boolean for the presence of element and by that boolean value, deciding whether to add element or not
angular.forEach($scope.newJoinTMP, function(item)
{
var isItemPresent = $scope.newJoin.some(function(item2)
{
return item.timePosted === item2.timePosted;
//you dont need this conditional handling for each iteration.
/* if (item.timePosted === item2.timePosted)
{
//snap.val().splice(snap.val().pop(item));
console.log("pop");
}
else
{
$scope.newJoin.push(item);
console.log("newJoin :", $scope.newJoin);
} */
});
if( ! isItemPresent ) {
$scope.newJoin.push(item);
} else {
//do if it was present.
}
});
If you want to avoid the nested loop (forEach, some, indexOf, or whatever) you can use an auxiliar object. It will use more memory but you will spent less time.
let arr = [{ id: 0 }, { id:0 }, { id: 1}];
let aux = {};
const result = arr.reduce((result, el) => {
if (aux[el.id] === undefined) {
aux[el.id] = null;
return [el, ...result];
} else {
return result;
}
}, []);
console.log(result);
You can use reduce
$scope.newJoin = $scope.newJoinTMP.reduce(function(c, o, i) {
var contains = c.some(function(obj) {
return obj.timePosted == o.timePosted;
});
if (!contains) {
c.push(o);
}
return c;
}, []);
The problem with your current code is, if newJoin is empty, nothing will ever get added to it - and if it isnt empty, if the first iteration doesn't match the current item being iterated from newJoinTMP - you're pushing.

Find data() key-value pairs for every element

What is the best way to view all jQuery data key-value pairs across every element (in jQuery 2.x)?
A selection-oriented approach ( e.g. $('*').data() ) obviously does not work, because the return value is tied to a single element.
I know that I can iterate over every element, checking each for data:
var allData = [];
$('html *').each(function() {
if($.hasData(this)) {
allData.push({ el: this, data: $(this).data() })
}
})
JSFiddle
This does produce the expected output, but iterating over each possible data key feels like a backwards approach to this problem.
Is there some way to find all element data directly?
N.B. I'm interested for debugging, not production code.
You could select every element within the body with $("body *") and apply jQuery's .filter() to it. Working example:
var $elementsContainingData $("body *").filter(function() {
if($.hasData(this)) return this;
});
console.log($elementsContainingData);
Edit
As #spokey mentioned before, there's an internal variable named "cache" within the jQuery object: $.cache.
This variable consists of a bunch of objects which contain keys like "data" or "events":
5: Object
data: Object
events: Object
handle: function (a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)}
__proto__: Object
You can iterate through that object and filter for the data:
var filteredCache = $.each($.cache,function() {
if(typeof this["data"] === "object") return this;
});
Here's an working example plus a function to merge that stuff into a single and more handy object consisting only of dataKey => dataValue pairings: Fiddle
Edit
As mentioned in comments this solution does not work in jQuery version 2.x since $.cache is deprecated.
My last suggestion is creating a hook for jQuerys data function in order to extend an own object$.dataCache = {}; each time data() is called.
Extending, replacing or adding jQuerys functions is done by accessing $.fn.functionName:
$.fn.data = function(fn,hook) {
return function() {
hook.apply(this,arguments);
return fn.apply(this,arguments);
}
}($.fn.data,function(key,value) {
var objReturn = {};
objReturn[key] = value;
$.extend($.dataCache,objReturn);
});
This also works great in jQuery version 2: Fiddle

Compare Objects in Array and Remove Duplicate & Update - Javascript

I have an array of objects that presents as follows:
0: Object
ConsolidatedItem_catalogId: "080808"
ConsolidatedItem_catalogItem: "undefined"
ConsolidatedItem_cost: "0"
ConsolidatedItem_description: "Test Catalog Item"
ConsolidatedItem_imageFile: "27617647008728.jpg"
ConsolidatedItem_itemNumber: "1234"
ConsolidatedItem_quantity: "1"
ConsolidatedItem_source: "CAT"
ConsolidatedItem_status: "02"
ConsolidatedItem_umCode: "EA"
1: Object
ConsolidatedItem_catalogId: ""
ConsolidatedItem_catalogItem: "undefined"
ConsolidatedItem_cost: "0"
ConsolidatedItem_description: "ALARM,SHUTDOWN SYSTEM,AXIOM,XP3, 0-1500 PSIG, HIGH AND LOW PRES Testing"
ConsolidatedItem_imageFile: ""
ConsolidatedItem_itemNumber: "10008"
ConsolidatedItem_quantity: "1"
ConsolidatedItem_source: "INV"
ConsolidatedItem_status: "02"
ConsolidatedItem_umCode: "EA"
I'm trying to update and remove an object if it's added again, or update the object. Preferably update the object with the new value. My code is as follows:
var result = $.grep(finalObject, function(e) {
return e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber;
});
console.log(result);
if (result.length == 0) {
finalObject.push(o);
shoppingCounter = finalObject.length;
$('#numberShoppedItems').text(shoppingCounter);
console.log(finalObject);
} else if (result.length == 1) {
finalObject.filter(function(x){
result = x;
console.log(result);
return x == result.ConsolidatedItem_itemNumber;
});
} else {
alert('Multiples Found');
}
}
I've tried multiple ways of getting the exact object and manipulating the data, however they've all failed. I would prefer to update the object, say if CatalogItem_itemNumber held the same value, if the CatalogItem_quantity was different - add the CatalogItem_quantity values together and update the array of objects.
I don't need an exact answer, a nudge in the right direction would do wonders though. I've looked at several of the related questions over the past couple of hours but none of them seem to address the issue. If you know of a question that has an answer, feel free to just link that as well. I may have missed it.
No Underscore.js please
When you find the matching record, you may update it by using $.extend
$.extend(result[0], o)
This will update the object in finalObject array in-place.
Alternatively, if you want to use the filter, you will need to insert the new object in the array.
finalObject = finalObject.filter(function(x) {
return x !== result[0];
});
finalObject.push(o)
Here we are allowing all the records that are not not equal to result to be returned in the resultant array that is received in finalObject. In next line, we are adding the new record.
Solved in the following manner:
1.) Verify object is not empty.
2.) Use .some() on object to iterate through it.
3.) Check if the finalObject, which is now e, has a match for the key in my temporary object I assemble, o.
4.) Update the values that need updating and return true;
Note: Originally I was going to remove the object by its index and replace it with a new object. This too can work by using .splice() and getting the index of the current object in that array you're in.
Here is the updating version:
if (o.ConsolidatedItem_quantity != '') {
var result = $.grep(finalObject, function(e) {
return e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber;
});
if (result.length == 0) {...}
else {
finalObject.some(function (e) {
if(e.ConsolidatedItem_itemNumber == o.ConsolidatedItem_itemNumber){
var a;
a = +e.ConsolidatedItem_quantity + +o.ConsolidatedItem_quantity;
e.ConsolidatedItem_quantity = a.toString();
document.getElementById(o.ConsolidatedItem_itemNumber).value=a;
return true;
};
});
}
}

How to apply a method to an entire object literal?

How do you apply a method to all properties of an object literal?
For Example:
var ObjL = {
x: $("someSelector > .x"),
y: $("someSelector > .y"),
otherx: $("someOtherSelector > .x"),
othery: $("someOtherSelector > .y"),
...
...
...
}
// <---something like ObjL.css("background-color","red") would go here
Would you just use ObjL.someMethod()?
Could you do this with an array?
If I understand you correctly, you want to apply a method aMethod to an element? The best solution IMHO is a foreach loop:
$.each($obj, function(prop, value) {
//call a method here, being the same on value or this.
value.css(blablabla, blablabla);
});
(deliberately i did not use the for loop since 1. u're using jquery and it's shorter, and 2. it has many problems regarding the owned or inherited-by-proto properties).
EDIT: yes, you can use a $.each loop as well for arrays. an alternative is using a regular for-counter loop (for(initial;condition;increment){ code }), since using for(in) loops in arrays lead to unexpected results.
This should do the trick
$.each(ObjL, function() {
this.css("background-color","red");
})
You could iterate over the object:
for (var key in ObjL) {
if (ObjL.hasOwnProperty(key)) {
ObjL[key].css( /* do your thang */ );
}
}

Categories