Dailycode.info

Short solution for short problems

Download a UTF-8 (with BOM) csv file from API with javascript

I had a webservice that generated a csv file. At first everything seemed ok. But when de users start testing, there were problems with special characters like ë and é and more  when the csv was opened with Excel. With notepad there were no problems. 
A colleague found out that it had something todo with UTF-8 witout BOM. If we changed the encoding to utf-8 (with BOM) then it opened correct in Excel. 
Now I first started to change  the API, trying all kinds of fixes. But at the end it was the front end were the problem occurred. The API side (.Net) looked like this:

#region Export
[Route("GetExport")]
[HttpPost]
[EnableCors(origins: "http://myserver.be", headers: "*", methods: "POST, OPTIONS", exposedHeaders: "Content-Disposition,MyFileName", SupportsCredentials =true)]
public HttpResponseMessage GetExport(BusinessObjects.ExportRequest request)
{
    this.LogMessage("GetExport IN API", JsonConvert.SerializeObject(request));
    HttpResponseMessage resultMessage;            

    if (request != null && request.IsValid())
    {

        var content = "Joëlle;Mark;Peter";
        var encoding = Encoding.UTF8;
        resultMessage = new HttpResponseMessage(HttpStatusCode.OK);
        resultMessage.Content = new StringContent(content, encoding, "text/csv");
        resultMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = request.GetFileNameForRequest()
        };
        resultMessage.Content.Headers.Add("MyFileName", request.GetFileNameForRequest());
    }
    else
    {
        resultMessage = new HttpResponseMessage(HttpStatusCode.BadRequest)
        {
            Content = new StringContent("Invalid ExportRequest.")
        };
    }

    return resultMessage;
}

Up to here everything was working ok. I found out that the problem was rather on the client side were I was getting the file:

There were 2 implementations (first for internet explorer, second for real browsers):

if (window.navigator.msSaveOrOpenBlob) { //Source: http://stackoverflow.com/questions/17836273/export-javascript-data-to-csv-file-without-server-interaction
    var blob = new Blob([decodeURIComponent(encodeURI(rslt.data.toString()))], {
        type: "text/csv;charset=utf-8"
    });
    navigator.msSaveBlob(blob, rslt.fileName);
}
else {
    var element = angular.element("<a/>");
    element.attr({
        href: "data:attachment/csv;charset=utf-8" + encodeURI(rslt.data.toString()),
        target: "_blank",
        download: (rslt.fileName) 
    })[0].click();
}

Now the only thing that did the trick was adding UTF-8 BOM at the start of the text. It was a little different for IE and the rest of the world.

if (window.navigator.msSaveOrOpenBlob) { //Source: http://stackoverflow.com/questions/17836273/export-javascript-data-to-csv-file-without-server-interaction
    var blob = new Blob([decodeURIComponent(encodeURI('\ufeff'+rslt.data.toString()))], {
        type: "text/csv;charset=utf-8"
    });
    navigator.msSaveBlob(blob, rslt.fileName);
}
else {
    var element = angular.element("<a/>");
    element.attr({
        href: "data:attachment/csv;charset=utf-8,%EF%BB%BF" + encodeURI(rslt.data.toString()),
        target: "_blank",
        download: (rslt.fileName) 
    })[0].click();
}

Now when I open the downloaded file in Excel, the special characters are showing fine.


Tech: My Techorama 2015 review

1.           ASP.NET 5

1.           ASP.NET 5

A session on the new ASP.NET 5. A lot of overlapping information. New features of visual studio 2015. This session also confirms that WEB API is the way to go in the future.

Here is a summary of the foundational improvements:

  • New light-weight and modular HTTP request pipeline
  • Ability to host on IIS or self-host in your own process
    • Showed in the session, you can host is from command line on USB stick.
  • Built on .NET Core, which supports true side-by-side app versioning
  • Ships entirely as NuGet packages
    • Not part of the System.Web.dll anymore.
  • Integrated support for creating and using NuGet packages
  • Single aligned web stack for Web UI and Web APIs
  • Cloud-ready environment-based configuration
  • Built-in support for dependency injection
  • New tooling that simplifies modern Web development
  • Build and run cross-platform ASP.NET apps on Windows, Mac and Linux
  • Open source and community focused

 

