This is the javascript coding standard that my colleague found on Github, but seriously this is a good standard and I recommend it to any developer
Category: Javascript Page 1 of 2
Javascript code
By using this library, it allows you to do the paging through the HTML DOM from the client side (Note: this is not about the ideal way or not the ideal way, I know the ideal way is to do paging server side)
To implement you just need to do 3 things:
1. Create a div container that wraps the container of item that you want to repeat and the navigation div, you can call it whatever you want
2. Create a div inside the container with class “page_navigation”
3. put class “content” on the container of the list item
Sample
- <div id=”page_container”>
- <div class=”page_navigation”></div>
- <ul class=”content”>
- <li>
- <p>One</p>
- </li>
- <li>
- <p>Two</p>
- </li>
- <li>
- <p>Three</p>
- </li>
- <li>
- <p>Four</p>
- </li>
- <li>
- <p>Five</p>
- </li>
- <li>
- <p>Six</p>
- </li>
- <li>
- <p>Seven</p>
- </li>
- <li>
- <p>Eight</p>
- </li>
- </ul>
- </div>
and I put this code on the document.ready event based on the id set on item 1
- <SCRIPT>
- jQuery(document).ready(function () {
- jQuery(‘#page_container’).pajinate({ items_per_page: 2 });
- });
- </SCRIPT>
The source code can be downloaded from here
and you can read the documentation from this github page
Knockout allows you to bind the HTML to your javascript object. It simplifies DOM manipulation and allow the portability of the javascript object and action. It is pretty much the same concept as MVVM in silverlight. You can wire up the function with button click easily, you can have for each against your array (e.g like repeater). It is so elegant, but debugging sometimes can be challenging as well. I’ve used Knockout along with JSON that allows me to build rich and interactive website
2 powerful function: ko.observable – this allow knockout to monitor this object value, ko.observableArray this is the extension of ko.observable against the array. With observable, knockout will keep tracking the value of that property and allow the DOM that has been bind against it to refresh
You can bind initial data from your MVC model to the variable in javascript and bind it, in this sample below, I use ToJson extension function
- namespace System.Web.Mvc
- {
- public static class HtmlHelperExtensions
- {
- ///<summary>
- /// Serializes an object to Javascript Object Notation.
- ///</summary>
- ///<param name=”item”>The item to serialize.</param>
- ///<returns>
- /// The item serialized as Json.
- ///</returns>
- public static string ToJson(this object item)
- {
- return new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(item);
- }
- }
- }
Sample code
- <script type=”text/javascript”>
- var initialData = @(new MvcHtmlString(Model.ToJson()));
- function JobResultViewModel()
- {
- var self = this;
- self.Jobs = ko.observableArray(initialData.JobSearchResults);
- self.Search = ko.observable(initialData.JobSearchModel);
- self.Pageno = ko.observable(initialData.PageNo);
- self.TotalPage = ko.observable(initialData.TotalPage);
- self.TotalRecord = initialData.TotalRecord;
- self.ShowNextButton = ko.computed(function(){
- return self.Pageno() < (self.TotalPage() – 1);
- });
- self.LoadNextPage = function() {
- $.getJSON(‘@Url.Action(“ResultJson”)‘, { Keyword: (self.Search().Keyword == null) ? “” : self.Search().Keyword,
- ProfessionId: self.Search().ProfessionId,
- RoleIds: self.Search().RoleId,
- SalaryTypeId: self.Search().SalaryTypeId,
- SalaryFromId: self.Search().SalaryFromId,
- SalaryToId: self.Search().SalaryToId,
- LocationId: self.Search().LocationId,
- AreaIds: (self.Search().AreaId.length == 0) ? 0 : self.Search().AreaId,
- WorkTypeId: self.Search().WorkTypeId,
- Pageno: self.Pageno() + 1
- }, function (SearchResult) {
- $.each(SearchResult, function(i, item)
- {
- self.Jobs.push(item);
- });
- self.Pageno(self.Pageno() + 1);
- //we need to refresh the repeater when we use jquery mobile ONLY
- $(“#JobRepeater”).listview(“refresh”);
- });
- }
- }
- ko.applyBindings(new JobResultViewModel());
- </script>
- <h2>Result</h2>
- <h1>There are <span data-bind=”text: TotalRecord”></span> jobs</h1>
- <a>Save Search</a>
- <ul name=”JobRepeater” id=”JobRepeater” data-role=”listview” data-bind=”foreach: Jobs”>
- <li><a data-bind=”attr: { href: UrlAction, title: JobName },text : JobName”></a><span data-bind=”text: Description”></span></li>
- </ul>
- <div data-bind=”visible: ShowNextButton”>
- <input type=”button” id=”btn_load_next” value=”Load More” data-bind=”click: LoadNextPage”/>
- </div>
Source:
Initially, I always pass individual object properties through JSON and form the model in the controller as I wasn’t sure how to pass/form a model from Javascript to controller
Controller
- [AllowAnonymous]
- public ActionResult JsonRegister(string username, string password, string confirmpassword,
- string email, string confirmemail)
- {
- MemberModel.RegistrationModel model = new MemberModel.RegistrationModel() {
- UserName = username,
- Password = password,
- ConfirmPassword = confirmpassword,
- Email = email,
- ConfirmEmail = confirmemail };
Javascript
- $.getJSON(‘@Url.Action(“JsonRegister”)‘, { UserName: $(“#UserName”).val(),
- Password: $(“#Password”).val(),
- ConfirmPassword: $(“#ConfirmPassword”).val(),
- Email: $(“#Email”).val(),
- ConfirmEmail: $(“#ConfirmEmail”).val()
- }, function (RegisterResult) {
- if (RegisterResult.success) {
- $(‘#RegistrationFields’).hide();
- $(‘#ErrorMessage’).text(”);
- $(‘#RegistrationMessage’).css(‘display’, ”);
- }
- else {
- $(‘#ErrorMessage’).css(‘display’, ”).text(RegisterResult.errors);
- }
- });
the code above is working just fine but I still feel that there is room for improvement. Below is the code that shows how you can still have your controller accepting the model instead of expanding the properties in the model as the parameters to the controller. The solution is just to have the model being assigned to a variable (in this context called as data) before passing it to the JSON, my previous code was forming the actual object in the JSON code
Controller
- [AllowAnonymous]
- public ActionResult JsonRegister(MemberModel.RegistrationModel model)
- {
- string error = string.Empty;
- if (ModelState.IsValid)
Javascript
- var data = { UserName: $(“#UserName”).val(),
- Password: $(“#Password”).val(),
- ConfirmPassword: $(“#ConfirmPassword”).val(),
- Email: $(“#Email”).val(),
- ConfirmEmail: $(“#ConfirmEmail”).val()
- };
- $.getJSON(‘@Url.Action(“JsonRegister”)‘, data, function (RegisterResult) {
- if (RegisterResult.success) {
- $(‘#RegistrationFields’).hide();
- $(‘#ErrorMessage’).text(”);
- $(‘#RegistrationMessage’).css(‘display’, ”);
- }
- else {
- $(‘#ErrorMessage’).css(‘display’, ”).text(RegisterResult.errors);
- }
- });
I’ve been learning Knockout recently and I found that sometimes it is hard to find out how your View Model is being formed especially when you create the view from Model in MVC
To inspect your view model, you can use firebug console and run below command, this will give you a full navigated View Model and allow you to drill down
console.group(“Dumping view model”);
console.dir(ko.toJS(new JobResultViewModel()));
console.groupEnd();
alternatively you can also put this code in your template
<div data-bind=”text: ko.toJSON($data)”></div>
Feel free to let me know if you have any other way to debug
I was struggling in finding out of how to make a simple delegate like in AJAX request through javascript. It takes me a few days to figure this out
Basically the problems are:
-I need to execute a piece code of javascript after getting the ticket from web service function
-The webservice function might not be responding to the first request because it waits for the state of the other external component
-The webservice will give the response when the external component is ready
-The client does not know when the external component is ready, neither the web service. But it wil be ready within 1-5 minutes which again depending external component
Possible Solution:
-Using the setTimeOut(function(){acquireTicket();}, 300000) will cause the application to wait for 5 mins before calling the web service , this approach will slowing down the user experience and waste of time because the external component can be ready earlier than 5 mins
-Using the while loop is not good because it makes the browser freezing while waiting and it will wasting the processing power because of the looping
Recommended Solution:
-Recall the function by itself using setTimeout Function using parameter to indicate whether it should go out of the loop or not
-The web service will be checked for every 2 seconds to check the response from the external component. Once the external component is ready then it will move on to execute the next line of code
ParseJSON returning you an object from your AJAX Call, the problem that I have is my object properties has invalid character (e.g “#”)
Assuming jsonData is my variable that contains the following information
I’d like to grab the property of “#innerxml”
Normally I can do this to get the property of an object but in this case I can’t due to invalid character
(jQuery.parseJSON(jsonData)[0]).#innerxml
So How do I access an object which has properties where one of the property name is using an invalid character (e.g “#”)
I can access with the following style
(jQuery.parseJSON(jsonData)[0])[‘#innerxml’]
I found a simple collapsible panel developed by a guy called Darren Ingram and I’d definitely recommend it to anyone wanted to implement collapsible panel. His Jquery implementation of collapsible panel is very simple. It just need 2 files (diQuery-collapsiblePanel.js and diQuery-collapsiblePanel.css – where the css classes can even be integrated to your own css class). I prefer this implementation because it’s just a div implementation and the JQuery script will be hooked up to the div elements (where the class name is collapsibleContainer) upon the page loaded. Simple and lightweight in comparison to the collapsible panel of AJAX toolkit (http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/CollapsiblePanel/CollapsiblePanel.aspx)
the source code for the collapsible panel by Darren Ingram can be downloaded from his website (http://www.darreningram.net/pages/examples/jQuery/CollapsiblePanelPlugin.aspx)
Simple function to encode and decode UTF8 character for unicode (this is for IE)
Encode
utf8bytes= unescape(encodeURIComponent(unicodecharacters));
Decode
unicodecharacters= decodeURIComponent(escape(utf8bytes));
This article is demonstrating how to wire up an enter key into a textbox. For example you have a search text box where you press enter then it will click go button and at the same page you have another textbox where you want to do another button click when you press the enter which means it’ is not necessary to post the page. This java script is used to capture the key event of enter and execute the LinkButton and ASP.NET button Click Event on the server side. Please add this javascript to your javascript common library or add this to your master page. This piece of code works in Firefox as well
function ButtonKeyPress(evt, thisElementName) { if(evt.which || evt.keyCode) { if ((evt.which == 13) || (evt.keyCode == 13)) { // alert('post back href: ' +document.getElementById(thisElementName).href); if (typeof document.getElementById(thisElementName).href != 'undefined') { location = document.getElementById(thisElementName).href; } else { document.getElementById(thisElementName).click(); } return false; } } else { return true; } }
And add this to your .NET code behind on the page load
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not Page.IsPostBack Then If (User.Identity.IsAuthenticated) Then Response.Redirect("frmTimeMain.aspx") End If txtGUID.Attributes.Add("onkeydown", "ButtonKeyPress(event, '" + lnkSubmit.ClientID + "')") txtPassword.Attributes.Add("onkeydown", "ButtonKeyPress(event, '" + lnkSubmit.ClientID + "')") End If End Sub