Monday, June 28, 2010

How to dynamically add Edit button to grid for editing row using the jqGrid formedit

Goal:

Dynamically add an Edit button to an empty column that will NOT trigger an inline edit but rather a jqGrid formedit for the selected row using the modal dialog option.

Problem:

All examples in the Demo version include editing inline and adding buttons to a column that only does an inline edit and the Demo version's getRowdata does not perform as expected. I tried it an could not get it working and the getRowData did not work as specified.

Solution:

gridComplete: function() {
var rows = $(item).jqGrid('getRowData');
for (var i = 0; i < rows[0].rows.length; i++) {
var row = rows[0].rows[i];
var idx = row.id;
if (!$(row).hasClass('jqgrow') && !$(row).hasClass('alt'))
continue;
var be = "";
$(item).setRowData(idx, { act: be });
$('#editAddress' + idx).click(function() {
$(item).editGridRow($(this).parent().parent('tr').attr('id'));
});
}
},


item = that is a variable that contains the id of my grid.

This is for editing an address so change the "editAddress" id prefix for your needs or create a generic function that will handle all of this:

gridComplete: function() {
SetupJqGridEditDeleteButtons(item);
},


function SetupJqGridEditDeleteButtons(item) {
var rows = $(item).jqGrid('getRowData');
for (var i = 0; i < rows[0].rows.length; i++) {
var row = rows[0].rows[i];
var idx = row.id;
if (!$(row).hasClass('jqgrow') && !$(row).hasClass('alt'))
continue;
var be = "";
$(item).setRowData(idx, { act: be });
$('#editItem' + idx).click(function() {
$(item).editGridRow($(this).parent().parent('tr').attr('id'));
});
}
}


Monday, June 14, 2010

TDD - Red-Light-Green_Light:: A critical view

Subject: The concept of red-light-green-light for TDD/BDD style testing has been around since the dawn of time (well almost). Having written thousands of tests using this approach I find myself questioning the validity of the principle

The issue:

False positive or a valid test strategy that can be trusted?

A critical view:

I agree that the red-green-light concept has some validity, but who has ever written 2000 tests for a system that goes through a ton of chnages due to the organic nature fo the application and does not have to change, delete or restructure their existing tests? If you asnwer to the latter question is" "Yes I had a situation(s) where I had to refactor my code and it caused me to have to rewrite/change/delete my existing tests", read on, else press CTRL+ALT+Del :-)

Once a test has been written, failed the test (red light), and then you comlpete your code and now get the green light for the last test, the test for that functionality is now in green light mode. It can never return to red light again as long as the test exists, even if the test itself is not changed, and only the code it tests is changed to fail the test. Why you ask? because the reason for the initial red-light when you created the test is not guaranteed to have triggered the initial red-light result for the same reasons it is now failing after a code change has been made.

Furthermore, when the same test is changed to compile correctly in case of a compile-breaking code change, the green-light once again has been invalidated. Why? Because there is no guarantee that the test code fix is in the same green-light state as it was when it first ran successfully.

To make matters worse, if you fix a compile-breaking test without going through the red-light-green-light test process, your test fix is essentially useless and very dangerous as it now provides you with a false-positive at best. Thinking your code has passed all tests and that it works correctly is far worse than not having any tests at all, well at least for that part of the system that the test-code represents.

What to do?

My recommendation is to delete the tests affected, and re-create them from scratch. I have to agree. Hard to do and justify if it has a significant impact on project deadlines.

What do you think?


Friday, April 30, 2010

jQuery - check/uncheck a checkbox

$('#PrimaryContacts').unbind().change(function() {
if ($('#PrimaryContacts option:selected').val() == 0) {
$('#filterPrimaryContact').removeAttr('checked').trigger('click');
}
else {
$('#filterPrimaryContact').trigger('click');
}

});


Also, in the example above, triggering the checkbox does not change the checkbox value. As depicted above, based on a dropdown box changing and no contact being selected from the drop down box, automatically uncheck the checkbox and trigger it in invoke any event handlers on the checkbox.

Monday, March 22, 2010

jscompress fails to compress my js file and errors out - why?

Issue:

You use the online compression utility jscompress.com to compress your js file but it fails with an error. Why this may be happening and how to fix it.

Possible causes:

Apparently not using open and closing curly brackets in an IF statement would cause this. Well turns out this is not the case. Look at the following example and see if you can figure out what the issue is :-)




