window.scrollTo(...) error: Microsoft JScript runtime error: Object expected - javascript

I know there are a lot of post about this, but i've been looking to do this all day.
What i try to acheive here is to click on a row in a GridView, then bring the page to scroll to that position, like an anchor in html would do.
This, is my link that i'll use to scroll. I call a function in my js file. This is in my GridView.
<asp:LinkButton runat="server" OnClientClick="window.scrollTo(0, GetPosition(this))" CommandName="select" ID="InkSelect" Text="SELECT" />
Then, i call this function in my js file, linked like this, just in case:
<script type="text/javascript" src="~js/monjs.js"></script>
In monjs.js, here is the function:
function GetPosition(element) {
var top = 0;
var e = document.getElementById(element);
while (e.offsetParent != undefined && e.offsetParent != null) {
top += e.offsetTop + (e.clientTop != null ? e.clientTop : 0);
e = e.offsetParent;
}
return top;}
And Visual studio is highlighting this line:
...... <a onclick="window.scrollTo(0, GetPosition(this));" .....
I tried many other way to do this, registering a script in the vb file, hardcoding window.scrollTo(0,100) in the onclick attribute, i'm out of ideas.
I tried row.focus, don't mention this one.
Thanks.

<a onclick="window.scrollTo(0, GetPosition(this));"
^
|
An Object
function GetPosition(element) {
var top = 0;
var e = document.getElementById(element);
^
|
Expecting a string
You are passing in an object and acting like it is a string.
var e = document.getElementById(element);
needs to be
var e = element;
If your function needs to handle both an object or a string, you can either pass in this.id with the onclick handler
OnClientClick="window.scrollTo(0, GetPosition(this.id))"
or do a typeof check.
var e = typpeof element === "string" ? document.getElementById(element) : element;

ok I managed to do something. AFter many many tries...
i used this in my aspx file:
<asp:LinkButton runat="server" OnClientClick="return Move(this);" CommandName="select" ID="_row" Text="SELECT" />
In my aspx.vb file, i used this in my page load function:
Dim myScriptName As String = "MovePageScript"
If (Not ClientScript.IsClientScriptBlockRegistered(Page.GetType(), myScriptName)) Then
Dim myScript As New StringBuilder()
myScript.Append("<script type=""text/javascript""> function Move(element) {")
myScript.Append("var top = 0;")
myScript.Append("var e = typeof element === 'string' ? document.getElementById(element) : element;")
myScript.Append("while (e.offsetParent != undefined && e.offsetParent != null) {")
myScript.Append("top += e.offsetTop + (e.clientTop != null ? e.clientTop : 0);")
myScript.Append("e = e.offsetParent; }")
myScript.Append("window.scrollTo(0, top);")
myScript.Append("return false;")
myScript.Append("} </script>")
ClientScript.RegisterClientScriptBlock(Page.GetType(), myScriptName, myScript.ToString(), False)
End If
And used this in my web.config file:
<pages maintainScrollPositionOnPostBack="true">
It cancels the selection of the row but at least it works... I'll have to check now if I can get this to work with Telerik's Ragrid XD

Related

Webforms - Expand Dynamically created TreeNodes on Title Click

So, I've been searching the interwebs for days now and still haven't got any answers. So, here I am :). I've got a TreeView that I am populating with XML from a Sitemap (Web.sitemap) and is acting as a menu on a website. I want to be able to have the menu nodes toggle on clicking its title. That way, I can get rid of the +- checkboxes to make it look neater. So far, I can get them to toggle. But, only after I have pre-populated the node by first clicking the checkbox associated with it. Has anyone got any ideas how I can go about this?
This is my TreeView div
<div class="menu" style="width: auto; float:left; margin-top: 20px;">
<asp:SiteMapDataSource ID="smdsMenu" runat="server" SiteMapProvider="MainMenuSiteMapProvider"/>
<asp:TreeView ID="tvMenu" runat="server" DataSourceID="smdsMenu" ExpandDepth="1" ImageSet="Arrows" margin-top="0px">
<LeafNodeStyle BackColor="Transparent" CssClass="tvMenuL2" />
<HoverNodeStyle Font-Bold="True" BackColor="#1e8acb" ForeColor="Black" Font-Underline="False" />
<ParentNodeStyle BackColor="#6E7E94" CssClass="tvMenuL1" Font-Bold="false" />
<RootNodeStyle BackColor="#2c4566" CssClass="tvMenuL0" />
<SelectedNodeStyle Font-Underline="True" ForeColor="#1e8acb" HorizontalPadding="0px" VerticalPadding="0px" />
</asp:TreeView>
</div>
This is my page loaded handler
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
tvMenu.Attributes.Add("onmousedown", "return OnTreeMouseClick(event)");
}
}
And this is my Javascript
<script lang="javascript" type="text/javascript">
function OnTreeMouseClick(evt) {
var src = window.event != window.undefined ? window.event.srcElement : evt.target;
var nodeClick = src.tagName.toLowerCase() == "span";
if (nodeClick) {
// Change tvMenu to ID of TreeView
var tvDataName = "tvMenu" + "_Data";
var tv = document.getElementById("tvMenu");
var tvData = window[tv.id + "_Data"];
var spanID = src.id;
var selectNode = document.getElementById(spanID);
var start = spanID.indexOf("tvMenu" + "t");
var length = 7; // length of TreeView ID + 1 for the letter t
var spanIndex = parseInt(spanID.substring(start + length));
if (spanIndex != NaN) {
var spanNode = "tvMenu" + "n" + spanIndex.toString();
var spanChildren = spanNode + "Nodes";
// Call toggle Node script
TreeView_ToggleNode(
tvData, // data
spanIndex, // index
document.getElementById(spanNode), // node
'', // lineType
document.getElementById(spanChildren) // children
);
}
}
return false;
}
</script>
I know that the node isn't being populated by my Javascript. But, I don't know how to use TreeView_PopulateNode without a datapath like the checkboxes do here.
<a id="tvMenun1" href="javascript:TreeView_PopulateNode(tvMenu_Data,1,document.getElementById('tvMenun1'),document.getElementById('tvMenut1'),null,' ','Overview','Home\\Overview','t','776cfb0b-fc9e-4ff1-8487-829a1162916d','tf')">
<img src="/WebResource.axd?d=8Ig4CKxOyXBIduEK8UJR2BXEYzKQWBLDFGfU4Y_g95G2TuDmM3zzGZE7CoW0qe4bVdRWK9Vp8x2MnX9eQ6Z66hsxeeTNg2xk5-CpNTJuS3Q1&t=636043022594211026" alt="Expand Overview" style="border-width:0;">
</a>
This is the generated HTML from my code
<span class="tvMenu_0 tvMenuL1 tvMenu_3" title="Overview" id="tvMenut1" style="border-style:none;font-size:1em;">Overview</span>
Any help with this would be GREATLY appreciated. Thanks.

