{Webresource development using HTML5}–Exploring field validation features in HTML5.

In this topic, I am going to walkthrough the cool HTML5 stuffs that you can use for field validation while you build webresources in Dynamics CRM.

Up until now, if you are not using HTML5, to validate a required field, you would need to write javascript to test for each field. Also your headache increases when the field needs to be made required based on some business logic.

But now with HTML5. All you need to do is set the required attribute for the field.

<input type="text" name="testfield1" required>

When you insert the field on the form and try to submit the form without any entering any data, you would get a validation from the browser like this.

image

Off-course you can change the ugly red border it is showing with a simple css style like the one below.

input:invalid {
  border: solid 1px #eee
}
Any required field when not entered, the browser will treat with this field as invalid. This is another feature of HTML5. You can put any css you want for this. 
So we have used the HTML5 feature to validate if the user does not input any data. Now how do you validate a pattern for input. For example – an email field would be required as well as it should have a valid format. Don’t be upset here. HTML5 has covered you up in this also.
We have the pattern attribute here. The pattern attribute accepts a regular expression.
Let us take an example here.
<input type="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" />
Once you put the field on the form, and try to submit the form without entering the email it should throw up validation from the browser.
image
Cool isn’t it? All this without any line of code.
Next time somebody asks you to develop a webresource, implement this and wow everyone.
Hope this helps!

{How to Fix} – This report requires a default or user-defined value for the report parameter. Error while executing SSRS report programmatically from plugins in Dynamics CRM

Looking at the title of the topic, you might be asking – Is this something to do with Dynamics CRM Plugins only? The answer is ‘NO’. It’s not. The error I am talking about is generic and you may get it from anywhere where it is trying to execute a SSRS report programmatically. However posting it in the hope that it might be beneficial for fellow CRM developers.

So let me give you a context of the requirement. Our Client had a HTML webresource based report with lot of tabular stuffs and input elements in it. On the webresource, they had an ‘Export To Excel’ button which when clicked would generate an excel with the same look and feel of the report. So this is what I suggested.

  • Develop a SSRS report with the same look and feel of the HTML webresource
  • Configure the SSRS report with the parameters required to generate the SSRS report.
  • When ‘Export’ to excel button is clicked, the necessary parameters would be passed to the SSRS through a plugin which would get the excel dump of the SSRS report.

All well and good this far and our client very much liked the idea. But every consultant would know that whenever you suggest an approach to your client and if they really like your idea, they would come up with something new. Well the same happened in my case. My client insisted on having this report accessible from outside the context of the HTML webresource. What it means is that the report should be visible to end-users and they should be able to run manually by selecting the appropriate parameters. No harm in this I thought, we have to build a report anyways.

So we started building the report. We created parameters and datasets for the parameter values and specified the option for ‘Available values’ for the parameter to the appropriate dataset.

image

All well this far. Ran the report from the report section with appropriate parameters. Report worked perfectly. Now integrated the code to call the SSRS report from Plugin. The moment we did that we started getting the error.

“This report requires a default or user-defined value for the report parameter. To run or subscribe to this report, you must provide a parameter value.”

Did some search and everywhere it was suggested to not select the option ‘Get Values from Query’ for the parameter values. We could have done that easily, but the point is that the report needs to be accessed independently. So we decided to develop a new report specific for export to excel from within the HTML webresource.

Before doing that, I really wanted to find the root cause of this issue. So I decided to investigate little further.

We were passing the report parameter from the plugin code like the one shown below.

var customerId =config.GetCustomer();

paramList.Add(new ReportParameter("pCustomerId", customerId));

 

The report was expecting a parameter of CustomerId. But the customer id I was passing was a string value because Microsoft.WebForms.Reporting.ReportParameter accepts only string values. But if you see from SQL perspective, it is ‘UNIQUEIDENTIFIER’ or a GUID value. So what I did is the query for the report parameters in SSRS, I cast the GUID as NVARCHAR.

Then when I ran the code again, voila! it worked for me. The reason why I was getting the error is because I was passing the GUID parameter as string.

 

Hope this helps!

{Knowhow–Webresource development with HTML5 features}–How to show default text in controls on your HTML webresources

Wanted to share this really cool stuff with fellow Dynamics CRM consultants who might not be aware of this html5 feature.

 

We had a webresource and where we had multiple input controls. Our client wanted that these input controls should show some default text to make the user understand the type of input the application is expecting in the input control.

For e.g – suppose we have a text box for email. We can show some default text like ‘some@example.com’ to highlight the format of the input to the end user. Typically in UI, it should render something like below.

image

If you try to implement this custom you would need to do the following things.

  • Create a common library to show the suggestive text
  • When the user starts to type in, the default text should go away
  • The default text should not be considered during mandatory field validation
  • If the user deleted the text, the default text should re-appear
  • Last but not the least, separate CSS styles for the default text and text entered by the user.

 

What if I say that you do not need to do all this if HTML5. All you need to do is set the value of a new attribute in HTML5 called placeholder. The code for the above screenshot would be the one below.

