Using Javascript/JQuery and getting undefined var when the page loads - javascript

I have this Javascript/JQuery code:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
name = $("#name").val();
alert("Name: " + name);
</script>
And this HTML:
<form name="report" action="send.php" method="post">
<input type="text" name="name" id="name" value="Senna" />
<input type="submit" value="Send" />
</form>
When the page loads i get "Name: undefined" instead of "Name: Senna".
Can someone help me to get the expected result?

While JavaScript provides the load event for executing code when a
page is rendered, this event does not get triggered until all assets
such as images have been completely received. In most cases, the
script can be run as soon as the DOM hierarchy has been fully
constructed. The handler passed to .ready() is guaranteed to be
executed after the DOM is ready, so this is usually the best place to
attach all other event handlers and run other jQuery code.
You need to indicate to execute the function once the page has been loaded. Currently you are only defining it and not decalring when to execute it.
$(document).ready(function(){
name = $('#name').val();
alert('Name: ' + name);
});
Or:
$(function(){
name = $('#name').val();
alert('Name: ' + name);
});

You should place your code inside the DOM ready handler:
$(function() {
var name = $("#name").val();
alert("Name: " + name);
});
Otherwise you are trying the work with elements which are not yet loaded.

You need the document.ready callback.
Place your code inside a function like this -
$(function(){
// code goes here
});
You need to use this callback to know when jQuery and the entire DOM is loaded. Only then can you start to manipulate the Markup and CSS with your jQuery code.
The code above is really just shorthand for this -
$(document).ready(function(){
// code goes here
});
This uses the .ready() method - http://api.jquery.com/ready/
An extract from the description of the .ready() function -
... The handler passed to .ready() is guaranteed to be executed after
the DOM is ready, so this is usually the best place to attach all
other event handlers and run other jQuery code. ...
emphasis added

Related

jQuery bind event on element fails

We are using jQuery 2.1.4 and have written out own JavaScript class that should take care of the event. It is a very simple "application". All it does is taking care of submitting a form. Before that, it processes the data.
Our initial method that we call on rendering the page:
OWebForm.prototype.init = function(){
console.log("init Method called");
...
$("#submit_message").on("click", this._submit);
console.log($("#submit_message"));
...
}
OWebForm.prototype._submit = function(e){
e.preventDefault();
console.log("_submit Method called");
...
}
Once the button "#submit_message" is clicked, it is supposed to call the _submit method of the OWebForm class. When looking at the element within the console I can see that it is not bound to anything, when the page is loaded. Hence the code is not executed once the button is clicked.
In the HTML I have the following code:
<script type="text/Javascript">
var _oWebForm = new OWebForm("0bcfwqx23xv02dfaqfujdqyafziic4b07uxkkg1y6lkof7x0px0vjm2tpaik2l2rmlrhnjya0bvctnpq26dqcom1ij5zpibodke3rs1z4f2syllthtj0kpl3p4vrw0vw");
_oWebForm.init();
</script>
From the documentation I understood, that the function has to exist before it is bound to an element event. Is this not the case when working with objects? How would I fix this?
Your script is executed before the DOM is loaded so the element doesn't exist yet, and the jQuery selector doesn't match anything, so no elements get a click handler bound to them. You need to call the init() method with in $(document).ready().
A page can't be manipulated safely until the document is "ready." jQuery detects this state of readiness for you. Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute.
$(document).ready(function() {
var _oWebForm = new OWebForm("0bcfwqx23xv02dfaqfujdqyafziic4b07uxkkg1y6lkof7x0px0vjm2tpaik2l2rmlrhnjya0bvctnpq26dqcom1ij5zpibodke3rs1z4f2syllthtj0kpl3p4vrw0vw");
_oWebForm.init();
});
This works for me:
var OWebForm = function(a){
};
OWebForm.prototype.init = function() {
alert("init Method called");
$("#submit_message").on("click", this._submit);
}
OWebForm.prototype._submit = function(e){
e.preventDefault();
alert("_submit Method called");
}
$(function() {
var _oWebForm = new OWebForm("0bcfwqx23xv02dfaqfujdqyafziic4b07uxkkg1y6lkof7x0px0vjm2tpaik2l2rmlrhnjya0bvctnpq26dqcom1ij5zpibodke3rs1z4f2syllthtj0kpl3p4vrw0vw");
_oWebForm.init();
});
<script src="http://code.jquery.com/jquery-1.11.3.js"></script>
<form id="myFrm">
<input type="text">
<input id="submit_message" type="submit" value="Click me To test">
</form>
You need to substitute:
$("#submit_message").on("click", this._submit);
with:
$(document).on("click", "#submit_message", this._submit);
If the submit_message is not already loaded!

JSF/PrimeFaces ajax updates breaks jQuery event listener function bindings