2.           The internet of your things (Iot)

Mainly about Azure and the capabilities to host applications on Azure. Interesting was the table storage. You can create a table service where different types of data can be stored in 1 table. It’s a no SQL datastore. This is ideal for storing structured non relational data.

Link to this:

https://azure.microsoft.com/en-gb/documentation/articles/storage-dotnet-how-to-use-tables/

 

3.           How to live longer and happier with Visual Studio 2015

This session was about the new features of Visual Studio 2015.

You can see that a lot of resharper functionality is now default in VS 2015.

Also integration with a BOWER, Gulp and Grunt are used very frequenly. For packages like AngularJS, bower is better than NuGet.

http://www.dotnetcurry.com/visualstudio/1096/using-grunt-gulp-bower-visual-studio-2013-2015

 

 

4.           EF7, Who are You and What Have You Done With My ORM?

Julie Lerman who gave the session is an expert on EF. She wrote books and gives trainings about it. Her conclusion in regard with the silver bullet key note is that the best way to go for the future is:

-       Keep using EF 6.0 in existing projects.

-       Start using EF 7.0 in new projects.

EF7 is a complete makeover of the entity framework. Since the start of EF they continued on the same code base. For EF7 they restarted completely from the beginning, to make it more light weight and also to tackle some challenges that were not possible to take with the old code base.

 

5.           "Write once, run anywhere”: Can AngularJS & Cordova do it?

This was definitely my favorite session. Christian Weyer explained in 1 hour and 30 min the complete lifecycle of a modern app that has 1 code base but can be published in any device!

 

He is co-owner of thinktecture that tackle very large implementations using .Net back-end, HTML5 and Javascript to code once, deploy anywhere.

 

Their code base is EF --> .Net WEB API --> AngularJS.

Using Cordova they can deploy the code to native iOS, Android and Windows Phone.

Then the AngularJS is also available in any browser and can even be build to native Apps for Windows and Mac OS.

 

6.           "It's alive!": Real-time applications with ASP.NET SignalR and AngularJS

Again a great session by Christian Weyer. SignalR is definitely something to look into. Very brief it’s a way to let the server communicate to the clients. E.g. when some data is updated and the clients need to refresh without the user having to click on a refresh button.

More info:

http://signalr.net/

 

7.           HTML 5 Security

This session was mainly about CORS and ways that javascript could inject bad code. If setup the code in the correct way, you could prevent this.

 

8.           Aurelia Deep Dive

This session was about an alternative to AngularJS. Another javascript framework. The demo were not impressive, some failed. I do not believe in Aurelia, since the community behind it is not comparable with AngularJS.

 

9.           Domain Driven Design for the Database Driven-Mind

Another view on application architecture. This looks promising, but at the moment not feasible because lack of knowledge and high impact on development. Also we are in a process of change that first need to be advanced.

 

10.        The Engaging User Experience & the Natural User Interface

Key note about user experience. Not very interesting. Talking a lot about xbox Kinect and face recognition.

 

11.        Chrome developer tools

Here is a good summery made by one of the attendees:

The Console tab

It’s probably safe to assume that you all know and use the Console Tab of Google Chrome to write your debug statements and evaluate JavaScript expressions. Most of the time we do that by using “console.log” statement which writes your logging messages to the console. If you are using a lot of those “console.log” statements in your code then things can quickly get messy and it will become difficult to work through your logs to find the one line you actually need.

To organize your statements you can use “console.groupCollapsed” and “console.groupEnd”. These functions will create a collapsable group in the log window so you can find your debug lines faster.


If you want to measure how fast your code is executing you can use “console.time” and “console.timeEnd”. This can also prove quite handy when you want to benchmark certain functions.


Device Emulation

The Device Emulator enables you to test out your website on several devices (phones, tablets, computers…) and on different network speeds (4G, 3G, GPRS…). This makes it very easy to test out your responsive design. The emulator even supports touch events!

