Uncaught ReferenceError: $ is not defined at iterateId - javascript

I know, based on this error lot of questions available in SO but my problem is bit different.
I'm using for each loop to get the id and text of the elements as below
function iterateId(id){
$("input[id*='" + id + "']").each(function(){
var idOfRadioButton = $(this).attr('id');
var textOfRadioButton = $(this).closest("div").children("label").first().text();
console.log(textOfRadioButton);
console.log(idOfRadioButton);
});
}
i'm passing id's from the array by using for loop as below
window.radioButtonOrNot = function(inputArray){
var array = inputArray;
for (i = 0; i < array.length; i++) {
console.log("Came " + array[i]);
iterateId(array[i]);
}
};
When i'm following the above approach, getting the error Uncaught ReferenceError: $ is not defined at iterateId. Any one know where i'm doing the mistake
Edit
I've included jQuery also. Following is the working scenario
window.setText = function(id, text){
if($("input[id$='" + id + "']").is(':visible')){
$("input[id$='" + id + "']").val(text);
}
};

As said by freedomn-m, may be my code is running before Jquery initialization. So, I've followed the below approach. Following approach is not a solution, but it's an alternate way to achieve the solution
I've used JavaScript instead of jQuery as below
var inputId = document.querySelectorAll("input[id*='" + id + "']");
for(i = 0; i < inputId.length; i++){
console.log(inputId[i].id);
if(document.getElementById(inputId[i].id) != null){
console.log(document.querySelector('label[for*='+ inputId[i].id +']').innerHTML);
}
}
Now everything working fine...

Related

Element.querySelector is undefined

Why does this code throw an error in the console reading TypeError: pizzaBox.querySelector is not a function. (In 'pizzaBox.querySelector('h6')', 'pizzaBox.querySelector' is undefined)?
function addToppingsToAll (toppings)
{
var pizzaBoxHolder = document.getElementById("PizzaBoxHolder");
var PizzaBoxList = pizzaBoxHolder.childNodes;
for ( var i = 0 ; i < pizzaBoxList.length ; i++ )
{
var pizzaBox = pizzaBoxList[i];
toppingList = pizzaBox.querySelector('h6');
toppingList.textContent = "You have " + toppings " on your pizza";
}
}
There are at least three isssues in your code:
You are probably iterating through some text nodes which don't have a .querySelector() method.
You are not initializing your for loop iteration variable i
You have an undeclared variable lineBoxList you are attempting to use.
You can simplify things by just using .querySelectorAll() and letting the selector do more of the work for you.
function addToppingsToAll (toppings) {
var toppingItems = document.querySelectorAll("#PizzaBoxHolder h6");
for (var i = 0; i < toppingItems.length; i++) {
toppingItems[i].textContent = "You have " + toppings " on your pizza";
}
}
querySelector is a method that appears on HTML Element Nodes. One or more of the childNodes must be some kind of node that is not an Element (such as Text Nodes or Comment Nodes).
This is probably most easily resolved with:
var PizzaBoxList = document.querySelector("#PizzaBoxHolder > *");

compare the return values of two functions (dynamic quiz)

