I want to be able to change multiple text inputs (but not all) by class, but can't seem to get it working.
Any ideas?
Basically I have multiple reset buttons on the same page I'd like to have 'resetting' the value of the targeted text inputs to nothing.
Here's the code:
$(".reset").on('click', function() {
document.getElementsByClassName('input-1').value = '';
});
It works fine when using getElementById, but I would rather minimise the code and not have to repeat it each time for every text input.
You are already using jQuery, so just use
$(".reset").on('click', function() {
$('.input-1').val('');
});
Notice the . before the class name, same as in .reset.
If you want to use vanilla JavaScript, you have to loop through the HTMLCollection returned by getElementsByClassName:
$(".reset").on('click', function() {
Array.from(document.getElementsByClassName('input-1')).forEach(el => el.value = '');
});
jQuery does that automatically for you.
You can use an special selector for this job:
let inputs = [... document.querySelectorAll("[class^='input-']")];
inputs.forEach(i => i.value = "");
class^= will return all the elements containing class attribute starting with "input".
Related
I found some JQuery solutions, but I am limited by school task restrictions to use pure Javascript, and I need to use specific early appended element that is still not in DOM for replacing by my CKEDITOR.
Code:
function newOption(){
...
mainUL = document.getElementById("myUL");
var inputA = document.createElement("input");
inputA.type ="text";
inputA.style = "margin-right: 45px";
inputA.name = "option[]";
inputA.id = inputID;
mainUL.appendChild(inputA );
CKEDITOR.replace(inputID).setData('Type anything you want ...');
...
}
By replacing my input with CKEDITOR will JS fail, because input, commonly, is still not in DOM. I tried to use
mainUL.innerHTML += "all elements like html text";
and this is working and will immediately insert elements into DOM, but I can't to use innerHTML, because it will remove old listeners (for example checked checkboxes that JS will set from checked to unchecked, what is my main problem due to I have to try using append DOM function).
Try changing the code to wrap the call to CKEDITOR.replace in a setTimeout:
setTimeout(function() {
CKEDITOR.replace(inputID).setData('Type anything you want ...');
},0).
This will allow the browser time to insert the element before trying to replace it.
And I assume that inputID has a valid value in it...
I'm trying to add a search link to an online form with a userscript using jQuery. I don't work too much in firefox and I feel like things that would normally work in chrome don't in ff 9/10 times for me. But anyway... this needs to be with ff.
I'm taking the text from a <p> element and creating a search url out of it (or trying to). Right now this is the function I'm trying that should be doing it... but it's doing nothing, not even any errors in console
$(function() {
var companyName = $('p')[7]; // Element that contains the name text
var companyText = companyName.text(); // Retrieve the text from element
var mixRankUrl = $("<a></a>").innerHTML("Search Mixrank"); // Create an <a> element
mixRankUrl.href = 'https://mixrank.com/appstore/sdks?search=' + companyText; // Define the href of the a element
var sdkPara = $('label.control-label')[10]; // Where I want it to go
sdkPara.append(mixRankUrl); // Append the element
});
Also, whoever wrote the html uses hardly any ids, and most classes are assigned to 10 or more elements... so unless there's a better way, I'm sort of stuck using node selectors (which stay the same form to form).
The problem is that you try to use jQuery method on DOM element. Don't understand why you don't have any errors with your code.
For exemple : $('p')[7] return a DOM element while $('p').eq(7) return a JQuery object. So you can't use a jQuery method like text() on your DOM element. You need to deal with jQuery object.
For the same reason, you had a problem with the declaration of your label object and with the modification of the href attribute of your link.
Try like this :
$(function() {
var companyName = $('p').eq(7); // Element that contains the name text
var companyText = companyName.text(); // Retrieve the text from element
var sdkPara = $('label.control-label').eq(10); // Where I want it to go
var mixRankUrl = $('<a>',{
text: 'Search Mixrank',
href: 'https://mixrank.com/appstore/sdks?search=' + companyText
}).appendTo(sdkPara); // Append the element
});
Does anyone know how to do replace multiple text by clicking a button with jQuery?
I've built a website that displays some text/data eg; "£100.00", but I what I need is to be able to 'replace' those monetary values with "£XXX.XX" with a 'Hide' button like you get on some banking websites. For example one web page has:
£100.00, £200.00, £130.00 etc etc..
...so when a user presses the Hide button, all of the numbers on the page turn to £XXX.XX. Ideally, the button should then display "Show" instead of "Hide" and switch back when toggled.
This is for a static dummy site, so no data base.
I suspect this is best handled with jQuery?
Thanks for your time,
D.
Case 1: Controlled Input
Assuming you can at least wrap all monetary values with something like this:
<span class="money-value">£200.00</span>
<span class="money-value">£300.50</span>
And that you can add button declared with:
<button id="secret-button">hide</button>
Then you could have some jQuery code doing this:
/**
* Simple search and replace version.
*/
$(function() {
$("#secret-button").click(function() {
$(".money-value").html($(".money-value").html().replace(/[0-9]/g,"X"));
});
});
or a more advanced one with:
/**
* Complet version.
*
* 1) on button click, if asking to hide:
* 1.1) iterate over all entries, save their text, and replace it with markers
* 1.2) toggle the button's text to "show"
* 2) on button click, if asking to show:
* 2.1) iterate over all entries, restore previous text
* 2.2) clear the hidden store
* 2.3) toggle the button's text to "hide"
*/
$(function() {
var hiddenStore = [];
$("#secret-button").click(function() {
if ($(this).html() == "hide") {
$(".money-value").each(function () {
var text = $(this).html();
hiddenStore.push(text);
$(this).html(text.replace(/[0-9]/g,"X"));
});
$(this).html("show");
} else {
$(".money-value").each(function (i) {
var text = hiddenStore[i];
$(this).html(text);
});
hiddenStore = [];
$(this).html("hide");
}
});
});
Complete solution is here: See here: http://jsfiddle.net/u79FV/
Notes:
this won't work for input field values
this assumes your text entries have been marked as shown above
Does what you want with the button's changing state.
Saves the values and puts them back.
Meant to work even if new fields are added dynamically.
Shankar Sangoli's answer uses a different way of saving the stored data, which you could as well consider (using the jQuery .data() method).
you may want to switch the button to an <input type="button" /> tag, in which case you'd use .val() instead of .html() to toggle its text.
Case 2: Uncontrolled Input
Assuming you don't have control over where the values may show up, then you need to do something a bit more complicated, which is to look in the whole page for something that would look like a currency format. I'd advise against it.
But, the jQuery Highlight plugin could be something to look at, as its code does something similar (in that it searches for pieces of code to modify), and you could then reuse some of solution 1 to make it fit your purpose.
That would be harder to design in a fool-proof fashion though.
You could use a regular expression:
var expression = /\d{1}/g;
var newString = myString.replace(expression,"X");
Then just dump newString into whatever control you need it to appear in.
Edit:
A jQuery idea for something like this would be to give all of the controls that have these numbers a common class identifier to make them easy to grab with the selector:
$(".numbers").each(function() {
$(this).text($(this).text().replace(/\d{1}/g, "X"));
}
... more readable ...
$(".numbers").each(function() {
var text = $(this).text();
var newText = text.replace(/\d{1}/g, "X");
$(this).text(newText);
}
If your markup is something like this you can try this.
<span>£1000.00</span><span class="showhide">Hide</span>
JS
$('.showhide').click(function(){
var $this = $(this);
var $prev = $this.prev();
if(!$prev.data('originalvalue')){
$prev.data('originalvalue', $prev.text());
}
if($this.text() == 'Hide'){
$this.prev().text($prev.data('originalvalue').replace(/\d{1}/g,"X"));
$this.text('Show');
}
else{
$prev.text($prev.data('originalvalue'));
$this.text('Hide');
}
});
In the above code I am basically storing the original value using jQuery data method within the span element itself which is used to display the actual value.
Once you click on Hide, get the previous span using prev() method and set its text with original value replacing all the numbers in it by X. Then change the link text from Hide to Show.
Next when you click on Show get the previous span using prev() method and set its text with the original value and change the link text from Show to Hide.
References: .prev(), .data()
$('#yourButton').click(function(){
var saveText = $('body').text();
$(this).data('oldText', saveText);
if ($(this).text() == "Hide"){
$('body').text($('body').text().replace(/\d{1}/, "X"));
$(this).text('Show');
}
else{
$('body').text($(this).data('oldText'));
$(this).text('Hide');
}
});
This is kind of a complicated problem actually. You will need to be able to save the state of the text when its in number form so you will be able to toggle back and forth. The above code is untested but hopefully it will give you an idea what you need to do.
function toggleMoney() {
$('.money').each(function() {
var $$ = $(this), t = $$.text();
$$.text($$.data('t') || t.replace(/\d/g, 'X')).data('t', t);
});
$('#toggleButton').text($('.money').text().match(/\d/) ? 'hide' : 'show');
}
http://jsfiddle.net/DF88B/2/
I am traversing checkboxes like this:
$('.day').each(function() {
// here I need to get the following 4 text inputs in the HTML
// and set some attributes on them
});
After every checkbox there are four text input fields (there are also some div, span tags for CSS around them). So inside the loop above I need to get four text input fields that follow the checkbox in the HTML source so I can set some attributes on them.
How would I go about that?
Hard to say without the markup, but you could try this.
$('.day').each(function() {
$(this).nextAll('input').slice(0,4).attr('someAttribute','somevalue');
});
If there's some stopping point, like another .day element, you could use nextUntil then .filter().
$('.day').each(function() {
$(this).nextUntil('.day').filter('input').attr('someAttribute','somevalue');
});
EDIT: When you say there are some <div> and other tags around them, I assumed that you meant in between them.
If you're actually saying that the inputs are nested in them, then you could do something like this:
$('.day').each(function() {
$(this).nextAll(':has(input)').slice(0,4).find('input').attr('someAttribute','somevalue');
});
or perhaps this:
$('.day').each(function() {
$(this).nextAll().find('input').slice(0,4).attr('someAttribute','somevalue');
});
or again, if there's a stopping point you can indicate like another .day, use nextUntil():
$('.day').each(function() {
$(this).nextUntil('.day').find('input').attr('someAttribute','somevalue');
});
if they are siblings within a parent container, you might be able to use $(this).nextAll('input').each(function(){}); or $(this).nextAll().find('input').each(function(){}); depending on your html structure. Or var p = $(this).parent(); if (p && p[0]) p[0].find('input').each(function(){});
This is a total guess, since you've shown no markup whatsoever:
$('.day').each(function() {
var $this = $(this);
var $inputs = $this.nextAll('input[type=text]');
$inputs.each(function () {
// do whatever with the inputs here
});
});
if your trying to set css properties to the inputs you can use css selectors which are quite powerful, like this
.day ~ input {
//set your styles for the input
}
what this means is you are selecting all the inputs exactely after .day
hope this helps.
Try
$('.day').each(function() {
// get input fields
var first_input = $(this).nextAll().filter('input:first');
var second_input = first_input.nextAll().filter('input:first');
var third_input = second_input.nextAll().filter('input:first');
var fourth_input = third_input.nextAll().filter('input:first');
// set attribute xyz to value
first_input.attr('xyz', 'value');
second_input.attr('xyz', 'value');
third_input.attr('xyz', 'value');
fourth_input.attr('xyz', 'value');
});
I'm writing a HTML form that's divided in fieldsets, and I need to get the form fields from a specific fiedset in a function.
Currently it's like this:
function conta(Fieldset){
var Inputs = Fieldset.getElementsByTagName("input");
var Selects = Fieldset.getElementsByTagName("select");
/* Doing the stuff I need to do in two iterations, one for each field type */
}
But who knows what the future may hold, and if the form gets some new field types (radios, checkboxes) this could become awful to mantain.
I know that form elements have the elements attribute that returns all the form fields and I was hoping I could use something like that.
(I know I still gotta discriminate the field type in a bunch of conditionals inside the iteration, but I think it would be faster and easier to keep. Unless it isn't and I should not be doing it)
#Ryan is on the right track if you want to use jQuery (and I would), but I'd suggest something more along the lines of:
$('fieldset#fieldset1 > input[type=text]').each( function() {
... do something for text inputs }
);
$('fieldset#fieldset1 > input[type=radio]').each( function() {
... do something for radios }
);
$('fieldset#fieldset1 > select').each( function() {
... do something for selects }
);
$('fieldset#fieldset1 > textarea').each( function() {
... do something for textareas }
);
As an improvement over if-then-else constructs.
Radio buttons and checkboxes are still input tags and will be in the Inputs var. The problem is, you'll need to add handlers for the checked state to see which radio buttons and checkboxes are selected.
Even worse, you can have more than one radio button and checkbox with the same name... in fact you have to for radio buttons or they don't work as expected.
No jQuery, no problem:
function condat(fieldset) {
var tagNames = ['input', 'select', 'textarea']; // Insert other tag names here
var elements = [];
for (var i in tagNames)
elements.concat(fieldset.getElementsByTagName(tagNames[i]);
for (var i in elements) {
// Do what you want
}
}
Filip Dupanović solution together with the second Cargowire comment worked for me, but only with a minor modification. Cargowire's second comment only produced an array which just holds the sliced characters of the tagNames array (I would have written this in a comment, but I lack the rep so far).
Here is what worked:
function condat(fieldset) {
var tagNames = ['input', 'select', 'textarea']; // Insert other tag names here
var elements = [];
for (var i in tagNames) {
elements = elements.concat([].slice.call(fieldset.getElementsByTagName(tagNames[i])));
}
for (var i in elements) {
// Do what you want.
// Attributes of the selected tag's can be referenced for example as
// elements[i].value = ...;
}
}
A usefull application of this would be to define buttons which only reset a fieldset instead of the whole form. Just use elements[i].value = elements[i].defaultValue; in the //do what you want part, for text inputs to be reseted. And of course bind the condat function onto the onclick event of the button providing the fieldset dom element as a paramenter.
Haven't tested this and don't know how it would work, but you could use JQuery here to select all the elements into a JQuery object
//$("input select textarea").each(function() {
$(":input").each(function() { //even better
// do stuff here
});
this would at least cleanup the code, although you would still have to add conditional statements based on field type like you mentioned.
You should use just querySelectorAll:
function condat(fieldset) {
var elements = fieldset.querySelectorAll('input, select, textarea');
elements.forEach(function(element){
// Do what you want with every element
});
}