You can enable/disable it by toggling the device icon Chrome Dev Tools - Mobile Iconin your Dev Tools.


The Network tab

The Network tab is used to monitor the performance of your application and helps you identify slow loading resources. It includes detailed timing data, HTTP request and response headers, cookies…

A very useful feature of the Network tab is that you can download its contents to a .HAR file. This could help us debug the “unreproducible bugs” reported by a QA Engineer. If he’s doing his tests with the Network tab opened he can just send the failed requests to a developer to investigate. All he has to do is right-click the network table and select “Save as HAR with Content”. This will download a .HAR-file that can be read using a tool called Chrome HAR Viewer.

Quick tips

Inline editing

To enable inline editing just open up the console and type “document.body.contentEditable = true” and press ENTER. You can now modify any text on your page by just typing into the browser window. If you have to build a multilingual application you can use this to easily test what would happen if the text in your title or menu items would be translated (and thus be longer or shorter than intended by the designer).

Blackbox scripting

You all know that you can debug javascript code by adding breakpoints to your code in the “sources tab”. Very often this tab includes a lot of scripts that you don’t care about (external libraries etc.). You can prevent the debugger from breaking in those scripts by “blackboxing” them. Just right-click on the file and select “Blackbox Script”. You can stop blackboxing a script by right-clicking the same file and selecting “stop blackboxing”.

Styling log statements

You can add CSS styling to your “console.log” statements. This can prove useful if you want something to stand out if it occurs.


Conclusion

Please note that this blogpost is just a high level overview of useful and time saving features that were presented by Shay Friedman (@ironshay) at Techorama. The Google Chrome dev tools contain a lot more functionality than what can be covered here. If you are curious to learn more or want to read on about the topics covered in this post you can visit https://developer.chrome.com/devtools.

 

12.        Decomposing AngularJS

This was an interesting session that gave a deeper view of how the AngularJS binding works. He actually created a fresh JavaScript Framework from scratch (using code blocks and copy paste) that bound model to the view.

 

13.        EF7 demo demo demo

This was a replacing session were Julie showed EF 7 in combination with ASP.NET 5 in action.


Disallow non numeric characters in an asp.net textbox

A very simple javascript that will block the entry of non numeric characters:

function isNumberKey(evt) {

    var charCode = (evt.which) ? evt.which : event.keyCode

    if (charCode > 31 && (charCode < 48 || charCode > 57))

        return false;

 

    return true;

}

Simply put this on the onkeydown event:

<dx:ASPxTextBox runat="server" ID="txtTaskSortOrder" Width="50px" Value='<%# Eval("TaskSortOrder")%>'

MaxLength="5" onkeypress="return isNumberKey(event);">

</dx:ASPxTextBox>

 

If the user enters non numeric characters, the entry will be withhold and not allowed in the textbox.


Adoba Forms in SAP: use javascript to manipulate text in textfield

I was looking for the javascript to replace any occurences of a text in a string.

If you put this code on the initialize event of a textfield, you can do it!

 

var b64 = this.rawValue;

b64 = b64.replace(/mderaeve.com/gi,'markderaeve.be');

this.rawValue = b64;

The /gi makes sure to do a global case-insensative replace. Be aware that you can lose formatting, such as enters. So for long texts this could not be the best solution.


