Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Wednesday, June 17, 2015

Minify CSS and JS files through PowerShell scripts

The below scripts can be used in scenarios where you need to minify CSS and JavaScript files of your website using PowerShell Scripts. (For example, during Post-build PowerShell scripts in TFS build).

Pre-requisite:
Microsoft Ajax Minifier should be installed on the machine (or TFS build server) where the PowerShell scripts would be executing.
Ajax Minifier can be downloaded from here.

PowerShell scripts to minify CSS files in a directory:

function applyCssMinification($dir)
{
$Minifier = “C:\Program Files (x86)\Microsoft\Microsoft Ajax Minifier\AjaxMin.exe”
get-childitem $dir -recurse -force -include *.css -exclude *.min.css | foreach-object {&$Minifier $_.FullName -out $_.FullName -clobber}

}

PowerShell scripts to minify JavaScript files in a directory:

function applyJsMinification($dir)
{
$Minifier = “C:\Program Files (x86)\Microsoft\Microsoft Ajax Minifier\AjaxMin.exe”
get-childitem $dir -recurse -force -include *.js -exclude *.min.js | foreach-object {&$Minifier $_.FullName -out $_.FullName -clobber}
}

Once defined call these functions by providing CSS and JS directory path as a parameter:

For example,

applyCssMinification "$Env:TF_BUILD_SOURCESDIRECTORY\Website\Content\CSS"


applyJsMinification "$Env:TF_BUILD_SOURCESDIRECTORY\Website\Content\Scripts"

Tuesday, July 15, 2014

FIX: CKEditor not showing up when site is deployed on IIS server (ckeditor-full version 4.4.2)

Scenario:

Recently, I came across an issue due to which CKEditor was not showing up after deploying website in IIS. It was showing an empty placeholder instead. It was showing up completely fine in development environment, and while running site through Visual Studio.

I had "ckeditor-full" (Version 4.4.2)" package added in my MVC project, and also bundles to load "\ckeditor\adapters\jquery.js" and "ckeditor\ckeditor.js" javascript files in the project.

I checked in the code but it all looked fine.

As a resolution, it turned out that, I had to include following line in my view before loading the bundles -

<script type="text/javascript">
    CKEDITOR_BASEPATH = "@Url.Content("~/Scripts/ckeditor/")";
</script>

Hope this will help someone.

Thursday, January 2, 2014

Accessing Model property in MVC View from Javascript

For example, you have following model in your MVC application:

public class Employee
{
public string EmployeeName
public int EmployeeNumber
}

You have bound this model to your MVC view (Razor/ Html), and there may be a case when you need to access "EmployeeName" in the Javascript from that view.

You can access value of "EmployeeName" property of your model by following way:

<script type="text/javascript">
function showEmployeeName()
{
alert('@(Model.EmployeeName)');
}

</script>

Wednesday, July 31, 2013

Replacement of InnerText property, while updating display text of elements such as (span, etc) in HTML.

This article aims to provide a javascript function to update display text of controls such as (SPAN, etc) in HTML using javascript. 

Generally, we tend to update innerText  property of such elements in this scenario, but when it works perfectly as expected in IE and Chrome, it fails in Firefox. Because,it's not supported.

Instead, include below javascript function in your JS library, and call it. This is more elegant and cross-browser solution of this problem.



function setTextContent(element, text) {
    while (element.firstChild!==null)
        element.removeChild(element.firstChild); // remove all existing content
    element.appendChild(document.createTextNode(text));
}


Sample call:

