Why are elements null in jquery, yet exist with document.getelementbyid() - asp.net

I"m trying to attached some jquery to checkboxes in a gridview, using document.ready:
$(document).ready(function()
{
var chkBox= document.getElementById("gvTimeSheet_ctl01_chkAll1");
//I can alert chkBox.id, element exists
var name = $("input[name='gvTimeSheet$ctl01$chkAll1']");
//Here, when I alert the id, I get a null
var ID = $("#gvTimeSheet_ctl01_chkAll1");
//Here, when I alert the id, I get a null
var withClass = $(".chkAll1Class");
//Here, when I alert the id, I get a null
var withClass2 = $(".Bill1");
//Here, when I alert the id, I get a null
//This line causes the browswer to crash and gives me the following error
//Microsoft JScript runtime error: 'null' is null or not an object
$("#gvTimeSheet_ctl01_chkAll1").click(function()
{
var checked_status = this.checked;
$("input[class=Bill1]").each(function()
{
this.checked = checked_status;
});
});
});*/
So, why are any attempts at finding an object null in jquery, yet exist in regular javascript within the same method? What am I missing here. I have the jquery js files brought in in a script tag directly above this method. I just can't seem to find any objects on this page with jquery. On other pages, I can.

Objects that result from a jQuery selector are actually wrappers around a DOM object, so you don't access it the same as a DOM object.
If you're alerting just "name.id", from your first example above, there won't be any such property on the jQuery wrapper. Try alerting your ID as follows:
alert(name.attr("id"));

var val = $("input:radio[name$='rdoselect']:checked").val();
if (val == 1) {
$('[id$=divDate]').attr('disabled', true);
}else {
$('[id$=divDate]').attr('disabled', false);
}

var ID = $("#gvTimeSheet_ctl01_chkAll1");
This returns a jQuery object, not an ID. ID.id would also be undefined. To get the ID, you need:
var ID = $("#gvTimeSheet_ctl01_chkAll1").attr("id");

Does the page you're adding this code to already include the Prototype JavaScript library?
jQuery's "$" method never returns null, so this shouldn't be a problem:
// This line causes the browswer to crash and gives me the following error
// Microsoft JScript runtime error: 'null' is null or not an object
$("#gvTimeSheet_ctl01_chkAll1").click(function() { .... });
All the comments about needing to use .attr('id') still stand (though I prefer $('#whatever')[0].id myself.)

Related

Method/property does not exist

I'm trying to convert the JavaScript code
if (window.ifEdit.editIsDirty()) { }
into Typescript. I got as far as the following
var iframe = document.getElementById('ifEdit');
var iWindow = <HTMLIFrameElement>(iframe).contentWindow;
var _editIsDirty = iWindow.editIsDirty();
I get the red squiggles under 'contentWindow' and 'editIsDirty' saying the method/property does not exist on the type. The .ts doesn't compile to a .js file.
I have searched, but did not manage to find a solution.
For the contentWindow part, the problem with your code is that the casting is done wrong, should be:
var iWindow = (<HTMLIFrameElement> iframe).contentWindow;
As for the editIsDirty, it's not a standard property of Window.
If it's something which is added in the environment in which you are running your javascript then you need to declare it like so:
interface IfEdit {
editIsDirty(): boolean;
}
interface Window {
ifEdit: IfEdit;
}
var iframe = document.getElementById("ifEdit");
var iWindow = (<HTMLIFrameElement> iframe).contentWindow;
var _editIsDirty = iWindow.ifEdit.editIsDirty();
Use the code in Playground.
Casting will be through as. this assures .contentWindow is accessible.
const iframe = document.getElementById('embed-player') as HTMLIFrameElement;
if (!iframe) {
// Handle case where iframe not found
return;
}
const contentWindow = iframe.contentWindow;
// Note: You will likely need more null handling for contentWindow's properties
console.log(contentWindow?.document);

How to create a template helper after a template has been rendered in Meteor?