<input type="email" name="email" placeholder="someone@example.com">
<input type="text" name="first_name" placeholder="First name">

The good thing is that the browser controls everything for you. If you are wondering what is input type = ‘email’ in the HTML above, well that is another new stuff in HTML5. To know more about that, you can refer to my following blog post.

https://debajmecrm.com/2015/09/22/webresource-development-part-i-using-new-html5-features-in-html-webresources-in-dynamics-crm/

So next time somebody asks you to develop a webresource, show off some your HTML5 skills as well Smile

 

Hope this helps!

{Webresource Development Part – I} Using new HTML5 features in HTML webresources in Dynamics CRM

How many times have you heard about HTML5. It’s one of the most talked about stuffs in the industry. HTML5 and jQuery – the killer combination. And again there is this topic which discusses about HTML5. So let me explain here why I choose to pen down this blog post.

HTML5 have been doing the rounds for quite sometime now. However strangely enough when I go to any majority of the CRM projects and do the code review for CRM webresources, I find the HTML webresources not using the latest features of HTML5. I can find lines and lines of code written to get stuffs work which can be achieved by a single attribute in HTML5. And it’s purely understandable that being a CRM consultant and being involved in CRM stuffs day in and day out, we sometimes tend to loose touch of what’s happening outside our CRM domain. So I would be writing a series of blog posts on webresource development using latest HTML5 and jQuery features so that it can be of help to others. Even if a single CRM developer gets benefitted by this, I would be extremely satisfied.

In this blog post, I would just go through the various new input elements that has been come with HTML5. I would discuss the important ones here.

  • Input Type: Number

    • No more complex validations required for fields of type numeric. All you need is to put up a HTML element like the one below. You would be automatically presented with the textbox where you can enter numbers and increment the numbers using the spin that renders with the textbox. The browser does all the validation for you.
      • <input type="number" name="numerictextbox" min="1" max="50">
  • Input Type: date

    • The datepicker is shown depending on the browser. No requirement for separate datepicker controls. Isn’t it great. Similarly you have the datetime control also which lets you select the time  part of it. Also you can try out the input type=’week’ and input type=’month’

      • <input type="date" name=”lastenteredon" max="2012-12-31">

    • image

  • Input Type: color
    • When you embed this element in the your webresource, a color picker would popup. Isn’t it great? Imagine you would be required to ask the user for their favourite color and then when you insert this new HTML5 control, your are done.
      • <input type="color" name="favcolor">

image

  • Input type:url
    • If you set this element, and enter any invalid url, you would get a message like this. And the best part is, all of it without writing a single line of code. The browser does the job for you.
      • <input type="url" name="website">

image

  • Input type:email.
    • this one is interesting. How many times have we used email in our web-resources. Ok setting this up would delegate the responsibility of validation of email address to the browser.
      • <input type="email" name="email">
    • image

Apart from this you can try out the below ones also.

  • Input type:tel – for telephone numbers
  • Input type:range – this would render as a slider.

 

To learn more about this, you can search in w3schools.com which is an excellent place for learning all the new cool features of HTML5. CRM developers, who still didn’t not get a chance to taste HTML5 stuffs, I am sure would love to get your hands on this.

In my next post, I would discuss how field and form validations can be done using the new HTML5 features.

 

Hope this helps!

{knowhow} – How to get the server time in Dynamics CRM?

Not sure of the title explains the topic much. So let me illustrate with an example on what we were trying to achieve for our customer.

The customer had a requirement where the users would need to enter weekly data and the report would be locked for the week by Thursday 5 PM PST time of every week. Our servers were located in PST Time zone. If you really ask me, when I first got this requirement, I really didn’t pay any heed to this as I though this would be pretty simple stuff.

So let’s see how this small stuff gave me some sincere and serious thinking. Let decide on how to approach a feasible solution for this. Considering that our customers had this report being accessed by users all round the world, the following are the options we had.

  • Determine the PST time using getTimeZoneOffset method.
  • Using actions.

Let us evaluate each option in specific order

 

Determining the PST Time using getTimezoneOffset method:

  • In javascript, we have the getTmezoneOffset method. Using this method, if we know the time zone offset from GMT, we can determine the time of that particular time zone. So if it is PST time zone, it is (UTC – 8). So a simple code like below should give us the PST Time, based on the logged in user’s timezone.
    $date = new Date();

    // convert to msec
    // subtract local time zone offset
    // get UTC time in msec
    $utc = $date.getTime() – ($date.getTimezoneOffset() * 60000);
    $pstdate = new Date($utc + (3600000*’-8’));
All so fine this far. So what’s the problem if we use this. Well getTimezoneOffset does not take into effect the DST (Daylight saving’s time). So we had to write code to include the day light saving based on the month from which the daylight savings would start and then adjust the time accordingly. We discussed this with our customer and they did not want us to go that route.
  • So actions was our next big bet. We will create an action with output parameter of type datetime and then assign the output parameter to the ‘Process Execution Time’. All set we thought. But CRM still had few surprises up its sleeve.

