How to split HTML code with javascript or JQuery
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
DeanYou 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.
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);
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?
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:
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,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("&", "&").replaceAll("<", "<").replaceAll("\"", """) %>
</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.)
精彩评论