0

I'm having troubles selecting a specific textarea element with an ID I know. Worst part of this is that the HTML page I have to work on contains two textarea with this ID. I know this is not right, but I have no control over that part.

So, in that page I have two main elements: <div id="left_column"> and <div id="right_column"> which both contains an element <textarea id="CPR_DESCRIPTION">

Between the left and right_columns div and their respective #CPR_DESCRIPTION child textarea there is a plethora of other elements and they are similar on each side.

I wish to select both these #CPR_DESCRIPTION textarea separately (because I have to add the content of the #left_column's #CPR_DESCRIPTION into #right_column's one) but all my attempts are failing so far.

I have tried:

$('#left_column textarea#CPR_DESCRIPTION');

$('#left_column, textarea#CPR_DESCRIPTION');

$('#left_column').find('textarea#CPR_DESCRIPTION');

It's worth noting that I manage to retrieve #left_column as a div, but when it comes to retrieving #CPR_DESCRIPTION, no success. Also note that #CPR_DESCRIPTION is NOT a direct child of #left_column.

Here is the relevant part of HTML as asked (prepare your eyes for horrible stuff):

<div id="left_column">
  <div id="property">
    <div class="body>
      <div class="inner">
        <iframe id="property">
          <html>
            <body class="dialog">
              <div id="G360Layout">
                <form id="fieldsForm">
                  <div id="mainContainer">
                    <div id="container_2">
                      <div id="fields_container">
                        <div id="container_Description">
                          <div id="component_188">
                            <table>
                              <tbody>
                                <tr>
                                  <td>
                                    <textarea id="CPR_DESCRIPTION" name="CPR_DESCRIPTION">
                                      egeezezez
                                    </textarea>
                                  </td>
                                </tr>
                              </tbody>
                            </table>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </form>
              </div>
            </body>
          </html>
        </iframe>
      </div>
    </div>
  </div>
</div>

So this is the monster I have to deal with, as you can see there are already duplicated IDs and worst part is that #right_column is EXACTLY the same.

here is my jQuery:

function doOnLoadLayoutDescription() {

alert("inside doOnLoadLayoutDescription");

var leftColumn = $('#left_column');
//alert("leftColumn.length="+leftColumn.length);
//var description = $('textarea#CPR_DESCRIPTION');
//var description = leftColumn.find('textarea#CPR_DESCRIPTION');
var description = $('#left_column').find('textarea[id=CPR_DESCRIPTION]');
alert("description.length="+description.length);
if(description.val()) {

    alert("inside description.val()");

    var text = description.val();

    alert(text);

    var rightColumn = $('#right_column');
    var readOnlyDescription = rightColumn .find('textarea#CPR_DESCRIPTION');
    if (readOnlyDescription.length) {

        alert("inside readOnlyDescription.length");

        readOnlyDescription.val(text);

        alert("switch done");

        }
    }
    alert("ouside doOnLoadLayoutDescription");
}

NOTE: I changed the question a bit because I said it was a div but it was a textarea, even if doesn't change much, might be a good idea to rectify this now.

NOTE2: This HTML page is generated from a .jsp page that is part of a Case Management System called Case360 which is not so known. As all the content of the .jsp is generated through a drag-and-drop layout builder, it explains why this HTML is almost impossible to read comfortably.

EDIT I think I found the issue: The script I gave up there is actually being wrapped up inside the iframe element and thus only searches inside that frame, thus not finding my #left_column element. I have tried putting it outside of the iframe, to gain scope on the whole page, not only the frame but then my form's script which calls the other script won't find it now. I need to get a way to get out of that frame stuff in order to work properly. I am working on that right now.

Any idea guys?