Template.prices.rendered = function() {
OrderFormContent = new Meteor.Collection(null);
var orderSubmission = function() {
//code that inserts stuff into the OrderFormContent collection
//the key **sqft** is assigned the value of **4000** };
orderSubmission();
};
Template.prices.helpers({
sqft: function() {
return OrderFormContent.findOne().sqft;
}
});
The code above doesn't load. Meteor tries to create the helper of {{sqft}} but can't because OrderFormContent does not get defined until after the page renders. It appears that Meteor tries to define the helper before the page is even rendered.
But I need to define this helper. And I need to have it defined only after the template is rendered (not created).
I cannot just nest Template.prices.helpers inside Template.prices.rendered.
Clarification:
If I comment out the Template.prices.helpers code the page will load. If I then run OrderFormContent.findOne().sqft manually in the console a value of 4000 is returned.
When I un-comment the Template.prices.helpers code the page fails to load and I get a Exception from Deps recompute function: ReferenceError: OrderFormContent is not defined error.
1) Defining global variables inside a function is against good practices of Javascript, and is invalid in strict mode (and thus will be invalid in the future when strict mode becomes a standard).
2) You can easily achieve your goal without defining helper after rendering. In fact, the error is not thrown when the helper is created, but when it's called. To fix this problem it's enough to include a simple check.
var OrderFormContent = null;
var orderFormContentDep = new Deps.Dependency();
Template.prices.rendered = function() {
OrderFormContent = new Meteor.Collection(null);
...
orderFormContentDep.changed();
};
Template.prices.helpers({
sqft: function() {
orderFormContentDep.depend();
if(!OrderFormContent) return null;
var item = OrderFormContent.findOne();
if(!item) return null;
return item.sqft;
});
});
When I got that error I moved the template helper to the client js and it went away. Only that didn't work for my purposes because it executed too often. So, I put it into an Iron Router route method to be rendered.

google earth plugin does not respond to appendchild and removechild

