Server side variables in javascript - javascript

I suppose this isn't a huge deal, since there are other way around this issue, but I'm really curious as to the answer, since I thought this was possible to do.
I have a public property that returns a boolean in my code behind. I'd like to access this server variable in my javascript validation function, but so far, not quite getting it.
Public Property editMode() As Boolean
Get
If Cache("editMode") IsNot Nothing Then
Return (DirectCast(Cache("editMode"), Boolean))
Else
Return False
End If
End Get
Set(ByVal value As Boolean)
Cache("editMode") = value
End Set
End Property
function validateEdit()
{
alert("editMode value is " + '<%#editMode()%>');
if ('<%#editMode()%>'.toString() == "True")
{
alert("You are currently in edit mode. Please save or cancel changes.");
return false;
}
return true;
}
I've tried a bunch of variations on this, but it's always False. In the current code the alert returns "editMode value is False"
When I use:
if ('<%#editMode()%>') ...
Then it's still always False, but it goes into the if condition, so the behaviour is as if it were always true.
One other thing to mention is that most javascript/server tag stuff I find says to use <%=editMode %>, but I can't do this because every time I use the = instead of the # I get an exception:
"The Controls collection cannot be
modified because the control contains
code blocks (i.e. <% ... %>)."
So I solved this by using # and saying
Page.Header.DataBind()
Page.Form.DataBind()
In the page load event handler.
Any ideas? Thank you in advance. :)
(Also, I usually use C#, so I might have unknowingly done something goofy in the VB part, so feel free to point that out too)

First, try changing to this:
<%=editMode()%>
Not sure if that's it, but it can't hurt. Second, are you in edit mode when you first load the page? That code is going to run server side and return the result to the user.
On the user's page, they will see:
function validateEdit()
{
alert("editMode value is " + 'False');
if ('False'.toString() == "True")
{
alert("You are currently in edit mode. Please save or cancel changes.");
return false;
}
return true;
}
Again, not sure if that is it, but it is important to understand that javascript is not making any calls to the server.

This helped me fix the error.
"The Controls collection cannot be modified because the control contains code blocks"
Moving the javascript function out of the head and into the body fixes the problem. Seems to be a few things that could cause this issue, but in my case, the most likely culprit is the AjaxToolKit.

One more thing.
You do realize you are converting a string to another string with
'<%#editMode()%>'.toString()
Right?
I think what you want is this
if ('<% =editMode.toString() %>'= 'True')...
or Better yet
if (<% =editMode.toString().ToLower() %>)...

Related

how to make sure I dont get exception error or any kind of error in React that stop execution or crashes the app

When developing React app should we check every property if exists to make sure our app does not crash? I currently have for ex something like below:
<h3>{block && block.box && block.box.title}</h3>
but I wonder if I should do it like this:
<h3>{block && block.box && block.box.title && block.box.title}</h3>
to make sure block.box.title exists before accessing it!
Any idea how can i handle these things in javascript in general, this approach seems kinda verbose to me.
UPDATE, should this check be enough:
<h3>{block.box.title && block.box.title}</h3>
In this example, I think it's safe to assume that block exists, otherwise your code is probally incorrectly written, so that check isn't needed.
Then, the double title makes no sense. The syntax you're using (and most people) is a bit of a cheat, it effectivly does this:
isset(block) && isset(block.box) && echo(block.box.title)===true
This makes use of the fact that a string is considered true and that javascript parses from left to right.
It evaluates/runs the 1st part: run the ISSET, continue the checks if that's true
It evaluates/runs the 2nd part: run the ISSET, continue the checks if that's true
...
It evaluates/runs the last part: Echo the output, continue the checks if it's true.
At the last point, it has already output the string, then it evaluates the outcome. If the string hasn't been output (it's empty or it doesnt exists) that will return false.
Response to your update: No that wont work. It will try to access the title property of null if box doesn't exist, which results in an error,
New js feature here:
<h3>{block?.box?.title}</h3>

Delayed response from jQuery (with some other odd artefacts)

