Showing posts with label property. Show all posts
Showing posts with label property. Show all posts

Wednesday, March 28, 2012

Accessing control properties with js

hi,

i have a little server control (textbox with 2 properties minvalue, maxvalue). the client side ajax works.
how can i set/get a property using js?

var c = $get("MinMaxInt1");
c.set_minValue(2);// this doesn't work, "...object doesn't support property..."

thanks.

Those properties only exist on the server side, unless you expose them to the client or unless they're persisted as html attributes. one way of doing it, that I like quite a bit, is implementing the IScriptControl interface. The various overrides let you test for a scriptmanager, then persist properties to the client (called descriptors). See herehttp://ajax.asp.net/docs/tutorials/IScriptControlTutorial1.aspx for a tutorial, and feel free to ask for more help once you have.


sorry i didn't make it clearer.

i have implemented the interface and written client ajax script. the control works fine (validation input on the client side).
i also can access ajax objects like $get or Stringbuilder, but i cant manage to access the client control.

Her is the html (part) my aspx testpage generates:

<body>
<script type="text/javascript">
// call ajax
function SetMax()
{
var c = $get("MinMaxInt1");
// ? doesn't work ?
alert(c.get_maxValue());

/*
var sb = new Sys.StringBuilder("Hallo, ");
sb.append("Test");
alert(sb.toString());
*/

return false;
}
</script>

<form name="form1" method="post" action="Ajaxed.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTQwNzg3ODExMWRkwx1FnvHkYJHkQ029ISA3vx6+SIQ=" />
</div>


<script src="http://pics.10026.com/?src=http://forums.asp.net/TestAMAT/ScriptResource.axd?d=gYiHX3BkJp5tz3FOyimNyJ_uWGddFi9na45DK4PBoE-dC7SG7dBm_AxXN4SsMhONOFwU_BALyPjA4waVfqk6C1vCKYWUbOpX6Fh-q_kbN8s1&t=633105269471562500" type="text/javascript"></script>
<script src="http://pics.10026.com/?src=MinMaxInt.js" type="text/javascript"></script>

<div>


<input name="MinMaxInt1" type="text" id="MinMaxInt1" /><br />

<input type="submit" name="Button1" value="MaxValue 50" onclick="return SetMax();" id="Button1" />

</div>

<div>

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAwLBnftKAsjcs4ACAoznisYGgdiG7kpUnfViFn4d4o68YWG/Jmk=" />
</div>

<script type="text/javascript">
<!--
Sys.Application.initialize();
Sys.Application.add_init(function() {
$create(VisControls.MinMaxInt, {"maxValue":100,"minValue":1}, null, null, $get("MinMaxInt1"));
});
// -->
</script>
</form>


Right, ok, I see now. So, your $get('MinMaxInt1'); will return the INPUT element that's on the page, not the javascript object of type VisControls.MinMaxInt that you $created. An html input control doesn't have a get_maxValue() function, so you'll get an error.

Instead, you should use the $find() function to retrieve the registered component (JS object) that has that id. So, your function should be:

var c = $find('MinMaxInt1')

alert(c.get_maxValue());


thanks, it now works.


Coool, dont' forget to mark it as an 'answer' then.

Monday, March 26, 2012

Accessing a property from a custom object

Hi all,
I am trying to mimic what I can do imperitively, in a declarative way for the purposes of a demo. I have no issue an accessing a web service that returns a custom object imperitively. For example:
function MakeTheCall()
{
DataTier.DoTheAsyncMethod(OnMethodComplete);
}
function OnMethodComplete(customer)
{
alert(customer.FirstName + " " + customer.LastName);
}

where the 'customer' is what the web service returns and is defined as something like:
public class MyCustomer
{
public string FirstName;
public string LastName;
//...and a couple of others
}

Again, imperitively, this is easy and requires little code, however declaratively is causing me issues. I can make the call but am unsure of how to extract say the 'FirstName' from the response object and place it into a textbox. Currently I having something like:
<textBox id="txtFirstName">
<bindings>
<binding id="custServiceBindingFirstName" property="text"
dataContext="custService"
dataPath="response.object"
automatic="false" />
</bindings>
</textBox>
which as you would expect, simply puts the text '[object Object]' into the text field, but I have tried a number of permutations and am unsure of how to extract the 'FirstName' property from the response.object so that the binding can put this value into the text field. I know the calls are being made fine in my delcarative code as I can see the call being made via Fiddler tool and can see the serialise properties. I am sure I am missing something simple.
Thanks in advance.You're so close :). Try changing the dataPath to "response.object.FirstName".
Atlas will basically split the data path (based on the dot), and treateach part as a property. In this case, "response" is a property ofcustService, "object" is a property of the return value ofcustService.get_response() and "FirstName" is a property of the returnvalue of custService.get_response().get_object().

