Showing posts with label JavaScript / Client Scripts. Show all posts
Showing posts with label JavaScript / Client Scripts. Show all posts

May 26, 2011

Serializing object to JSON returns empty string?

Consider the following code:

string JSONObject = string.Empty;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(this.GetType());
using (MemoryStream ms = new MemoryStream())
{
    serializer.WriteObject(ms, this);
    // Donchev - we need to reset because the write has gone to the end of the stream
    // and the StreamReader.ReadToEnd() won't seek to the beginning of the stream again.
    using (StreamReader sr = new StreamReader(ms))
    {
        JSONObject = sr.ReadToEnd();
        sr.Close();
        sr.Dispose();
    }
    ms.Close();
    ms.Dispose();
}
return JSONObject;

It seems perfectly correct but have a few problems.

And the first one is very important – it is based on wrong assumption and it is returning empty string because of that.

I will let you tackle it for a while to see if you can find where the problem is.

Ready?

If not – I’ll tell you – the problem is that when I wrote this code, I was expecting the ReadToEnd() method of the StreamReader class to auto reset the stream to its beginning, it sounds for some reason to me that this method it is saying - “Read the whole thing.”.

Unfortunately this assumption evaluated to false.

The method actually says - “Read from where you are to the end of the thing.”.

So before calling JSONObject = sr.ReadToEnd();

I needed to simply call:

ms.Seek(0, SeekOrigin.Begin);

In order to reset the pointer to the beginning of the stream.

Voilla!

The other question I asked myself is why the pointer is at the end of the stream (after the string is empty and not some portion of the stream, it should be at the end).

The answer – the serializer.WriteObject() method is probably not resetting it to be at the beginning after it completes its job.

Not quite sure who is responsible for resetting the stream – the caller or the callee, we can have a long discussion about this.

Anyway – just wanted to share this with you. I know it is very old thing but I am trying to write for much of the things that made an impression on me.

Aug 10, 2009

A nice DOM property I bet most of you have missed ...

In my previous post on this topic I mentioned the properties you can use to detect changes in HTML input controls:
http://donchevp.blogspot.com/2009/08/nice-dom-property-i-bet-most-of-you.html

Now I want to inform you that I have found an article which has all the controls included with the property you can use to track for changes:

http://www.codestore.net/store.nsf/unid/DOMM-4UTKE6

The first thing I noticed is that it is kind of inconvenient for the SELECT DOM object for example.
You should iterate through all the items and check their selected property with their defaultSelected property ...

Aug 5, 2009

A nice DOM property I bet most of you have missed ...

Have you ever heard about the defaultValue and the defaultChecked properties?
They seems to be a standard DOM properties so the major browsers seem to support them.
What they do?
The defaultValue property is about textboxes (input type="text") and it will contain the value which the textbox has at the time it was rendered on the page.
The defaultChecked property is almost the same, it is about a checkbox and it tells you whether the checkbox was rendered checked or not.

So doing something like:

function hasTextBoxChanged(textBox) {
return textBox.defaultValue == textBox.value;
}

would tell you whether the textbox passed as an argument has changed its value since it was rendered on the page.

Same function for checkbox would be something like:

function hasCheckBoxChanged(checkbox) {
return checkbox.defaultChecked == checkbox.checked;
}

I find those properties very helpful. If you play a bit with jQuery you can find a real life application of them.
I am however wondering if there are such properties for dropdowns and some other controls.
If I find - I'll definatelly post again.

Hope it helps someone outthere ...


P.S. if the control is a part of update panel and it was udpated in the code behind it will not be counted as a change as the defaultValue / defaultChecked properties will be set again (those properties are taken to be the value of the control when it was rendered).

Aug 2, 2009

W3C Zoom CSS property. I really want this feature included!!!

Lot's of people are discussing this.
And the designers are often saying something like:
"I cannot imagine a scenario where you will need to use the Zoom CSS property."
To the readers that haven't yet hit this problem - the CSS Zoom property seems to be proprietary and to be working for IE (I think version 6 and above).

