I've had this javascript function that I've used many many times over ...
function showHideObjects()
{
var args;
args = showHideObjects.arguments;
for(var i=0;i<args.length;i++)
{
if(document.getElementById(args[i]))
{
if(args[i+1] == 'flip')
{
if(document.getElementById(args[i]).style.display == '')
{ document.getElementById(args[i]).style.display = 'none';}
else
{ document.getElementById(args[i]).style.display = '';}
}
else
{
document.getElementById(args[i]).style.display = args[i+1];
}
}
i++;
}
}
Now I'm working with ASP.NET and need that same function but in jQuery but I can't find any information about dynamic parameters in jQuery. Is there a way to do this in jQuery?
To provide a little more background ... you could call the above code with a line like ... showHideObjects('div1','none') and it'd hide div1. Or you could call ... showHideObjects('div1','none','div2','','div3','flip') and it'd hide div1, show div2 and switch div3 from either hidden or shown.
jQuery is just JavaScript. Your code will work fine with jQuery.
It is purely a javascript feature. Jquery do not have any special feature for this.
As some have already said, jQuery is Javascript and your code will work just fine. BUT you can do the same thing with jQuery that you are now doing with your function. You are getting elements which you change to have either display none or nothing.
jQuery has Selectors, which you can use to select the elements from the DOM to which you want to do something to. You can forexample use selectors to select the element you want and then just cast .toggle(). It does the exactly same thing as your function but with just 1 line of code.
EDIT: Added an example:
If you have a div, which has a class hideNseek, you can use this to toggle it to show or hide:
$(".hideNseek").toggle();
$(".hideNseek") is selectors which selects all classes that have that name.
Like others have said, your function will work just fine. You don't NEED jQuery to do what you are doing. If you wanted to use jQuery you could do something like:
function showHideObjects() {
var args = arguments,
l=args.length;
for ( var i=0; i<l; i++ ) {
var elem = $( "#"+args[i] ),
type = args[i+1];
if ( elem.length ) {
if ( type == "flip" ) {
elem.toggle();
} else {
elem.css("display", type);
}
}
i++
}
}
You can't call different actions on a group in JQuery. However, you can perform the same action (hide, show, toggle) on a group of elements by using the appropriate selector to get the group. Here's a quick example that has buttons to toggle all the div elements and all the span elements on the page with the JQuery toggle function, along with a fiddle for testing:
HTML:
<div>div 1</div>
<span>span 1</span>
<div>div 2</div>
<span>span 1</span>
<input id="toggleSpans" type="button" value="toggle spans"/>
<input id="toggleDivs" type="button" value="toggle divs"/>
JavaScript:
$('#toggleDivs').click(function(){
$('div').toggle();
});
$('#toggleSpans').click(function(){
$('span').toggle();
});
If that is not good enough, you can easily group and call these methods in a custom function as you do in your old JavaScript function, or just keep your old method.
UPDATE:
Check out the different selectors you can use. In your specific case, you'd need to use ID Selector along with Multiple Selector, but you could make your function much more powerful if you allowed passing in any JQuery selector rather than just the ids. For example:
showHideObjects('#div1, <otherSelectorsToHide>','none',
'#div2, <otherSelectorsToShow>','',
'#div3, <otherSelectorsToToggle>','flip');
Related
I'm trying to change the attribute of an object with removeAttribute to take away the hidden status of it but so far nothing seems to work.
My code seems to have no effect. Am I doing something wrong?
function changePage() {
document.getElementById.("p2");
p2.removeAtribute.("hidden") ;
}
I've also tried it all on one line as well like so
function changePage() {
document.getElementById.("p2").p2.removeAtribute.("hidden") ;
}
I've never seen the use of dots before opening parentheses.
E.g.
document.getElementById.("p2").p2.removeAtribute.("hidden") should be document.getElementById("p2").removeAtribute("hidden")
(You are also referencing the element by id after you just retrieved it, which is unnecessary.)
Your first example didn't work because you retrieved the element and did nothing with it, then tried to access a p2 variable that wasn't declared. Again, you also have the . before parentheses.
Here's the js example:
function changeVisibility()
{
var p2 = document.getElementById('p2');
switch (p2.style.visibility)
{
case 'hidden':
document.getElementById('p2').style.visibility = 'visible';
break;
case 'visible':
document.getElementById('p2').style.visibility = 'hidden';
break;
}
}
<div id="p2" style="visibility:hidden">
test
</div>
<br />
<button onclick="changeVisibility()">
change visibility with basic js
</button>
And here's the jQuery example:
function changePage()
{
$('#p2').toggle();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="p2" style="display:none">
test
</div>
<br />
<button onclick="changePage()">
change visibility with basic js
</button>
The basic JS version uses the visibility style, and you can see that it doesn't collapse the element, it only makes it invisible.
jQuery has a nice built-in .toggle function that changes the display of the element. If it is hidden, it collapses the element. When the element is displayed, it is re-assigned whatever the display style is for that element. Building that in basic js would take a lot more work, as you are then tracking state (if you want to make the method reusable). You can make jQuery work similarly to the basic js version if you use the css properties, but toggle is quite nice and simple.
Your main issue is that you were mixing the getting of the element with methods that are only available on jQuery objects. I suggest reading the jQuery tutorials for basic accessors, which can get elements by id, class name, etc.
I know there are several questions/solutions to this problem, and I am looking for a combination of two simple solutions(I am not a coder, just a copy/paste/manipulator) so here goes: I need a script which involves a button that toggles show/hide divs on top of a large imagemap, whose function is to turn on/off labels contained within each div. As the imagemap is large and contains groups, I am looking for a way to loop the following functional script:
$(document).ready(function() {
$(".hide").click(function() {
$(this).siblings(".hideShow").hide();
});
$(".show").click(function() {
$(this).siblings(".hideShow").show();
});
});
The loop is needed as I will have well over 200 labels to toggle(removing them will clear some visual space). The html above lists two buttons, whereas I need only one which toggles between the two, like the one behind this jquery bit:
var toggleState = false;
$('.show').click(function() {
$(".text").toggle();
$(this).toggleClass('hide').attr('title', toggleState ? 'Show All' : 'Hide All');
toggleState = !toggleState;
})
The former jfiddle found here: http://jsfiddle.net/MztAm/
The latter here: http://jsfiddle.net/y8ZTj/1/
Actually, as the latter script is more desireable, is it possible to turn it into a loop, replacing ".text" to accomodate many instances?
The best I could come up with: http://jsfiddle.net/qmv3dmya/ though I need a new instant of the jquery piece for every grouping. But I'll end up putting the series in a separate *.js sheet to be referenced by the main page.
It is possible that I don't understand your question correctly, but if I do, then perhaps this information will be helpful:
(1) You do not need a loop. With jQuery, selecting all DIVs with class="text" looks like this:
$('.show').click(function() {
$(".text").toggle();
});
(2) This bit: $(".text") creates an object that contains a list of all DIVs that have class="text"
(3) This bit: .toggle() applies that method to each element contained in $('.text')
Therefore, all elements with class="text" will be toggled visible/invisible as a group. No need for a loop.
jsFiddle Demo
If you did need a loop, you could use .each(), like this:
$('.text').each(function(){
// Whatever you do in here will be done once to each DIV
// (or other element) contained in the object ("list") of
// all elements with `class="text"`
});
You can you siblings function see below.
Jquery:
var toggleState = false;
$('.show').click(function() {
$(this).siblings(".text").toggle();
$(this).toggleClass('hide').attr('title', toggleState ? 'Show All' : 'Hide All');
toggleState = !toggleState;
});
DEMO
NOTE: using jQuery 1.3.2 (Yep I'm upgrading but still need to be at 1.3.2 for this)
Looking for a better way to implement this
HTML Element (This is coming from a custom PHP framework and is very cumbersome to make changes to):
<select id="car[0][car_id]" name="car[0][car_id]">
... 100+ options
</select>
I can add another drop down dynamically which looks like this:
<select id="car[1][car_id]" name="car[1][car_id]">
... 100+ options
</select>
and
<select id="car[2][car_id]" name="car[2][car_id]">
... 100+ options
</select>
Now I'm iterating through them like this:
function showCarinfo() {
for ( var car_number = 0; $("#car\\["+car_number+"\\]\\[car_id\\]").length > 0; car_number++ ) {
// do stuff
}
}
on change selection:
$("input[name*=car_id]").change(function(){
// display info for each car selected from each drop down select menu
showCarinfo();
});
Is there a better way to implement the on change and iterating methods? I am using the 'Attribute Contains Selector' ( http://api.jquery.com/attribute-contains-selector/ ) but looks like it's causing a big performance issue with the on change event.
UPDATE:
I've replaced the * with $ to search the last part and this (I think) does help with performance a little but still looking if this is the best solution
$("input[name$=car_id]").change(function(){
// display info for each car selected from each drop down select menu
showCarinfo();
});
The performance issue is in your showCarinfo function. You're preforming DOM selection in a loop.
Don't do that. Instead cache the selection...
function showCarinfo() {
var cars = $("input[name*=car_id]");
for ( var car_number = 0; car_number < cars.length; car_number++ ) {
cars.eq(i); // do stuff
}
}
or you can use .each()
function showCarinfo() {
$("input[name*=car_id]").each(function() {
// do stuff
});
}
Also, if the only thing the handler is doing is calling that function, a small optimization would be to do this...
$("input[name*=car_id]").change(showCarinfo);
Just as a guess, but I would try binding the change event to all input elements and filtering them when the event is called:
$("input").change(function() {
if ($(this).attr('name').indexOf('car_id') == 0) {
showCarinfo();
}
});
That way jQuery doesn't have to block page execution to attach event handlers to the elements based on selectors.
You can use this:
$('input[name$="[car_id]"]').change(function(){
// codes
});
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 have created a view in Drupal. I'm using JavaScript to modify the CSS in each row. The script runs on the first row, but does not make the changes on the rest of rows from the view.
This is the script:
<script language="javascript" type="text/javascript">
window.onload = floatbr;
function floatbr() {
var f = document.getElementById('firstright') // Get div element
var s = document.getElementById('secondright') // Get div element
var w = document.getElementById('catwrapper') // Get div element
var sh = s.offsetHeight // secondright div height
var wh = w.offsetHeight // catwrapper div height
f.style.height = wh - sh + 'px'; }
</script>
I'm using it from this page: http://agsone.100webcustomers.com/floatbottom.php
having the script in the page once does not do the trick.
having the script in the view footer and repeating the script does not work.
The link to the jSfiddle with HTML, CSS and JavaScript is the following one: http://jsfiddle.net/YTN3K/.
Drupal provides and already uses jQuery, so you should use it too. Drupal has its own way to manage JavaScript and comes with some additional JavaScript API, mainly to handle passing variables from PHP to JavaScript properly, register script to run on page load and content addition, etc.
jQuery is well documented and popular, so finding documentation, tutorial and howto is easy. Its own documentation page is a good start. But it requires basic understanding of what an XHTML document is and how it is structured.
It's hard to tell from your question and the markup you've linked to exactly what you're trying to do, so here's some general information to get you going:
The function you're currently using, getElementById, returns a single element: The one on the page with that id value. (id values must be unique on the page.)
To deal with multiple elements, you have several options. Two of the most popular:
You can start with a given element and then use its childNodes, firstChild, nextSibling, and similar properties to navigate from it to other elements nearby.
You can use getElementsByTagName (on the document or on an element) to find all elements within that container (including ones several levels down) that have a given tag. For instance, document.getElementsByTagName("p") gives you a NodeList of all paragraphs on the page.
These are properties and methods of the "DOM" (the Document Object Model), which is the tree of elements and associated information the browser creates when parsing and rendering your HTML.
References:
DOM2 Core
DOM2 HTML bindings
DOM3 Core
HTML5 Specification's DOM info
Here's an example showing some very basic operations (live copy):
HTML:
<div id="justOneDiv">I'm the <code>justOneDiv</code> element. I'm unique on the page. JavaScript code on the page turned me red.</div>
<div id="container">I'm a container called "container" with <span>various</span> <code>span</code> elements. <span>Code</span> on the <span>page</span> has made all of the <code>span</code> elements in this container <span>bold</span>.</div>
<div>I'm a container with <span>various</span> <code>span</code> elements. <span>Note</span> that the <code>span</code> elements are <span>not</span> bold, because I'm <span>not</span> in the container above.</div>
<div>I'm a <code>div</code> with no class.</div>
<div class="foo">I'm a <code>div</code> with class "foo". Code on the page turned me blue.</div>
<div class="bar">I'm a <code>div</code> with class "bar". Code on the page turned me green.</div>
<div>Another classless <code>div</code></div>
<div class="foo other">Another "foo", also with class "other"</div>
<div class="bar">Another "bar"</div>
<div>Another classless <code>div</code></div>
<div class="foo">Another "foo"</div>
<div class="bar test">Another "bar", also with class "test"</div>
<div>Another classless <code>div</code></div>
<div class="foo">Another "foo"</div>
<div class="bar">Another "bar"</div>
<div>Another classless <code>div</code></div>
<div class="foo">Another "foo"</div>
<div class="bar">Another "bar"</div>
JavaScript:
(function() {
hookEvent(window, "load", go);
function go() {
var list, index, div, container;
// Get just the one element, turn it red
document.getElementById("justOneDiv").style.color = "red";
// Get the spans within the specific container
container = document.getElementById("container");
list = container.getElementsByTagName("span");
// Loop through making those spans bold
for (index = 0; index < list.length; ++index) {
list.item(index).style.fontWeight = "bold";
}
// Get a NodeList of all divs on the page
list = document.getElementsByTagName("div");
// Loop it, turning "foo"s blue and "bar"s green
for (index = 0; index < list.length; ++index) {
div = list.item(index);
if (/\bfoo\b/.test(div.className)) {
div.style.color = "blue";
}
else if (/\bbar\b/.test(div.className)) {
div.style.color = "green";
}
}
}
function hookEvent(element, eventName, handler) {
// Very quick-and-dirty, recommend using a proper library,
// this is just for the purposes of the example.
if (typeof element.addEventListener !== "undefined") {
element.addEventListener(eventName, handler, false);
}
else if (typeof element.attachEvent !== "undefined") {
element.attachEvent("on" + eventName, handler);
}
else {
element["on" + eventName] = handler;
}
}
})();
Side note: The operations above can be made dramatically simpler by leveraging the utility functionality provided by any decent JavaScript library like jQuery, Prototype, YUI, Closure, or any of several others.
For example, using that same HTML, here's the JavaScript code using jQuery for the same result (live copy):
jQuery(function($) {
// Get just the one element, turn it red
$("#justOneDiv").css("color", "red");
// Get the spans within the specific container
// Loop through making those spans bold
$("#container span").css("font-weight", "bold");
// Turn all divs with the class "foo" blue
$("div.foo").css("color", "blue");
// Turn all divs with the class "bar" green
$("div.bar").css("color", "green");
});
The DOM is the official API; libraries like jQuery provide alternate or enhanced APIs. They're very useful and powerful, but I would recommend having some understanding of the DOM itself, even if you use a library and end up rarely writing code directly to the DOM API.