Thursday 20 October 2016

Variable scope in JavaScript


See the example code below :

function Test1() {
    // 1)  Declare using var            
    if (true) {
        var x = 10;
    }
    console.log(x); // 10

    // 2) Declare using let
    if (true) {
        let x = 5;
        console.log(x); // 5
    }
    console.log(x); // 10

    // 3) Declare using const
    if (true) {
        const x = 8;
        console.log(x); // 8
    }
    console.log(x); // 10
}

1. Declare variable using var
If you declare variable in JavaScript using var keyword, variable is accessible through out 
the function even thought you declared it inside any loop (e.g if, while...). See the above 
example where x is declared using var keyword inside if loop still it is accessible 
through out the function scope. If you  declare variable without giving any keyword then it becomes global variable even if you declare it inside the function (throw ReferenceError in strict mode). 

2. Declare variable using let 
 let keyword allows you to declare variable withing the limited scope of the block, 
statement or expression. Variables declared using let have their scope to the block 
in which they are defined, as well as in any contained sub-blocks. Unlike var, let does not create a property on the global object. E.g.

var x = 'global';
        let y = 'global';
        console.log(this.x); // "global"
console.log(this.y); // undefined 

You can not re-declare same variable in same scope using let. E.g
        switch (x) {
            case 0:
                let x;
                break;
    
            case 1:
                let x; // SyntaxError for redeclaration.
                break;
    }

See the second example in first code variable scope is limited to block even if you change 
the value it won’t reflect outside the scope.

1. Declare variable using const 
Const keyword is block scoped much like let. It creates a constant that can be either global
or local to the function in which it is declared. Constant initialization is required. You must
specify its value while declaring the constant. Constants once created never change their 
value and can’t be re-declared. The const declaration creates a read-only reference to a 
value but not all values are immutable. If you create object you can alter the values of 
object but can not reassign. E.g.

const A = 10;
// A = 12 // throw error;

const myObj = { "Name""AP" };
// myObj = { "City": "AHD" }; // throw error;

// Object.freeze(myObj);
myObj.Name = "Ajay" // works fine if object is not freezed      

      

Tuesday 13 September 2016

Signature Pad using SVG

HTML :
<svg height="200" width="400" style="background-color:#ffd800;" viewBox="0 0 400 200" >
        <rect id="SignPad" height="200" width="400" fill="#ffa" style="cursor:default;">
        </rect>
        <path id="Sign" stroke="black" stroke-width="2" fill="none" 
pointer-events="none" stroke-linecap="round" />
</svg>

JavaScript :
 $(document).ready(function () {
        var signPad = $('#SignPad'),
        sign = $('#Sign'),
        signaturePath = '',
        isMouseDown = false;

        signPad.mousedown(function (e) {
            signaturePath += 'M' + getCoords(e) + ' L'+ getCoords(e) +' ';
            sign.attr('d', signaturePath);
            isMouseDown = true;
        })

        signPad.mousemove(function (e) {
            if (isMouseDown) {
                signaturePath += 'L' + getCoords(e) + ' ';
                sign.attr('d', signaturePath);
            }
        })

        signPad.mouseup(function (e) {
            isMouseDown = false;
        })

        function getCoords(e) {
            return e.offsetX + ',' + e.offsetY;
        }
    });

Example :

Monday 22 August 2016

Custom File manager in CKEditor


Let’s take CKEditorTest.html. Write below code to use CKEditor in your html page.

<script src="~/Scripts/ckeditor/ckeditor.js"></script>
<script src="~/Scripts/ckeditor/adapters/jquery.js"></script>

<div class="row">    
    <textarea id="txtEditor"></textarea>
</div>

<script>
$(document).ready(function () {

 // Change in CKEditor config allow to set custom file browser Url 
        CKEDITOR.editorConfig = function (config) {

            // Enter Url of your target page which 
                you wants to open on browse button click.
            config.filebrowserBrowseUrl = "http://localhost:12081/filemanager.html";
        }        

        $('#txtEditor').ckeditor();
    });
</ script>

The above script will create instance of CKEditor and also set custom file browser window.

Now in filemanager.html page, Add below script to select file and set in parent CKEditor window. 

<script>
    $(document).ready(function () {
        $("jquery selector").click(function () {

            //  Source path of file
            var url = this.src;
            var parentWindow = (window.parent == window) ? window.opener : window.parent;

            // Find Function number from Querystring
            var funcNum = QueryString('CKEditorFuncNum');

            if (parentWindow['CKEDITOR']) {
                // Invoke function
                parentWindow['CKEDITOR'].tools.callFunction(funcNum, url);
                window.close();
            }
        });
    });

    function QueryString(name) {
        name = name.replace(/[\[]/"\\[").replace(/[\]]/"\\]");
        var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
            results = regex.exec(location.search);
        return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g" "));
    }
</script>

Hooray ! Now you can create your custom file manager with your own settings.

Friday 22 July 2016

Custom Value Provider in MVC

Value providers are components which provides data to model binders. MVC has some default value providers which feed data to model binders.

1.  FormValueProvider  : Fetch data from Request.Form and pass to model binders.

2. RouteDataValueProvider : Fetch data from RouteData.Values

3. QueryStringValueProvider : Fetch data from Request.QueryString

4. HttpFileCollectionValueProvider : Fetch data from Request.Files.

Model binders search data from value providers and bind to the model. Given value providers are default in MVC but you can also create your custom value provider depends on your requirement.  I have wrote small code to create custom value provider.

Create Value provider class :
using System.Web.Mvc;
public class CustomValueProvider : IValueProvider
{
        public bool ContainsPrefix(string key)
        {
            // Do logic as per requirement. e.g here we are cheking for cookie with given  key
            return HttpContext.Current.Request.Cookies[key] != null;
        }

        public ValueProviderResult GetValue(string key)
        {
            // if ContainsPrefix == true then this method called which return actual value of key.
            return new ValueProviderResult(HttpContext.Current.Request.Cookies[key].Value,
                                                                 HttpContext.Current.Request.Cookies[key].Value, 
                                                                 CultureInfo.CurrentCulture);
        }
}

Create Factory to register value provider :

 // Create Factory for your Value provider
    public class MyCustomValueFactory : ValueProviderFactory
    {
        public override IValueProvider GetValueProvider(ControllerContext controllerContext)
        {
            // Register custom value provider
            return new CustomValueProvider();
         }
    }

And last step, Add factory to value providers factories in Application_Start event in global.asax

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {            
            // Register custom value provider factory
            ValueProviderFactories.Factories.Add(new MyCustomValueFactory());
        }
}

Your custom value provider is ready. Now let’s use it in real code.
 public ActionResult Index()
 {
     Response.Cookies.Add(new HttpCookie("ajay""Ajay Patel"));
     return View();
 }

[HttpPost]
public JsonResult TestPostMethod(string ajay)
{
     return Json("Hey I got value :)");
}

Model binders search “ajay” in default values providers if not found from default providers  then search in custom value providers. If model binder found value of “ajay” then it will stop search further for same parameter and search for next parameter if any.

That’s All.