To all those designers - there ARE scenarios where you will want to let the user zoom everything proportionally without using the browser buttons / sliders / shortcuts, but with CSS / JS only.
I will give you few examples:

1. I needed to create an overview control of page. It should represent the page in a smaller percentage and, upon scroll, the page should scroll proportinally. I can have a div with the same DOM tree (or even an IFrame loading the same page or something). In this case I URGENTLY need the CSS Zoom property.
2. Telerik radReporting - the ReportViewer has a dropdown to let the user choose a zoom level to preview the page (web based and not after clicking print preview or something). Actually the Print Preview browser command isn't an option as the report viewer may be on the page with other controls and the user SHOULD BE ABLE to zoom in and out only the portion of the page where the report is (it is an IFrame with the data rendered as HTML, I believe). In telerik case - there seems to be some browser detection and when the browser isn't capable of zooming in / out - the dropdown with the zooming levels is simply hidden (they have no other choice unfortunatelly and I support them for this decision).

Now, as you may expect - in my scenario I cannot simply hide the overview control as the page heavilly depends on it.
Should I now have my revenge now? I've seen all those messages accross the web telling you that there are better browsers to use than IE.
Should I now display a message like:
"Sorry, your browser isn't capable of zooming in and out, only IE supports this, so please switch to IE."

I really hate those browser wars and if you really want to know my opinion - yes, IE may be harder to design. It may be messing up the containers, it may not be passing the ACID N test.
But it is the only browser that is suitable for my scenario (at least from my search in IE all the posts were following the same line - "zoom is IE proprietary, it won't work under other browsers").
Why are all other browsers sleeping then?


P.S. I have found something like -moz-zoom or something but wasn't able to make it work under FireFox (if it works under Firefox it should also probably work under Google Chrome as they are using the same engine I think).
P.P.S. - haven't tested but I think the zoom CSS property should also be available under Opera as they (as far as I know) use the IE core.

P.P.P.S - if anyone know how can we ask W3C to reconsider this for at least the next revision of CSS I would be glad to give my vote. I also advice telerik to do the same. Not only the reporting will work in all browsers but they may be able to do some other great controls using this property.

Really annoying ...

Jun 3, 2009

radGrid - check if there was a row selected, before selecting another one [2]

The previous post on this topic was about pointing some solution, which doesn't always work.
I think I was able to identify the problem for this issue.

It is becasue the chain of events is the following when you select a new row:

1. RowDeselected.
2. RowSelecting.
3. RowClick.
3. RowSelected.

I am not quite able to find the logic here.
I think in normal english I should be able to say:

"I am clicking on a row."
"I am in a process of selecting a row." (if not canceled)
"I am deselecting the old row."
"I have selected the new row."

At least the RowClick in my opinion should be fired prior the events described above as it occurs before everything else. You are initiating the above chain of events by clicking on a row so all of them should follow in my opinion.

To me the fact that RowDeselected is before RowSelecting is not such a bad solution. I just can't get why the RowClick is between RowSelecting and RowSelected events.

Any clues?

Jun 2, 2009

radGrid - check if there was a row selected, before selecting another one.

Okay, we had the radGrid with AllowMultiRowSelection property turned off.
But we needed to check if there is already a selection in the grid (on the client side), then get the item and do some calculations.

So far so good.
But it appeared that it is very difficult to get the previous item selected in a grid when selecting a new one.

The OnRowSelected event as you may suspect is raised too late in order to get this information as the selection is already changed.
So I thought the OnRowSelecting event will be the best time to perform this.

Guess what? It wasn't. At least for me.
Each time I checked the

sender.MasterTableView.get_selectedItems().length > 0

The statement evaluated to false (which means to me that when the OnRowSelecting event is raised AFTER the selection is Clear()).

