a developer's notes – a semi-technical web development BLOG

May 13, 2015

Javascript Namespace Function Expression Sample

Filed under: Javascript / JQuery — Duy Nguyen @ 12:05 pm
Tags: , ,

A sample of how to structure your JS file per page. This works good for organizational purposes and it will avoid name clashing.

var PageName = {

// define your functions as variables.
    bindCheckBox: function () {
        $("#mycheckbox").on("click", function () {
            PageName.checkboxClick();
        });
    },

    enableConfirmButton: function (bool) {
        if (bool)
            $("#mybutton").removeAttr("disabled");
        else
            $("#mybutton").attr("disabled", "disabled");
    },

    checkboxClick: function () {
        if ($("#mycheckbox").is(":checked"))
            this.enableConfirmButton(true);
        else
            this.enableConfirmButton(false);
    }
}

// Start of document.ready in jquery
$(function () {
    // calling the global variable you created.
    PageName.bindCheckBox();
});

If you want to use an Immediately Invoked Function Expression (IIFE)


(function() {
     // This creates a function that invokes itself with NO GLOBAL FUNCTIONS.
}());

November 13, 2014

Form Validation with Javascript events. Handle Input, Paste, and Keyup across all browsers

Filed under: Javascript / JQuery — Duy Nguyen @ 12:47 pm
Tags: , , , , , , , ,

While testing mobilePay in Chrome on an Android device, it was discovered that the
keyupevent was not firing for validation. Our response was to include input, an HTML5 event, to ensure that changes were firing the validation handlers.

$('form :input').on('keyup input', this.toggleSubmitBtn);

Currently, we are validating the form on every user’s input change, which would enable/ disable the submit button. The disadvantage of this is that we have to capture every single event that the user could possibly interact with the element.

The paste event is one of the events that we recently have implemented to handle. The inputevent we realize fires when the user pastes in an HTML5 browser, which means only non-HTML5 browsers actually need the pasteevent. Below is a table of support for paste validation:

$('form :input').on('keyup input paste', this.toggleSubmitBtn);

The paste event fires across all test devices, but javascript validation logic is carried out beforethe data on the clipboard gets placed into the element. Because all the browsers except for IE8 supported HTML5, however, the inputevent fired afterthe clipboard data was placed in the element. Without the inputevent, none of the browsers supported paste validation.

Solution

InputPropertyChange: function () {
    if (!window.addEventListener) { //IE 5-8 
        var $inputs = $("input[type!='hidden']");
        $.each($inputs, function (index, input) {
            $(index).on('paste'), function () {
                setTimeout( function() {
                    $(input).trigger('keyup');
                }, 250);
            }                
        });
    }
}

This was written up by my colleague Will Hanson and I.

April 25, 2014

jquery.validate : Unable to get property ‘getAttribute’ of undefined or null reference

Filed under: Javascript / JQuery — Duy Nguyen @ 12:31 pm
Tags: , , , , ,

I got this error recently in jquery.validate.js:
“Unable to get property ‘getAttribute’ of undefined or null reference”

Jq_ErrorAttr

GetAttributeError

Turns out the error was from a input type checkbox needing a name attribute and not just an Id attribute.

April 2, 2014

Using HTML5 Data Annotations for Zipcode and Telephone Numbers

Filed under: ASP.NET MVC,Javascript / JQuery — Duy Nguyen @ 11:22 am
Tags: , , , , , ,

Setup your view model properties with HTML 5 attributes:

[Required]
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }

[Required]
[DataType(DataType.PostalCode)]
public string ZipCode { get; set; }

Then in your script file, you can have controls use jquery.MaskedInput and also add the bootstrap css class “form-control”

    setupMaskInputs: function () {
        // Any view model property that has a [DataType(DataType.PhoneNumber)] attribute, renders type=tel
        if ($("input[type='tel']").length > 0) {
            $("input[type='tel']").mask("(999) 999-9999? ext.9999", { placeholder: " " });
        }

        // Any view model property that has a [DataType(DataType.PostalCode)] attribute, renders type=zip
        if ($("input[type='zip']").length > 0) {
            $("input[type='zip']").mask("99999?-9999", { placeholder: " " });
        }

        // @Html.EditorFor is used to render any inputs that need the html 5 type attributes.
        // But @Html.EditorFor, won't allow you to add a css class, so we do it here.
        $('input[type=text],input[type=tel],input[type=datetime],input[type=date],input[type=number],input[type=password],textarea,input[type=email],input[type=url],input[type=zip]').each(function (idx, item) {
            if (!$(item).hasClass('form-control'))
                $(item).addClass('form-control');
        });
    }

