select a different element other than the one clicked - javascript

How do I select an element with jquery, when a different element is clicked, when you don't know the name of the element? The code below is looping over the all the categories. I don't know how many categories there are, or what the names will be. When the 'insertUrl' link is clicked, I need to select the text area.
The only thing I can thinking is running an function in onclick and passing the name of the text area as a parameter.
Also, I'm not sure that I can use a selector when every link has the same id, so is this even possible?
<%
FullName = objCategory.ID & "|" & objCategory.Name
%>
<TD COLSPAN="2">
<TEXTAREA ROWS="5" CLASS="formWide" id="<%=FullName %>"><%= objCategory.Text %></TEXTAREA><br />
Insert URL
</TD>

If the HTML structure stays the same you can use .prev()
You shouldn't have elements with the same ID. You can use classes class="insertUrl"
<%
FullName = objCategory.ID & "|" & objCategory.Name
%>
<TD COLSPAN="2">
<TEXTAREA ROWS="5" CLASS="formWide" id="<%=FullName %>"><%= objCategory.Text %></TEXTAREA><br />
Insert URL
</TD>
and
$(".insertUrl").click(function() {
var textarea = $(this).siblings('textarea');
});

maybe its better if you use:
$(this).siblings('textarea');
this way you have more flexibility with the html controls order.
this way, if you remove the or change something else inside that TD the script will still works.

An even better way would be to use the <label> element. This way, you can insert later additional elements between the text comment and the textarea, and it still will work.
<textarea id="ta_id1" onclick="click_processing_func"></textarea>
<label for="ta_id1" class="link">Insert Url</label>
Now, if anyone clicks on the label, textarea will receive the click event.

Related

Select element id with special character in it with jquery/javascript