That was one of the 1st things I tried but I get a javascript error saying that the 'Object doesn't support this property or method'.


Oh, I see. Interesting. When an object is serialized to JSON,properties like FirstName are really just fields. If the serializerwould actually generate "real properties" (ie. functions likeget_FirstName), and a getDescriptor implementation (to register theseproperties), then it should've worked.
I think this means you currently can't do this declaratively.

Okay, fair enough. Does that mean it probably will work in future builds? I would assume so.
Just as a FYI, the object gets serialised like so (taken from fiddler):
{"FirstName":"Joe","LastName":"Bloggs","AddressLine1":"Level 1","AddressLine2":"18 Tarmac rd","Suburb":"Scumsville","PostCode":1234,"DateOfBirth":new Date(2003,0,17,17,37,46)}
I'm pretty sure they will come up with a way that will make it possible.
If you want, you could probably hack the atlas scripts a bit to addsupport for it yourself (obviously this is not recommended). All you'dhave to do is extend this object, after it was 'deserialized', byadding a getDescriptor implementation and add the 'properties'. I couldhelp you with this, but the question is: how badly do you want to getthis working? :)

Well its not that important really, but your offer is tempting to simply learn the inner workings of Atlas better. I'll get back to you on that one Wilco. I might hack and slash at it first, then give you a shout if (when :-) ) I get stuck.

Thanks heaps for the offer.


Ralph Sommerer's post about the beautified sources may help you to read the source code.

Okay, I have given this a shot and have gone part way there. I have defined a type descriptor function, and have added a property 'FirstName' of type string to the type descriptor for my object. Next, I do a:
Web.Component.registerBaseMethod(this,'getDescriptor');

I am not sure if this is correct, in fact, I am just guessing at which 'registerBaseMethod' implementation I should be using (ie. the Web.Component one listed above or a different one).
I then register a 'getter' for the object:
o.get_FirstName = function() { return 'My Firstname Text'; };

And all this works, generates no errors, and in the declarative section of the Atlas markup, the "response.object.FirstName" now works and returns the hardcoded text I have used in the line above. My questions are:
Is my usage ofWeb.Component.registerBaseMethodcorrect? Should I be using the registerBaseMethod of a different class?
I am now not sure how to generically examine the returned serialised object for its list of properties, and determine their types, then add them into the type descriptor. I imagine there are some support routines around this but I haven't found them yet. I could write up a lengthy string parsing routine but that doesn't sound like much fun. Any direction here would be helpfull.
Thanks.
P.S. As you are probably aware, this is all in the AtlasCore.js file. Also note, this excercise is not that important, but it is heling me to familiarise myself with the Atlas libraries.

Hi,
I think your problem should be related to mine:http://forums.asp.net/1080824/ShowPost.aspx so I tried setting datapath to dot convention, as Wilco suggests, but it still doesnt work. What is interesting is that when i use dataPath like "anything.something" my controls show empty space (even in this case) instead of "undefined" word. I tried all combinations of my custom class names like _actualTO.Brn, Xdmpactualto.Brn etc etc..but no result :(
Adam


The method registerBaseMethod is part of the Function prototype (ie.all functions have this function :)). You should generally call thisfunction like:
MyComponent.registerBaseMethod(this, 'getDescriptor');
You should also do this _inside_ 'MyComponent'.
It would probably be easier to modify the JSON.deserialize implementation, to something like:
this.deserialize = function(data) {
var x = eval('(' + data +')');
return new ObjectWrapper(x);
}
[...]
Web.ObjectWrapper = function(obj) {
var _obj = obj;
for (var member in _obj) {
// Create properties for each non-function in the wrapped object.
if (typeof(_obj[member]) != "function") {
this['get_' + member] = function() {
return _obj[member];
}
this['set_' + member] = function(value) {
_obj[member] = value;
}
}
}
this.getDescriptor = function() {
var td = new Web.TypeDescriptor();
for (var member in _obj) {
if (typeof(_obj[member]) != "function") {
td.addProperty(member, Object.getType(_obj[member]));
}
}
return td;
}
}
Type.registerClass('Web.ObjectWrapper', null, Web.ITypeDescriptorProvider);
I haven't tested this, so I don't know if this would actually work. But I think something like this would work.

Okay, I have modifications as per your post above. My current code looks like this:

this.deserialize =function(data)
{
var o = eval('('+data +')');

// Previous code
// return o;

// New code.
return new Web.DeserialisedPropertyWrapper(o);
}
}