So I found a workaround to help myself persist the previous selected item of the grid:

var lastRow = null;

function RowDeselected(sender, eventArgs) {
lastRow = sender;
}

function RowSelecting(sender, eventArgs) {
if (lastRow) {
    
// There was a selection before we try to select. Do whatever you need here.
}
    
else {
    
// There wasn't any selected item, this is the first one.
     }
}

To me it seems that problems may arise. I will test some more to see for side effects and will report back.


Any comments are appreciated.

May 12, 2009

MindFusion diagramming Part 5 - Changing pen colors with JavaScript (ClientMode)

In order to change the pen (borders) of a shape you first need to instantiate a pen class.
It is in the com.mindfusion.diagramming namespace (Java class).

So you need to do the following:


var pen = new Packages.com.mindfusion.diagramming.Pen();


Now, to set the color of the pen we need a java.awt.Color instance. Luckily there are static properties which will return a color instance for the most used colors. See what I mean:

var blackColor = Packages.java.awt.Color.black;
var greenColor = Packages.java.awt.Color.green;

Now, to set the pen color to the color we will use setColor() method:

pen.setColor(Packages.java.awt.Color.green);

To set the width to be 1 pixel we need to use the floating point 0.1, not 1:

pen.setWidth(0.1);

Here is the function return a pen with 1 px border and green color:
function getGreenPen()
{
var pen = new Packages.com.mindfusion.diagramming.Pen();
pen.setWidth(0.1);
pen.setColor(Packages.java.awt.Color.green);
return pen;
}

You can now use an instance of a shape and set its pen. For example, you can use the OnNodeActivatedScript and add the following function:

function onNodeActivated(diagram, args)
{
var node = args.getNode();
node.setPen(getGreenPen());
}


Hope it helps a bit.

Apr 30, 2009

Instantiate Java class in JavaScript

I know I am mostly writing about C# and .NET and so on and you may wonder way do I write about java but I found this interesting and useful even in .NET projects.
I was playing with the mindfusion diagram latelly (you can check my posts under the Mind Fusion Diagramming in the blog categories) and found myself in a situation where I needed to instantiate a class from the mindfusion package (i think it was table cell but this doesn't matter right now).

So in order to instantiate Java class in JavaScript you may do this from the Packages object.
For example if you have a class like:
java.MyClass

you can instantiate it this way in javascript:

var myClass = Packages.java.MyClass();

Let's suppose the class has Name property, you can call it like this:

alert(myClass.Name);
// If the class has a property "Name", call it ...

Hope this helps somebody out there...
So long and thanks for al the fish ;)

NOTE : I haven't tested this under browsers other than Internet Explorer 7. Hopefully it will work ...

Apr 13, 2009

MindFusion diagramming Part 4 - Cancel link creation between specific kinds of shapes

You can check between what kind of shapes the link is created and remove it if you need to do so. I will give you an example on how to cancel the connection between Actor and Actor shapes.

First - add LinkCreatedScript to your diagram and make it point a JavaScript function, here is mine declaration:

    
<ndiag:DiagramView ID="diagramView" runat="server" Style="left: 0px; width: 800px;
        
position: absolute; top: 0px; height: 505px" Behavior="DrawControls" BackColor="White"
        AllowInplaceEdit="true" LinkCreatedScript="onLinkCreated" />

Now add the onLinkCreated function in the page head :

  
<script type="text/javascript">
     function onLinkCreated(diagram, args) {
        
var link = args.getLink();
        
var shapeOrigin = link.getOrigin().getShape();
        
var shapeDestination = link.getDestination().getShape();
        
if (shapeDestination.getDisplayName() == 'Actor' && shapeOrigin.getDisplayName() == 'Actor') {
           diagram.getLinks().remove(link);
           alert(
'Cannot crate link between ' + shapeOrigin.getDisplayName() + ' and ' + shapeDestination.getDisplayName());
        }
     }
  
</script>