I am dynamically adding kml files to google earth. For this, I have written javascript functions to add a kml and to remove a kml. These functions work fine for the first time for a kml. But if called again they do not respond. This happens for each kml that I try to add or remove. If I keep the page on browser for some time, then these functions again respond once and again become unresponsive.
function add(id, fileurl)
{
var link = ge.createLink('');
var href= fileurl;
link.setHref(href);
var networkLink = ge.createNetworkLink("'" + id + "'");
networkLink.set(link, true, true);
ge.getFeatures().appendChild(networkLink);
}
function remove(id)
{
for(var i=0; i<ge.getFeatures().getChildNodes().getLength(); i++)
{
if(ge.getFeatures().getChildNodes().item(i).getId() == id || ge.getFeatures().getChildNodes().item(i).getId() == "'" + id + "'")
{
id = ge.getFeatures().getChildNodes().item(i).getId();
ge.getFeatures().removeChild(ge.getElementById(id));
break;
}
}
The issue is that you can't re-add a feature using an ID that you have already used until all references to it have been released. This is usually done by the internal garbage collector - but you can also force it by calling release() on the object you are deleting. This ...
Permanently deletes an object, allowing its ID to be reused.
Attempting to access the object once it is released will result in an
error.
Also when an object is created with the API the object does not have a base address. In this case, the object can be returned by passing only its ID to getElementById(). This can then be used to remove the feature.
e.g.
function remove(id) {
ge.getElementById(id).release();
}
Really though I would look to avoid using IDs altogether and would simply keep a variable that points to the feature, then use that to remove. e.g.
function add(fileurl) {
var link = ge.createLink(''); //no id
link.setHref(fileurl);
var networkLink = ge.createNetworkLink(''); //no id
networkLink.set(link, true, true);
ge.getFeatures().appendChild(networkLink);
return networkLink;
}
var link1 = add("http://yoursite.com/file.kml");
var link2 = add("http://yoursite.com/file2.kml"); // etc...
// then to remove, simply...
link1.release();
link2.release();
OK. So I figured out that if you remove an object from GE, and then try to add another object with the same id, GE complains and won't create the object - unless some time (approx. 30 seconds in my case) has passed. This time actually is required by JavaScript to garbage collect the object.
Setting the object to null doesn't give immediate result but may help Garbage Collector.
Also release() method offered by GE does not help.

ASP.Net Drop Down List not passing a value when updated using ajax

I have some jQuery that I'm using to open a pop-up window where a new consignor can be added to the database. The original window has a dropdownlist of all of the current consignors. When you add the new consignor in the pop-up window, that window closes and the original window then reloads the dropdownlist's data and selects the one just created.
All of that works perfectly. My issue is that when you fill out the rest of the form and submit it, it passes an empty string instead of the value of the selected item. Is this because it's an ASP.Net script? I don't know a lot about ASP.Net, but I've never had this issue with PHP. Can someone explain how I would go about refreshing the dropdownlist without refreshing the entire page and still get the list to pass it's value upon form submission?
My javascript code on the page that opens the pop-up and reloads the list is below:
function openConsignorAdd() {
var url;
url = "/admin/consignor/csAdd.aspx";
window.open(url, "WizardWindow", "width=400,height=500,resizable=yes,scrollbars=yes");
}
function loadNewAdded(fn, cs_txt_id) {
// var pagePath = window.location.pathname;
var pagePath = "/admin/getNewList.asp";
var paramList = "data=";
//Call the page method
$.ajax({
type: "POST",
url: pagePath + "?type=" + fn + "&cs_txt_id=" + cs_txt_id,
data: paramList,
success: function (data) {
//create jquery object from the response html
var $response = $(data);
//query the jq object for the values
var results = $response.filter('select#results').html();
if (fn == "consignor") {
$("select#<%=itemConsigner.ClientID%>").html(results);
} else if (fn == "cdr") {
$("select#<%=itemCDR.ClientID%>").html(results);
}
},
error: function () {
alert("Failed To Refresh!\n\nYou must manually refresh the page.");
}
});
}
My javascript code on the pop-up page to refresh the list is:
function refreshOpener(cs_txt_id) {
window.opener.loadNewAdded("consignor", cs_txt_id);
}
Those both work. And to get the value of my dropdownlist, I simply use:
if (itemConsigner.SelectedValue.ToString() != string.Empty)
{
itemCsTxtId = itemConsigner.SelectedValue.ToString();
}
with my dropdownlist being:
<asp:DropDownList ID="itemConsigner" runat="server" TabIndex="1"></asp:DropDownList>
If you need more info, just let me know. Any help is appreciated.
It seems that the issue is that since I am making the change after the page loads, the server does not see my new addition as one of the original options so ignores it completely. This is good so that people cannot just edit your forms I guess. So what I did was instead of getting the value of itemConsigner.SelectedValue, I grab the value for Request.Form["itemConsigner"] with the long ID. That way it doesn't validate that my submitted option was an original option.
Might be a silly observation but without all the code I'm not sure if this is the case. Are you just updating the original list with the id in the select options. The value needs to be populated as well for each. That could be why you are getting an empty value on after form submission.

Flex DropdownList CreationComplete error

I have a DropdownList that shows a list of providers & the Provider associated with that Patient must be selected.
The Dropdown list:
<s:DropDownList id="providerList"
width="80%"
fontSize="12"
fontWeight="bold"
selectionColor="white"
creationComplete="providerList_creationCompleteHandler(event)"
dataProvider="{model.practiceProviderList.practiceProviders}"/>
where practiceProviders is an ArrayCollection
The CreationCompleteHandler function:
protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
var firstN:String;
var lastN:String;
var providerObj:Provider = new Provider();
if (model.patientDetails.patientDetail.patientProviders != null && model.patientDetails.patientDetail.patientProviders.length > 0)
{
firstN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.firstName;
lastN = patientDetailsModel.patientDetails.patientDetail.patientProviders.getItemAt(0).provider.providerName.lastName;
for (var count:int = 0; count < patientDetailsModel.practiceProviderList.practiceProviders.length; ++count)
{
providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;
if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
{
this.providerList.selectedIndex = count;
}
}
}
}
The issue is when I go to this page the first time, the error is :
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.newwavetechnologies.modules::demographics/providerList_creationCompleteHandler()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:166]
at com.newwavetechnologies.modules::demographics/__providerList_creationComplete()[C:\harish\flex\apps\workspace\dataCollection-flexUserInterface\src\com\newwavetechnologies\modules\demographics.mxml:359]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:12266]
at mx.core::UIComponent/set initialized()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\UIComponent.as:1577]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:759]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1072]
where line 166 is:
if (providerObj.providerName.firstName == firstN && providerObj.providerName.lastName == lastN)
The providerObj is null the first time. But when hit back and come to the same page again, everything works fine and 1 of the providers in the list is selected correctly.
Probably I think the first time, the creationComplete handler method is called before the List is populated. The 2nd time when the call is made, the list is populated and the handler works fine. It would be great if someone can help me in this regard on how to go about this.
Thanks
Harish
It's hard to tell what's going on here, but the problem lies here:
providerObj = patientDetailsModel.practiceProviderList.practiceProviders.getItemAt(count, 0).provider as Provider;
There's a tonne of places in that line that Null pointer exceptions could occur.
Most likely - the practiceProvider returned at position count doesn't have a provider set. We can't see how this value is populated, but given this code works later, I'd say you've got a race condition happening - the data is being accessed before it's been set.
At very least, you should add a guardClause for this:
var practiceProviders:ArrayCollection = patientDetailsModel.practiceProviderList.practiceProviders;
for (var count:int = 0; count < practiceProviders.length; ++count)
{
providerObj = practiceProviders.getItemAt(count, 0).provider as Provider;
if (!providerObj)
continue;
// etc
}
The race condition is a little trickier, given the asyncronous natoure of flex server calls. (I'm assuming that you're loading the data from a remote server).
There's two approaches to solve this - either
defer execution of this method until the data has loaded - you could do this by adding an eventListener to the ResultEvent of the RemoteService
or
Don't worry about it the first time around, but re-execute the method whenever the data changes.
eg:
protected function providerList_creationCompleteHandler(event:FlexEvent):void
{
dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE,onCollectionChange,false,0,true);
updateProviders();
// Rest of existing creationComplete code moved to updateProviders();
}
private function updateProviders()
{
// Code from existing creationComplete handler goes here
}
private function onCollectionChange(event:CollectionEvent):void
{
updateProviders();
}

Resources