Michael De Keyser
  • 787
  • 1
  • 17
  • 45
  • Your first and third examples should work. You're not getting help here because there must be more to the situation. – isherwood Mar 08 '13 at 14:11
  • 3
    Could you make a jsfiddle of the relevant part of your HTML structure + JavaScript and then we could wonder what on earth is happening. – Samuli Hakoniemi Mar 08 '13 at 14:11
  • You may also be encountering a limitation (not a bug) of jQuery, where will only act on a single ID of the same name: http://stackoverflow.com/questions/1053882/does-duplicate-ids-screw-up-jquery-selectors – isherwood Mar 08 '13 at 14:14
  • Please post your HTML. – Lowkase Mar 08 '13 at 14:14
  • `.find` will work as seen in this [**fiddle**](http://jsfiddle.net/nf5j4/) As the elements with the same identifier are not at the same level you are ok. Something else is causing this issue. We need the exact **relevant** HTML. Same id elements cause issues if there is more than one in the same selector than it only ever returns the first match. – Nope Mar 08 '13 at 14:15
  • by any chance, can you add additional classes to those duplicate id divs? (if so I recommend you to do that) ...or the is html you working with static?... otherwise even if you success to make this work in one browser, it may not work in other (ID is pretty much saying "uniq" on the page ) – equivalent8 Mar 08 '13 at 14:15
  • adding additional classes is already something I thought I could do but I have time to try to make it work without that so I'll make this option my last hope ;). I'm currently trying to gather a relevant html part that will not overload your eyes. :P – Michael De Keyser Mar 08 '13 at 14:25
  • As I don't know if you guys receive a notification when a question is edited, I'm notifying you here! – Michael De Keyser Mar 08 '13 at 14:53
  • Sadly, I can't produce a jsFiddle as it won't accept any tag in it. When I alert $('#left_column') I get "div#left_column" but when I want to check the size of it, I get 0. And if I try with .children().size() I get 0 as well... Wtf ? – Michael De Keyser Mar 11 '13 at 09:57

3 Answers3

2

Since jQuery may not allow duplicate ID selectors (as it shouldn't), try this:

$('#left_column').find('textarea[id=CPR_DESCRIPTION]');
isherwood
  • 58,414
  • 16
  • 114
  • 157
  • `$('#left_column').find('#CPR_DESCRIPTION')` and `$('#right_column').find('#CPR_DESCRIPTION')` works fine http://jsfiddle.net/nf5j4/ The issue will be if you would just do `$("CPR_DESCRIPTION")` as then jQuery only returns the first one. In the previous 2 examples there is only ever one match as they are in different selectors. – Nope Mar 08 '13 at 14:17
  • Take your URL out of code mode so I can click it. I'm feeling very lazy this morning. :-) – isherwood Mar 08 '13 at 14:17
  • You're almost certainly right (for most cases), but this might be worth trying. – isherwood Mar 08 '13 at 14:18
  • I have tried this, changing div for textarea but doesn't work either, even if it should. – Michael De Keyser Mar 08 '13 at 14:50
  • I don't see this scenario in your 'I tried' list. Did you use it with the exact syntax as above (updated for your scenario)? – isherwood Mar 08 '13 at 16:45
0

IDs are required to be unique, so just $("#CPR_DESCRIPTION") will work just fine.

In the general case, however, you should use .find() like so:

$(somelement).find(".selector");

However if you know the selector for the first element, you can just use a simple descendant selector:

$("#someelement .selector") // any level deep
$("#someelement>.selector") // only first-level children
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
0

Finally, I was able to make this work. So as I explained in my question under EDIT, the main problem was that my script was wrapped in the <iframe> element. This made it easy to select the first #CPR_DESCRIPTION textarea using a simple $('#CPR_DESCRIPTION'). The remaining problem was to be able to get into the second <iframe> to find the second #CPR_DESCRIPTION. In order to do that, I miraculously found a function in some dark places of an old project that does the job. I don't understand it much though (yeah I know it's not nice). But here is the code of that function:

function getFrameElement(fFrames, sName) {
    var frame = null;
    var retFrameEle = null;
    var i = 0;
    for (i=(fFrames.length-1) ; i > -1 ; i--) {
        var fFrame = fFrames[i];
        if (fFrame.name == sName) {
            retFrameEle = fFrame;
            break;
        }
        if (fFrame.id == sName) {
            retFrameEle = fFrame;
            break;
        }
        retFrameEle = getFrameElement(fFrame.frames, sName);
        if (retFrameEle != null) break;
        }
    return retFrameEle;
}

I simply call this function like this: getFrameElement(top.frames, "doc_content") with "doc_content" being the id and name of the frame I'm looking for.

Note that this is written in basic javascript which means I needed to keep on with basic javascript and simply using

getFrameElement(top.frames, "doc_content").document.getElementById("CPR_DESCRIPTION");

made the trick to find the second #CPR_DESCRIPTION textarea.

Thank you for all those who helped :)

Michael De Keyser
  • 787
  • 1
  • 17
  • 45