setTextContent($('span.displayText), result);

Friday, July 5, 2013

When should we not use MVC bundling?

As we all know MVC bundling and minification is a very powerful feature, but recently I faced a strange problem in one of the project as detailed below.

I was using Trent Richardson's Timepicker control to avail time picker functionality in my MVC 4 application. I had relevant JQuery file bundled using MVC bundling feature. I found this working quite well in development environment (Visual Studio 2012).
But when I deployed the website on IIS, I started facing a strange issue, and there was a javascript error "function expected" in that particular bundle. I could see the bundle got loaded because developer tool was showing javascript code when that bundle was selected in "scripts" tab.

Finally, when I referenced the JQuery file directly instead of bundle, it started working fine on IIS. Though the problem got solved, I was than now curious to know what was wrong with that particular file if bundled, and if MVC bundling was actually an issue, then why it was working well in development environment, but not in IIS?

Posting this on various forums gave me following two detailed answers which helped me in identifying in which situations we should avoid using bundling -

Answer 1

Minification is a complex process by making scripts/styles smaller using techniques such variable name shortening, white space elimination, comments removal, etc... It uses ASP.NET Web Optimization that depends on WebGrease for minification. Of course, there can have issues but I personnaly never noticed that.
Here are some situations, where you should not use bundling
  • There is only one file in your bundle. Why bundling ?
  • You are using only famous frameworks such as JQuery or jQuery UI. Do not redistribute scripts that are already served by someone else. Google/Microsoft/Amazon/... already provide CDN for the most popular, open-source JavaScript libraries.
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
  • Your bundle takes only a few Bytes. Web performance Optimization suggests to limit the number of web requests. Everything has a cost. Not very optimal, but sometimes it's better to put inline scripts in your page.
  • In some architectures. Bundles requests contains a unique identifier used for caching. If any file in the bundle changes, the ASP.NET optimization framework will generate a new token, guaranteeing that browser requests for the bundle will get the latest bundle. When working with some architectures, JS updates can be frequent and will invalidate all your bundles.
  • On Dev Environment. It's is really really painful to debug a bundle.
Answer 2

What bundling suppose to do is to put together the script/stylesheet files in a single bundle into a single request and send it to the client so that the browser has to make less calls to get those required script files. In a development environment, when you do debugging in visual studio. It doesn't do the above process unless you specify it to do so. But in a production environment, when the debug is set to false in the web.config file. it will start to do the above process. There can be some other reasons as well. such as the script might have two versions. one for debugging and one for production. I came across such a situation with knockout. in my development environment I had referenced the debug version of the script. But when I put it into the production environment, everything came to a hault. There was a release version for the 
knockout script file and I had to reference that to make everything work again
 
 
Hope this will help you

Tuesday, June 25, 2013

Javascript: Function to check if the string is numeric (i.e. valid number)

Following is the javascript function which accurately validates if the supplied string a valid number or not.

function isNumber(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}



Trim, Ltrim, Rtrim, FullTrim - trimming string functions in Javascript


JQuery 1.9+ have inbuilt functions for string trimming, but they aren't supported in many browsers, such as, IE 8, IE 9, etc., and so I refrain myself from using those function, and hence there is a need to have our custom function to perform this job!

Following are javascript functions for trimming strings: 

function StringTrim(inputText){return inputText.replace(/^\s+|\s+$/g, '');};

function StringLtrim(inputText){return inputText.replace(/^\s+/,'');};

function StringRtrim(inputText){return inputText.replace(/\s+$/,'');};

function StringFulltrim(inputText){return inputText.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' ');};

Add them in javascript library of your application, and you can use them to trim strings in various ways, such as, left trim, right trim, trim, and full trim.

Hope this helps!

Friday, October 5, 2012

Convert string into a date, Add days to a date, Format date in different date format in JQuery

This article aims to explain writing a Javascript method (using JQuery functions) to achieve following:
- Convert a string into a date
- Add days to the date
- Format date into a valid date format

Prerequisites:
- JQuery library (For example, jquery-1.5.1.min.js, etc)

Source code:
<script type="text/javascript">
function ConvertToDate(strDate, dayPartIdx, monthPartIdx, yearPartIdx) {
//Pass dayPartIdx, monthPartIdx, yearPartIdx parameters depending upon the date format in strDate
//If its dd/mm/yy - pass 0,1,2 respectively.
        var day = strDate.split("/")[dayPartIdx],
        month = strDate.split("/")[monthPartIdx],
        year = strDate.split("/")[yearPartIdx];
        month = month - 1; //Date function considers 0 as January
        var convertedDate = new Date(year, month, day,0,0,0,0);
        return convertedDate;
    }

    function AddDaysToDate(strDate, numDays) {
        var dtDate = ConvertToDate(strDate, 0, 1, 2);
        var ms = dtDate.getTime() + (86400000 * numDays);
        return $.datepicker.formatDate('dd/mm/yy', new Date(ms));
    }
</script>

Sample call:
alert(AddDaysToDate('20/09/2012', 30));

P.S. - It is assumed that the passed string "strDate" is a valid date. However, you can add more validations to validate it before attempting to convert into a date.

Thursday, May 10, 2012

Incremental and Decremental operators in .NET and JavaScripts

Some things are easiest to learn.. but hard to recollect with spontaneity, if we are asked to.
Incremental and Decremental operators fall in the same category, may be even for experienced programmers.

To avoid confusions, I am herewith writing a simple scenario.
Note, Incremental and Decremental operators are having same behavior in .NET and JavaScript.


i= 1 //Initial value assignment.
i++= 1 //This is, post-incremental; it will first return and than increment.
i= 2 //i was incremented by 1 during above statement.
++i= 3 //This is, pre-incremental; it will first increment and than return.
i= 3 //i was incremented by 1 during above statement.
i+=1= 4 //same as ++i.
i= 4 //i was incremented by 1 during above statement.
i--= 4 //This is, post-decremental; it will first return and than decrement.
i= 3 //i was decremented by 1 during above statement.
--i= 2 // This is, pre-decreemental; it will first decrement and than return.
i= 2 //i was decremented by 1 during above statement.
i-=1= 1 //same as --i.
i= 1 //i was decremented by 1 during above statement.

Sunday, May 6, 2012

Investigation: "'google' is undefined" - while working with Google Map Controls

Recently, I ran into a strange issue while working with Google Map Controls.
I was using GoogleMap Controls version 6.0, and for that I included "Artem.Google.dll" downloaded from codeplex site.
My webpage has only "asp:ScriptManager", and a google map control from Artem.Google.UI namespace.

It was working fine with Firefox and other browsers, but it was giving me error of "'google' is undefined in some javascript. Though I had no javascript in my webpage, I could easily guess this is somewhere in Web resources that's been requested from Artem.Google.DLL.
Even I tried with the sample solution codeplex has provided, and I was facing the same issue in IE and Chrome.

Finally, when I ran fiddler alongside browsing the website in Internet Explorer, I could see some of the javascripts (which are added as web resources in DLL) are not getting downloaded, and the reason was the firewall security rules. Once I unblocked specific contents from firewall, it started working!

So whenever you face this issue, make sure your internet explorer is able to access all the java scripts that are being referenced as a web resource in your DLL.

You can easily check this in a fiddler.
Keep Fiddler running while attempting to access your site in Internet Explorer.
Once you receive "'google' is undefined error", move back to Fiddler, and check on which request it failed. 
To check that, just select any resource request entry in left-hand side pan, and click "webview" tab on right-hand side to see what response it got while requesting a resource.

Hope this will help!

Wednesday, April 18, 2012

Investigation: SelectedIndexChanged not firing for DropDownList or RadioButtonList

Issue: SelectedIndexChanged event not firing for a DropDownList or a RadioButtonList, CheckBoxList or any control that is inherited from "ListControl" abstract class.

Following can be the possible reasons:
1. AutoPostBack is not set to true for these controls.
Set this property to true.
2. Script execution is turned off for browser.
SelectedIndexChanged event is dependant on background JavaScript methods. So, if the Javascript is turned off for the browser then this event will not be fired.
So, in this case, either you need to enable javascript for the browser.
Or, if you absolutely cannot enable it (due to strange requirements of your users), you need to place a button besides the dropdown. You do not need to write Click event for this button, as Buttons are postback controls, so and clicking on that will invoke the postback, and that will automatically fireup all SelectedIndexChanged events which were pending since last postback.
3. If you are using Telerik's RadAjaxManager, make sure you are adding the controls properly in RadAjaxManager.
For example,
RadAjaxManager1.AjaxSettings.AddAjaxSetting("rbOptions","rbOptions",null);

Tuesday, April 17, 2012

Development and Deployment - Troubleshooting, Investigations (Series of articles)

At times, we, developers or deployment people do come across some technical problems that eat up our hours (and days sometimes).. and when we find the resolution, or real cause of the issue, it makes us feel that such issues were not worth of the time and efforts we spent.

Here, I am making a collection of such issues/ troubleshooting notes that may help us to take extra care in order to avoid that issues raising while we develop or deploy.

There are each new post for each different issue/ troubleshooting note, and this post is an index that will keep growing as I add new post in this category.

Keep checking this place regularly.

INDEX:

ASP.NET



ASP.NET MVC

Monday, April 16, 2012

Print Page Content to printer (or virtual print output) in ASP.NET using iFrame

Sometimes, there is a need to give user a facility to print the web page contents (or part of them) as they appear in their browser.

This article is to explain how we can achieve the same using iFrame, and javascript:

While designing your webpage, you should decide which contents should allowed to be printed, and can wrap them within DIV or any HTML container. (You can also print all contents of your page)

For this example, lets assume the DIV (with ID - "divFormContents") contains the contents you facilitate users to print.

Now, add an iFrame (with id = ifmContents, and with following style) in your webpage:

height: 0px; width: 0px; position: absolute

Write following javascript in your webpage.


function printPageContents() {
var content = document.getElementById("divFormContents");
var printContents = document.getElementById("ifmContents").contentWindow;
printContents.document.open();
printContents.document.write(content.innerHTML);
printContents.document.close();
printContents.focus();
printContents.print()
}

Finally, write a call to this javascript method (printPageContents())

That's all we need to do, and the users will now be able to print all the contents that reside within the container ("divFormContents") in our example

Show long text in Tooltip

As we all know, standard ToolTip property of ASP.NET server controls is having a limit of number of characters. Means if you have a long text of say, 10-12 lines, and some hundreds of words, the tooltip will be truncated in browser after a certain limit.

JQuery plugin is providing its own control to deal with this limit. But, in case, your project has not included JQuery libraries, you can still achieve this by writing some javascripts and attaching them in your controls.

For this, you first need to write javascript methods that will overwrite default behavior of tooltip. Technically speaking, you need to write methods for "onmouseover" and "onmouseout" respectively as follow:


function showCustomTooltip(hostControl) {
//hostControl = control where you want to override Tooltip
var tooltipText = hostControl.title;
var toolTipContainer = document.createElement('SPAN');
var textNode = document.createTextNode(tooltipText);
toolTipContainer.appendChild(textNode);
hostControl.parentNode.insertBefore(toolTipContainer, hostControl.nextSibling);
toolTipContainer.className = "customTooltipCss";
hostControl.title = "";
}
function hideCustomTooltip(hostControl) {
var controlText = hostControl.nextSibling.childNodes[0].nodeValue;
hostControl.parentNode.removeChild(hostControl.nextSibling);
hostControl.title = controlText;
}


next thing is to, attach this methods to the controls where you want to show tooltip. Say, the control name is "lblInfo"

protected void Page_Load(object sender, EventArgs e)
{
lblInfo.Attributes.Add("onmouseover", "showCustomTooltip(this)");
lblInfo.Attributes.Add("onmouseout", "hideCustomTooltip(this)");
}


Finally, as you can in the JavaScript code that I have assigned "className" property to "customTooltipCss" we need to add this class in CSS file (or whatever method you are using for accessing styles in your page.)


.customTooltipCss
{
position: absolute;
width: 400px;
margin: 1px;
padding: 2px;
background: #FFFFBB;
border: 1px solid lightgray;
}


That's all we need to do.
Please see screenshot to see how the tooltip appears while implemented using above method.

Wednesday, April 11, 2012

How to validate a page using Java script

Lets consider a following scenario:

There is a web page which has many input control, and validators (required field validator, custom validator, etc).

Now, there is a link button which already has some javascript written for its "onclientclick" event.
So, generally when this button is clicked:
a. First,it will execute java scripts written in onClientClick
b. page-level validations (i.e. required field validators, etc) will be performed
c. if page-level validations are passed, server-side validations will be performed
d. if server-side validations are passed, server-side Click event will be executed.

So, even if the inputs are invalid, it will always execute, onClientClick.

But there are certain cases when you need your main code of OnClientClick javascript to be executed only if the page is valid.
In such cases, you can add a code to validate page in your onClientClick method, and to allow execution of further code only if page is valid. For that, we can use "Page_ClientValidate" and "Page_IsValid".

Write following java script in "onclientclick" event of that link button in order to achieve this -


OnClientClick = "if(typeof(Page_ClientValidate) == 'function')
{ Page_ClientValidate(); if (Page_IsValid == true) { JavaScriptFunctionForTargettedAction(); } } return false;"/>


Here JavaScriptFunctionForTargettedAction() is the javascript code/ method you have originally intended to execute in onclientclick evnet