1. What we did is - we get the link that was just created from the args.
2. We get the Origin and Destination shapes from the link.
3. We then checked their display names and verify they are Actor and Actor.
4. We asked the diagarm object to remove a link, to be more specific - our link, the one that was just created.


I think there may be more elegant ways to achieve this, but currently this is the only I could think of.
Hope it helps somebody out there ...

MindFusion diagramming Part 3 - adding Overview control to the form.

Here is the third part of the tutorial.
Adding overview isn't realy a big deal. You only need to add the following markup in your page (the solution we created in the previous two samples):

<ndiag:Overview Style="position:absolute; top: 320px; height: 180px; left:810px; width:160px;" runat="server" DiagramViewID="diagramView" />

The thing you need to obey here is to give the diagram overview control a correct DiagramViewID property, which should be the ID of the DiagramView control you have on your form.

Here is what we have so far (the tree tutorials combined):


Apr 6, 2009

MindFusion diagramming Part 2 - adding shapes list

In the previous example, I show you how to add simple diagram to your web forms. Now I am going to show you how to add a simple shapes list, containing all the shapes that comes with the MindFusion product.

It is very simple, actually, only 1-2 lines of markup:

<ndiag:ShapeListBox ID="shapeList" runat="server" Style="left: 810px; width: 160px; position: absolute; top: 1px; height: 320px; background-color: white" />

This should be added to the code you built in the previous example : http://donchevp.blogspot.com/2009/04/mindfusion-diagramming-part-1-adding.html.

Let's see what we got now:





MindFusion diagramming Part 1 - adding simple diagram to the form.

We worked quite a bit with this product and I must say it is a good one.
It can be used to easilly draw diagrams. It has a lot of built-in shapes and a designer to draw new one.
Let's add a digaram on the form.
First of all, download the product from here : http://mindfusion.eu/download-netdiagram.html and install them.
Add the following lines to your web.config:

In page / controls section, add the following:
<add tagPrefix="ndiag" namespace="MindFusion.Diagramming.WebForms" assembly="MindFusion.Diagramming.WebForms"/>

Then add reference to :
MindFusion.Common
MindFusion.Diagramming
MindFusion.Diagramming.WebForms

Open your page and add the following markup to create a diagram:

<ndiag:DiagramView ID="diagramView" runat="server" Style="left: 0px; width: 800px;
position: absolute; top: 0px; height: 505px" Behavior="DrawControls" BackColor="White" AllowInplaceEdit="true" />

I added few additional properties to decorate and set behaviours. We will discuss them later. I also allowed InplaceEdit, which means that when you double click on a shape, you will be able to edit the text.
Finally, copy the JDiagram.jar into your root directory (you can place it in a directory of your choice, but you will need to set the
JarLocation property to point to this file.

Let's see what we did so far:





Pretty nice for 1 minute of work, huh?
There is more ;). This product seems to come from Bulgaria, so there will be no problem with it :).

Using JavaScript functions over a string in C#.

I needed to find a way to invoke the real escape / unescape javascript function over a string in C#.
It appeared to be easy to do so by using the Microsoft.JScript namespace classes.

Add a reference to it and then you can simply do something like this:

string escaped = Microsoft.JScript.GlobalObject.escape("This will be JS escaped for sure!");

"escaped" variable will then have the value of :

This%20will%20be%20JS%20escaped%20for%20sure%21

I am still very new to this namespace, there were a lot of things to find out there ...

Check it out. It may appear to be very useful for those of you who are processing JS on-the-fly...

Mar 16, 2009

Fixing sup - sub for radEditor example

I made few posts on telerik radEdit. There was something I considered a small issue. Which actually may appear not to be issue, but to me it was.
So i decided to get a bit more familiar with the telerik radEdit client side scripting API (thanks to Tervel for his valuable comments).
So the problem for me was that if you type normal text, then click on the sub icon to make index and then click on the sup to raise to the power of something, the result was a text on the same level as the normal text.

