I am iterating over a list nested within a div (.catHOLDER), finding the img tag and trying to return the img src. The problem I have is that the function is returning all of the function source code instead of the string value, but oddly if I alert in the loop it returns the string value;
$(document).ready(function(){
function getnestedimg() {
$('.catHOLDER ul').children('li').each(function(i,value) {
var imgstr = $(value).find('img').attr('src');
if (imgstr !== undefined) {
alert(imgstr);
}
});
}
getnestedimg();
});
The above code will display an alert with path of the img src, but if I try to return imgstr it returns me the function code instead;
$(document).ready(function(){
function getnestedimg() {
$('.catHOLDER ul').children('li').each(function(i,value) {
var imgstr = $(value).find('img').attr('src');
if (imgstr !== undefined) {
return imgstr;
}
});
}
getnestedimg();
});
Returns the following;
function getnestedimg() {
$('.catHOLDER ul').children('li').each(function(i,value) {
var imgstr = $(value).find('img').attr('src');
if (imgstr !== undefined) {
//alert(imgstr);
//ret urn gotya;
return imgstr.val();
}
});
}
Can anyone help me in my plight, or if there is a better way to iterate over the children tags nested with the div?
The return statement inside the getnestedimg function, is acually inside the nested anonymous function you pass to each. That's why it's not returning any value to the caller of getnestedimg. You should store this value in a function variable of getnestedimg, as suggested.
Also, I recommend you read up on closures.
I'd use something like this:
var image_src = $('.catHOLDER ul > li img[src]').first().attr('src');
> li img[src] selects only img tags that have a src attribute and are descendants of li elements. .first() grabs only the first one.
If no elements match those conditions, image_str === undefined.
$.fn.extend({
getsrc : function() {
return $(this).find(">ul> li img").map(function() {
return $(this).attr("src");
});
}
});
$(document).ready(function() {
var catHOLDERimgsrc = new Array();
catHOLDERimgsrc=$(".catHOLDER").getsrc();
console.log(catHOLDERimgsrc);
})
but a plugin for this ? i would do it direct :
$(document).ready(function() {
var catHOLDERimgsrc = new Array();
catHOLDERimgsrc=$(".catHOLDER").find(">ul> li img").map(function() {
return $(this).attr("src");
});
console.log(catHOLDERimgsrc);
})
imo the nicest way to iterate to get a set of value arranged in an array (that is if you want all the images src otherwise you change selector then if not enough you can do anything inside the map function)
Related
I am working on js validation and want to pass one function into another but i got error "Uncaught ReferenceError: item is not defined".
My code:
validation();
function validation() {
var reg = /^([A-Za-z0-9_\-\.])+\#([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,10})$/;
function common_inputs() {
var inputs = $(' input').toArray();
inputs.forEach(function(item) {
var element = $(item);
if (!element.val() == "") {
element.closest('.my__item').removeClass('error');
}
if ( !reg.test(element.val())) {
element.closest('.my__item').addClass('error');
}
})
}
function inputValidatorClick() {
common_inputs()
var element = $(item);
if (element.val() == "") {
element.closest('.my__item').addClass('error');
}
}
$('.my-button').click(inputValidatorClick)
$(' input').keyup(common_inputs)
}
},
It seems that there is problem with passing argument "item", but i am new in JS and have no idea how to solve it.
Does anyone knows how to solve it?
i would like to have it in one function - common_inputs. To not copy
the same part of code
I see that inside your inputValidatorClick function, you do something that is already inside common_inputs function.
Also, you can remove validation which is just used to wrap common_inputs function.
var reg = /^([A-Za-z0-9_\-\.])+\#([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,10})$/;
function common_inputs() {
$('input').each(function () {
$(this).closest('.my__item').removeClass('error');
});
$('input').filter(function () {
return this.value === '' || !reg.test(this.value);
}).each(function () {
$(this).closest('.my__item').addClass('error');
});
}
$('.my-button').click(common_inputs);
$('input').keyup(common_inputs)
First, we collect all of the <input> tags and remove all of the error classes from the parents (my__item).
Then, we filter the inputs which have invalid values (empty or not match with the regex pattern). From there, We add class error to the parents.
For the code below, I wanted to make the _formsOk function work for both Javascript arrays and "JQuery objects". In function1(), I tried to create a Javascript array with all DOM elements except those that have a parent element with id="objectTypesContainer". Basically, function1() filters out the DOM elements I don't want before calling _formsOk() function, which does the actual form validation.
function1() {
var allForms = $('form:not(.vv_hidden)', this.selectMarketsContainer);
var nonObjectTypeForms = [];
allForms.each(function () {
if ($(this).parent().attr("id") !== "objectTypesContainer"){
nonObjectTypeForms.push($(this)[0]);
}
});
return this._formsOk(nonObjectTypeForms);
},
_formsOk: function($forms) {
var formOk = true;
console.log(typeof $forms)
$forms.each(function () { // This line fails
var validator = $(this).validate(DEFAULT_VALIDATION_OPTIONS);
if (!(validator && validator.form())) {
formOk = false;
}
});
return formOk;
},
However, I realized that because nonObjectTypeForms is now a JS Array rather than a "JQuery Object", the line marked (// This line fails) now fails.
The original code looked like this:
function1() {
var allForms = $('form:not(.vv_hidden)', this.selectMarketsContainer); // This is a "JQuery object", so no error occurs
return this._formsOk(allForms);
},
_formsOk: function($forms) {
var formOk = true;
console.log(typeof $forms)
$forms.each(function () { // This line fails
var validator = $(this).validate(DEFAULT_VALIDATION_OPTIONS);
if (!(validator && validator.form())) {
formOk = false;
}
});
return formOk;
},
Is there a way I can convert a JS array into a JQuery object ? I don't want to change _formsOk function definition just yet.
Instead of putting all elements in a new array, just use .filter() from the jQuery object.
allForms.filter(function () {
return $(this).parent().attr("id") !== "objectTypesContainer")
});
This will remove all the items you don't need in your selection and now allForms will only have the wanted elements.
I have a problem. It is my first try to work with objects in Javascript and I run in a problem.
I have an object that contains a DOM-Element and I want to add to the children of that element a click-function. Inside the click-function I want to call another object-function but that doesn't work. To call another object function I have to use this.functionname() but because I am inside the click-function this isn't anymore my object but the child-Element that I add the click-function to. So my question is: How do call my object-function from inside of a click-function.
Here is my Code (the if-condition in the middle of the code isn't important):
function ManagementCard(card) {
this.card = card;
this.row = null;
this.rowAlt = null;
this.managementCard = this;
}
ManagementCard.prototype.initializeCard = function () {
this.card.find(".card ul li div:first-child").click(function () {
row = $(this).parent();
if(this.rowAlt != null && this.rowAlt[0] != $(this).parent()[0])
{
this.rowAlt.children("div:last-child").collapse('hide');
$(this.rowAlt).css('background-color', '');
$(this.rowAlt).css('color', '');
this.rowAlt = null;
}
this.toggleManagementRow(); <=== Important! Call object-function from inside of a click-function which is inside the object-function
});
}
ManagementCard.prototype.getCard = function () {
return this.card;
}
Keep the reference to the object in another variable e.g. self. It is a common thing to do that in JavaScript
ManagementCard.prototype.initializeCard = function () {
var self = this;
this.card.find(".card ul li div:first-child").click(function () {
row = $(this).parent();
if(this.rowAlt != null && this.rowAlt[0] != $(this).parent()[0])
{
this.rowAlt.children("div:last-child").collapse('hide');
$(this.rowAlt).css('background-color', '');
$(this.rowAlt).css('color', '');
this.rowAlt = null;
}
self.toggleManagementRow();
});
}
I have numerous input boxes that I'm trying to store the names of into an array. I'm using this currently to get the names:
var getImplementedNames = function (selector){
$(selector).each(function() {
console.log($( this ).attr('name').replace('imp-', ''));
});
}
console.log(getImplementedNames('[id^=imp]'));
This works, but now I'd like to add all the reslts to an array. I've tried;
var array = [getImplementedNames('[id^=imp]')];
console.log(array);
Which returns an undefined array.
I'm not sure of how this is supposed to be properly handled.
Use .map()
var getImplementedNames = function (selector) {
return $(selector).map(function () {
return $(this).attr('name').replace('imp-', '');
}).get();
}
usage
console.log(getImplementedNames('[id^=imp]'));
Read Return Value from function in JavaScript
Your function isn't currently returning anything. Try:
var getImplementedNames = function (selector){
return $(selector).map(function() {
return $( this ).attr('name').replace('imp-', '');
});
}
console.log(getImplementedNames('[id^=imp]'));
for example:
<li class="list" id="first-list"></li>
var li = document.getElementById("first-list");
matchSelector(li, "li.list"); // this should return true
now my solution could be described as:
function matchSelector(element, selector){
var all_matched_elements = $(selector);
return element in all_matched_elements
}
but obviously this includes some unnecessary work.
is there a better solution?
You can use jQuery is method.
Something like:
var li = document.getElementById("first-list");
matchSelector(li, "li.list");
function matchSelector(element, selector){
return $(element).is(selector);
}
Working example: http://jsfiddle.net/NqwxQ/
Use jQuery's .is() to determine if an element can be matched by the specified selector. This function returns a boolean value.
For instance:
var $li = $("li");
$li.each(function() {
if ($(this).is(".list")) {
// Take action
}
});