BACKGROUND
I am creating a dynamic, multiple-choice quiz written in JavaScript as a culmination to this course. I am following the parasitic inheritance pattern outlined in a follow-up post by the author of the course, and am having trouble completing the project.
PROBLEM
If you refer to this JSBIN, you will see that I have created functions to loadQuestion, displayQuestion, getUserAnswer, getCorrectAnswer, and checkAnswer. checkAnswer is where I am stuck. In this function id like to check if the returned value of getUserAnswer is equal to the returned value of getCorrectAnswer on the currently loaded question, and if so, just log a string to the console for now.
Question.prototype.displayQuestion = function(){
var questionToDisplay = '<div class="question">' + this.question + '</div><ul>';
choiceCounter = 0;
var quizDiv = document.getElementById('quiz');
this.choices.forEach(function(eachChoice){
questionToDisplay += '<li><input type="radio" name="choice" value="' + choiceCounter + '">' + eachChoice + '</li>';
choiceCounter++;
});
questionToDisplay += '</ul>';
quizDiv.innerHTML = questionToDisplay;
};
var i = 0;
Question.prototype.loadQuestion = function(){
if(i < allQuestions.length){
var quest = new MultipleChoiceQuestion(allQuestions[i].question, allQuestions[i].choices, allQuestions[i].correctAnswer);
quest.displayQuestion();
i++;
return quest.getCorrectAnswer();
}
};
Question.prototype.getCorrectAnswer = function() {
return this.correctAnswer;
};
Question.prototype.getUserAnswer = function(){
var radio = document.getElementsByName('choice');
for(var i=0; i < radio.length; i++){
if(radio[i].checked){
return radio[i].value;
}
}
};
//Non-functioning code, this is what im trying to figure out.
/*Question.prototype.checkAnswer = function(){
if(Question.prototype.loadQuestion() == Question.prototype.getUserAnswer()){
console.log('it worked!');
} else {
console.log('keep trying!');
}
};*/
//Load the first question
Question.prototype.loadQuestion();
var button = document.getElementById('next');
button.onclick = function(){
//get the user-selected radio input.
Question.prototype.getUserAnswer();
//Question.prototype.checkAnswer();
//load next question
Question.prototype.loadQuestion();
};
I am new to javascript (and programming) and suspect that the problem lies in some misunderstanding of how return values work?
Thank you!
Found the problem.
You're not adding 1 to the value of radio[i]. Remember that this is an array, and so all the indices will be decreased by 1 because we start counting from 0.
Here is your function:
Question.prototype.getUserAnswer = function(){
var radio = document.getElementsByName('choice');
for(var i=0; i < radio.length; i++){
if(radio[i].checked){
return +(radio[i].value) + 1;
}
}
};
I realize now the problem was more with my approach than any one error. I followed and improved upon an example of another student. Here is the repo for the project as it stands. The most important thing I've learned is how to encapsulate the variables I need all functions to have access too. In this case, a variable called currentQuestionIndex that increments and is available to all functions was important to the solution.

Uncaught TypeError: Cannot read property x of undefined

Getting the above error in Chrome console while the actual script works and generates the right output, wonder how I can get rid of this error and what is causing it.
JSFiddle: http://jsfiddle.net/wJUeP/
HTML Code:
<ul id="menu"></ul>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
JS Code:
$(function(){
var data = [{"weekending":"09\/10\/2013","jobs":[{"jobnumber":"1001","jobaddress":"Test1001","employees":[{"employeenumber":"1","name":"James Blabla","class":"FHM","notes":"xx","nt-wkmon":"2","t12-wkmon":"5","dt-wkmon":"4","status-wkmon":"Public Holiday","startTime-wkmon":"4","finishTime-wkmon":"6","nt-wktue":"7"}]},{"jobnumber":"1002","jobaddress":"Test1002","employees":[{"employeenumber":"1","name":"Cameron Le","class":"FHQ","notes":"xx","nt-wkmon":"2","t12-wkmon":"5","dt-wkmon":"4","status-wkmon":"Public Holiday","startTime-wkmon":"4","finishTime-wkmon":"6","nt-wktue":"7"},{"employeenumber":"2","name":"David Le","class":"FHQ","notes":"xx","nt-wkmon":"2","t12-wkmon":"5","dt-wkmon":"4","status-wkmon":"Public Holiday","startTime-wkmon":"4","finishTime-wkmon":"6","nt-wktue":"7"}]},{"jobnumber":"1003","jobaddress":"Test1003","employees":[{"employeenumber":"1","name":"Nick G","class":"sdf","notes":"sdf","nt-wkmon":"2","t12-wkmon":"5","dt-wkmon":"4","status-wkmon":"Public Holiday","startTime-wkmon":"4","finishTime-wkmon":"6","nt-wktue":"7"}]}]}];
for(var i = 0, j = data[0].weekending.length; i<j; i++) {
rootMenu = data[0].jobs[i];
$("#menu").append("<li id='job_" + rootMenu.jobnumber + "'>" + rootMenu.jobnumber);
if(rootMenu.hasOwnProperty("employees")) {
$("#menu").append("<ul id='employees_job_" + rootMenu.jobnumber + "'>");
for(var n = 0, m = rootMenu.employees.length; n<m; n++) {
var subMenu = rootMenu.employees[n];
if(subMenu.hasOwnProperty("name")) {
$("#employees_job_" + rootMenu.jobnumber).append("<li>" + subMenu.name + "</li>");
}
}
$("#menu").append("</ul>");
} else {
$("#menu").append("</li>");
}
}
});
Note: I'm still in the development stage of my application and I have the flexibility to change and manipulate the data structure, if embedded JSON data looks bad I can change it, actual data is stored in a XML file and then read by PHP and outputted as JSON.
the for loop condition is incorrect.
you have used j = data[0].weekending.length which is equal to 10 and you are iterating over the data[0].jobs object which has only 3 jobs. You are iterating more than 3 times over the jobs and hence you are getting the error.
checkout the fiddle http://jsfiddle.net/wJUeP/7/
The error is here:
j = data[0].weekending.length
This is returning 10, which is the length of the string in the weekending property == 10 ("09/10/2013")
I think you need this instead:
j = data[0].jobs.length

