I have a Boolean variable. It is stored in a hidden input field. Basically, if the user is signed in, it is false, if not, it is true.
There are download buttons which will link to a file download. My aim is to make it so that, if they aren't signed in, the button will not show, and the link will not work (it would be nice to have an alert saying they need to sign in or something, but that would probably be more effort than it's worth).
I have a function that performs onload of body:
function hide_download_btns(){
if (document.getElementById('download_btn_var_input').value == "true") {
document.getElementsByClassName('project_download_btn').item(0).hidden = true
}
}
My problem is where it asks for the nth term .item(0). This is where it selects the div on which to perform the function, however, I want the function to affect all divs with the class name 'project_download_btn'.
I'm not a fan of jQuery, so it would be great to avoid that if possible.
You can simply loop through the elements instead of just taking the 0th.
var buttons = document.getElementsByClassName('project_download_btn');
for(var i=0; i< buttons.length; i++){
buttons[i].hidden = true;
}
if (document.getElementById('download_btn_var_input').value == "true") {
var el = document.getElementsByClassName('project_download_btn');
for (var i = 0; i < el.length; i++) {
el[i].hidden = true;
}
}
document.getElementsByClassName returns array so what you are interested is :
document.getElementsByClassName('project_download_btn')[0]
Loop through each div that contains your download button and set hidden to true:
if (document.getElementById('download_btn_var_input').value == "true") {
var button_divs_array = document.getElementsByClassName('project_download_btn');
for (var i = 0; i < button_divs_array.length; i++) {
button_divs_array[i].hidden = true;
}
}
Related
I am working client side on a web page that I am unable to edit.
I want to use JS to click on a particular button, but it does not have a unique identifier.
I do know the class and I do know a (unique) string in the innerHTML that I can match with, so I am iterating through the (varying number) of buttons with a while loop looking for the string:
var theResult = '';
var buttonNum = 0;
var searchString = '720p';
while (theResult.indexOf(searchString) == -1
{
theResult = eval(\"document.getElementsByClassName('streamButton')[\" + buttonNum + \"].innerHTML\");
buttonNum++;
}
Now I should know the correct position in the array of buttons (buttonNum-1, I think), but how do I reference this? I have tried:
eval(\"document.getElementsByClassName('streamButton')[\" + buttonNum-1 + \"].click()")
and variation on the position of ()'s in the eval, but I can't get it to work.
You could try something like:
var searchStr = '720p',
// Grab all buttons that have the class 'streambutton'.
buttons = Array.prototype.slice.call(document.querySelectorAll('button.streamButton')),
// Filter all the buttons and select the first one that has the sreachStr in its innerHTML.
buttonToClick = buttons.filter(function( button ) {
return button.innerHTML.indexOf(searchStr) !== -1;
})[0];
You don't need the eval, but you can check all the buttons one by one and just click the button immediately when you find it so you don't have to find it again.
It is not as elegant as what #Shilly suggested, but probably more easily understood if you are new to javascript.
var searchString = '720p';
var buttons = document.getElementsByClassName("streamButton"); // find all streamButtons
if(buttons)
{
// Search all streamButtons until you find the right one
for(var i = 0; i < buttons.length; i++)
{
var button = buttons[i];
var buttonInnerHtml = button.innerHTML;
if (buttonInnerHtml.indexOf(searchString) != -1) {
button.click();
break;
}
}
}
function allOtherClick() {
console.log("Wrong button clicked");
}
function correctButtonClick() {
console.log("Right button clicked");
}
<button class='streamButton' onclick='allOtherClick()'>10</button>
<button class='streamButton' onclick='allOtherClick()'>30</button>
<button class='streamButton' onclick='correctButtonClick()'>720p</button>
<button class='streamButton' onclick='allOtherClick()'>abcd</button>
I would stay clear of eval here, what if the text on the button is some malicious javaScript?
Can you use jQuery? if so, check out contains. You can use it like so:
$(".streamButton:contains('720p')")
Is there a way to deselect or unclick a button that has been clicked using javascript?
So basically I have a button:
if (i === 10) {
var clicked = document.getElementById('i10');
clickedButton.push(click.textContent);
clicked.style.color = "pink";
}
So when i click that button it turns the text to pink. Is there a way to click on the button again and have it remove the push and turn the text back to black?
Sorry, Javascript isn't my strongest point.
Web programming lesson time: if you want to set styles, don't use JavaScript to set the style, use CSS for the styling definitions, and then only use JavaScript to point to that CSS.
In your CSS:
.highlight {
color: pink;
background: blue;
font-style: fantasy;
whatever-else: StuffGoesHere;
}
And then your button handling:
button.addEventListener("click", function(evt) {
var e = find.your.element.however.you.need();
e.classList.toggle("highlight");
});
Magic: simply by doing things the right way, the code is extremely straight forward, AND we're not hardcoding the styling, we're simply referring to where styling should be defined.
"But what if the browser doesn't support .classList?": the only reason to say this is because you did not keep up with how much browser have improved. Every browser supports classList.
Of course, if you need to do more than just toggles, write your function as a standalone operation, and throw elements at it:
var records = {};
function toggleHighlight(e) {
e.classList.toggle("highlight");
if (e.classList.contains("highlight")) {
// element is now highlighted, do things accordingly:
records[e.id] = e.textContent;
// ...
} else {
records[e.id] = false;
// ...
}
}
button.addEventListener("click", function(evt) {
var e = find.your.element.however.you.need();
toggleHighlight(e);
});
Do this help you?
function onclick(){
var clicked = document.getElementById('i10');
if(clicked.style.color == "pink"){
clicked.style.color == "black";
}
else{
clicked.style.color == "pink";
//do your businesses
}
}
From the shared code, you can do something like check if the textContent already exists in teh array if so it is already clicked so remove it from the array and change the color
if (i === 10) {
var clicked = document.getElementById('i10'),
index = clickedButton.indexOf(click.textContent);
if (index > -1) {
clickedButton.push(click.textContent);
clicked.style.color = "pink";
} else {
clickedButton.splice(index, 1);
clicked.style.color = "";
}
}
Yes:
if (i === 10) {
var clicked = document.getElementById('i10');
var index = clickedButton.indexOf(click.textContent);
if (index === -1) {
// toggle on
clickedButton.push(click.textContent);
clicked.style.color = "pink";
} else {
// toggle off
clickedButton.splice(index, 1);
clicked.style.color = "";
}
}
This will check if click.textContent is already in the clickedButton array. If it is it will remove it from that array as well as reset button color to whatever default is.
Please note that, searching arrays using indexOf is not supported in IE7-8. If you need support for those browsers, you will need to implement this as well:
if (!('indexOf' in Array.prototype)) {
Array.prototype.indexOf= function(find, i /*opt*/) {
if (i===undefined) i= 0;
if (i<0) i+= this.length;
if (i<0) i= 0;
for (var n= this.length; i<n; i++)
if (i in this && this[i]===find)
return i;
return -1;
};
}
The above is taken from StackOverflow thread: Fixing JavaScript Array functions in Internet Explorer (indexOf, forEach, etc.).
I have a button that is defined as follows :
<button type="button" id="ext-gen26" class=" x-btn-text">button text here</button>
And I'm trying to grab it based on the text value. Hhowever, none of its attributes contain the text value. It's generated in a pretty custom way by the look of it.
Does anyone know of a way to find this value programmatically, besides just going through the HTML text? Other than attributes?
Forgot one other thing, the id for this button changes regularly and using jQuery to grab it results in breaking the page for some reason. If you need any background on why I need this, let me know.
This is the JavaScript I am trying to grab it with:
var all = document.getElementsByTagName('*');
for (var i=0, max=all.length; i < max; i++)
{
var elem = all[i];
if(elem.getAttribute("id") == 'ext-gen26'){
if(elem.attributes != null){
for (var x = 0; x < elem.attributes.length; x++) {
var attrib = elem.attributes[x];
alert(attrib.name + " = " + attrib.value);
}
}
}
};
It only comes back with the three attributes that are defined in the code.
innerHTML, text, and textContent - all come back as null.
You can do that through the textContent/innerText properties (browser-dependant). Here's an example that will work no matter which property the browser uses:
var elem = document.getElementById('ext-gen26');
var txt = elem.textContent || elem.innerText;
alert(txt);
http://jsfiddle.net/ThiefMaster/EcMRT/
You could also do it using jQuery:
alert($('#ext-gen26').text());
If you're trying to locate the button entirely by its text content, I'd grab a list of all buttons and loop through them to find this one:
function findButtonbyTextContent(text) {
var buttons = document.querySelectorAll('button');
for (var i=0, l=buttons.length; i<l; i++) {
if (buttons[i].firstChild.nodeValue == text)
return buttons[i];
}
}
Of course, if the content of this button changes even a little your code will need to be updated.
One liner for finding a button based on it's text.
const findButtonByText = text =>
[...document.querySelectorAll('button')]
.find(btn => btn.textContent.includes(text))
I have a form that pop up inside a layer, and I need to make everything inside that form read only regarding what type of input it is. Anyway to do so?
This is quite simple in plain JavaScript and will work efficiently in all browsers that support read-only form inputs (which is pretty much all browsers released in the last decade):
var form = document.getElementById("your_form_id");
var elements = form.elements;
for (var i = 0, len = elements.length; i < len; ++i) {
elements[i].readOnly = true;
}
With HTML5 it's possible to disable all inputs contained using the <fieldset disabled /> attribute.
disabled:
If this Boolean attribute is set, the form controls that are its
descendants, except descendants of its first optional
element, are disabled, i.e., not editable. They won't received any
browsing events, like mouse clicks or focus-related ones. Often
browsers display such controls as gray.
Reference: MDC: fieldset
You can use the :input selector, and do this:
$("#myForm :input").prop('readonly', true);
:input selects all <input>, <select>, <textarea> and <button> elements. Also the attribute is readonly, if you use disabled to the elements they won't be posted to the server, so choose which property you want based on that.
Its Pure Javascript :
var fields = document.getElementById("YOURDIVID").getElementsByTagName('*');
for(var i = 0; i < fields.length; i++)
{
fields[i].disabled = true;
}
Old question, but nobody mentioned using css:
pointer-events: none;
Whole form becomes immune from click but also hovers.
You can do this the easiest way by using jQuery. It will do this for all input, select and textarea elements (even if there are more than one in numbers of these types).
$("input, select, option, textarea", "#formid").prop('disabled',true);
or you can do this as well but this will disable all elements (only those elements on which it can be applied).
$("*", "#formid").prop('disabled',true);
disabled property can applies to following elements:
button
fieldset
input
optgroup
option
select
textarea
But its upto you that what do you prefer to use.
Old question, but right now you can do it easily in pure javascript with an array method:
form = document.querySelector('form-selector');
Array.from(form.elements).forEach(formElement => formElement.disabled = true);
1) form.elements returns a collection with all the form controls (inputs, buttons, fieldsets, etc.) as an HTMLFormControlsCollection.
2) Array.from() turns the collection into an array object.
3) This allows us to use the array.forEach() method to iterate through all the items in the array...
4) ...and disable them with formElement.disabled = true.
$("#formid input, #formid select").attr('disabled',true);
or to make it read-only:
$("#formid input, #formid select").attr('readonly',true);
Here is another pure JavaScript example that I used. Works fine without Array.from() as a NodeList has it's own forEach method.
document.querySelectorAll('#formID input, #formID select, #formID button, #formID textarea').forEach(elem => elem.disabled = true);
// get the reference to your form
// you may need to modify the following block of code, if you are not using ASP.NET forms
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
// this code disables all form elements
var elements = theForm.elements;
for (var i = 0, len = elements.length; i < len; ++i) {
elements[i].disabled = true;
}
This one has never failed me and I did not see this approach on the other answers.
//disable inputs
$.each($("#yourForm").find("input, button, textarea, select"), function(index, value) {
$(value).prop("disabled",true);
});
disable the form by setting an attribute on it that disables interaction generally
<style>form[busy]{pointer-events:none;}</style>
<form>....</form>
<script>
function submitting(event){
event.preventDefault();
const form = this; // or event.target;
// just in case...
if(form.hasAttribute('busy')) return;
// possibly do validation, etc... then disable if all good
form.setAttribute('busy','');
return fetch('/api/TODO', {/*TODO*/})
.then(result=>{ 'TODO show success' return result; })
.catch(error=>{ 'TODO show error info' return Promise.reject(error); })
.finally(()=>{
form.removeAttribute('busy');
})
;
}
Array.from(document.querySelectorAll('form')).forEach(form=>form.addEventListener('submit',submitting);
</script>
Javascript : Disable all form fields :
function disabledForm(){
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
inputs[i].disabled = true;
}
var selects = document.getElementsByTagName("select");
for (var i = 0; i < selects.length; i++) {
selects[i].disabled = true;
}
var textareas = document.getElementsByTagName("textarea");
for (var i = 0; i < textareas.length; i++) {
textareas[i].disabled = true;
}
var buttons = document.getElementsByTagName("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].disabled = true;
}
}
To Enabled all fields of form see below code
function enableForm(){
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++) {
inputs[i].disabled = false;
}
var selects = document.getElementsByTagName("select");
for (var i = 0; i < selects.length; i++) {
selects[i].disabled = false;
}
var textareas = document.getElementsByTagName("textarea");
for (var i = 0; i < textareas.length; i++) {
textareas[i].disabled = false;
}
var buttons = document.getElementsByTagName("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].disabled = false;
}
}
As the answer by Tim Down I suggest:
const FORM_ELEMENTS = document.getElementById('idelementhere').elements;
for (i = 0; i < FORM_ELEMENTS.length; i++) {
FORM_ELEMENTS[i].disabled = true;
}
This will disable all elements inside a form.
for what it is worth, knowing that this post is VERY old... This is NOT a read-only approach, but works for me. I use form.hidden = true.
Thanks Tim,
That was really helpful.
I have done a little tweaking when we have controls and we handle a event on them.
var form = document.getElementById("form");
var elements = form.elements;
for (var i = 0, len = elements.length; i < len; ++i) {
elements[i].setAttribute("onmousedown", "");
}
I have a div element in an HTML document.
I would like to extract all elements inside this div with id attributes starting with a known string (e.g. "q17_").
How can I achieve this using JavaScript ?
If needed, for simplicity, I can assume that all elements inside the div are of type input or select.
var matches = [];
var searchEles = document.getElementById("myDiv").children;
for(var i = 0; i < searchEles.length; i++) {
if(searchEles[i].tagName == 'SELECT' || searchEles.tagName == 'INPUT') {
if(searchEles[i].id.indexOf('q1_') == 0) {
matches.push(searchEles[i]);
}
}
}
Once again, I strongly suggest jQuery for such tasks:
$("#myDiv :input").hide(); // :input matches all input elements, including selects
Option 1: Likely fastest (but not supported by some browsers if used on Document or SVGElement) :
var elements = document.getElementById('parentContainer').children;
Option 2: Likely slowest :
var elements = document.getElementById('parentContainer').getElementsByTagName('*');
Option 3: Requires change to code (wrap a form instead of a div around it) :
// Since what you're doing looks like it should be in a form...
var elements = document.forms['parentContainer'].elements;
var matches = [];
for (var i = 0; i < elements.length; i++)
if (elements[i].value.indexOf('q17_') == 0)
matches.push(elements[i]);
With modern browsers, this is easy without jQuery:
document.getElementById('yourParentDiv').querySelectorAll('[id^="q17_"]');
The querySelectorAll takes a selector (as per CSS selectors) and uses it to search children of the 'yourParentDiv' element recursively. The selector uses ^= which means "starts with".
Note that all browsers released since June 2009 support this.
Presuming every new branch in your tree is a div, I have implemented this solution with 2 functions:
function fillArray(vector1,vector2){
for (var i = 0; i < vector1.length; i++){
if (vector1[i].id.indexOf('q17_') == 0)
vector2.push(vector1[i]);
if(vector1[i].tagName == 'DIV')
fillArray (document.getElementById(vector1[i].id).children,vector2);
}
}
function selectAllElementsInsideDiv(divId){
var matches = new Array();
var searchEles = document.getElementById(divId).children;
fillArray(searchEles,matches);
return matches;
}
Now presuming your div's id is 'myDiv', all you have to do is create an array element and set its value to the function's return:
var ElementsInsideMyDiv = new Array();
ElementsInsideMyDiv = selectAllElementsInsideDiv('myDiv')
I have tested it and it worked for me. I hope it helps you.
var $list = $('#divname input[id^="q17_"]'); // get all input controls with id q17_
// once you have $list you can do whatever you want
var ControlCnt = $list.length;
// Now loop through list of controls
$list.each( function() {
var id = $(this).prop("id"); // get id
var cbx = '';
if ($(this).is(':checkbox') || $(this).is(':radio')) {
// Need to see if this control is checked
}
else {
// Nope, not a checked control - so do something else
}
});
i have tested a sample and i would like to share this sample and i am sure it's quite help full.
I have done all thing in body, first creating an structure there on click of button you will call a
function selectallelement(); on mouse click which will pass the id of that div about which you want to know the childrens.
I have given alerts here on different level so u can test where r u now in the coding .
<body>
<h1>javascript to count the number of children of given child</h1>
<div id="count">
<span>a</span>
<span>s</span>
<span>d</span>
<span>ff</span>
<div>fsds</div>
<p>fffff</p>
</div>
<button type="button" onclick="selectallelement('count')">click</button>
<p>total element no.</p>
<p id="sho">here</p>
<script>
function selectallelement(divid)
{
alert(divid);
var ele = document.getElementById(divid).children;
var match = new Array();
var i = fillArray(ele,match);
alert(i);
document.getElementById('sho').innerHTML = i;
}
function fillArray(e1,a1)
{
alert("we are here");
for(var i =0;i<e1.length;i++)
{
if(e1[i].id.indexOf('count') == 0)
a1.push(e1[i]);
}
return i;
}
</script>
</body>
USE THIS I AM SURE U WILL GET YOUR ANSWER ...THANKS