When we called the action through javascript, we started getting the below error.

Conversion from type 'CrmDateTime' to type 'Date' is not valid
Oops. Surely did not expect this to happen. After bit of searching, realized that ProcessExecution time is of type CRM Datetime and cannot be set directly to a datetime variable. However if you set it to a datetime field of some entity, it would work. Strange isn’t it?
So now what? Finally I came up with the below idea.
  1. Create an action
  2. Set an output parameter of a the action of type ‘String’. Just notice I have mentioned String and not datetime. I will come back to this.
  3. Create a custom workflow activity with a output parameter of type string to hold the current server time.
  4. Set the output parameter in the custom workflow activity with the string representation of the server time

public class GetCurrentPSTTime : CodeActivity
{
[Output(“Current PST Time”)]
public OutArgument<String> CurrentPSTTime { get; set; }

        protected override void Execute(CodeActivityContext context)
{
CurrentPSTTime.Set(context, DateTime.Now.ToString(“yyyy-MM-dd hh:mm:ss”));
}
}

Just notice the format of the date that I have used here. The reason I have used it is because when I get back this in my client side code, I can directly convert it to datetime object in javascript.

The final step is to set the output parameter of the action with the value of the output parameter of the action

And finally I was able to achieve this. Seems like a mountain solution to a molehill requirement isn’t it.

 

Sharing this in case someone finds this useful.

 

Hope this helps!

{knowhow}–How to perform intersect queries using the same relationship twice in the in Dynamics CRM fetchxml.

Title seems confusing. Right? Well even to me it’s not a great title to explain the topic. For me, nothing is better than real time examples. So let me illustrate the same with an example.

So I was in this project where my customer wanted me to create a view that would show users in the system who have both – Role1 and Role2 in the system. Role1 and Role2 are two security roles in the system. Now imagine this query from SQL perspective. It would something like below.

select distinct sr.systemuserid, su.domainname
        FROM [Role] r INNER JOIN [SystemUserRoles] sr ON r.RoleID = sr.RoleID
        INNER JOIN [SystemUser] su ON su.systemuserid = sr.systemuserid
        WHERE r.Name = ‘role1’
        INTERSECT
        select distinct sr.systemuserid, su.domainname
        FROM Role] r INNER JOIN SystemUserRoles] sr ON r.RoleID = sr.RoleID
        INNER JOIN SystemUser] su ON su.systemuserid = sr.systemuserid
        WHERE r.Name = ‘role2’

For people who are not accustomed to SQL, nothing to worry. The below figure explain what the query does.

 

image

 

The query returns the intersection of the users who have both role1 and role2. Now to achieve the same stuff in a view, we would need to configure fetchxml query for the same. Unfortunately if we try to join the SystemUser table with the SecurityRoles twice, then CRM would give you the following error – “The relationship you are adding already exists in the query

 

image 

 

So is there no way you can achieve this? Well I asked some people and the answer I got was ‘No’. I understood that from UI we cannot we do this for sure.

However just for an experiment I tried the below fetchxml and executed it programmatically.

<fetch version=’1.0′ output-format=’xml-platform’ mapping=’logical’ distinct=’true’> 
  <entity name=’systemuser’>   
    <attribute name=’systemuserid’ />
    <attribute name=’fullname’ />
    <order attribute=’firstname’ descending=’false’ />
    <filter type=’and’>
      <condition attribute=’isdisabled’ operator=’eq’ value=’0′ />
    </filter>
    <link-entity name=’systemuserroles’ from=’systemuserid’ to=’systemuserid’ visible=’false’ intersect=’true’>     
      <link-entity name=’role’ from=’roleid’ to=’roleid’ alias=’ac’>
        <attribute name=’name’ />
        <filter type=’and’>         
          <filter type=’or’>           
            <condition attribute=’name’ operator=’eq’ value=‘role2’ />           
          </filter>         
        </filter>       
      </link-entity>     
    </link-entity>
    <link-entity name=’systemuserroles’ from=’systemuserid’ to=’systemuserid’ visible=’false’ intersect=’true’>     
      <link-entity name=’role’ from=’roleid’ to=’roleid’ alias=’anc’>       
        <attribute name=’name’ />
        <filter type=’and’>         
          <filter type=’or’>           
            <condition attribute=’name’ operator=’eq’ value=‘role1’
/>           
          </filter>         
        </filter>       
      </link-entity>     
    </link-entity>   
  </entity> 
</fetch>

And voila! It worked. It returned me all the users who have both role1 and role2 in the system.

So what I did is I created a view for this and updated the fetchxml of the view programmatically.  You need to access the savedquery entity and update the fetchxml property programatically.

 

P.S – The limitation of this approach is that since the fetchxml is not supported through UI, it cannot be imported as part of the solution. You would need to update the fetchxml using some executable programmatically. So if your customer is stuck on achieving this kind of functionality, this can be your way out.

 

Hope this helps!