I'm working on dokuwiki plugin and I've found interesting think about how js stores element id. I'm not sure what is going on... So I have a code from dokuwiki linkwiz.js file which is using to determine if ':' char is in the part of the id string:
dw_linkwiz.textArea = $editor[0];
//some code between
// prepend colon inside namespaces for non namespace pages
if(dw_linkwiz.textArea.form.id.value.indexOf(':') != -1 &&
link.indexOf(':') == -1){
link = ':' + link;
}
the $editor is the jQuery object. As you can see to get id of the element they uses form.id.value but in some cases when I setting id of the element dynamicly using jQuery .attr method, the form.id.value is undefined and the id string is simply kept in form.id . Do you know why it happes? Which is more standard compilant?
Normally a DOM elements id will be a string and not an object, so form.id will be a string with the id value. It shouldn't be an object with a value. This plugin may have defined another object with an id property that contains a value property, but thats not a standard DOM element.
id in this case is not the id attribute of an element, but a field named "id" in the form.
Simplified it looks like this:
<form>
<input name="id" value="some:page">
<textarea>the editor</textarea>
</form>
dw_linkwiz.textArea is the DOM object of the textarea. dw_linkwiz.textArea.form.id.value is "some:page".
Related
need to create variables from all elements having id attribute
name of each variable should be just the value of id attribute
for example <div id='btnsave'>SAVE</div> - should be a variable named btnsave
here is my try - without success:
let els = $("*");
els.forEach(function(el){
if(el.hasId()){
console.log(el.attr('id'));
window[el] = $('#' + el);
}
});
If you're using id attributes for your elements then they already have references accessible through the properties of the window object which match their id value:
console.log(window.foo.textContent);
console.log(window.fizz.textContent);
<p id="foo">bar</p>
<p id="fizz">buzz</p>
Given your comment under the question:
I have a lot of divs as buttons and is simpler to write btnsave.on('click'... then $('#btnsave').on('click'...
In that case you simply need to cache the selector at the top of your script (within scope) and use it where required. This is a standard pattern to follow.
Creating jQuery objects from every element in the DOM with an id and storing them in the window object is an anti-pattern, which will cause performance issues and most likely break native code which expects those references to contain DOMElement objects, not jQuery objects.
Do not do it.
To get elements by any attribute you can use query selector.
let elementsWithId = {}
document.querySelectorAll('[id]').forEach(el => {
elementsWithId[el.id] = el
})
console.log(elementsWithId)
You can record a jQuery element to window variable. Example:
window[el.id] = $(el)
But as people mentioned, this is a bad practice.
I have the following code:
$("#modal-bool-element").change(function(e) {boolSettings($(e.target))});
function boolSettings(e) {
elem = e;
var boolSettingsParent = elem.closest("#bool-settings");
if (elem.is(":checked") == true) {
elem.val(true);
boolSettingsParent.find("#modal-bool-show").prop("disabled", false);
} else {
elem.val(false);
boolSettingsParent.find(".bool-reset, .bool-offset").hide();
boolSettingsParent.find("#modal-bool-show").val("never");
boolSettingsParent.find("#modal-bool-show").prop("disabled", true);
boolSettingsParent.find("#modal-bool-offsetValue, #modal-bool-reset, #modal-bool-offsetUnit").val("");
}
}
What I would like to do is to pass the value of an atrribute to find method along with the classname or id. That attr is elem.attr("model-id").
I have tried like this:
boolSettingsParent.find(`#modal-bool-show [model-id='{elem.attr(model-id)}']`)
But I am not getting any value. How can I achieve the desired result?
Remove the space:
boolSettingsParent.find(`#modal-bool-show[model-id='{elem.attr(model-id)}']`)
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
The space means you're looking for a descendant element of #modal-bool-show with that attribute. Without the space, it means you only want #modal-bool-show if it also has that attribute value.
You mentioned a class but haven't shown picking one. To do that, you'd tack on a class selector:
boolSettingsParent.find(`#modal-bool-show[model-id='{elem.attr(model-id)}'].some-class`)
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^
BUT, just the id should be sufficient unless you want to skip the element if it doesn't have that attribute and/or class, because you can't have more than one element in the DOM with the same id — doing so is invalid. So adding more things to the selector is fine if you want the selector not to match anything if the element with that id doesn't have the attribute and/or class, but if you're doing it so the selector matches the "right" element with that id, that's a problem because it means you have more than one element with the same id.
I assumed in the above that you were using some templating system that handled the {...} for you, but if you meant to use a substitution in JavaScript's template literal, they use the format ${...}, not {...}. So:
boolSettingsParent.find(`#modal-bool-show[model-id='${elem.attr(model-id)}'].some-class`)
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^
I have a element like this
<input type="checkbox" data-parent="0" value="1229">
and I want to get all the checkboxes with data-parent that have a value of N.
Here is what I tried in my click event handler method.
checkChildren = function (id) {
var cbs = $(input[type="checkbox"][data-parent=id]);
}
but there is some syntax error near 'data-parent=id'
Your CSS selector is wrong. Change it to:
var cbs = $('input[type="checkbox"][data-parent="' + id + '"]');
you need to pass a string selector to jquery, first building it with a javascript expression
additionally, the html tag attribute values ("checkbox" and "0") need to both be quoted
var selector = 'input[type="checkbox"][data-parent="' + id + '"]';
var cbs = $(selector);
edit, details why:
input[type="checkbox"][data-parent=id]
when the javascript parser hits this, it tries to execute it as javascript code, and give the result to $().
Here's what it (javascript parsing engine) tries:
looks for a variable named input
Finds an opening bracket [ after the input object and evaluates the contents, type="checkbox"
(this operation sets the variable type to the string "checkbox" and returns the string "checkbox")
substitutes the returned value into the first brackets, input["checkbox"]
(the bracket operator looks up the checkbox property of the input object, like input.checkbox, and returns the value of the property or undefined)
Similarly evaluates for the second set of brackets value[data-parent=id]
(but this time runs into an error because data-parent=id is ambiguous, it's trying to set the result of subtract parent from data to the variable id)
I append a HTML String to DOM
var str = "<input time=\"y\" name=\"changeDate\" type=\"text\" class=\"input_M3_1\" id=\"textfield2\" value='' dataType=\"Sino\" >";
then append to dom and give a value;
$('#datadiv').append(str);
$("input[name='changeDate']").val('2014-8-15');
After this,I Use jquery selector
var date='2014-8-15';
$("input[value="+date+"][name='changeDate']");
Use the selector I just cannot find the it,And also I see it had add a new attribute name "realvalue".
val modifies the value property of the element not it's value attribute. For understanding the difference between attributes and properties you can check this question: Properties and Attributes in HTML
You can filter the inputs that have specific value property using filter method:
$("input[name='changeDate']").filter(function() {
return this.value === date;
});
A page has elements without id - only with names. How to access them by javascript like this?
document.getElementById('id').value := "...";
UPDATED:
Thanks to all! Is it possible to access then to element with specified value (radiobutton)?
<nobr><label><input style="vertical-align:middle" type="radio" name="name" value="value1" checked="checked"/><span style="vertical-align:middle" class="label">value1</span></label></nobr><br/>
<nobr><label><input style="vertical-align:middle" type="radio" name="name" value="value2"/><span style="vertical-align:middle" class="label">value2</span></label></nobr><br/>
document.getElementsByName('name')
This returns a nodeList, which you can access like an array.
There is the DOM HTML getElementsByName method that returns a collection of nodes with that name. Note that the name property is not required to be unique, so you may get more than one and that the returned collection is live, so adding or removing elements with the subject name will modify the collection.
use document.getElementsByName('elementName'). this will give you an array-like collection, get the element by index
The other answers cover your original question. Regarding your update about accessing by value, there is no getElementsByValue() function, but if it is your intention to select the particular radio button that has both a specified name and value you can do something like this:
function getElementByNameAndValue(n, v) {
var els = document.getElementsByName(n),
i;
for (i=0; i < els.length; i++)
if (els[i].value == v)
return els[i];
return null;
}
var r = getElementByNameAndValue("name", "value1");
Above function will return a reference to the first matching element or null if nothing matched. If you want to allow for more than one element with the same name and value you could modify this to return an array (though I don't know why you'd have more than one element with the same name and value, at least not with radio buttons).
Note that also this can easily be modified to return a reference to the currently checked element, just change the if in the loop to be if (els[i].checked).
You may be able to do some or all of this using document.querySelector(), but I don't use it myself because I need to support older IE. You can definitely replace all of the above with one line of jQuery.