I have a jsp that contains a number of diffenent elements ids. Example:
<div id="divName">
...
<tr id="tr_0_123/45">
<input type="hidden" name="field_0_123/45" value="NAME_Field" id="field_0_123/45">
</tr>
</div>
The problem is that I need to be able to read the value field from my input. To do so I use
function workOnValue(){
var idTr = 'tr_0_123/45';
var idName = 'field_0_123/45';
${"#divName #"+idTr +" input[id='"+idName+"']).each(function(){
do something...
}
}
When I run this code the JQuery does not find any input with that id, meanwhile with any other kind of id that does not include the character / it does.
I tried $.escapeSelector but my jQuery version is too old to work with it.
I tried to use idName.replace("/","\\/"); or .replace(/[|\(\)#\\\/]/g, '\\$&');
Do you have any suggestions?
Well if you just want to escape the / you can replace idName with idName.replace("/", "\/"), but also in the HTML itself there is no closing " at the end of the ID definition, so the actual ID name itself is perhaps cut off with the /, as "s aren't necessary for IDs with no spaces, and supposedly, with no slashes either.
So just add a closing " to the ID of the inputs.
Another thing though is if you're selecting by ID, there's no reason to select the parent node's ID, since every ID is unique. You can change all of the code to either ${"input[id='"+idName+"']) or ${"#divName input") or ${"#" + idTr +"input"), if you only have 1 input type that u want to select in the elements.
Your HTML is malformed; a tr should be in a tbody or thead which is in a table. Also content in a tr should be inside a td or a th. Please see the output of console.log( $tr[0] ); in the demos below.
You can select the input element directly using it's id; the id attribute is unique - if it's not, then your HTML would still be malformed after you correct the table HTML. You can use $('[id="id-value"]') to select by id. The two demos demonstrate that you'll correctly select the input element whether or not the table html is malformed. See output of console.log( $input ); below.
$tr = $('[id="tr_0_123/45"]');
$input = $('[id="field_0_123/45"]');
console.log( $tr[0] );
console.log( $input.val() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="divName">
...
<tr id="tr_0_123/45">
<td><input type="hidden" name="field_0_123/45" value="NAME_Field" id="field_0_123/45"></td>
</tr>
</div>
$tr = $('[id="tr_0_123/45"]');
$input = $('[id="field_0_123/45"]');
console.log( $tr[0] );
console.log( $input.val() );
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="divName">
...
<table>
<tbody>
<tr id="tr_0_123/45">
<td><input type="hidden" name="field_0_123/45" value="NAME_Field" id="field_0_123/45"></td>
</tr>
</tbody>
</table>
</div>
NOTE
If you have access to the JSP page generating the IDs please edit it to remove special characters.
If the IDs of the input elements are not unique - the fact that you're using .each() implies so, edit the JSP page to make them unique or change the id attribute to a class attribute instead.
References
HTML: Allowed Characters in id Attribute
Best Practice for Naming the Id Attribute of Dom Elements
What is the standard naming convention for html/css ids and classes?

How can I validate that dynamically generated fields are not empty?

I am working on a bootstrap environnement with classic asp.
I have a dynamically generated input fields
<input type="number" size="5" name="montantafacturer_<%=irs("INSPECTIONID")%>">
<button onclick="_EVENTSPARAM('events_ajouteralafacturation','<%=irs("INSPECTIONID")%>');">add</button>
There can be up to 100 dynamically generated fields on one page.
The basics are that i should fill the field montantafacturer_<%=irs("INSPECTIONID")%> with a numeric value and click on add to insert value in the database in a postback method
I am wondering if i can insert a javascript code to check if my field is filled rather than getting the field empty error from postback response... to gain time
ie :
<input type="number" size="5" name="montantafacturer_<%=irs("INSPECTIONID")%>">
<button onclick="**IF montantafacturer_<%=irs("INSPECTIONID")%>" IS NOT EMPTY THEN** _EVENTSPARAM('events_ajouteralafacturation','<%=irs("INSPECTIONID")%>');">add</button>
I wonder if this can be done via inline javascript.
Please advise how.
iid = irs("INSPECTIONID")
if iid <> "" then %>
<input type="number" size="5" name="montantafacturer_<%=iid%>">
<button onclick="_EVENTSPARAM('events_ajouteralafacturation','<%=iid%>');">add</button>
<$ end if %>
That way if your recordset is empty, no HTML is output. If you move the IF/THEN to just before the Button tag, then no button will be created for an empty value.
First of all, welcome to StackOverflow
Secondly ... It's been a very long while when I stopped using Classic ASP (more than 15 years ago), it's nice to see that he still has a small place out there :)
Last, but not the least... your question
as you have input and buttons, I'm sure you have a for loop and outside I will assume you have a <form> tag wrapping all inputs and buttons
To accomplish what you're trying to do, and making use of better code techniques, I would most likely end up with something as (and assuming that you can use jQuery to lift a bit of the javascript... let me know if you can't, and I'll re-write without it)
<form action="/yourpage.asp" method="POST">
<table class="table">
<tbody>
<% For ... %>
<tr class="tr-<%=irs("INSPECTIONID")%>">
<td>
<input
type="number"
size="5"
id="montantafacturer_<%=irs("INSPECTIONID")%>"
name="montantafacturer_<%=irs("INSPECTIONID")%>">
</td>
<td>
<button
class="btn"
data-event="events_ajouteralafacturation"
data-input="<%=irs("INSPECTIONID")%>"
>add</button>
</td>
</tr>
<% Next %>
</tbody>
</table>
</form>
<script>
$(function() {
// for every button with class "btn", fire "onButtonClick" fn upon click
$(".btn").on("click", onButtonClick);
});
function onButtonClick(evt) {
evt.preventDefault();
var btn = $(evt.currentTarget); // the clicked button
var btnEvent = btn.data("event");
var btnInput = btn.data("input");
// your logic
var input = $("#montantafacturer_" + btnInput).val();
if(input.length === 0) {
// show the error in any way you prefer
return;
}
// if we reach here, we have data in the input
_EVENTSPARAM(btnEvent, btnInput);
// you can now fire some code to submit the form
// or just this value, or even disable the button while it
// is being used to send the data (prevent double click), etc.
}
</script>
the <tr class="tr-<%=irs("INSPECTIONID")%>"> was a technique that I used back then so I could add a class that would mark that row with another color, to give some feedback to the user that something was happening with that row data, for example
$(".tr-" + btnInput).addClass("updating");
I've also added id to the input to use $("#...") instead of search by name
Small rant on using JS inline
Why would you ever use inline JS? It really isn't practical or readable - highly recommend moving that into an external source.
How to use JS inline (pls don't)
But if there is absolutely no way around for you, you can always just throw all your normal JS code inside an inline event like onclick.
<button onclick="
// this makes me sad
const allInputs = document.querySelectorAll('[name^=montantafacturer_]');
allInputs.forEach(input => {
if (input.value.length > 0 && !isNaN(input.value)) {
// number
} else {
// empty / Not a Number
}
});
">
add
</button>
This is about what you are looking for.
Mentions
Really, don't use inline JS
As pointed out by another user - you may want to use the HTML property required

Trying to target an element if it has a label

Attempted to log a label to console via
var labelTest = document.getElementById('js_8').label;
console.log(labelTest);
However it is returning undefined.
Edit: correcting some stuff, sorry at work and trying to do this in between other tasks. What my end result needs to be is targeting the inner html of the js_8 ID, but with React it is different for each of the Pages that it is on. So I want to add an extra stipulatoin of having that label attribute.
HTML:
<span data-reactroot="" label="1715724762040702" class="_xd6" data-pitloot-persistonclick="true" display="inline" data-hover="tooltip" data-tooltip-content="Copy Text to Clipboard" id="js_8"><div class="_xd7">1715724762040702</div></span>
I'm not sure exactly what you're after, but this is a way to connect a <label> and <input> together via JavaScript.
var some_id = 'someid',
my_label = getLabel(some_id);
function getLabel(id) {
return document.querySelector('[for=' + id + ']')
}
my_label.click();
<label for='someid'>My Label</label>
<input type='text' id='someid' />
You can associate a <label> with an <input>, <output>, <select> or <textarea> element in one of two ways:
The for attribute:
<label for="js_8">Test</label>
<input id="js_8">
Or by wrapping the element with a label:
<label>Test<input id="js_8"></label>
You can then access the associated label(s) as an array like this:
var labelsTest = document.getElementById('js_8').labels;
// labelsTest will be an array of 0 or more HTMLLabelElement objects
console.log(labelsTest);
Label-able elements can have more than one label.
So essentially I believe I am going to want to utilize var x = getAttribute("label") . The fact that the attribute was titled label confused me, and in turn I goof'd.

Jquery insert an image to a HTML table

I want to use jQuery to insert an image after a certain row of a HTML table. I tried to use the appendTo function, but it did not work. I guess its something wrong with my jQuery selector. Can anyone correct my code?
Thanks!
HTML code:
<div class="articles">
<table align="center">
<tr><th><label for="id_chemical_name">Chemical name:</label></th><td><textarea id="id_chemical_name" rows="2" cols="17" name="chemical_name">Spinosad</textarea></td></tr>
<tr><th><label for="id_T">Number of time intervals:</label></th><td><input type="text" name="T" value="10" id="id_T" /></td></tr>
<!--I would like to insert an image after the row 'Number of time intervals'-->
<tr><th><label for="id_a">Logistic model parameter (α):</label></th><td><input type="text" name="a" value="0.746" id="id_a" /></td></tr>
</table></div>
jQuery code:
<script type="text/javascript" src=" ../stylesheets/jquery-1.7.2.js"></script>
<script>
$(document).ready(function(){
$('<img src = "https://www.google.com/images/srpr/logo3w.png" />').appendTo('#id_T');
})
</script>
Here is a demo of the question.
You cannot insert an image directly to a table without enclosing it in a tr and td/th element. I think this is what you are trying to do:
$('<tr><th colspan="2"><img src = "https://www.google.com/images/srpr/logo3w.png" /></th></tr>').insertAfter($("#id_T").parent("td").parent("tr"));
The element with ID id_T is an <input> - specifically a textbox - which cannot have child elements (and certainly not a child image).
You may want to try insertBefore or insertAfter instead, or you could use something like:
$('#id_T').closest('td').appendTo...
to move up the DOM from the input and find the containing <td>.
#id_T is a text input, you can't append an image to it.
Why can't you just put the image in manually? Especially since you can't just dump an image in the middle of a table structure like that.
To add a image to the same TD that id_T is in. Do that
$('<img src = "https://www.google.com/images/srpr/logo3w.png" />').appendTo($('#id_T').parent());
Any table's content should be inside td or th tag which should be in valid tr tag. Check your selector place again.

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
Dean
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.
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.)

Categories