March 8, 2014

Jquery Validation Unobtrusive with ASP.NET MVC

Filed under: Javascript / JQuery — Duy Nguyen @ 2:46 pm
Tags: , , , , ,

Things to remember:

1. Input controls must be wrapped within a form
2. For validation messages to appear, you must have a validation message property for each input.

@Html.TextBoxFor(x => x.MyTextBox)
@Html.ValidationMessageFor(x => x.YourProperty)

3. If you want the validation message to appear immediately upon page load, you have to run this jquery method:

$('form').valid();

4. You can customize your validation message style with these css classes that you can override:

.field-validation-error span{
     color: red;
}

//Adds an asterisk before the message
.field-validation-error span:before{
     content: "*";
}

input.input-validation-error{
     border: 1px solid red;
}

January 30, 2014

jquery.validate.unobtrusive VS jquery.unobtrusive-ajax

jquery.validate.unobtrusive is directly from jQuery.
jquery.unobtrusive-ajax is Microsoft’s version, that uses jquery.validate.unobtrusive.

January 29, 2014

Dynamically added checkbox not posting value to Action Method in controller

I noticed that @Html.CheckboxFor(model => model.MyCheckBox) creates a hidden input with the same name as the actual checkbox. So when you dynamically add a checkbox, make sure you also add in a hidden input with the same name attribute.


var chkboxDiv = $(document.createElement('div')).attr({
	id: 'dynamicChkBoxdiv_'
});

chkboxDiv.html(
	'<input ' +
		'class="myChkBx"' +
		'type="checkbox"' +
		'value=""' +
		'data-val-required="The Active field is required."' +
		'data-val="true"' +
		'name="myChkBxName"/>' +
	'<input ' +
		'type="hidden"' +
		'value=""' +
		'name="myChkBxName"/>' +
);

You also need to add a click event handler to update the hidden value so when the form is submitted, the controller will get the correct ‘checked’ value.

Notice the second parameter that specifies a css class. When you add your dynamic controls, add a css class so you can specify which elements should get the click event delegate. All of your dynamically added controls that have the css class, will now have the same click event.

$("#dynamicChkBoxdiv_").parent().on("click", '.myChkBx', function (e) {
	var name = e.target.name;
	var checkVal = e.target.checked;
	$("input[name^='" + name + "']").val(checkVal); //this will update both the checkbox and hidden input's value
});

Binding Click Events to dynamically added controls with jQuery

Filed under: Javascript / JQuery — Duy Nguyen @ 1:23 pm
Tags: , , , , , , , , , ,

When you dynamically add controls, make sure the container that the controls are added to, has an ID attribute.

Example:

<div id="dynamicCollectionDiv">
           //dynamic controls are added inside this div
</div>

Then you can use jquery to add a ‘click’ delegate on any newly added controls. You used to be able to use the “.live” method but this is now deprecated. Use the “.on” method instead. You must reference the parent container to do the actual binding.

$("#dynamicCollectionDiv").parent().on("click", '.dynamicControlCssClass', function () {
        // do something
    });

Notice the second parameter that specifies a css class called “dynamicControlCssClass.” When you add your dynamic controls, add a css class so you can specify which elements should get the click event delegate. All of your dynamically added controls that have the css class “dynamicControlCssClass,” will now have the same click event.

January 22, 2014

MVC 4 – Using HTML5 “data-” attributes with Jquery

Filed under: ASP.NET MVC,Javascript / JQuery — Duy Nguyen @ 11:55 am
Tags: , , , , ,

You can create data- HTML attributes with your controls using this technique.