I am registering a change event listener for every input in the HTML using jQuery as below:
<h:head>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
$(':input').each(function() {
$(this).change(function() {
console.log('From docReady: ' + this.id);
});
});
});
function changeHandler() {
console.log("from changeHandler");
}
//]]>
</script>
</h:head>
<h:body>
<h:form id="topForm">
<p:commandButton id="myButton" value="update"
action="#{testBean.submit}"
partialSubmit="true" process=":myForm:panel"
update=":myForm:panel" />
</h:form>
<h:form id="myForm">
<p:panel id="panel">
<p:inputTextarea id="myTextarea"
value="#{testBean.val}"
onchange="changeHandler();"/>
</p:panel>
</h:form>
</h:body>
Both change events are being triggered if the user changes the content of myTextarea. However after pressing the update button, which partially updates the myTextarea, only the changeHandler is triggering afterwards. The event bound in $(document).ready() is not triggering anymore.
Is this PrimeFaces related and/or an expected behavior? If yes then how can I ensure to trigger the second event without rerunning document ready script again.
As to the cause of your problem, the ajax request will update the HTML DOM tree with new HTML elements from the ajax response. Those new HTML elements do —obviously— not have the jQuery event handler function attached. However, the $(document).ready() isn't re-executed on ajax requests. You need to manually re-execute it.
This can be achieved in various ways. The simplest way is to use $(document).on(event, selector, function) instead of $(selector).on(event, function). This is tied to the document and the given functionRef is always invoked when the given eventName is triggered on an element matching the given selector. So you never need to explicitly re-execute the function by JSF means.
$(document).on("change", ":input", function() {
console.log("From change event on any input: " + this.id);
});
The alternative way is to explicitly re-execute the function yourself on complete of ajax request. This would be the only way when you're actually interested in immediately execute the function during the ready/load event (e.g. to directly apply some plugin specific behavior/look'n'feel, such as date pickers). First, you need to refactor the $(document).ready() job into a reusable function as follows:
$(document).ready(function(){
applyChangeHandler();
});
function applyChangeHandler() {
$(":input").on("change", function() {
console.log("From applyChangeHandler: " + this.id);
});
}
(note that I removed and simplified your completely unnecessary $.each() approach)
Then, choose one of the following ways to re-execute it on complete of ajax request:
Use the oncomplete attribute of the PrimeFaces command button:
oncomplete="applyChangeHandler()"
Use <h:outputScript target="body"> instead of $(document).ready(),
<h:outputScript id="applyChangeHandler" target="body">
applyChangeHandler();
</h:outputScript>
and reference it in update attribute:
update=":applyChangeHandler"
Use <p:outputPanel autoUpdate="true"> to auto update it on every ajax request:
<p:outputPanel autoUpdate="true">
<h:outputScript id="applyChangeHandler">
applyChangeHandler();
</h:outputScript>
</p:outputPanel>
Use OmniFaces <o:onloadScript> instead of $(document).ready(), <h:outputScript> and all on em.
<o:onloadScript>applyChangeHandler();</o:onloadScript>

My JavaScript code is not working locally, but works fine on jsfiddle, why?

I created some JavaScript code that submits the form out the <form> tag. Here is the code:
<script type="text/javascript">
var myForm = document.forms['myForm'];
var formSubmit = document.getElementById('formSubmit');
formSubmit.onclick = function(){
myForm.submit();
}
</script>
<form name="myForm" action="http://msn.com" method="post">
</form>
<div id="formSubmit"><button>Click me</button></div>
When I try this code on http://jsfiddle.net/HrCxz/ it works fine. But When I add this code in an HTML file and run the page, it doesn't work. What's wrong with the code? Please help me fix this.
In the fiddle your code is run inside an onload handler. This is the default option, but the left-hand panel allows you to change it. If you change it to run in the <head> then the fiddle doesn't work either: http://jsfiddle.net/HrCxz/1/
You need to either add an onload handler of your own, or move your script block to after the elements it tries to manipulate. Script blocks are executed in the order they're found as the browser parses the page top to bottom. JS in any given script block can only manipulate elements that have already been parsed, i.e., ones that appear closer to the beginning of the source, unless you put your code in an event handler called from the onload event (or from document ready for browsers that support it or if you use a library that provides it or otherwise code it yourself).
JSFiddle is using onload event.
Step 1:
Try this by moving your JS below the <form> tag,
<form name="myForm" action="http://msn.com" method="post">
</form>
<div id="formSubmit"><button>Click me</button></div>
<script type="text/javascript">
var myForm = document.forms['myForm'];
var formSubmit = document.getElementById('formSubmit');
formSubmit.onclick = function(){
myForm.submit();
}
</script>
Step 2:
Or you can attach onload event, like this,
<script type='text/javascript'>//<![CDATA[
window.addEvent('load', function() {
var myForm = document.forms['myForm'];
var formSubmit = document.getElementById('formSubmit');
formSubmit.onclick = function(){
myForm.submit();
}
});//]]>
</script>
<form name="myForm" action="http://msn.com" method="post">
</form>
<div id="formSubmit"><button>Click me</button></div>
You are calling the click function on the div element, did you need to do this on the button? var formSubmit = document.getElementById('BUTTONIDHERE');
Your code sample does not work because the JavaScript is being processed before the browser has a chance to load the DOM elements. It is necessary to either place the your JavaScipt snippet just before the closing body tag (so it's processed after your DOM elements are loaded), or to use an 'on load' or 'on ready' event handler to detect when the DOM is loaded and then fire your Javascript.
Here are three examples of how to fire your JavaScript when the DOM elements have loaded:
1)If you're using jQuery, past your Javascript into the $(document).ready() event handler:
$(document).ready(function() {
// Handler for .ready() called.
var myForm = document.forms['myForm'];
var formSubmit = document.getElementById('formSubmit');
formSubmit.onclick = function(){
myForm.submit();
}
});
2) You can use jQuery's alternate syntax for document 'ready':
$(function() {
// Handler for .ready() called.
var myForm = document.forms['myForm'];
var formSubmit = document.getElementById('formSubmit');
formSubmit.onclick = function(){
myForm.submit();
}
});
2) Add your JavaScript to a callback function bound to the window 'load' event - this is also an event handler:
window.addEvent('load', function() {
var myForm = document.forms['myForm'];
var formSubmit = document.getElementById('formSubmit');
formSubmit.onclick = function(){
myForm.submit();
}
})
Cheers!

