Friday, June 17, 2011

Hide/show column at run time in MVC Telerik Grid with ajax binding

Environment: Telerik Grid for MVC, Razor/Aspx, ajax binding.

I had a search page with some search criteria and on the click of the button, an ajax call is made to get the data. After successful retrieval of data, it is bound to a Telerik Grid.

Issue: Now I had to add a check box to the search criteria, which when checked, should display the results in the grid with this new column (the new column is the one listed by the check box). If unchecked, the column has to hidden. All this with the ajax call backs.

Solution:
1. I tried setting the ViewBag with the an object bearing the checkbox value, so that on the UI, I could check the value of ViewBag's object and turn the column on/off in the Telerik Grid. It didnt work.
2. Tried hinding the table column (td) of this new column, after the successful ajax call back. Didnt work.

Successful:
Finally tried setting the client event of the Telerik grid - "RowDataBound" and in the javascript function "Grid_RowDataBound", hid/displayed the new column in question.


    function Data_GridRowDataBound(e)
    {
        var row = e.row;
 
        //Hide column if the checkbox has not been checked. 
         if($("#Required").attr('checked') == false)
        {
            $('#Data th:eq(8)').hide();
            if($(row).parent().html() != null)
            {
                var cReqdCell = row.cells[8];
                $(cReqdCell).hide();
            }
        }
        else
        {
            $('#Data th:eq(8)').show();
        }
}

In my case, I had to hide the column on initial page load. That I achieved by calling the below javascript method on the jquery's ready method.


        if($("#Required").attr('checked') == false)
        {
            $('#Data colgroup').find('col:eq(8)').hide();
            
            $('#Data th:eq(8)').hide();
            
            $("#Data tbody tr").find("td:eq(8)").each(function(){
                $(this).hide();
            });
        }
$(document).ready(function() { 
  
         HideColumns();
}
Unfortunately I couldn't find the solution on Telerik forums or from their paid support ticket answer. 

Monday, January 3, 2011

Refresh primary key column after insert using Domain Services in RIA services on Entity framework

Situation: 2 tables where a primary key in one table is foreign key in another table.
E.g. table Agendum {Id - identity column and primary key, heading, description}
table Take {Id - identity column and primary key, heading, description, AgendumId - foreign key}

Issue I was facing: I wanted to insert Agendum entity into Agendum table, retrieve the identity column value so that when I insert Take entity into Take table, I can pass the AgendumID which is the identity column of Agendum table.

I am using: Domain services (RIA services) on Entity framework. This is a silverlight app.

Wrong way of doing, which I was trying to do:

            //First insert into Agenda table and get the agenda id back
            Agendum _agenda = new Agendum();
            _agenda.Heading = tbAgendaTitle.Text;
            _agenda.SourceUri = tbAgendaSource.Text;
            m_domainCtx.Agendums.Add(_agenda);
            m_domainCtx.SubmitChanges(Callback, null);
 
            Take _take = new Take();
            _take.Heading = tbTakeTitle.Text;
            _take.Description = tbTakeDesc.Text;
            _take.AgendaId = _agenda.Id;
 
            m_domainCtx.Takes.Add(_take);
            m_domainCtx.SubmitChanges(Callback, null);
As I was trying to call SubmitChanges twice, I was getting the error: 
A SubmitChanges operation is already in progress on this DomainContext.

After reading the article on the blog: http://blogs.msdn.com/b/adonet/archive/2008/03/26/stored-procedure-mapping.aspx, I figured the proper way of doing it. 

Proper way of doing: 
            //First insert into Agenda table and get the agenda id back
            Agendum _agenda = new Agendum();
            _agenda.Heading = tbAgendaTitle.Text;
            _agenda.SourceUri = tbAgendaSource.Text;
            m_domainCtx.Agendums.Add(_agenda);
 
            Take _take = new Take();
            _take.Heading = tbTakeTitle.Text;
            _take.Description = tbTakeDesc.Text;
            _take.Agendum = _agenda;
 
            m_domainCtx.Takes.Add(_take);
            m_domainCtx.SubmitChanges(AdminPostCallback, null);
So, you dont have to retrieve the primary key and assign it explicitly. The associations are known to the Domain Service. Hence just assigning the entity will take care of it. 
Hope it helps.