JavaScript runtime error: Unable to get property 'value' of undefined or null reference

I wrote a javascript code to display the next date of a specific calendar
My Function
function verificaDataReferencia(mensagem)
{
if(document.getElementById("txtDataReferencia1Hidden") == null || document.getElementById("txtDataReferencia2Hidden") == null || document.getElementById("ddlDataPub") == null || document.getElementById("txtDataRefInfo") == null)
var objtxtDataReferencia1Hidden = document.getElementById("txtDataReferencia1Hidden").value;
var objtxtDataReferencia2Hidden = document.getElementById("txtDataReferencia2Hidden").value;
> Breakpoint var objtxtDataArquivo = document.getElementById("ddlDataPub").value;
var mensagem = document.getElementById("txtDataRefInfo").value;
if((objtxtDataReferencia1Hidden == objtxtDataArquivo) || (objtxtDataReferencia2Hidden == objtxtDataArquivo))
{
var x = alert(mensagem);
return x;
}
}
Html
<asp:TextBox style="Z-INDEX: 112; POSITION: absolute; TOP: 9px; LEFT: 572px" id="txtDataReferencia1Hidden"
runat="server" CssClass="inputLabel" Width="15" Height="15px"></asp:TextBox>
<asp:TextBox style="Z-INDEX: 113; POSITION: absolute; TOP: 9px; LEFT: 606px" id="txtDataReferencia2Hidden"
runat="server" CssClass="inputLabel" Width="14" Height="14px"></asp:TextBox>
the problem is that the page is running well in chrome but when i run my application in IE it throw an error
0x800a138f - JavaScript runtime error: Unable to get property 'value'
of undefined or null reference
please help me to overcome from this problem.
private void Page_Load(object sender, System.EventArgs e)
{
if(! IsPostBack)
{
txtNomePortugues.SetFocus();
BO.Pasta pasta = new BO.Pasta(CodPasta);
if (CodigoArquivo == 0 && !IsJustificativa && pasta.EnviaEmail)
btnGravar.Attributes.Add("onclick", "verificaDataReferencia(); confirmaEnvioEmail('" + GetString("Mensagem_Confirmacao_Alerta_Arquivos") + "');");
else
btnGravar.Attributes.Add("onclick", "verificaDataReferencia();");
The issue is here:
var mensagem = document.getElementById("txtDataRefInfo").value;
var objtxtDataReferencia1Hidden = document.getElementById("txtDataReferencia1Hidden").value;
var objtxtDataReferencia2Hidden = document.getElementById("txtDataReferencia2Hidden").value;
Reason being txtDataRefInfo, txtDataReferencia1Hidden, txtDataReferencia2Hidden is a server side control and not the client side. Try this:
var objtxtDataReferencia1Hidden = document.getElementById('<%=txtDataReferencia1Hidden.ClientID%>');
var objtxtDataReferencia2Hidden = document.getElementById('<%=txtDataReferencia2Hidden.ClientID%>');
var mensagem = document.getElementById('<%=txtDataRefInfo.ClientID%>');
You need to set the ClientIDMode attribute on the control to:
ClientIDMode="Static"
This works with .Net 4.0 and upwards
comment this line for IE it may be ok :
// > Breakpoint var objtxtDataArquivo = document.getElementById("ddlDataPub").value;
The problem is that txtDataReferencia1Hidden and txtDataReferencia2Hidden are the server name of controls, not the client name (look the source of page from the browser).
Use this:
var objtxtDataReferencia1Hidden = document.getElementById('<%=txtDataReferencia1Hidden.ClientID%>');
var objtxtDataReferencia2Hidden = document.getElementById('<%=txtDataReferencia2Hidden.ClientID%>');
there is missing an action behind this if(document.getElementById("txtDataReferencia1Hidden") == null || document.getElementById("txtDataReferencia2Hidden") == null || document.getElementById("ddlDataPub") == null || document.getElementById("txtDataRefInfo") == null)
I would expect you write the line in this way (do not forget the negation using !):
if(!document.getElementById("txtDataReferencia1Hidden") || !document.getElementById("txtDataReferencia2Hidden") || !document.getElementById("ddlDataPub") || !document.getElementById("txtDataRefInfo")) return;
You are checking to see if the elements are null in your if statement -
if(document.getElementById("txtDataReferencia1Hidden") == null || document.getElementById("txtDataReferencia2Hidden") == null || document.getElementById("ddlDataPub") == null || document.getElementById("txtDataRefInfo") == null)
But even if they are null you are trying to get the value. Ex:
var mensagem = document.getElementById("txtDataRefInfo").value;
So if "txtDataRefInfo" is null the statement will return true and try to get the value anyways. Hence the undefined or null reference.

My JavaScript works as inline code but not as an include file. Any ideas why and how to fix it?

I have this form:
<form id="searchForm" class="search_field" method="get" action="">
...
...
</form>
Then this javascript:
var form = document.getElementById("searchForm");
form.doSearch1.onclick = searchPage;
form.doSearch2.onclick = searchPage;
form.showFeatureChoices.onclick = function( )
{
var cbs = form.featType;
for ( var c = 0; c < cbs.length; ++c )
{
cbs[c].checked = false;
}
document.getElementById("featuresDiv").style.display = "block";
}
function searchPage()
{
var form = document.getElementById("searchForm");
var searchText = form.searchBox.value.replace(/-/g,"");
form.searchBox.value = searchText;
if (searchText != "")
{
// collect features to search for:
var features = [ ];
var featTypes = form.featType;
for ( var f = 0; f < featTypes.length; ++f )
{
if ( featTypes[f].checked ) features.push( featTypes[f].value );
}
featureList = "'" + features.join("','") + "'";
searchMsg("Searching for '" + searchText + "' ...");
// startStatusUpdate(1000);
// findTask.execute(findParams, showResults);
var accord = dijit.byId("accordianContainer");
var resultsPane = dijit.byId("resultsPane");
accord.selectChild(resultsPane,true);
doSearch( searchText, featureList );
}
else
{
searchMsg("No search criteria entered, enter search text");
}
}
If I embed this code in same file as the <form..., it works fine.
If however, I have this js in another file and use as include file:
<script type="text/javascript" src="Views/JS/main.js"></script>
I get following error: "Object required" and it points to these lines:
form.doSearch1.onclick = searchPage;
form.doSearch2.onclick = searchPage;
Any ideas how to fix this?
Just a bit more info, the js code shown above in a file called main.js which is in a folder called JS and Js is in a folder called Views. The
Thanks a lot in advance
When you include the JavaScript code in the same page, where is it in relation to the form element? (Before or after it?) How about when you reference the external JavaScript file?
I'm guessing that in the former case the code is at the end of the file, while in the latter case the script reference tag is at the beginning?
If that's true then what's happening is this code is being executed before the DOM is ready:
var form = document.getElementById("searchForm");
form.doSearch1.onclick = searchPage;
form.doSearch2.onclick = searchPage;
If the form tag hasn't been rendered to the DOM yet then that first line won't find anything, and the subsequent lines will fail as a result. One approach is to put the script reference tags at the end, but that seems like a hack to me. Sometimes there are good reasons to keep them in the page header, not the least of which is cleaner management of the code in many cases. There are other ways to hold off on executing JavaScript code until the DOM is ready.

Formatting Razor ViewData in Javascript

So I have been looking through relevant questions and I can't figure out exactly why my script tag is malformed.
<script language="javascript" type="text/javascript">
var showME = false;
var showSuffix = "";
#if (ViewData["showME"] != null && ViewData["showSuffix"] != null)
{
<text>
showME = #(Convert.ToBoolean(ViewData["showME"]) ? "true" : "false");
showSuffix = '#Html.Raw(Json.Encode(ViewData["showSuffix "]))';
</text>
}
</script>
EDIT!
The answer below is correct but I tracked down the malformed part to this line.
var videoHelpUrl = #(Url.Action("Index", "Help", new { Id = 46 }));
Try this:
<script language="javascript" type="text/javascript">
var videoHelpUrl = '#Url.Action("Index", "Help", new { Id = 46 })';
console.log(videoHelpUrl);
</script>
console.log will output the Url.
Note: Always keep in mind that everything following # in a Razor view will be processed by the Razor engine. This is why you can surround #Url.Action(...) with quotes. It will be processed first by Razor engine and then by Javascript when it is executed.
If you try using double {{ }} as in;
#{
if (ViewData["showME"] != null && ViewData["showSuffix"] != null)
{
<text>
showME = #(Convert.ToBoolean(ViewData["showME"]) ? "true" : "false");
showSuffix = '#Html.Raw(Json.Encode(ViewData["showSuffix "]))';
</text>
}
}
See if that works.

Confirm Delete pop up with Record Count

General Info:
Aspx page holds an Ascx User control. Inside the User control, the Repeater is contained inside a View, contained inside a Multiview.
Asp.Net 2.0 framework / C#
Details:
I have a repeater (inside an ascx user control) that shows records, and the first column is a checkbox. If checked, that row will be deleted.
OUtside the repeater, I have a button that will deleted all rows that are checked.
Everything works fine, but have been asked to add a pop up "confirm delete" message that includes the number of records that will be deleted if the user clicks "Ok" on the pop up.
Something like:
"You are about to delete 8 records".
Currently my button looks like this:
<asp:Button ID="btnDeleteAllRecords" runat="server" Text="Delete all Checked Records" Onclick="btnDeleteAllRecords_Click" OnClientClick="javascript:GetCbCount();" />
I have this javascript code block:
<script type="text/javascript">
function GetCbCount()
{
var cb = document.getElementById("rptrVoicemail").getElementsByTageName("input");
var cbCount;
for(i = 0; i < cb.lenght; i++)
{
if(cb[i].type == "checkbox")
{
if(cb[i].checked)
{
cbCount = cbCount + 1;
}
}
}
return confirm('You are about to delete' + cbCount + 'records.');
}
</script>
When I click my button I'm getting:
Error: 'document.getElementById(...)' is null or not an object
on this line:
var cb = document.getElementById("rptrVoicemail").getElementsByTageName("input");
Why is the JS not seeing my repeater? Is it because it's buried inside a MultiView? How can the JS be corrected so that the pop up will show the record count in the message?
UPDATE:
I changed the script to:
function GetCbCount(){
var inpt = document.getElementById("vmDiv");
var checkboxes = inpt.getElementsByTagName("input");
var cbCount;
for(i = 0; i<checkboxes.lenght;i++){
if (checkboxes[i].type == "checkbox" && checkboxes[i].checked){
cbCount = cbCount + 1;
}
}
return confirm('You are about to delete ' + cbCount + ' Voicemails.');
}
This should work:
document.getElementById('<%= rptrVoicemail.ClientID %>').getElementsByTageName("input");
Another approach is this little script that returns the ClientID. You could add it even to an included JS-file.
function GetClientId(strid)
{
var count=document.forms[ 0 ].length ;
var i = 0 ;
var eleName;
for (i = 0 ; i < count ; i++ )
{
eleName = document.forms [ 0 ].elements[ i ].id;
pos=eleName.indexOf( strid ) ;
if(pos >= 0) break;
}
return eleName;
}
Found here.
If you are using a master page or nesting controls (inside ascx, view, etc.) the framework will change the IDs that are rendered with elements.
If you do a "View Source" or use FireBug, you might see that rptrVoicemail became something like ctl00_ContentPlaceHolder1_someUserControl_ctl00_multiViewID_ctl28_rptrVoicemail.
You can use getElementById('<%= rptrVoicemail.ClientID %>') to get at the ID of the element as it would be rendered on the client.
Edit: To help debug, do something like this... you get the point.
var rptr = document.getElementById('<%= rptrVoicemail.ClientID %>');
rptr.borderColor = 'pink'; // draw a border to check it's the right element

Categories