I'm getting a mind-boggling response from jQuery that I'm hoping someone can help me with. I have a simple problem ... I'm setting the "value" of a HTML form's hidden field (aka, <input type='hidden'> when the form loads. I have a form with three hidden fields and two are working just fine. The third ... well here's the problem:
Once the form has completed loading (and yes it has loaded and is visible ... as indirect proof the previous two hidden fields have loaded and successfully been set by jQuery), I run the following code (just showing relevant snippet as this final field is a date set to "today"):
case "today":
SetFieldValue (targetElement , Date.today().toString("yyyy-MM-dd HH:mm:ss") );
console.log ('Setting ' + jQuery(targetElement).attr('id') + ' to "today": ' + Date.today().toString("yyyy-MM-dd HH:mm:ss") );
break;
The SetFieldValue is a little function I wrote to allow setting DOM elements regardless of what type it was. The code is follows:
function SetFieldValue ( domObject, value ) {
// as a safety function, check if a string representation of the domObject was passed in and convert it to a jQuery object if it was
if ( jQuery.type(domObject) === "string") {
domObject = jQuery(domObject);
}
if ( jQuery.inArray (domObject.prop('tagName').toLowerCase(),['input' , 'select' , 'textarea']) >= 0 ) {
console.log ("setting to value attribute: " + value);
domObject.attr('value',value);
console.log ("now set to: " + domObject.attr('value') + "(" + domObject.attr('id') + ")" );
} else {
console.log ("setting to html attribute");
domObject.html( value );
}
return domObject;
}
Please note the console.log messages as this is important in understanding the craziness of the problem. When I run this, here's what I get on the console:
Now I set a breakpoint at the last line of the "today" case statement (aka, on the "break;" line). Based on the console messages all is well. It appears the DOM element #activity-start_time has been set. Well here's where it gets weird.
The first thing I do is test the reference to "targetElement" and the first thing the debugger console give me is an empty array:
What? That's pretty odd. While I'm pondering that a few seconds pass and all of sudden it resolves itself to what I'd expect (I don't retype it into the console it simply changes from the empty set to what you see below):
Now that the targetElement is exactly as I'd expect I do a simple check with jQuery that the DOM element of #activity-start_time is reporting the same value. You can see the result above. It's precisely the same as targetElement except it HAS NOT got a value. What?!?
I'm at a complete loss. Any help would be greatly appreciated.
Ken
p.s. I will note that other people have suggested using .prop instead of .attr both seem to behave precisely the same.
I know I didn't provide enough context for people to really dig into this problem but I have in the end solved it. What was the issue? It was silly really ... isn't always? Anyway it was just a case of the DOM element in questions 'id' not beging unique. Grrr. It's always the obvious things that you then go onto overlook that get you in trouble.
Anyway, thanks for your patience and help.

Whats happening? One day its OK, the next day its 'undefined'?