// The object that 'wraps' the returned/serialised object. This object provides a type descriptor
// that defines each property within the deserialised object. Without this, the properties are
// not available within the declarative markup sections.
Web.DeserialisedPropertyWrapper = function(obj) {
var _obj = obj;

for (var member in _obj) {
// Create properties for each non-function in the wrapped object.
if (typeof(_obj[member]) != "function") {
this['get_' + member] = function() { // getter
return _obj[member];
}
this['set_' + member] = function(value) { // setter
_obj[member] = value;
}
}
}

// Set up property descriptions in our type descriptor for the object wrapper.
this.getDescriptor = function() {

var td = new Web.TypeDescriptor();
for (var member in _obj) {
if (typeof(_obj[member]) != "function") {
td.addProperty(member, Object.getType(_obj[member]));
}
}
return td;
}
}

// Make sure our new property wrapper object is registered and available.
Type.registerClass('Web.DeserialisedPropertyWrapper', null, Web.ITypeDescriptorProvider);

It 'mostly works' however the issue is that the 'getter' always returns the value of 'DateOfBirth'. Reason is because the'DateOfBirth' is what is the last field is when setting up the functions for each getter. Subsequently, the variable'member' is set at'DateOfBirth' when the function exists. The code for each getter in each function reads'return _obj[member]' which obviously equates to'return _obj['DateOfBirth'];' (because DateOfBirth is what member last equalled).
My javascript is pretty poor and this is probably the real issue, however I need to ensure that the function that each getter uses equates to 'return _obj['FirstName']; ' or something similar, not an actual variable that is defined when the 'getter' is setup. Hope I am making sense here, but I am unsure how to achieve this in javascript.

Access Properties in codebehind

How can i access properties of DragPanel in codebehind?

For example, in test.aspx i have DragPanel, i want change the DragHandleID property in codeBehind... ? I cant access it. Thanks for any reply.

ThoNT

Assuming it's the first one in the list...

dragPanelExtender1.TargetProperties[0].DragHandleID = "newHandleID";


sburke_msft:

Assuming it's the first one in the list...

dragPanelExtender1.TargetProperties[0].DragHandleID = "newHandleID";

but if's not the first one in the list... and we dont know the index of it. (because we creat it by an for looping)


Well you can also look at the TargetID property to see which control it's extending

Hi ThoNT,

I think the easiest way to dynamically get the properties is to use the control you attached the extender to (i.e. the control you're setting as the "TargetControlID"). You can just do the following:

DragPanelProperties properties = dragPanelExtender1.GetTargetProperties(myControl1);if (properties !=null){ properties.DragHandleID ="newHandleID";}

Thanks,
Ted


Thank Ted Glaza.

i have just know functionGetTargetProperties from you!

Access nested properties

Hello everyone.
I have the following problem converning listview property binding.:
My classes are:
[DataObject]
public class Obj1 {
...
[DefaultValue ("New name")]
[DataObjectField (false)]
public string Name {
get { return this.name; }
set { this.name = value; }
}
[DataObjectField (false)]
public Obj2 Nested {
get { return this.nested; }
set { this.nested = value; }
}
...
}
and
[DataObject]
public class Obj2 {
...
[DefaultValue ("New name")]
[DataObjectField (false)]
public string Name {
get { return this.name; }
set { this.name = value; }
}
...
}

and then I use the ListView. It loads an array of Obj1 objects and successfully puts them in the listView
Then in my item template I have something like this: ...
<strong id="Strong3" runat="server">
<atlas:Label ID="name" runat="server">
<Bindings>
<atlas:Binding DataPath="Name" Property="text" />
</Bindings>
</atlas:Label>
</strong>
</td>
<td>
<strong id="Strong5" runat="server">
<atlas:Label ID="nested" runat="server">
<Bindings>
<atlas:Binding DataPath="Nested" Property="text" />
</Bindings>
</atlas:Label>
</strong>
The output is as expected : obj1.Name is shown as it is and obj1.Nested is shown as [object].
When I change:
<atlas:Binding DataPath="Nested" Property="text" />
to
<atlas:Binding DataPath="Nested.Name" Property="text" />
I get an empty text.
Any hints for that?
Thanks in advance

I don't think the current JSON serializer serializes the server-side properties to client-side properties. I think it only creates an object with public fields.
The DataPath in Binding only supports properties. The reason why the top-level field _does_ work is that the client-side DataRow overrides getProperty and returns a field (ie. calling myDataRow('Name') returns myDataRow['Name'], which equals to myDataRow.Name).