Passing 'this' as parameter in JavaScript

I have the following code:
HTML:
<label id="copyAddress" class="copyAddress" onclick="CopyAddress(this);">
Copy Address
</label>
JS:
function CopyAddress(copyAddressLink) {
PopulateTarget(copyAddressLink);
}
function PopulateTarget(link) {
var targetGroup = $(link).closest('someClass');
}
In PopulateTarget function 'link' variable is undefined, while in CopyAddress it has values as is should.
What can cause this problem? Is there some restriction for passing parameters in Java Script? How this should behave? If you need more code to post please tell me.
Since you are anyhow using jQuery, why are you using obtrusive Javascript?
Use this instead:
HTML:
<label id="copyAddress" class="copyAddress">Copy Address</label>
Javascript:
$(document).ready(function(){
$('#copyAddress').click(function(){
var targetGroup = $(this).closest('.someClass');
});
});
You're missing a dot on "someClass", it should be ".someClass".
Maybe your code will work after you fix that. However: since you're using jQuery (it seems you are), you should attach the click handler the jQuery way, instead of inline on the HTML. This means:
$(document).ready(function(){
$('#copyAddress').click(CopyAddress);
})
function CopyAddress() {
PopulateTarget(this);
}
function PopulateTarget(link) {
var targetGroup = $(link).closest('someClass');
}
You should not intermix your HTML and JS. You should instead attach your JS handlers programmatically in your JS code:
<!-- note: no onclick in this html -->
<label id="copyAddress" class="copyAddress">Copy Address</label>
// Wait until the page is loaded before starting to look for elements
$(function(){
// Assuming jQuery 1.7
$('#copyAddress').on('click',copyAddress);
// …alternatively, for older jQuery
$('#copyAddress').click(copyAddress);
function copyAddress(evt){
// The 'target' property of the event object passed in is the object
// upon which the event was first triggered.
PopulateTarget(evt.target);
}
});
In the case of the above, you could just use this instead of evt.target, since you bound the event directly on that object. However, this becomes more powerful if you have a variety of items on the page that perform this function. You can attach the event handler once to some parent object, and then ask—during the callback—which element was clicked on. That would look like:
// Watch for any element with a copyAddress class to be clicked on,
// even if they are added after this code has run
$(document.body).on('click','.copyAddress',function(evt){
var target = evt.target;
console.log("You clicked on",target);
});
As it seems you are using jQuery:
You can use jQuery.proxy to bind this to a specific value. It is used like this:
jQuery.proxy(function () { console.log(this); }, this);

Workaround for passing parameter to jQuery ready()

I have some code called on jQuery document.ready() which is used in multiple HTML files. Now the difference is each of these HTMLs uses a different div id.
I know one option is to just check for hardcode div ids inside $(document).ready() . But I wanted to write a generic code which would take the div Ids based on the currrent/calling HTML page?
So is there any way or workaround for passing parameter to jQuery ready() ?
$(document).ready() just wants a function as an argument so you can write a function that takes your ID as an argument and returns a function for $(document).ready(). For example, instead of this:
$(document).ready(function() {
$('#some_id').click(/*...*/);
});
you could do this:
function make_ready(id) {
return function() {
$('#' + id).click(/*...*/);
};
}
$(document).ready(make_ready('some_id'));
Then you could put your make_ready in some common location and use it to build the functions for your $(document).ready() calls.
document ready just takes in an handler function as a parameter.
You can still define a generic code in you document ready function, by storing the current div id for each html.
<input type="hidden" id="current_div" value="div1" />
$(document).ready(function() {
var div_id = $('#current_div').val();
// generic code
});

Categories

Resources