Reputation: 31
This should be trivial but I'm having issues...
Basically what I am trying to do is append a new "div" to "selected-courses" when a user clicks on a "course". This should happen if and only if the current course is not already in the "selected-courses" box.
The problem I'm running into is that nothing is appended to the "selected-courses" section when this is executed. I have used alert statements to make sure the code is in fact being run. Is there something wrong with my understanding of the way .on and .each work ? can I use them this way.
Here is a fiddle http://jsfiddle.net/jq9dth4j/
$(document).on("click", "div.course", function() {
var title = $( this ).find("span").text();
var match_found = 0;
//if length 0 nothing in list, no need to check for a match
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (matched == 0) {
var out = '<div class="selected-course">' + '<a href="#">' + title + '</a>'+'</div>';
$("#selected-box").append(out);
}
});
//checks to see if clicked course is already in list before adding.
function match(str) {
$(".selected-course").each(function() {
var retval = 0;
if(str == this.text()) {
//course already in selected-course section
retval = 1;
return false;
}
});
return retval;
}
Upvotes: 1
Views: 908
Reputation: 8577
Relying on checking what text elements contain is not the best approach to solve this kind of question. It is prone to errors (as you have found out), it can be slow, it gives you long code and it is sensitive to small changes in the HTML. I would recommend using custom data-*
attributes instead.
So you would get HTML like this:
<div class="course" data-course="Kite Flying 101">
<a href="#">
<span>Kite Flying 101</span>
</a>
</div>
Then the JS would be simple like this:
$(document).on('click', 'div.course', function() {
// Get the name of the course that was clicked from the attribute.
var title = $(this).attr('data-course');
// Create a selector that selects everything with class selected-course and the right data-course attribute.
var selector = '.selected-course[data-course="' + title + '"]';
if($(selector).length == 0) {
// If the selector didn't return anything, append the div.
// Do note that we need to add the data-course attribute here.
var out = '<div class="selected-course" data-course="' + title + '"><a href="#">' + title + '</a></div>';
$('#selected-box').append(out);
}
});
Beware of case sensitivity in course names, though!
Here is a working fiddle.
Upvotes: 1
Reputation: 3847
Your Issues are :
1.this.text()
is not valid. you have to use $(this).text()
.
2.you defined var retval = 0;
inside each statement
and trying to return it outside each statement
. so move this line out of the each statement
.
3.matched
is not defined . it should be match_found
in line if (matched == 0) {
.
4. use trim()
to get and set text, because text may contain leading and trailing spaces.
Your updated JS is
$(document).on("click", "div.course", function () {
var title = $(this).find("span").text();
var match_found = 0;
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (match_found == 0) {
var out = '<div class="selected-course">' + '<a href="#">' + title + '</a>' + '</div>';
$("#selected-box").append(out);
}
});
function match(str) {
var retval = 0;
$(".selected-course").each(function () {
if (str.trim() == $(this).text().trim()) {
retval = 1;
return false;
}
});
return retval;
}
Upvotes: 0
Reputation: 4776
There was a couple of little issues in your fiddle.
See fixed fiddle: http://jsfiddle.net/jq9dth4j/1/
function match(str) {
var retval = 0;
$(".selected-course").each(function() {
if(str == $(this).text()) {
retval = 1;
return false;
}
});
return retval;
}
You hadn't wrapped your this
in a jquery object. So it threw an exception saying this
had no method text()
.
Second your retval
was declared inside the each so it wasn't available to return outside the each, wrong scope.
Lastly the if
in the block:
if (matched== 0) {
var out = '';
out += '<div class="selected-course">' + '<a href="#">' + title + '</a>'+'</div>';
$("#selected-box").append(out);
}
was looking at the wrong variable it was looking at matched
which didn't exist causing an exception.
Upvotes: 2
Reputation: 9060
Try this code, read comment for where the changes are :
$(document).on("click", "div.course", function () {
var title = $(this).find("span").text().trim(); // use trim to remove first and end whitespace
var match_found = 0;
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (match_found == 0) { // should change into match_found
var out = '';
out += '<div class="selected-course">' + '<a href="#">' + title + '</a>' + '</div>';
$("#selected-box").append(out);
}
});
function match(str) {
var retval = 0; // this variable should place in here
$(".selected-course").each(function () {
if (str == $(this).find('a').text().trim()) { // find a tag to catch values, and use $(this) instead of this
retval = 1;
return false;
}
});
return retval; // now can return variable, before will return undefined
}
Updated DEMO
Upvotes: 0