Define a new HTML Attributes anonymous object with your Html helpers. Below, I create a text box with some additional properties I want to be able to access with jQuery. Using properties that start with “data_”, you will be able to access the property with jquery’s data() method. Note: using property names that start with “data-” will result in a compilation error.

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>
<h1>Tesing data-properties in MVC</h1>

<div>@Html.Label("Product: ")@Html.Label("Book")</div>
@Html.Label("Quantity:")

@Html.TextBox("myTextbox", "", 
    new
    {
        @class = "myCssClass",
        data_my_new_property = "hello world",
        //data-dashTest = "hello dashTest", This will not work. Compilation Error 
        data_product_id = "productId1",
        data_minimum ="0",
        data_price = "5.00",
        data_val = "true",
        data_val_number = "The field Quantity must be a number.",
        data_val_range = "The field Quantity must be between 0 and 10000.",
        data_val_range_max = "10000",
        data_val_range_min = "0",
        data_val_required = "The Quantity field is required.",
        @style = "width: 100px;"
    })

<input type="button" value="clickMe" />

<script>
    $(function () {
        var $qtyInput = $('.myCssClass');
        var myProperty = $qtyInput.data().price; // value is 5.00
        //You can also do this
        var txBox = document.getElementByID('myTextbox');
        console.log(txBox.getAttribute('data-my-new-property'));
    });

</script>

This is the HTML that gets rendered

<input name="myTextbox" 
class="myCssClass" 
id="myTextbox" 
style="width: 100px;" 
type="text" value="" 
data-val-required="The Quantity field is required." 
data-val-range-min="0" 
data-val-range-max="10000" 
data-val-range="The field Quantity must be between 0 and 10000." 
data-val-number="The field Quantity must be a number." 
data-val="true" 
data-my-new-property = "hello world",
data-product-id="productId1" 
data-price="5.00" 
data-minimum="0">

Here is what jquery’s data() method converts property names to. Interestingly, the underscores are removed and camel casing is applied to the name.

data-dash-watch

Here is another good article on the subject.
http://unmatchedstyle.com/news/html5-data-attributes-jquery.php

January 8, 2014

How to add / remove textbox dynamically with jQuery

Filed under: Javascript / JQuery — Duy Nguyen @ 10:00 pm
Tags: , , , , , , ,

This is a great tutorial!
http://www.mkyong.com/jquery/how-to-add-remove-textbox-dynamically-with-jquery/

<html>
<head>
<title>jQuery add / remove textbox example</title>
 
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
 
<style type="text/css">
	div{
		padding:8px;
	}
</style>
 
</head>
 
<body>
 
<h1>jQuery add / remove textbox example</h1>
 
<script type="text/javascript">
 
$(document).ready(function(){
 
    var counter = 2;
 
    $("#addButton").click(function () {
 
	if(counter>10){
            alert("Only 10 textboxes allow");
            return false;
	}   
 
	var newTextBoxDiv = $(document.createElement('div'))
	     .attr("id", 'TextBoxDiv' + counter);
 
	newTextBoxDiv.after().html('<label>Textbox #'+ counter + ' : </label>' +
	      '<input type="text" name="textbox' + counter + 
	      '" id="textbox' + counter + '" value="" >');
 
	newTextBoxDiv.appendTo("#TextBoxesGroup");
 
 
	counter++;
     });
 
     $("#removeButton").click(function () {
	if(counter==1){
          alert("No more textbox to remove");
          return false;
       }   
 
	counter--;
 
        $("#TextBoxDiv" + counter).remove();
 
     });
 
     $("#getButtonValue").click(function () {
 
	var msg = '';
	for(i=1; i<counter; i++){
   	  msg += "\n Textbox #" + i + " : " + $('#textbox' + i).val();
	}
    	  alert(msg);
     });
  });
</script>
</head><body>
 
<div id='TextBoxesGroup'>
	<div id="TextBoxDiv1">
		<label>Textbox #1 : </label><input type='textbox' id='textbox1' >
	</div>
</div>
<input type='button' value='Add Button' id='addButton'>
<input type='button' value='Remove Button' id='removeButton'>
<input type='button' value='Get TextBox Value' id='getButtonValue'>
 
</body>
</html>
Next Page »

Create a free website or blog at WordPress.com.