function SetupDeliveredVPRecontactNotes($item, id) {
var theData;

$.ajax({
data: { deliveredVPId: id },
url: $('#ajaxGetDeliveredVPRecontactNotesUrl').val(),
type: "GET",
async: false,
dataType: "html",
success: function(data, result) {
$item.empty();

var input = '';
$item.append('input');
theData = data;
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$item.empty();
alert("An error occurred: The operation to retrieve the DeliveredVP's Recontact Notes has failed");
}
}); //ajax

return theData;
}


Solution:

The issue is the closing textarea tab, concatenate it as

''
will fix the issue

Monday, March 15, 2010

How to check off a checkbox using jQuery

$('#someCheckbox').attr('checked','true')

Tuesday, February 9, 2010

How to find out if you are runnig on a 64-bit Processor

Goal:

Find out if you are runing on a 64-bit processor

Answer:

Go to the command prompt (type cmd int the Start -> Search box)

type the follownig command: set | find "PRECESSOR_ARCHITECTURE"

If you get ADM64 back (or something similar with 64 in it) you are running on a 64-bit processor, and would be able to install and run for example Windows 7's 64 bit OS. If you get something like x86 you are running on the older 32-bit architecture.

Wednesday, December 30, 2009

Restructuring ASP.Net MVC app

So the issue is, you have a very large ASP.Net MVC app with many controllers and actions and don't know (or do) on how to restructure it for better maintenance.

This article contains some thoughts around what my experiences were with building a large scale app with 10K+ lines of jQuery and 266 Actions dispersed over 98 Controllers.

In the beginning:

Yes God created .... no I created a relatively small scale Mvc app based on a very limited set of requirements, more like a XP experience or learn as you go. The user community did not know what they wanted and the prototype was based on a missed conception of what the business' core day-to-day focus was (of course we did not know this at the time). There were only a few controllers and they were small.

Then we discovered the jQuery Grid by Tony Tomov (awesome free plug-in) which supports a ton of ajax features, so we decided to use it for all of our lists and also for a lot of CRUD functions. This very quickly expanded the controllers to a very large size. At this time I decided to not split the controllers as it might introduce bugs. For example an Account has a New, Update, Delete, Create and Edit action, and now it has a List and CUD action (2 actions) added for each grid. Since the Account page has 9 tabs with 13 grids it now has an added 26 actions on that single AccountController controller and then some for other ajax type functions.

So then very quickly, as the customers saw the app, new requirements were added and the controllers grew even bigger.

The decision then came as to what to do and how to refactor the code. I ran this past a colleague of mine to find out what he thinks: Large controller with all the logically related actions together (yes all 39 actions at some point) or to split them into smaller but many different controllers? It seemed that keeping it all in one controller was a good decision since when you need to fix something on the account page with all the tabs with grids on them you know you need to go to the AccountController controller, right!? However, what if the requirements change and these grids need to be also displayed in other places, that's right, like on the Contact's maintenance page that has the same tabs as the Account page (only filtered by the contact for that account). Now I have a duplicate set of actions that perform essentially an identical function to those on the Account's controller. That is when it became clear that the controllers' actions should not be arranged according to how the screens look like but to adhere to the SRP.

Lets look at an example. The Account has a list of Calls, Contacts, Contracts and Lessons Learned. Even though these are tabs on the account's page, they need to be self contained. So this is how they were disseminated and re-arranged to adhere to SRP:

AccountController: New, Create, Edit, Update, Delete, List actions
CallController: New, Create, Edit, Update, Delete, List actions
ContactController: New, Create, Edit, Update, Delete, List actions
ContractController: New, Create, Edit, Update, Delete, List actions
LLController: New, Create, Edit, Update, Delete, List actions

The AccountController had a very large constructor since we used IoC Castle Windsor to inject the Repository (DAO type functions) into the constructor; to support all the DAO functions for calls, contacts, contracts and lessons learned. Now the constructor of each controller is very small and only cares about the Repositories it needs. In addition, to mention one example, the Calls tab on the account and contact screens now share the same action defined on another controller specifically to support the jqGrid functions for calls, the CallGridController with its 2 (yes only 2) actions ListCallsForjqGrid() and SaveCallForjqGrid(), rather than duplicating it. Now another developer knows that no matter where the jqGrid is displayed for calls, they can always find it on the CallGridController.

These are just some of the benefits of creating smaller controllers. Feel free to comment and share your ideas and experiences.