Digging a bit in the client API of radEdit I found that you can obtain the editor undo manager. You can also fire commands so the problem should be easy to fix (I should mention here that I am really happy with the architecture of radEditor, it has everything a developer may need in order to extend the control to fit his / her needs.

Ok, now to the problem. I thought all I need to do is to make radEdit check if a sup is selected when you click sub and switch it off if so. Same thing should happen for sub. Luckily radEdit has client side event handler
OnClientCommandExecuting which is rised prior command execution. So you will need an event handler like this:

OnClientCommandExecuting="cmdPreExec"

Having the eventhandler attached, you need to write a function to check if the user clicks either sup or sub. Then to check if the other command was recently fired, if so - it will fire it again to switch it off. Here are the functions:

    
function cmdPreExec(editor, args) {
        
var strCommand = getLastCommandReal(editor);
        
if (strCommand) {
           cmd = args.get_commandName();
          
if (cmd == "Superscript") {
            
if (strCommand == "Subscript") {
                editor.fire(
"Subscript");
             }
           }
          
if (cmd == "Subscript") {
            
if (strCommand == "Superscript") {
                editor.fire(
"Superscript");
             }
           }
        }
     }

    
function getLastCommandReal(editor) {
        
var manager = editor.get_commandsManager();
        
var commands = manager.get_commands();
        
var lastCommand = null;
        
        
if (!commands) {
          
return null;
        }
        
else {
          
for (i = commands.length - 1; i > -1; i--) {
            
if (!commands[i]) {
                
return null;
             }
            
if (commands[i]._title != "Typing...") {
                
return commands[i]._title;
             }
           }
        }
     }

The second function is to get the last command name from the undo manager, excluding the "Typing..." which is also registered there.
Please note that I see some potential problems which I haven't considered yet, you may have some side effects.
This post is more to show you how to work with some of the client side objects / events and methods than to use in real life.

Actually I am 99.99999 % sure there will be a problem with this code ;). This code was written in abouth 15 - 20 minutes so there should be a bug for sure. I can think of at least two bugs ;).

Here is a video on how this code performs for me:



Mar 12, 2009

tinyMCE has the sup - sub issue too

Just to inform you that tinyMCE cannot handle the sup / sub correctly also.

Here is a video:

Oct 27, 2008

JavaScript Call SetTimeout or other function with parameters.

I needed to do this few days ago. I struggled to find out how.

Hope this will help to other guys in the same situation (it's so simple that you may never figure it out until someone tell you :D ):


    
var t;
    
function myButtonToTimeOut(id)
     {
        
// We will call the onTimeOut function in a setTimeOut()
        // and will pass the id as a parameter:
        t = setTimeout(function(){onTimeOut(id);}, 2000);
     }
    
function onTimeOut(id)
     {
        alert(
'The caller with ' + id + ' was clicked 2 seconds ago.');
        clearTimeout(t);
     }

what do we do here?
Well, we have a global variable which will hold
the timeOutID (required to clear the timeout).
We have a target function which we want to call in let's say 2 seconds. But we want to pass some parameters to it (for example the sender of the event).

What we do is to create another function (myButtonToTimeOut) in the function body we call the setTimeOut, and pass as parameter a new function which contains our desired call:


function(){onTimeOut(id);}

Voilla. The other things (such as the global variable t) are here only to make this thing work. If you want to test this snippet simply add it to the head of an html page, add few buttons and set their onclick as this one:

onclick="myButtonToTimeOut(this.id);"

When you click on the button, after two seconds you should receive an alert showing you which button was pressed.

Please note: As the code was intended to only show you how to call setTimeOut with parameters, it may have some bugs in it (for example I am not quite sure what will happen if you click two times quickly on the button, or on two diferrent buttons, as t is holding the timeOutId it may get overriden and as a result, some of the alerts may continue to appear).


Have a nice programming!