I am writing a greasemonkey script. Recently i had this same problem twice and i have no idea why is this happening.
function colli(){
.....
var oPriorityMass = bynID('massadderPriority');//my own document.getElementById() function
var aPriorities = [];
if (oPriorityMass) {
for (var cEntry=0; cEntry < oPriorityMass.childNodes.length; cEntry++) {
var sCollNumber = oPriorityMass.childNodes[cEntry].getAttribute('coll');
if (bynID('adder' + sCollNumber + '_check').checked)
aPriorities.push(parseInt(sCollNumber));
}
}
.....
}
So the mystery of this is, one day i had oPriorityMass named as oPririoty. It was working fine, but the whole function was not yet complete and i started working on another functions for my script. These functions have no connection with each other.
Few days later i decided to go back to my function in the above example and finish it. I ran a test on it without modifying anything and got an error in the firefox's (4) javascript error console saying that oPriority.chilNodes[cEntry] is undefined. NOTE, few days back i have tested it exactly the same way and there was no such problem at all.
Ok, so, i decided to rename oPriority to oPriorityMass. Magically, problem got solved.
At first i thought, maybe there was some conflict of 2 objects, with the same name being used in different functions, which somehow continued to live even outside of function scope. My script is currently over 6000 lines big, but i did a search and found out that oPriority was not mentioned anywhere else but in this exact function.
Can somebody tell me, how and why is this happening? I mentioned same thing happened twice now and they happened in different functions, but the same problem node.childNodes[c] is undefined yet node is not null and node.childNodes.length show correct child count.
What is going on? How do i avoid such problems?
Thank you
EDIT: The error given by error console is
Error: uncaught exception: TypeError: oPriorityMass.childNodes[cEntry] is undefined
In response to Brocks comment:
GM_log(oPriorityMass.childNodes[cEntry]) returns undefined as a message. So node.childNodes[c] is the thing that is undefined in general.
My script creates a div window. Later, the above function uses elements in this div. Elements do have unique IDs and i am 100% sure the original site don't know about them.
My script has a start/stop button to run one or the other function when i need to.
I have been refreshing the page and running my script function now. I have noticed that sometimes (but not always) script will fail with the described error on the first run, however, if i run it again (without refreshing the page) it starts working.
The page has a javascript that modifies it. It changes some of it's element widths so it changes when the browser is resized. But i know it has no effect on my div as it is left unchanged when i resize browser.
EDIT2:
function bynID(sID) {
return top.document.getElementById(ns(sID));
}
function ns(sText) {
return g_sScriptName + '_' + sText;
}
ns function just adds the script name in front of the ID. I use it when creating HTML element so my elements never have the same id as the web page. So bynID() is simple function that saves some typing time when i need to get element by ID.
I have modified my colli() function to include check
if (oPriorityMass) {
if (!oPriorityMass.childNodes[0]) {
GM_log('Retrying');
setTimeout(loadPage,2000);
return;
}
for (var cEntry=0; cEntry < oPriorityMass.childNodes.length; cEntry++) {
var sCollNumber = oPriorityMass.childNodes[cEntry].getAttribute('coll');
if (bynID('adder' + sCollNumber + '_check').checked)
aPriorities.push(parseInt(sCollNumber));
}
}
The loadPage function does 1 AJAX call, then i run few XPATH queries on it, but the actual contents are never appended/shown on the page, just kept inside document.createElement('div'), then this function calls colli(). So now, as i have modified my function, i checked the error console and saw that it may take up to 5 tries for it to start working correctly. 5 x 2seconds, thats 10 seconds. It is never 5 retries always, may vary There's got to be something else going on?
In Firefox, childNodes can include #text nodes. You should check to make sure that childNodes[cEntry] has nodeType == 1 or has a getAttribute method before trying to call it. e.g.
<div id="d0">
</div>
<div id="d1"></div>
In the above in Firefox and similar browsers (i.e. based on Gecko and WebKit based browsers like Safari), d0 has one child node, a text node, and d1 has no child nodes.
So I would do something like:
var sCollNumber, el0, el1;
if (oPriorityMass) {
for (var cEntry=0; cEntry < oPriorityMass.childNodes.length; cEntry++) {
el0 = oPriorityMass.childNodes[cEntry];
// Make sure have an HTMLElement that will
// have a getAttribute method
if (el0.nodeType == 1) {
sCollNumber = el0.getAttribute('coll');
el1 = bynID('adder' + sCollNumber + '_check');
// Make sure el1 is not falsey before attempting to
// access properties
if (el1 && el1.checked)
// Never call parseInt on strings without a radix
// Or use some other method to convert to Number
aPriorities.push(parseInt(sCollNumber, 10));
}
}
Given that sCollNumber seems like it is a string integer (just guessing but it seems likely), you can also use:
Number(sCollNumber)
or
+sCollNumber
whichever suits and is more maintainable.
So, according to your last edit, it now works, with the delay, right?
But when I suggested the delay it was not meant to do (even more?) ajax calls while waiting!!
NOT:
if (!oPriorityMass.childNodes[0]) {
GM_log('Retrying');
setTimeout(loadPage,2000);
return;
More like:
setTimeout (colli, 2000);
So the ajax and the other stuff that loadPage does could explain the excessive delay.
The random behavior could be caused by:
return top.document.getElementById(ns(sID));
This will cause erratic behavior if any frames or iframes are present, and you do not block operation on frames. (If you do block such operation then top is redundant and unnecessary.)
GM does not operate correctly in such cases -- depending on what the script does -- often seeming to "switch" from top scope to frame scope or vice versa.
So, it's probably best to change that to:
return document.getElementById (ns (sID) );
And make sure you have:
if (window.top != window.self) //-- Don't run on frames or iframes
return;
as the top lines of code.
Beyond that, it's near impossible to see the problem, because of insufficient information.
Either boil the problem into a Complete, Self Contained, Recipe for duplicating the failure.
OR, post or link to the Complete, Unedited, Script.

Javascript if statement refuse to load correctly from exterior script IE6 IE5.5

I see a very funny behaviour in my page when it comes to IE6 and IE5.5. I have a script (supersleight if you know about it) that puts PNG's back in business when dealing with IE6 and IE5.5. During execution of this, I want to change the background into using the Explorer alpha filter (if Javascript is turned on, use filter, otherwise stick to solid white).
I do this by:
if(document.getElementById('transparency') != null)
document.getElementById('transparency').style.filter= "alpha(opacity=60)";
...transparency is the id of the object in question.
Putting this at the end of the HTML page (or anywhere after 'transparency' was initiated) results in the script working. Putting it at the very end of the exterior script (deferred) however results in the filter NOT being applied.
However, when I remove the if statement and just tell the browser to use the filter it works (however only a few of the pages has got the 'transparency' id).
I tried to apply the if statement differently by using an alert box and trying both != null and == null and I get nothing.
This made me very curious so I tested this:
var tt = 5;
if(tt == 5)document.getElementById('transparency').style.filter= "alpha(opacity=60)";
Which gave an even stranger result with an error screen saying
tt is undefined
All of this runs perfectly in IE 7 and above...
I realize this is really two different issues but still...
Can anyone give me a clue as to what's going on?
Does this work?
var t = document.getElementById('transparency');
if (t && t.style) t.style.filter="alpha(opacity=60)";
How about this?
try {
document.getElementById('transparency').style.filter= "alpha(opacity=60)";
} catch (e) { }

Is there anything wrong with this statement? (Javascript)

I would like to know if there is anything wrong with the below statement.
document.getElementById(monthId).options[document.getElementById(monthId).selectedIndex].value
Am asking this because, sometimes it seems to work fine and the rest of the time, it throws up an error - Object doesn't support this property or method.
BTW, monthId is the clientID of the dropdown present in a gridview in an asp.net page.
Thanks!
If no value is selected in the dropdown list, selectedIndex would be -1.
It's hard to evaluate without some more code as context. But without sanity checks around this line of code I would expect it to fail with an index out of bounds type exception when there is no selected index.
I tend to error check when using getElementById. I would expect that that is where your problem is.
Try this, and then test it in a debugger, but I will put an alert in.
var elem = document.getElementById(monthId);
if (elem.options) {
options[document.getElementById(monthId).selectedIndex].value
} else {
alert("elem doesn't have an options property");
}
You may want to not assume that the value property exists either, and do the same basic thing as I did here.
Once you get it working smoothly, where you know what is going to happen, you can start to remove the unneeded variables and go back to your original line, but for debugging, it is simpler to have one operation on each line and use separate variables, so that the debugger can show you what is happening.
You may want to understand the difference between undefined and null, and there are various pages on this topic but this one isn't too bad.
http://weblogs.asp.net/bleroy/archive/2005/02/15/Three-common-mistakes-in-JavaScript-2F00-EcmaScript.aspx
You can debug your problem by adding a breakpoint to your code in IE development tools, Firebug, Opera dragonfly or Chrome development tools and check your values.
Or you could add alert statements to check your values. Personally i think the code goes awry when selectedIndex is -1 (selectedIndex = -1 would occur when nothing is selected).
Check for yourself:
alert(document.getElementById(monthId)); // Returns null if nothing is found
alert(document.getElementById(monthId).selectedIndex); // If the selectedIndex is below 0 it could cause your error
document.getElementById(monthId).options[document.getElementById(monthId).selectedIndex].value

Categories