views:

60

answers:

4

Hi
I'm making a website using JSP and servlets and I have to now break up a list of radio buttons to insert a textarea and a button. I have got the button and textarea to hide and show when you click on the radio button it shows the text area and button. But this only appears at the top and when there are hundreds on the page this will become awkward so i need a way for it to appear underneath. Here is what my HTML looks like when complied:

<form action="addSpotlight" method="POST">
        <table>


            <tr><td><input type="radio" value="29" name="publicationIDs" ></td><td>A System For Dynamic Server Allocation in Application Server Clusters, IEEE International Symposium on Parallel and Distributed Processsing with Applications, 2008</td> </tr>


            <tr><td><input type="radio" value="30" name="publicationIDs" ></td><td>Analysing BitTorrent's Seeding Strategies, 7th IEEE/IFIP International Conference on Embedded and Ubiquitous Computing (EUC-09), 2009</td> </tr>


            <tr><td><input type="radio" value="31" name="publicationIDs" ></td><td>The Effect of Server Reallocation Time in Dynamic Resource Allocation, UK Performance Engineering Workshop 2009, 2009</td> </tr>


            <tr><td><input type="radio" value="32" name="publicationIDs" ></td><td>idk, hello, 1992</td> </tr>


            <tr><td><input type="radio" value="33" name="publicationIDs" ></td><td>sad, safg, 1992</td> </tr>


            <div class="abstractWriteup"><textarea name="abstract"></textarea>
            <input type="submit" value="Add Spotlight"></div>

        </table>
    </form>

Now here is what my JSP looks like:

<form action="addSpotlight" method="POST">
        <table>
            <%int i = 0; while(i<ids.size()){%>

            <tr><td><input type="radio" value="<%=ids.get(i)%>" name="publicationIDs" ></td><td><%=info.get(i)%></td> </tr>
            <%i++; }%>

            <div class="abstractWriteup"><textarea name="abstract"></textarea>
            <input type="submit" value="Add Spotlight"></div>

        </table>
    </form>

Thanks in Advance
Dean

A: 

you can use after(html) or before(html) you only need to add to every radiobutton a unique value but you already did that with value="<%=ids.get(i)%>"

something like this?

$("input[value='PutIdHere']").parent().after(htmlContent);
michel
+1  A: 

You can easily move DOM nodes around using Node#insertBefore. (That link is to MDC, but it's a standard method and well-supported.)

Here's an example using Prototype, but you can do it with jQuery or other libraries, or just straight DOM methods like the one linked above (it's just more hassle without a library):

// Called at some point during page init to hook up the event handler
function hookRadioButtons() {
    var form;

    form = $('theForm'); // Assuming you put an ID on the form
    form.observe('click', radioButtonClick);
}

// Event handler for radio button clicks
function radioButtonClick(event) {
    var btn, div;

    // Get the (extended) DOM element for the button
    btn = event.findElement('input[type=radio]');
    if (btn) {
        // Get the (extended) DOM element for the div
        div = $('theDiv'); // Assuming you gave the div an ID

        // Starting from the button, go `up` to the table cell,
        // then over to the following cell, and then insert the
        // div at the top of it
        btn.up('td').next().insert({
            top: div
        });

        // Show the div (if it's hidden)
        div.show();
    }
}

That's completely off the cuff and untested (and full of assumptions), it's just to give you an idea.

T.J. Crowder
A: 

Move the div "abstractWriteup" to after the closing table tag. It's invalid code to have it inside a table without a containing row and cell anyway, and this will ensure that it appears below the table.

EDIT

I realise I may have misunderstood - you want the div to appear below the radio button which has been clicked, don't you?

graphicdivine
Yes and i will move it in my source.
Dean
A: 

You can't put <div> inside a table. It's invalid and browsers may render it in odd ways, like, as you said, as the top.

You would have to either:

  1. close the table, put the div and then if you need more rows after that open a second table. To ensure two tables have the same row widths, you can set table-layout: fixed on the tables and add <col> elements with explicit widths for the non-liquid columns. Or,

  2. include the textarea/submit in a new <tr><td>.

Having said that, I don't know why you're using a table here when you aren't really doing anything with the columns. A simple <div> for each radio would be easier to handle.

Since you will also only ever have one radio ticked, you can re-use the same textarea/submit elements, and just move them to the right row onclick. With JavaScript disabled they'll just stay at the bottom.

<form id="publications" method="post" action="...">
    <% for(int i= 0; i<ids.size(); i++) { %>
        <div>
            <input type="radio" name="publicationIDs" value="<%= ids.get(i) %>" id="pid_<%= ids.get(i) %>">
            <label for="pid_<%= ids.get(i) %>">
                <%= info.get(i).replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll("\"", "&quot;") %>
            </label>
        </div>
    <% } %>
    <div id="abstractsubmit">
        <textarea name="abstract"></textarea>
        <input type="submit" value="Add Spotlight">
    </div>
</form>

Note: <label> added, for better usability (can click on name to select radio). replaceAll here is acting as a poor man's HTML encoder. You need an HTML encoder every time you output text into HTML, otherwise characters like < in the text will mess up the page, and potentially create cross-site-scripting security holes.

Unfortunately, in an appalling oversight, the original version of JSP didn't include an HTML encoder. Many, many libraries for web-related software have one you can use to avoid having to write out all these replaceAll​s. Also, if you're using JSP 2.0+, you should consider using JSTL c: tags rather than scriptlets. <c:out> gives you an output-with-HTML-encoding behaviour by default.

Example script to move the abstract element about:

<script type="text/javascript">
    var radios= document.getElementById('publications').elements.publicationIDs;

    function update() {
        // Get div containing selected radio
        //
        var selected= null;
        for (var i= radios.length; i-->0;)
            if (radios[i].checked)
                selected= radios[i].parentNode;

        // Move abstract div just after it
        //
        var a= document.getElementById('abstractsubmit');
        if (selected===null) {
            a.style.display= 'none';
        } else {
            a.style.display= 'block';
            selected.parentNode.insertBefore(a, selected.nextSibling);
        }
    }

    // Bind to all radios, and reflect initial form selectedness state
    //
    for (var i= radios.length; i-->0;)
        radios[i].onclick= function() { setTimeout(update, 0); };
    update();
</script>

setTimeout is used here because the onclick event fires before the radio have been selected to reflect the click, so update can't yet read which radio is chosen. The right thing to do would be to use onchange instead, but unfortunately that doesn't fire at a useful time in IE, so onclick is what we're left with.

update is run at the start because when you're doing forms you can never be sure what your initial state is. Browsers often try to remember form fields when returning to a page, which may result in a radio unexpectedly being ticked at start of play.

(You could make this a little shorter with jQuery. But not massively shorter.)

bobince