Improving jquery select speed

I have this code which manipulates the asp.net treeview html code.
This code gets run frequently, so its important that it runs as fast as possible.
I want to learn more about jquery selectors and improving its speed. So far I was able to get this code myself.
Some things I am not sure about is if you want the third child element, do I use [2] or .eq(2) or :nth-child(2)? Also what if I use $ to select something that was from an array of selected stuff, is this necessary, or is it already selected?
Does anyone know any tricks or hints I can do to improve my jquery select efficiency?
Thanks.
function showResultsOnTreeview(treeviewID, filenameDictionary) {
var sectionNodes = $("#" + treeviewID + " > table");
var numOfSections = sectionNodes.length;
var i, j, sectionName, divContainer, itemNodes, numOfItems, itemName, itemTag, itemPath;
for (i = 0; i < numOfSections; i += 1) {
sectionName = $(sectionNodes[i]).text();
divContainer = $(sectionNodes[i]).next('div');
divContainer.hide();
itemNodes = $('table', divContainer);
numOfItems = itemNodes.length;
for (j = 0; j < numOfItems; j += 1) {
itemTag = $('td', $(itemNodes[j])).eq(2);
itemTag.removeClass('treeViewResult');
itemName = getNameFromItem($(itemNodes[j]).text());
itemPath = filenameDictionary[itemName];
if (itemPath != null) {
if (itemPath.indexOf(sectionName + "/" + itemName) != -1) {
itemTag.addClass('treeViewResult');
divContainer.show();
}
}
}
}
}
There is some optimisation you can do. The first on is for sure to use .eq() instead of []. Like here, you hare creating a jQuery object :
var sectionNodes = $("#" + treeviewID + " > table");
But then later, you do this :
sectionName = $(sectionNodes[i]).text();
divContainer = $(sectionNodes[i]).next('div');
Here you are creating 2 more, unneeded, jquery object, you could just do this :
sectionName = sectionNodes.eq(i).text();
divContainer = sectionName.next('div');
Then, i do't know if you have a different way to do it, but if you can remove the "loop in a loop", that would be great.
After, instead of using context selectore ($('selector', $element)), use find. Context use find so it will reduce the number of function calls. Take this line for example :
$('td', $(itemNodes[j])).eq(2)
You are creating 2 jQuery object when you can do the same without an extra object and could use .find():
itemTag = itemNodes.eq(j).find('td').eq(2);
Basicly, use .find() instead of context and avoid creating unneeded jQuery object. Hope that will help.

Use "event's" output as a variable

I have a problem to manipulate checkbox values. The ‘change’ event on checkboxes returns an object, in my case:
{"val1":"member","val2":"book","val3":"journal","val4":"new_member","val5":"cds"}
The above object needed to be transformed in order the search engine to consume it like:
{ member,book,journal,new_member,cds}
I have done that with the below code block:
var formcheckbox = this.getFormcheckbox();
formcheckbox.on('change', function(checkbox, value){
var arr=[];
for (var i in value) {
arr.push(value[i])
};
var wrd = new Array(arr);
var joinwrd = wrd.join(",");
var filter = '{' + joinwrd + '}';
//console.log(filter);
//Ext.Msg.alert('Output', '{' + joinwrd + '}');
});
The problem is that I want to the “change” event’s output (“var filter” that is producing the: { member,book,journal,new_member,cds}) to use it elsewhere. I tried to make the whole event a variable (var output = “the change event”) but it doesn’t work.
Maybe it is a silly question but I am a newbie and I need a little help.
Thank you in advance,
Tom
Just pass filter to the function that will use it. You'd have to call it from inside the change handler anyway if you wanted something to happen:
formcheckbox.on('change', function(cb, value){
//...
var filter = "{" + arr.join(",") + "}";
useFilter(filter);
});
function useFilter(filter){
// use the `filter` var here
}
You could make filter a global variable and use it where ever you need it.
// global variable for the search filter
var filter = null;
var formcheckbox = this.getFormcheckbox();
formcheckbox.on('change', function(checkbox, value){
var arr = [],
i,
max;
// the order of the keys isn't guaranteed to be the same in a for(... in ...) loop
// if the order matters (as it looks like) better get them one by one by there names
for (i = 0, max = 5; i <= max; i++) {
arr.push(value["val" + i]);
}
// save the value in a global variable
filter = "{" + arr.join(",") + "}";
console.log(filter);
});

Categories