How to call a javascript function fomr your code behind (c#)

There are many ways to call javascript from the code behind, this is one of them: After a button click for exemple you can use this code to call javascript:

System.Web.HttpContext.Current.Response.Write("<SCRIPT LANGUAGE='JavaScript'>");
System.Web.HttpContext.Current.Response.Write("alert('test');");
System.Web.HttpContext.Current.Response.Write("</SCRIPT>");

Remove send TO from the item menu

I have a SharePoint site that handles important documents with enhanced security. Users are allowed to view the documents, but no changes are allowed. So I decided to use Rights Management Services in cooperation with WSS security. Now I can even prevent users from saving and printing the word documents. But then SharePoint allowed a menu feature: "Send To"  which allowed the user to copy a document locally. This feature was not easy to remove. It's not possible using WSS security.

I tried a solution that proposed to add a empty javascript to the page or masterpage. This script would replace the AddSendSubMenu(m,ctx) script from the core.js in the WSS directory. But it didn't work. Then I found a solution on this site that worked for me. It involved changing the AddSendSubMenu javascript in the core.js file. One IISRESET was required. You could change the script or just empty the complete function, but I chose to add an IF to check for the document library name. Because it only applied for 1 particular document library.

Here is the change I made to the script:

function AddSendSubMenu(m,ctx){if(ctx.listName !="{3971CB40-C660-48BB-BF86-9FF3917A053A}"){
...script text
}

 

You can find the ID if the library in the content database, in the table Alllists or by clicking the settings link of the library and removing the url spacial characters.

You can find the core.js file here Drive :\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\1033


How to change Option item index with javascript

Again a small script that enables you to order items in a listbox or (html) optoin. Just include this script in your page:

function move(index,to,list) 
{
    var total = list.options.length-1;
    if (index == -1) return false;
    if (to == +1 && index == total) return false;
    if (to == -1 && index == 0) return false;
    var items = new Array;
    var values = new Array;
    for (i = total; i >= 0; i--) 
    {
        items[i] = list.options[i].text;
        values[i] = list.options[i].value;
    }
    for (i = total; i >= 0; i--) 
    {
        if (index == i) 
        {
            list.options[i + to] = new Option(items[i],values[i], 0, 1);
            list.options[i] = new Option(items[i + to], values[i + to]);
            i--;
        }
        else 
        {
            list.options[i] = new Option(items[i], values[i]);
        }
    }
    list.focus();
}

 

When you are using asp.Net you can set this script from the code behind like this:

btnUp.Attributes.Add("onclick", "move(" + lstOrder.ClientID + 
".selectedIndex, -1,"+lstOrder.ClientID+")");
btnDown.Attributes.Add("onclick", "move(" + lstOrder.ClientID + 
".selectedIndex,+1," + lstOrder.ClientID + ")");

 

You can now click on the up and down arrows to move an item in the list.

         

I had lots of help from this site: http://javascript.internet.com/forms/selection-order.html


Add en remove items from asp listboxes using javascript

As I told you before, I'm working on a ASP.Net program. Because of the minimal use, I decided to use plain javascript and no AJAX. Also for deployment issues. I have a simple scenario, 2 listboxes. When I add a value to one, it should disappear in the other. Here is the setup:



 

I add the javascript via the code behind to the asp:images. The code is called in the page load event. This is the code that does the trick:

StringBuilder script = new StringBuilder();        
script.Append("javascript:");        
script.AppendFormat("var ind = {0}.selectedIndex;", lstOut.ClientID);        
script.Append("if (ind>-1){");        
script.AppendFormat("var sel = {0}.value;", lstOut.ClientID);        
script.AppendFormat("var len = {0}.length;",lstIn.ClientID); 
script.AppendFormat("{0}.options[len] = new Option({1}.options[ind].text,sel);" 
, lstIn.ClientID, lstOut.ClientID);        
script.AppendFormat("{0}.options[ind] = null;", lstOut.ClientID);        
script.Append("}");        
btnRight.Attributes.Add("onclick", script.ToString());         

script = new StringBuilder();        
script.Append("javascript:");        
script.AppendFormat("var ind = {0}.selectedIndex;", lstIn.ClientID);        
script.Append("if (ind>-1){");        
script.AppendFormat("var sel = {0}.value;", lstIn.ClientID);        
script.AppendFormat("var len = {0}.length;",lstOut.ClientID); 
script.AppendFormat("{0}.options[len] = new Option({1}.options[ind].text,sel);" 
, lstOut.ClientID, lstIn.ClientID);        
script.AppendFormat("{0}.options[ind] = null;", lstIn.ClientID);        
script.Append("}");        
btnLeft.Attributes.Add("onclick", script.ToString()); 

 

This is the Javascript that is generated for the right arrow image:

var ind = ctl00_CPHMiddle_lstOut.selectedIndex;
if (ind>-1){var sel = ctl00_CPHMiddle_lstOut.value;
var len = ctl00_CPHMiddle_lstIn.length;
ctl00_CPHMiddle_lstIn.options[len] = new Option(ctl00_CPHMiddle_lstOut.options[ind].text,sel);
ctl00_CPHMiddle_lstOut.options[ind] = null;}

 

When the user is finished with the listboxes he presses a save button that gets all items out of the right listbox and writes them to the database. This is the second challenge, because you will notice that the Listbox loses the state after a postback. This problem can be solved with a hidden field and more javascript!

This code is placed on the page load, behind the code of the listboxes. This is executed before the postback occurs and it doesn't interfear with the asp event. 

script = new StringBuilder();
script.Append("javascript:");
script.AppendFormat("var len = {0}.length;var values='';", lstIn.ClientID);
script.Append("for (i = 0; i < len; i++){");
script.AppendFormat("values = values + {0}.options[i].text 
+'*'+{0}.options[i].value+'/';", lstIn.ClientID);
script.Append("}");
script.AppendFormat("{0}.value = values;",unitsIn.ClientID);
btnSave.Attributes.Add("onclick", script.ToString());

 

As you can see we place the text and the value in the values array, split up the text and value by a '*' and split up the items with '/'. When we want to extract the values in the event handler of the button, we use the string.split method. The code looks like this:

//Write all untis to the selected department.

List<CCUnit> units = new List<CCUnit>();
string [] strArrunitsIn = unitsIn.Value.Split('/');
foreach (string str in strArrunitsIn)
{
	if (!String.IsNullOrEmpty(str))
        {
        	string[] item = str.Split('*');
                CCUnit unit = new CCUnit();
                unit.Guid = item[1];
                unit.Description = item[0];
                units.Add(unit);
        }
}
//Update
 

You can ask questions or request the complete code be commenting or email.

 

Using Javascript to get values from asp.Net listbox

If you are not so familiar with Ajax, or just not using it, it could be nice to know Javascripting.

I had to extract a value from a listbox and put it into a textbox, also I wanted to keep the selectedvalue somewhere.

This is how I did it:

ListBox1.Attributes.Add("onclick", "javascript:var w = " + ListBox1.ClientID + ".selectedIndex;
" + txtDepartment.ClientID + ".value = " + ListBox1.ClientID + ".options[w].text; 
" + selItem.ClientID + ".value=" + ListBox1.ClientID + ".value");
 

You can go even further, when you want a Text in the listbox and 2 values, you can use string concatination in Javascript. This is a little more complicated, but still easy programming. In the following code I get the values from the listbox, seperate them and set the selected item of a dropdown and the value of a hidden field! In .Net always use the clientID property, because the name of the field depends on where the field is on.

script = "javascript:arrres= " + ListBox1.ClientID + ".value.split('*');";
script += selItem.ClientID + ".value=arrres[0];";
script += drpUserRoles.ClientID + ".value = arrres[1];";
ListBox1.Attributes.Add("onclick", script);

 

I'm not using Ajax for this project, so maybe there will be some more javascript posts in the near future.

 

Get value from Listbox using javascript.

If you are not so familiar with Ajax, or just not using it, it could be nice to know javascipting.

I had to extract a value from a listbox and put it into a textbox, also I wanted to keep the selectedvalue somewhere.

This is how I did it:

ListBox1.Attributes.Add("onclick", "javascript:var w = " + ListBox1.ClientID + ".selectedIndex;
" + txtDepartment.ClientID + ".value = " + ListBox1.ClientID + ".options[w].text; 
" + selItem.ClientID + ".value=" + ListBox1.ClientID + ".value");
 

You can go even further, when you want a Text in the listbox and 2 values, you can use string concatination in javascript. This is a little more complicated, but still easy programming. In the following code I get the values from the listbox, seperate them and set the selected item of a dropdown and the value of a hidden field!

script = "javascript:arrres= " + ListBox1.ClientID + ".value.split('*');";
script += selItem.ClientID + ".value=arrres[0];";
script += drpUserRoles.ClientID + ".value = arrres[1];";
ListBox1.Attributes.Add("onclick", script);

 

I'm not using Ajax for this project, so maybe there will be some more javascript posts in the near future.