I want to overwrite some standard text from my CMS.
<form accept-charset="UTF-8" action="/da-DK/listings" class="new_listing"
enctype="multipart/form-data" id="new_listing" method="post"
novalidate="novalidate"><div style="margin:0;padding:0;display:inline">
<input name="utf8" type="hidden" value="✓"><input name="authenticity_token" type="hidden"
value="vvEeH5tHhuGME4jNDPhw0o4w8KoWpwgchgrU7xG/7LQ="></div>
<label class="input" for="listing_title">CHANGE THIS TEXT</label>
I want to change the text where it says "CHANGE THIS TEXT" using javascript. I know very basic javascript though, so I hoped someone here could help me.
I already have code that enables me to change a text with an ID, but this label doesn't have an ID, so I don't know how to go about it.
Thank you for your time.
The script can only be posted in the head section of the whole site (even though it's specific to one ingle page).
Here is my other script that worked for ID:
<script>
var texts = [];
texts["new-listing-link"] = "NEW TEXT HERE";
var interval = setInterval(function() { setText(); }, 100);
function setText() {
var textsCopy = texts.slice();
for (var key in texts) {
var element = document.getElementById(key);
if (element != null) {
element.innerHTML = texts[key];
delete texts[key];
}
}
if (texts.length == 0) {
window.clearInterval(interval);
}
}
</script>
How can I go about it? :)
I'm pretty sure I'm only allowed to use javascript and not jQuery
Here's another way, no need to change what you've got
document.querySelector('label[for=listing_title]').innerHTML = 'New Label';
no jQuery bloat, no fumbling through arrays, quick and simple
querySelector works just like jQuery, but it has native speed and zero bloatage.
label[for=listing_title] finds the label that has an attribute "for" with the value "listing_title" ... so, while not guaranteed to be unique, not many forms have more than one label "for" an input
var texts = {}; // note {} not []
texts["label[for=listing_title]"] = "NEW TEXT";
var interval = setInterval(function() {
setText();
}, 100);
function setText() {
var textsCopy = texts.slice(); // why???
for (var key in texts) {
var element = document.querySelector(key);
if (element != null) {
element.innerHTML = texts[key];
delete texts[key];
}
}
if (texts.length == 0) {
window.clearInterval(interval);
}
}
With the above version, you can mix id's as well as the more complex selectors ... so, your original substitution could be done as well in the same loop by adding
texts["#new-listing-link"] = "NEW TEXT HERE";
Note the '#' before the id
Another hint or two:
var texts = {
"label[for=listing_title]": "NEW TEXT",
"#new-listing-link": "NEW TEXT HERE"
}; // declare the text object in one go
var interval = setInterval(setText, 100); // this is equivalent (not exactly identical, but functionally identical to your code
// rest of your code
The script can only be posted in the head section of the whole site (even though it's specific to one ingle page).
Here is my other script that worked for ID:
<script>
var texts = [];
texts["new-listing-link"] = "NEW TEXT HERE";
var interval = setInterval(function() { setText(); }, 100);
function setText() {
var textsCopy = texts.slice();
for (var key in texts) {
var element = document.getElementById(key);
if (element != null) {
element.innerHTML = texts[key];
delete texts[key];
}
}
if (texts.length == 0) {
window.clearInterval(interval);
}
}
</script>
How can I go about it? :)
I'm pretty sure I'm only allowed to use javascript and not jQuery
This should do the trick (quick'n'dirty):
slice=Function.prototype.call.bind([].slice);
slice(document.querySelectorAll(".input")).map(function(x){ return x.textContent="Killroy was here"; });
Check the Fiddle
MDN on Array.prototype.slice()
MDN on Array.prototype.map()
MDN on Document.querySelectorAll()
If you need just this label, choose:label[for=listing_title] as in Jaromanda Xs answer
var label = document.getElementsByTagName("label")[0] // If this is the first label of the page
label.value = "new text";
PLEASE READ QUESTION BEFORE READING CODE!!!
I've added a checkbox element on Dialog definition of the table dialog (it works). Now I want the checkbox to be checked by default when the table being edited has a certain class (which is usually visible on the advanced tab). According to the documentation, I should be able to do something like this in my setup function. I've tried many things and you could hopefully help me. This is my code.
CKEDITOR.on( 'dialogDefinition', function( evt )
{
var dialog = evt.data;
if(dialog.name == 'table' || dialog.name=='tableProperties')
{
// Get dialog definition.
var def = evt.data.definition;
var infoTab = def.getContents( 'info' );
infoTab.add(
{
type: 'checkbox',
id: 'myCheckBox',
label: 'Table Has Property',
setup: function()
{
//Class to look for if I successfully get the input's value
var classValueToLookFor = 'has-property';
// The current CKEditor Dialog Instance
var thisDialog = CKEDITOR.dialog.getCurrent();
// The Element whose value I want to get
var classElement = theDialog.getContentElement('advanced','advCSSClasses');
// Trying to Get Value of this class Element According to documentation
var containedClasses = theDialog.getValueOf('advanced','advCSSClasses');
// Trying to debug the value above
console.log(containedClasses); // This shows nothing
// Trying to debug InitValue which shows something according to prototype
console.log(classElement.getInitValue()); //This also shows nothing
//Checking if Element has the class I'm looking for to mark the checkbox
if(containedClasses.indexOf(classValueToLookFor) != -1)
{
//Check current checkbox since value has been found
this.setValue('checked');
}
}
onClick: function() // You can ignore this function, just put it in case you were wondering how I'm putting the has-property, might help someone else (works well) ;)
{
var checked = this.getValue();
var classValueToSet = 'has-property';
var thisDialog = CKEDITOR.dialog.getCurrent();
var containedClasses = theDialog.getValueOf('advanced','advCSSClasses');
if(checked)
{
if(containedClasses.indexOf(classValueToSet) != -1)
{
//console.log('already contains class: '+classValueToSet);
}
else
{
containedClasses += containedClasses+" "+classValueToSet;
}
}
else
{
if(containedClasses.indexOf(classValueToSet) != -1)
{
containedClasses = containedClasses.replace(classValueToSet,'');
}
else
{
//console.log('already removed class: '+classValueToSet);
}
}
thisDialog.setValueOf('advanced','advCSSClasses',containedClasses);
}
}
}
Here are some debug statements that can be helpful to add into the setup function and understand what is going on, you shouldn't need to go through all I've went through ;)
console.log('in setup function');
console.log(classElement);
console.log(classElement._);
console.log(classElement.getInitValue());
console.log(classElement.getInputElement());
var inputElement = classElement.getInputElement();
var inputElementId = inputElement.getId();
console.log($('#'+inputElementId+'.cke_dialog_ui_input_text'));
console.log(classElement.getInputElement().value);
It would be nice to test your answer before suggesting. Many of the things I've tried should work in theory, but are practically not working.
Alright, so finally after a few days of trial and error, this is what finally worked for me. Maybe it could be helpful to someone. I'm sure there should be a much cleaner way to do this. All the best to everyone.
setup: function()
{
//This current checkbox
var checkbox = this;
//the class I want to find on my table
var var classValueToLookFor = 'has-property';
//Current Dialog instance
var thisDialog = CKEDITOR.dialog.getCurrent();
//This code below gets a <td> element in the table
var startElement = thisDialog.getParentEditor().getSelection().getStartElement();
// This gets me the parent of the <td> element which is my current table instance
var parentTable = $(startElement.$.offsetParent);
//Finally check if the table has the property I'm looking for.
if(parentTable.hasClass(classValueToLookFor))
{
//Mark the checkbox
checkbox.setValue('checked');
}
}
I'm trying to figure out a way to change the maxlength of ajax called input fields by pulling the value to set out of the field's label and updating the default value. The field labels all follow the same format - id, class, type and maxlength. The new maxlength value to set is always present in the id ...max_X_characters...
`<input id="ecwid-productoption-16958710-Line_5_:0028max_4_characters:0029" class="gwt-
TextBox ecwid-productBrowser-details-optionTextField ecwid-productoption-
Line_5_:0028max_4_characters:0029" type="text" maxlength="200"></input>`
So in this example I need to set the maxlength to 4.
The other problem is that there are multiple input fields, often with different maxlength values. See here for an example.
I was thinking of setting a script to pull out the value once the fields have loaded, but I don't mind admitting it, this one's over my head - hopefully one of you bright guys n gals can figure it out!
Update: Thanks for the suggestions, I've tried both, in various combinations, but can't get them to work.
Here's the code suggested by Ecwid's tech team that sets all input fields on the page to one maxlength (6 in this case)
`Ecwid.OnPageLoaded.add(function(page){if (page.type == "PRODUCT") {
$("input.ecwid-productBrowser-details-optionTextField").attr('maxlength','6');
};
})`
However, as I stated there are input fields with different maxlengths for some products.
I've tried replacing the '6' above with a function, based on your suggestions, to get the maxlength from the input id, but can't get it to work.
Any more ideas?
Thanks
Update:
Cracked it (nearly), here's the working code
`Ecwid.OnPageLoaded.add(function(page){
var regex = new RegExp("max_(\\d+)_characters");
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
var inp = inputs[i];
if (regex.test(inp.id)) {
var newLimit = inp.id.match(regex)[1];
inp.maxLength = newLimit;
}
}
});`
Thanks so much for your help, it works like a dream on the product page but there is another area where it doesn't. A customer can edit the input text via a pop-up, from the shopping basket.
The fields have similar code:
`<input id="ecwid-productoption-16958710-Line_5_:0028max_4_characters:0029"
class="gwt-TextBox ecwid-productBrowser-details-optionTextField ecwid-productoption-
Line_5_:0028max_4_characters:0029" type="text" maxlength="200"></input>`
Suggestions very welcome
Chris
UPDATE:
Many, many, many thanks to ExpertSystem (you genius you!) - I think we've got it. (tested on IE10, firefox 21, chrome 27).
The code below is for people using Yola and Ecwid together, but I guess the original code may work for people using other sitebuilders. It limits the number of characters a user can enter into input fields, in Ecwid, by checking for a number in the input field's title (in this case the value between 'max' and 'characters') and replacing that as the field's maxLength value. It limits fields in the product browser, in the html widgets and in the cart pop-up.
Here it is:
Go to Yola's Custom Site Tracking Code section. In the 'Footer Code' column (actually placed at the bottom of the 'body'), place this code:
<script>
Ecwid.OnPageLoaded.add(function(page){
var regex = new RegExp("max_(\\d+)_characters");
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
var inp = inputs[i];
if (regex.test(inp.id)) {
var newLimit = inp.id.match(regex)[1];
inp.maxLength = newLimit;
}
}
});
</script>
<script>
var regex = new RegExp("max_(\\d+)_characters");
function fixMaxLength(container) {
var inputs = container.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
var inp = inputs[i];
if (regex.test(inp.id)) {
var newLimit = inp.id.match(regex)[1];
inp.maxLength = newLimit;
}
}
};
</script>
and this into the 'Header Code' column:
<script>
document.addEventListener("DOMNodeInserted", function() {
var popups = document.getElementsByClassName("popupContent");
for (var i = 0; i < popups.length; i++) {
fixMaxLength(popups[i]);
}
});
</script>
That's it! You're good to go.
It is not exactly clear what is meant by "ajax called input fields", but supposing that the input fields are created and added to DOM inside a success callback for some AJAX call, you can place the following piece of code in your pages <head>:
var regex = new RegExp("max_(\\d+)_characters");
function fixMaxLength(container) {
var inputs = container.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
var inp = inputs[i];
if (regex.test(inp.id)) {
var newLimit = inp.id.match(regex)[1];
inp.maxLength = newLimit;
}
}
}
And then, at the end of the AJAX call's "onSuccess" callback, append this:
fixMaxLength(document);
UPDATE:
Based on your comments below, if you need to apply fixMaxLength() to div's of class "popupContent", which get dynamically added to your DOM, an easy way (not the most efficient though) would be adding a listener for DOM modification events (e.g. somewhere in <head>):
document.addEventListener("DOMNodeInserted", function() {
var popups = document.getElementsByClassName("popupContent");
for (var i = 0; i < popups.length; i++) {
fixMaxLength(popups[i]);
}
});
(NOTE: I have only tested it on latest versions of Chrome and Firefox, so I am not really sure for which other/older browsers this does work.)
(NOTE2: GGGS, has tested it (and found it working) on IE10 as well.)
How about a regular expression on your id attribute? Such as the following:
jQuery('input').each(function() {
var idVal = jQuery(this).attr('id');
var regex = /max_(\d+)_characters/g;
var result = regex.exec(idVal);
var length = result[1];
});
This is a loop over all the inputs. Once this is run, the length variable will have the proper length each go through, for your next step.
I hope it's not a problem to post much specific code here, but I figure it will be better explained if everyone can just see it, so I will give you my code and then I will explain my problem.
My code:
function addBeGoneLinks () {
var beGoneClassElems;
var beGoneSpan;
var beGoneLink;
var beGonePrintSafe;
var spacesSpan;
//var middotSpan = document.createElement ('span');
var interactionContainer = document.getElementsByClassName('feedItemInteractionContainer');
for (var i=0; i<children.length; i++)
{
beGonePrintSafe = false;
beGoneClassElems = children[i].getElementsByClassName('beGone')
beGonePrintSafe = true;
if (beGoneClassElems.length == 0)
{
beGoneLink = document.createElement('a');
beGoneLink.href = 'javascript:void(0);';
beGoneLink.appendChild(document.createTextNode('Be Gone'));
beGoneLink.className = 'beGone';
beGoneLink.id = 'beGoneLink' + i.toString();
beGoneLink.addEventListener ("click", function() {beGone();}, false);//This line!
beGoneLink.align = 'right';
spacesSpan = document.createElement('span');
spacesSpan.innerHTML = ' - ';
if (interactionContainer[i] != undefined)
{
interactionContainer[i].appendChild(spacesSpan);
interactionContainer[i].appendChild(beGoneLink);
}
}
}
}
Here I have a function from a Greasemonkey script that I am working on. When one of the links is clicked, my aim is to have it call the function beGone() which will, among other things, remove the whole element a few parents up, thereby removing their sibling's, their parents and their parents' siblings, and one or two levels after that.
My idea was just to get the id of the link that was pressed and pass it to beGone() so that I could then get the parents using its id, but I do not know how to do that. Am I able to have the id of a link passed by the function that it calls? If not, is there any other way to do this?
I am not sure whether I am missing some really simple solution, but I haven't been able to find one rooting around the web, especially because I was unsure how I would search for this specific problem.
Try this:
beGoneLink.addEventListener("click", beGone, false);
beGone = function (evt) {
evt.target; // evt.target refers to the clicked element.
...
}
You can then use evt.target.id, evt.target.parentNode, etc.
Let's say I have an html form. Each input/select/textarea will have a corresponding <label> with the for attribute set to the id of it's companion. In this case, I know that each input will only have a single label.
Given an input element in javascript — via an onkeyup event, for example — what's the best way to find it's associated label?
If you are using jQuery you can do something like this
$('label[for="foo"]').hide ();
If you aren't using jQuery you'll have to search for the label. Here is a function that takes the element as an argument and returns the associated label
function findLableForControl(el) {
var idVal = el.id;
labels = document.getElementsByTagName('label');
for( var i = 0; i < labels.length; i++ ) {
if (labels[i].htmlFor == idVal)
return labels[i];
}
}
First, scan the page for labels, and assign a reference to the label from the actual form element:
var labels = document.getElementsByTagName('LABEL');
for (var i = 0; i < labels.length; i++) {
if (labels[i].htmlFor != '') {
var elem = document.getElementById(labels[i].htmlFor);
if (elem)
elem.label = labels[i];
}
}
Then, you can simply go:
document.getElementById('MyFormElem').label.innerHTML = 'Look ma this works!';
No need for a lookup array :)
There is a labels property in the HTML5 standard which points to labels which are associated to an input element.
So you could use something like this (support for native labels property but with a fallback for retrieving labels in case the browser doesn't support it)...
var getLabelsForInputElement = function(element) {
var labels = [];
var id = element.id;
if (element.labels) {
return element.labels;
}
id && Array.prototype.push
.apply(labels, document.querySelector("label[for='" + id + "']"));
while (element = element.parentNode) {
if (element.tagName.toLowerCase() == "label") {
labels.push(element);
}
}
return labels;
};
// ES6
var getLabelsForInputElement = (element) => {
let labels;
let id = element.id;
if (element.labels) {
return element.labels;
}
if (id) {
labels = Array.from(document.querySelector(`label[for='${id}']`)));
}
while (element = element.parentNode) {
if (element.tagName.toLowerCase() == "label") {
labels.push(element);
}
}
return labels;
};
Even easier if you're using jQuery...
var getLabelsForInputElement = function(element) {
var labels = $();
var id = element.id;
if (element.labels) {
return element.labels;
}
id && (labels = $("label[for='" + id + "']")));
labels = labels.add($(element).parents("label"));
return labels;
};
document.querySelector("label[for=" + vHtmlInputElement.id + "]");
This answers the question in the simplest and leanest manner.
This uses vanilla javascript and works on all main-stream proper browsers.
I am a bit surprised that nobody seems to know that you're perfectly allowed to do:
<label>Put your stuff here: <input value="Stuff"></label>
Which won't get picked up by any of the suggested answers, but will label the input correctly.
Here's some code that does take this case into account:
$.fn.getLabels = function() {
return this.map(function() {
var labels = $(this).parents('label');
if (this.id) {
labels.add('label[for="' + this.id + '"]');
}
return labels.get();
});
};
Usage:
$('#myfancyinput').getLabels();
Some notes:
The code was written for clarity, not for performance. More performant alternatives may be available.
This code supports getting the labels of multiple items in one go. If that's not what you want, adapt as necessary.
This still doesn't take care of things like aria-labelledby if you were to use that (left as an exercise to the reader).
Using multiple labels is a tricky business when it comes to support in different user agents and assistive technologies, so test well and use at your own risk, etc. etc.
Yes, you could also implement this without using jQuery. :-)
Earlier...
var labels = document.getElementsByTagName("LABEL"),
lookup = {},
i, label;
for (i = 0; i < labels.length; i++) {
label = labels[i];
if (document.getElementById(label.htmlFor)) {
lookup[label.htmlFor] = label;
}
}
Later...
var myLabel = lookup[myInput.id];
Snarky comment: Yes, you can also do it with JQuery. :-)
All the other answers are extremely outdated!!
All you have to do is:
input.labels
HTML5 has been supported by all of the major browsers for many years already. There is absolutely no reason that you should have to make this from scratch on your own or polyfill it! Literally just use input.labels and it solves all of your problems.
with jquery you could do something like
var nameOfLabel = someInput.attr('id');
var label = $("label[for='" + nameOfLabel + "']");
If you're willing to use querySelector (and you can, even down to IE9 and sometimes IE8!), another method becomes viable.
If your form field has an ID, and you use the label's for attribute, this becomes pretty simple in modern JavaScript:
var form = document.querySelector('.sample-form');
var formFields = form.querySelectorAll('.form-field');
[].forEach.call(formFields, function (formField) {
var inputId = formField.id;
var label = form.querySelector('label[for=' + inputId + ']');
console.log(label.textContent);
});
Some have noted about multiple labels; if they all use the same value for the for attribute, just use querySelectorAll instead of querySelector and loop through to get everything you need.
Solution One <label>: One <input>
Using HTML 5.2 reference
Considering the <label> pointing to <input> using for=, the labels element will be a non empty array, and act as a link to the <label> element, accessing all properties of it, including its id=.
function myFunction() {
document.getElementById("p1").innerHTML = "The first label associated with input: <b>" + document.getElementById("input4").labels[0].id + "</b>";
}
<form>
<label id="theLabel" for="input4">my id is "theLabel"</label>
<input name="name1" id="input4" value="my id is input4">
<br>
</form>
<p>Click the "click me" button to see the label properties</p>
<button onclick="myFunction()">click me</button>
<p id="p1"></p>
Solution Many <label>: One <input>
With more than one <label> using for=, you can make a loop to show all of them, like this:
function myFunction2() {
var x = document.getElementById("input7").labels;
let text = "";
for (let i = 0; i < x.length; i++) {
text += x[i].id + "<br>";
}
document.getElementById("p7").innerHTML = text;
}
<b>Three labels for one input</b><br>
<br>
<form>
<label id="theLabel2" for="input7">my id is "theLabel2</label><br>
<label id="theLabel3" for="input7">my id is "theLabel3</label><br>
<label id="theLabel4" for="input7">my id is "theLabel4</label><br>
<input name="name1" id="input7" value="my id is input7">
<br>
</form>
<p>Click the "click me" button to see the label properties</p>
<button onclick="myFunction2()">click me2</button>
<p id="p7"></p>
$("label[for='inputId']").text()
This helped me to get the label of an input element using its ID.
Answer from Gijs was most valuable for me, but unfortunately the extension does not work.
Here's a rewritten extension that works, it may help someone:
jQuery.fn.getLabels = function () {
return this.map(function () {
var parentLabels = $(this).parents('label').get();
var associatedLabels = this.id ? associatedLabels = $("label[for='" + this.id + "']").get() : [];
return parentLabels.concat(associatedLabels);
});
};
A really concise solution using ES6 features like destructuring and implicit returns to turn it into a handy one liner would be:
const getLabels = ({ labels, id }) => labels || document.querySelectorAll(`label[for=${id}]`)
Or to simply get one label, not a NodeList:
const getFirstLabel = ({ labels, id }) => labels && labels[0] || document.querySelector(`label[for=${id}]`)
It is actually far easier to add an id to the label in the form itself, for example:
<label for="firstName" id="firstNameLabel">FirstName:</label>
<input type="text" id="firstName" name="firstName" class="input_Field"
pattern="^[a-zA-Z\s\-]{2,25}$" maxlength="25"
title="Alphabetic, Space, Dash Only, 2-25 Characters Long"
autocomplete="on" required
/>
Then, you can simply use something like this:
if (myvariableforpagelang == 'es') {
// set field label to spanish
document.getElementById("firstNameLabel").innerHTML = "Primer Nombre:";
// set field tooltip (title to spanish
document.getElementById("firstName").title = "Alfabética, espacio, guión Sólo, 2-25 caracteres de longitud";
}
The javascript does have to be in a body onload function to work.
Just a thought, works beautifully for me.
As it has been already mentionned, the (currently) top-rated answer does not take into account the possibility to embed an input inside a label.
Since nobody has posted a JQuery-free answer, here is mine :
var labels = form.getElementsByTagName ('label');
var input_label = {};
for (var i = 0 ; i != labels.length ; i++)
{
var label = labels[i];
var input = label.htmlFor
? document.getElementById(label.htmlFor)
: label.getElementsByTagName('input')[0];
input_label[input.outerHTML] =
(label.innerText || label.textContent); // innerText for IE8-
}
In this example, for the sake of simplicity, the lookup table is directly indexed by the input HTML elements. This is hardly efficient and you can adapt it however you like.
You can use a form as base element, or the whole document if you want to get labels for multiple forms at once.
No checks are made for incorrect HTML (multiple or missing inputs inside labels, missing input with corresponding htmlFor id, etc), but feel free to add them.
You might want to trim the label texts, since trailing spaces are often present when the input is embedded in the label.
The best answer works perfectly fine but in most cases, it is overkill and inefficient to loop through all the label elements.
Here is an efficent function to get the label that goes with the input element:
function getLabelForInput(id)
{
var el = document.getElementById(id);
if (!el)
return null;
var elPrev = el.previousElementSibling;
var elNext = el.nextElementSibling;
while (elPrev || elNext)
{
if (elPrev)
{
if (elPrev.htmlFor === id)
return elPrev;
elPrev = elPrev.previousElementSibling;
}
if (elNext)
{
if (elNext.htmlFor === id)
return elNext;
elNext = elNext.nextElementSibling;
}
}
return null;
}
For me, this one line of code was sufficient:
el = document.getElementById(id).previousElementSibling;
In most cases, the label will be very close or next to the input, which means the loop in the above function only needs to iterate a very small number of times.
Use a JQuery selector:
$("label[for="+inputElement.id+"]")
For future searchers... The following is a jQuery-ified version of FlySwat's accepted answer:
var labels = $("label");
for (var i = 0; i < labels.length; i++) {
var fieldId = labels[i].htmlFor;
if (fieldId != "") {
var elem = $("#" + fieldId);
if (elem.length != 0) {
elem.data("label", $(labels[i]));
}
}
}
Using:
$("#myFormElemId").data("label").css("border","3px solid red");
I know this is old, but I had trouble with some solutions and pieced this together. I have tested this on Windows (Chrome, Firefox and MSIE) and OS X (Chrome and Safari) and believe this is the simplest solution. It works with these three style of attaching a label.
<label><input type="checkbox" class="c123" id="cb1" name="item1">item1</label>
<input type="checkbox" class="c123" id="cb2" name="item2">item2</input>
<input type="checkbox" class="c123" id="cb3" name="item3"><label for="cb3">item3</label>
Using jQuery:
$(".c123").click(function() {
$cb = $(this);
$lb = $(this).parent();
alert( $cb.attr('id') + ' = ' + $lb.text() );
});
My JSFiddle: http://jsfiddle.net/pnosko/6PQCw/
I have made for my own need, can be useful for somebody: JSFIDDLE
$("input").each(function () {
if ($.trim($(this).prev('label').text()) != "") {
console.log("\nprev>children:");
console.log($.trim($(this).prev('label').text()));
} else {
if ($.trim($(this).parent('label').text()) != "") {
console.log("\nparent>children:");
console.log($.trim($(this).parent('label').text()));
} else {
if ($.trim($(this).parent().prev('label').text()) != "") {
console.log("\nparent>prev>children:");
console.log($.trim($(this).parent().prev('label').text()));
} else {
console.log("NOTFOUND! So set your own condition now");
}
}
}
});
I am bit surprised no one is suggesting to use the CSS relationship method?
in a style sheet you can reference a label from the element selector:
<style>
//for input element with class 'YYY'
input.YYY + label {}
</style>
if the checkbox has an id of 'XXX'
then the label would be found through jQuery by:
$('#XXX + label');
You can also apply .find('+ label') to return the label from a jQuery checkbox element, ie useful when looping:
$('input[type=checkbox]').each( function(){
$(this).find('+ label');
});
If you use the for attribute, you can use querySelector(...) to get
the associated label.
HTML/JavaScript
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<label for="myCheckbox">Log Report to Console?</label>
<input name="myCheckbox" type="checkbox" oninput="doSomething(event)" />
<script type="text/javascript">
function doSomething(e) {
const query = `label[for="${e.target.name}"]`; // This is string interpolation NOT JQuery
const label = document.querySelector(query);
}
</script>
</body>
</html>
Plain JavaScript
function doSomething(e) {
// const query = `label[for="${e.target.name}"]`; // This is string interpolation NOT JQuery
// Maybe it is safer to use ".getAttribute"
const query = `label[for="${e.target.getAttribute("name")}"]`;
const label = document.querySelector(query);
// Do what you want with the label here...
debugger; // You're welcome
console.log(label);
}