I have a form that has many select menus, most of them are Yes/No and depending on the selected option, I display/hide some advanced options. One of the select menus is the following:
<td><%= f.select :CBIAvailable, ['Yes' , 'No'],{}, {:id=>"cbi_available_id", :class=>"cbi_available_class", :onChange=>"showHideOptions('cbi_available_id','cbi_options_id')", :onLoad=>"showHideOptions('cbi_available_id','cbi_options_id')"} %></td>
When I change from 'Yes' to 'No' or the opposite, showHideOptions javascript functions is called properly, but I can't have that function to be called when I reload the form.
Anyone can tell me what am I dong wrong?
Thanks
UPDATE
<script language="javascript" type="text/javascript">
function showHideOptions(selectorId,optionsId) {
if (document.getElementById) {
var selector = document.getElementById(selectorId);
var options = document.getElementById(optionsId);
if (selector.value == 'Yes') {
options.style.display = 'block';
return false;
} else {
options.style.display = 'none';
return false;
}
}
window.onLoad = showHideOptions('cbi_available_id','cbi_options_id');
function yourFunction(){
//get that select element and evaluate value
//do you change stuff here
}
window.onload = yourFunction; //this gets fired on load
//"select" is your element,
//fetched by methods like document.getElementById();
select.onchange = yourFunction; //this gets fired on change
//you can also use attachEvent (IE) or addEventListener (Others)
here's a working demo:
<select id="testSelect">
<option value="yes">YES</option>
<option value="no">NO</option>
</select>
function getOption() {
alert('foo');
}
var select = document.getElementById('testSelect');
select.onchange = getOption;
window.onload = getOption;
This could happen when you receive postback from your remote server and your response doesn't have <script type="javascript">... yourfunction()...</script>.
Each time you get new response you should send script and exacute it or append to your html element approciate event handler.
Another solution is to use jQuery and use .live() event. This event attach dynamically behaviour to your html. I strongly recommend you to use jQuery with live because this library is one of most used libraries in production environment.
Edit
<script type="text/javascript" src="path_to_jquery.js"></script>
<script type="text/javascript">
function showHideOptions(id1,id2){
//Your code
}
$(document).ready(function() {
//This function waits for DOM load
//execute your function for first time
showHideOptions('cbi_available_id','cbi_options_id');
//This selector you have to modify or show us generated html to
// choose the best selector for this purpose
$('.cbi_available_class').live('change',function(){
//This will fire change event of html class="cbi_available_class"
showHideOptions('cbi_available_id','cbi_options_id');
});
});
</script>
Related
I have two files: a html file (with the code below) and a javascript file (it creates a value for the <span id="quantity">) The code works fine, but the word only changes if I refresh the whole page.
I want the word to change from 'articles' to 'article' or vice versa as soon as the 'quantity' changes. Is this possible? And if so, how?
<span id="quantity" class="simpleCart_quantity"></span>
<span id="quantityText"></span>
<script type="text/javascript">
$(window).load(function()
{
var quantity = document.getElementById("quantity"),
quantityText = document.getElementById("quantityText");
if (parseInt(quantity.innerHTML, 10) === 1) {
quantityText.innerHTML = "article";
} else {
quantityText.innerHTML = "articles";
}
});
</script>
You might want to look into MVVC framework like Knockout JS. For example, you would set the contents of the #quantity <span></span> element to be an observable.
However, try reading this SO thread to find a solution similar to what you probably are hoping for. In summary, change events only occur from the browser on the blurring of form fields, so you'll need to implement a $("#quantity").trigger('change')
Once you have a trigger set-up after the DOM element has been loaded, you can do the following:
$('#myParentNode').on('change','#mynum', function() {
// Add your logic in here
$('#quantityText').text('articles') .... .. .. .....
});
Normally, the span element doesn't fire a change event, so you cannot subscribe to it, like you would normally do in an input element.
However, you can trigger such an event using jQuery in the same code, which changes the value of the span (I assume there is such code, because normally spans don't change value).
Here is an example which simulates this change every 10 seconds, and triggers the change event. It also includes a handler for that change event, which duplicates the value in the other span.
<span id="quantity" class="simpleCart_quantity">1</span>
<span id="quantityText"></span>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var quantity = $("#quantity"),
quantityText = $("#quantityText");
setInterval(function() {
var currentVal = parseInt(quantity.html());
if (currentVal >= 10) {
quantity.html(1);
}
else {
quantity.html(currentVal + 1);
}
quantity.trigger('change');
}, 10000);
quantity.on('change', function(sender, args) {
quantityText.html($(this).html());
});
});
</script>
There will be number of such div created with unique div id,
when i click on click me it should show an alert for that productid,
i am doing it like
<div id="xyz{productid}">
Click Me
</div>
.....
<script type="text/javascript">
var uuid="{productid}"
</script>
<script src="file1.js">
code from file1.js
$(function () {
var d = "#xyz" + uuid;
$(d).click(function () {
alert("Hello" + uuid);
return false;
});
alert(d);
});
So code is also ok,but the basic problem with it is,
since i m doing it on category page where we have number of products,this function is getting bound to last product tile only,
I want it to be bound to that specific div only where it is been called
..............................
got a solution
sorry for late reply,was on weekend holiday, but i solved it by class type of architecture, where we create an object with each tile on page,and at page loading time we initialize all its class vars,so you can get seperate div id and when bind a function to it, can still use the data from its class variables, i m posting my code here so if any one want can use it,
UniqeDiv= new function()
{
var _this = this;
var _divParams = null;
var _uuid=null;
//constructor
new function(){
//$(document).bind("ready", initialize);
//$(window).bind("unload", dispose);
_uuid=pUUID;
initialize();
$('#abcd_'+_uuid).bind("click",showRatingsMe)
dispose();
}
function initialize(){
}
function showRatingsMe(){
alert(_uuid);
}
function dispose(){
_this = _divParams = null
}
}
//In a target file, im including this js file as below
<script type="text/javascript">
var pUUID="${uuid}";
</script>
<script type="text/javascript" src="http://localhost:8080/..../abc.js"></script>
You can use attribute selector with starts with wild card with jQuery on() to bind the click event for dynamically added elements.
$(document).on("click", "[id^=xyz]", function(){
//your code here
alert("Hello"+this.id);
return false;
});
I would add a class to each of your dynamic divs so that they are easier to query. In the following example, I'm using the class dynamic to tag the div's that are added dynamically and should have this click listener applied.
To attach the event, you can use delegated events with jQuery's on() function. Delegated events will fire for current and future elements in the DOM:
$(function() {
var d="#xyz"+uuid;
$(document).on('click', 'div.dynamic', function() {
alert("Hello"+uuid);
return false;
});
});
You can read more about event delegation here.
You can use
$("[id*='divid_']").click(function(){
});
but for this you need to make sure that all div IDs start with "divid_".
In the following jquery, it works when I finish typing a value (keyup) in a textbox:-
<script type="text/javascript">
$(function(){
var minTenderNum;
$("#tenmoney").keyup(function(){
var minTenderMoney = $(this).val();
if(minTenderMoney <=1000)
minTenderNum = 3;
else if(minTenderMoney > 1000)
minTenderNum = 5;
$('#sunum').children().remove().end();
maxTenderNum = minTenderNum + 4;
for(var i=minTenderNum;i <=maxTenderNum;i++)
$('#sunum').append(new Option(i, i, true, true));
$("#uniform-sunum>span").html('');
});
});
</script>
<select id="sunum" name="sunum">
</select>
sometimes, a value already exists when the page is onload, but I have to modify the value and "key up" so that the function starts again.
If I wish to include an event for on load, how shall I modify the function? Thanks!
one of the ways to do this is On document ready You can fire a keyup event like this
$("#tenmoney").trigger('keyup');
add this line inside document ready callback
$(function(){
});
or even beter just call $.keyup() without any argument which will trigger keyup event on that element like this
$("#tenmoney").keyup();
How can I retrieve the new selected value and the previous selected value with JavaScript when onChange or similar event is called?
<select size="1" id="x" onchange="doSomething()">
<option value="47">Value 47</option>
...
function doSomething() {
var oldValue = null; // how to get the old value?
var newValue = document.getElementById('x').selected.value;
// ...
Thank you! :)
Using straight JavaScript and DOM, something like this (live example):
var box, oldValue;
// Get a reference to the select box's DOM element.
// This can be any of several ways; below I'll look
// it up by ID.
box = document.getElementById('theSelect');
if (box.addEventListener) {
// DOM2 standard
box.addEventListener("change", changeHandler, false);
}
else if (box.attachEvent) {
// IE fallback
box.attachEvent("onchange", changeHandler);
}
else {
// DOM0 fallback
box.onchange = changeHandler;
}
// Our handler
function changeHandler(event) {
var index, newValue;
// Get the current index
index = this.selectedIndex;
if (index >= 0 && this.options.length > index) {
// Get the new value
newValue = this.options[index].value;
}
// **Your code here**: old value is `oldValue`, new value is `newValue`
// Note that `newValue`` may well be undefined
display("Old value: " + oldValue);
display("New value: " + newValue);
// When done processing the change, remember the old value
oldValue = newValue;
}
(I'm assuming all of the above is inside a function, like a page load function or similar, as in the live example, so we're not creating unnecessary global symbols [box, oldValue, 'changeHandler`].)
Note that the change event is raised by different browsers at different times. Some browsers raise the event when the selection changes, others wait until focus leaves the select box.
But you might consider using a library like jQuery, Prototype, YUI, Closure, or any of several others, as they make a lot of this stuff a lot easier.
Look here: Getting value of select (dropdown) before change
I think the better,
(function () {
var previous;
$("select").focus(function () {
// Store the current value on focus, before it changes
previous = this.value;
}).change(function() {
// Do something with the previous value after the change
alert(previous);
});
})();
The following code snippet may help
<html>
<script type="text/javascript">
this.previousVal;
function changeHandler(selectBox)
{
alert('Previous Val-->'+selectBox.options[this.previousVal].innerHTML)
alert('New Val-->'+selectBox.options[selectBox.selectedIndex].innerHTML)
this.previousVal=selectBox.selectedIndex;
}
</script>
<body>
<select id="selectBox" onchange="changeHandler(this)">
<option>Sunday</option><option>Monday</option>
<option>Tuesday</option><option>Wednesday</option>
</select>
<script type="text/javascript">
var selectBox=document.getElementById("selectBox")
this.previousVal=selectBox.selectedIndex
</script>
<body>
</html>
Below worked for me.
Add below two events to your select HTML tag:-
onFocus='this.oldValue = this.value'; //if required in your case add this line to other events like onKeyPressDown and onClick.
onChange = 'alert(this.oldValue); this.value=this.oldValue'
I have an <input> field in my web page, and I want to add a particular method on it, let say fooBar().
Here is what I do:
<input id="xxx" .../>
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
This works well. However, for some reasons I will not detail here (in fact the HTML is generated by JSF components), the <script> will be declared before the <input> tag.
So in others words, I will have that in my HTML:
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
<input id="xxx" .../>
So of course this code will not work correctly, as the script will try to get ($("xxx")) and modify an element that does not exist yet.
If I want to stick on the exact order of these two tags, what is the best way to accomplish what I want?
Edit
In my case, $ refers to prototype, but I am also using jQuery in my application. And I must be compatible with IE6 :o(
You need to run your script after the document is loaded. With jQuery you'd do that with:
$(document).ready(function () {
//do stuff here
});
I can't tell which library you're using here, but they all have an equivalent of jQuery's document ready.
Here's the prototype equivalent:
document.observe("dom:loaded", function() {
// do stuff
});
Try putting your code in load event:
$(window).load(function(){
$("#xxx").fooBar = function() { ... };
});
If the code has to be directly before the input, you can check if it has loaded after a certain period of time.
<script type="text/javascript">
//Sets up a function to execute once the input is loaded
f = function ()
{
//Checks if 'xxx' exists (may vary between frameworks)
if ($("xxx") !== undefined)
{
$("xxx").fooBar = function() { ... };
//Escapes the timer function, preventing it from running again
return true;
}
//If still not loaded check again in half a second (0.5s or 500ms)
setTimeout(f,500);
return false;
}
f();//Initialize the timer function
</script>
<input id="xxx" .../>
Instead of adding a method to the dom node, why not make it a separate function, so instead of
$("xxx").fooBar = function() {
doStuff(this);
};
you would have something like
function xxx_fooBar () {
var me = document.getElementById('xxx');
doStuff(me);
};
Another suggestion: If you can add attributes to the <input> element, you could do something like this...
<script>
function xxx_init (e) {
e.fooBar = function () {
doStuff(this);
};
}
</script>
<input onload="xxx_init(this)" id="xxx" .../>
Or you could do as others suggest and attach the scripts to the window.onload event.