1

Firstly I have gone through some questions having same title as mine like this etc. but none solved my problem.

HTML part -

<tr id="row_question_container">
    <td valign="top" colspan="2">
        <div id="at_test_area-1" class="at_test_area">
            <div id="at_questions_container">
                <div id="1" class="question_block completed unmarked" style="display: none;">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
                <div id="2" class="question_block completed marked">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
                <div id="3" class="question_block incomplete unmarked" style="display: none">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
                <div id="4" class="question_block incomplete unmarked" style="display: none">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
            </div>
        </div>
    </td>
</tr>

What I am trying to achieve is to get next/closet id of div (to navigate using next and previous buttons) having class incomplete or marked. After reading through similar questions, I tried following jQuery, but it returned undefined

var marked_question = $('#at_questions_container').next('.marked').attr('id');
alert(marked_question);
Jonas
  • 121,568
  • 97
  • 310
  • 388
Dr. Atul Tiwari
  • 1,085
  • 5
  • 22
  • 46
  • 1
    The problem is that you're working from the container level, whereas `next()` works on siblings, so you should look at the current visible child element and use `next()` on that. – Rory McCrossan Oct 20 '15 at 16:47

4 Answers4

1

jQuery's next() function will look for siblings of #at_questions_container, rather than child elements.

Since you're looking for a child of #at_questions_container, you should use the children() function instead, in combination with the :first selector:

var theID = $('#at_questions_container').children('.marked:first').attr('id');

Using children() is a much safer approach, since it will only search one depth, thus preventing any sub-elements which also have a class of .marked from being returned. For example, from the jQuery docs:

The .children() method differs from .find() in that .children() only travels a single level down the DOM tree while .find() can traverse down multiple levels to select descendant elements (grandchildren, etc.) as well.


As a slight post-script to the above, the use of the :first selector is not essential. When calling attr('id'), jQuery will automatically return the ID attribute of the first element in the collection.

BenM
  • 52,573
  • 26
  • 113
  • 168
0

For descendants you should use find() or children() depending on how deep you wish to go

var marked_question = $('#at_questions_container').find('.marked').attr('id');
console.log(marked_question);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table>
<tr id="row_question_container">
    <td valign="top" colspan="2">
        <div id="at_test_area-1" class="at_test_area">
            <div id="at_questions_container">
                <div id="1" class="question_block completed unmarked" style="display: none;">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
                <div id="2" class="question_block completed marked">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
                <div id="3" class="question_block incomplete unmarked" style="display: none">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
                <div id="4" class="question_block incomplete unmarked" style="display: none">
                <!-- Question / Option / Settings etc in nested tables are here -->
                </div>
            </div>
        </div>
    </td>
</tr>
</table>
AmmarCSE
  • 30,079
  • 5
  • 45
  • 53
  • Thanks. I got it, but then since this will return the first `marked` only how to navigate to next/closest marked? – Dr. Atul Tiwari Oct 20 '15 at 16:54
  • @Dr.AtulTiwari, after using `find` you can use `next` like `$('#at_questions_container').find('.marked').next('.marked')` – AmmarCSE Oct 20 '15 at 16:56
  • I tested `.next('.marked')`, but I think it's returning as object, In console I got output as - `[div#3.question_block.incomplete.marked, div#4.question_block.incomplete.marked, prevObject: jQuery.fn.jQuery.init[3], context: document]` – Dr. Atul Tiwari Oct 20 '15 at 17:04
  • @Dr.AtulTiwari, right, if you want the id you need to include the `attr('id')` like `$('#at_questions_container').find('.marked').next('.marked').attr('id')` – AmmarCSE Oct 20 '15 at 17:05
  • sorry, that was my mistake, I knew but it didn't strike me. But I am still facing hard time on how to navigate back and forth... for better understanding, I created a [jsfiddle](http://jsfiddle.net/atultiwari/nva1uo3g/),if you please look where am I doing wrong, because next marked is returning undefined... – Dr. Atul Tiwari Oct 20 '15 at 17:25
  • anyways tried so hard but was unable to figure out how to make Next and Previous navigation work. But I learned at least two things from your answers. I will close this question now, and ask separately about navigation. Thanks, Upvoted and selected. – Dr. Atul Tiwari Oct 20 '15 at 17:40
  • 1
    @Dr.AtulTiwari, so sorry, I am in the middle of work right now. If you still dont figure it out let me know and I can help you later today or tommorow – AmmarCSE Oct 20 '15 at 17:52
  • Hi, I tried my best to create navigation buttons, but couldn't. Stuck since last 5 days. When you get some free time, will you please look into my newly ask question - [Link](http://stackoverflow.com/questions/33326796/navigate-next-or-previous-div-by-class-in-jquery) – Dr. Atul Tiwari Oct 25 '15 at 06:31
0

Try this:

var marked_question = $('#at_questions_container').find('.marked:first').attr('id');

You want to find descendants of at_questions_container and the first selector will give you the first one found. next works on sibling elements.

AtheistP3ace
  • 9,611
  • 12
  • 43
  • 43
0

try:

var marked_question =$('#at_questions_container').find('.marked').first().attr('id');
alert(marked_question);
  • And how do you get from `first()` to the next one? Please be more specific. – Max Leske Oct 20 '15 at 19:52
  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – Max Leske Oct 20 '15 at 19:52
  • var marked_question =$('#at_questions_container').find('.marked').first(); var nextValue = marked_question.next().attr('id'); console.log(nextValue); – Radu Gheorghies Oct 21 '15 at 06:29
  • Edit your answer and put that code there, not in a comment. It will improve the value of your answer (plus it will be more readable). Also, consider adding an explanation. Code only answers are discouraged on SO. – Max Leske Oct 21 '15 at 06:32