Overlay screen with transparency achieve by using position: relative and absolute

New trick learned by doing build this layout, have transparent under my two foundation columns. The looking is like this:

transparent wrap under two columns

The div layout is like this:

<div class=”clearfix blueWrap”>
<div class =”orangeWrap”></div>
<!– below two columns is the purple wrap in the picture –>
<div class=”medium-6 columns”></div>
<div class=”medium-6 columns”></div>
</div>

 just few line of css:
  .blueWrap{position:relative;}
  .orangeWrap{
        background-color: rgba(68, 68, 68, 0.47);
	position:absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
       }
 

then just use the foundation media query to make sure when it was in the big screen don’t display that transparent overlay screeen.

@media only screen and (min-width: 64.063em) {
.orangeWrap {
width:70%;
}

Advertisements

How make your background image full size of the screen and cross mobile,table and desktop in Foundation

Recently a task is using the existing foundation basic page to rewrite it to a new design. It is my first time working in Foundation Framework, previous I always using bootstrap.

And from doing this get understand how foundation works. Wow, take a day to achieve it.

And for make the background image full size of the screen and cross the mobile,table and desktop that took me few hours to fix it.

I just like to put my piece of code over there, hope that could help my fans.

.main-background{    
	background:#f38f04 url('/images/bg-img.png') no-repeat center center fixed; 
        background-size: cover;
        -webkit-background-size: cover;
        -moz-background-size: cover;
        -o-background-size: cover;
	width: 100% !important;
	z-index: 0;
}

the fixed and width:100% !important that is very important to make it happens.

How to write your own HtmlHelper render input text in asp.net mvc and working with Date Range Picker

When I was built a tourist website my client’s like have a date range picker. So I search internet found there is this bootstrap date range picker, I am big fun with bootstrap and this is the frond end css framework I am very confident with it.

You could just write html to your view to display it, but what happen if I need use in multiply place and different projects. So I like customize one HtmlHelper to render it.

For how to figure it out in html,.here is the github links.

https://github.com/dangrossman/bootstrap-daterangepicker

I also have picture show:customizeHtmlHelperRenderDateRange02

This date range pick also allow single date pick, how see the help document, because in here I focus how to make it to a Htmlhelper.

Step1: download it, and you only need the moment.js(this is big, if you worries the speed,use the CDN, why CDN help the speed? this is because when the moment.js also used in another projects online, and it already open, then someone go to your website and click it, then you don’t need download it) and daterangepicker-bs3.css

customizeHtmlHelperRenderDateRange01

For me I used it in my asp.net mvc project, I simple just put it inside my bundle.

Step2: start HtmlHelper to render text input box, this time I like also bind it to my model, so it will just like the existing htmlhelper render input text,but write your own one helper you understand how the HtmlHelper works.

here is the method

public static MvcHtmlString MyOwnTextBoxFor<TModel, TValue>(
     this HtmlHelper htmlHelper,
     Expression<Func<TModel, TValue>> expression,
     string type,
     string title,
     string placeholder,
     bool isRequired,
     bool isAutoFocus,
     object htmlAttributes = null)
        {
            MvcHtmlString html = default(MvcHtmlString);
            Dictionary<string, object> attributesOptions = new Dictionary<string, object>();

            if (htmlAttributes != null)
            {
                var attributes =
                  HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                foreach (var item in attributes)
                {
                    attr.Add(item.Key, item.Value);
                }
            }

            attr.Add("type", type);
            attr.Add("class", "form-control");
            if (!string.IsNullOrEmpty(title))
            {
                attr.Add("title", title);
            }
            if (!string.IsNullOrEmpty(placeholder))
            {
                attr.Add("placeholder", placeholder);
            }
            if (isAutoFocus)
            {
                attr.Add("autofocus", "autofocus");
            }
            if (isRequired)
            {
                attr.Add("required", "required");
            }

            html = InputExtensions.TextBoxFor(htmlHelper,
                                              expression,
                                              attr);

            return html;
        }

And here is the several over load method, so in the view you have more options

public static MvcHtmlString MyOwnTextBoxFor<TModel, TValue>(
      this HtmlHelper htmlHelper,
      Expression<Func<TModel, TValue>> expression,
      object htmlAttributes = null)
        {
            return MyOwnTextBoxFor(htmlHelper, expression,"text", string.Empty, string.Empty, false, false, htmlAttributes);
        }


        public static MvcHtmlString MyOwnTextBoxFor<TModel, TValue>(
          this HtmlHelper htmlHelper,
          Expression<Func<TModel, TValue>> expression,
          string type,
          object htmlAttributes = null)
        {
            return MyOwnTextBoxFor(htmlHelper, expression, type, string.Empty, string.Empty, false, false, htmlAttributes);
        }


        public static MvcHtmlString MyOwnTextBoxFor<TModel, TValue>(
          this HtmlHelper htmlHelper,
          Expression<Func<TModel, TValue>> expression,
          string title,
          object htmlAttributes = null)
        {
            return MyOwnTextBoxFor(htmlHelper, expression, "text", title, title, false, false, htmlAttributes);
        }

        public static MvcHtmlString MyOwnTextBoxFor<TModel, TValue>(
          this HtmlHelper htmlHelper,
          Expression<Func<TModel, TValue>> expression,
          string type,
          string title,
          object htmlAttributes = null)
        {
            return MyOwnTextBoxFor(htmlHelper, expression, type, title, title, false, false, htmlAttributes);
        }


        public static MvcHtmlString MyOwnTextBoxFor<TModel, TValue>(
          this HtmlHelper htmlHelper,
          Expression<Func<TModel, TValue>> expression,
          string title,
          bool isRequired,
          bool isAutoFocus,
          object htmlAttributes = null)
        {
            return MyOwnTextBoxFor(htmlHelper, expression, "text", title, title, isRequired, isAutoFocus, htmlAttributes);
        }

and in the view simple just use it like this

@Html.MyOwnTextBoxFor(m=>m.StartDate)

For date range pick you need a piece of javascript

@section scripts
{// }//for more option could read the github helper document

actually the input text type could be “text”, “email”, “number”, so make it more useful create a enum hoder it,then for the type replace it with that enum method.

public enum MyInputTypesOption
        {
            text,
            color,
            date,
            datetime,
            email,
            month,
            number,
            password,
            range,
            search,
            tel,
            time,
            url,
            week
        }

After this you need change

//string type, //comment out this
MyInputTypesOption type,//use this

//so for the overload method instead of type "text", could use MyInputTypesOption.text

And in the method this time for the attribute I put it in

Dictionary<string, object> attributesOptions = new Dictionary<string, object>();

that is because in the end there use the

InputExtensions.TextBoxFor(htmlHelper,
                                              expression,
                                              attributesOptions);

the big benefit for this just you don’t need send a anonymous objects, and you could pass the html attributes straight way and with intelligence.

And one thing is important, is the date range need input type is “text”.
to create the string.

Have fun!

How to customize your own HTML helper in asp.net mvc is very easy

Write your own HTMLHelper is very easy,it just create a extension method for HtmlHelper, it allow you save time to write html tags and attributs and also allow you put logic inside it. so that will keep your views very nice and clean.

In asp.net mvc, in you page header

using System.Web.Mvc;

Now you just need render a string in your view, In system.Web.Mvc,so you just need write a method return MvcHtmlString(acturally this just string).

here is the example method:

   //for write extension method there two things is important, the method must static,so your don't need //     //create a instance and anther thing is the key word this 
  public static MvcHtmlString SubmitButton(this HtmlHelper htmlHelper, string buttonText,string id,bool isDisabled,string btnClass,object htmlAttributes = null)
        {
            string html = string.Empty;
            string disable = string.Empty;

            //Ensure ID is a valid identifier
            id = id.Replace(" ", "").Replace("-", "_");

            html = "";

            html = string.Format(html, buttonText, disable, id, btnClass, GetHtmlAttributes(htmlAttributes));

            html = html.Replace("'", "\"");

            return new MvcHtmlString(html);
            

        }

what is GetHtmlAttributes(htmlAttributes)? this another method read your object and return string

//what use static, so you can use it without create a instance
public static string GetHtmlAttributes(object htmlAttributes)
        {
            string ret = string.Empty;

            if (htmlAttributes != null)
            {
                var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
                foreach (var item in attributes)
                {
                    ret += " " + item.Key + "=" + "'" + item.Value + "'";
                }
            }

            return ret;
        }

//what happen if I only like pass text of the button, other parameters is optional
//here is the implemetation

public static MvcHtmlString SubmitButton(this HtmlHelper htmlHelper,
      string buttonText, string id, bool isDisabled, string btnClass,
      object htmlAttributes = null)
    {
      string html = string.Empty;
      string disable = string.Empty;

      if (string.IsNullOrEmpty(id))
        id = buttonText;
      if (string.IsNullOrEmpty(btnClass))
        btnClass = "btn-primary";

      // Ensure ID is a valid identifier
      id = id.Replace(" ", "").Replace("-", "_");

      html = "";
      if (isDisabled)
        disable = " disabled";

      html = string.Format(html, buttonText, disable, 
                          id, btnClass, 
                          GetHtmlAttributes(htmlAttributes));
      html = html.Replace("'", "\"");

      return new MvcHtmlString(html);
    }

//create more method call the above method 
//so in your view you have more options
//only like pass the test of button
public static MvcHtmlString SubmitButton(this HtmlHelper htmlHelper,
      string buttonText,
      object htmlAttributes = null)
    {
      return SubmitButton(htmlHelper, buttonText, null, false, null, htmlAttributes);
    }
//like put id over there for my javascript to do somthing with it
public static MvcHtmlString SubmitButton(this HtmlHelper htmlHelper,
      string buttonText, string id,
      object htmlAttributes = null)
    {
      return SubmitButton(htmlHelper, buttonText, id, false, null, htmlAttributes);
    }
//like have id ,disable my button too
public static MvcHtmlString SubmitButton(this HtmlHelper htmlHelper,
      string buttonText, string id, bool isDisabled,
      object htmlAttributes = null)
    {
      return SubmitButton(htmlHelper, buttonText, id, isDisabled, null, htmlAttributes);
    }

Intergrate with google analytics — retrieve data back from google analytics

Recently task need retrieve data back from google analytics and put it into the existing website. Online have a lot tutorial explain how to do it.

Here I just record my one over there hope could help my fans.

And I have a exsiting asp.net C# mvc project is on life and they are already embedded google analytics, and my job is to create a admin function so when the projects admin login there is a page display that google analytics datas.

And google already have a client side library for the .net developer to user it.

Step1: PM> Install-Package Google.Apis.Analytics.v3

Step2: For retrieve data from google analytics, you actially just need do two things.

1) Authenticate with google analytics

2) using Google analytics core reporter

I have some words about  Authenticate with google analytics, for me I personally think that just use the Service Account is fine. if you like restrict who is going to see that datas in asp.net mvc is very easily to retrieve it.

So for Authenticate with google analytics using Service Account steps:

1) you need have google account, I mean google account, could be your gmail account and could be your company email.

2)Then use you google account register a Google analytics account.

3) go to the google console enable Google analytics.

4)Create a service account by:

  • First click create a new OAuth2 projects( that is google recommend), then pop out a new window choose the service account, and download that key, put this key into your application,
  • Second don’t forget to go back to google analytics, register that service account email to give permission to this email address.

All of above things ready, now you could start write your code to using the core reporter service.

Here is my implementation class for

   
namespace XXX.XXX.Service.GAServices
{
    #region two way Authenticate with google analytics
    public  class GAAuthenticateHelper
    {
        public static AnalyticsService AuthenticateServiceAccount(string serviceAccountEmail, string keyFilePath)
        {

            // check the file exists
            if (!File.Exists(keyFilePath))
            {
                Console.WriteLine("An Error occurred - Key file does not exist");
                return null;
            }

            string[] scopes = new string[] { 
                
                      AnalyticsService.Scope.Analytics,  // view and manage your analytics data
                     // AnalyticsService.Scope.AnalyticsEdit,  // edit management actives
                     // AnalyticsService.Scope.AnalyticsManageUsers,   // manage users
                      AnalyticsService.Scope.AnalyticsReadonly
                                           };     // View analytics data            

            var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
            try
            {
                ServiceAccountCredential credential = new ServiceAccountCredential(
                    new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = scopes
                    }.FromCertificate(certificate));

                // Create the service.
                AnalyticsService service = new AnalyticsService(new BaseClientService.Initializer()
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "GA Dashboard", // to do this
                });
                return service;
            }
            catch (Exception ex)
            {

                Console.WriteLine(ex.InnerException);
                return null;

            }
        }
    }

    #endregion


    #region Google analytics core reporter
    // Google analytics query help for retrieve datas https://ga-dev-tools.appspot.com/query-explorer/
  public class GAReportingHelper
  {
      public class OptionalValues
      {
          private string dimensions { get; set; }
          private string filter { get; set; }
          private string sort { get; set; }
          private string segment { get; set; }
          private int maxResults { get; set; }
          private DataResource.GaResource.GetRequest.SamplingLevelEnum sampleingLevel = DataResource.GaResource.GetRequest.SamplingLevelEnum.DEFAULT;

          public string Dimensions { get { return dimensions; } set { dimensions = value; } }
          public string Filter { get { return filter; } set { filter = value; } }
          public string Sort { get { return sort; } set { sort = value; } }
          public string Segment { get { return segment; } set { segment = value; } }
          public int MaxResults { get { return maxResults; } set { maxResults = value; } }
          public DataResource.GaResource.GetRequest.SamplingLevelEnum Sampling { get { return sampleingLevel; } set { sampleingLevel = value; } }
          public OptionalValues()
          {
              this.dimensions = null;
              this.filter = null;
              this.sort = null;
              this.segment = null;
              this.sampleingLevel = DataResource.GaResource.GetRequest.SamplingLevelEnum.DEFAULT;
              this.maxResults = 1000;
          }
      }

      public static GaData Get(AnalyticsService service, string profileId, string startDate, string endDate, string metrics, OptionalValues optionalValues)
      {
          DataResource.GaResource.GetRequest request = service.Data.Ga.Get(String.Format("ga:{0}", profileId), startDate, endDate, metrics);
          if (optionalValues == null)
          {
              request.MaxResults = 1000;
          }
          else
          {
              request.MaxResults = optionalValues.MaxResults;
              request.Dimensions = optionalValues.Dimensions;
              request.SamplingLevel = optionalValues.Sampling;
              request.Segment = optionalValues.Segment;
              request.Sort = optionalValues.Sort;
              request.Filters = optionalValues.Filter;

          }
          return ProcessResults(request);
      }
      // Just loops though getting all the rows.  
      private static GaData ProcessResults(DataResource.GaResource.GetRequest request)
      {
          try
          {
              GaData result = request.Execute();
              List<IList> allRows = new List<IList>();
              // Loop through until we arrive at an empty page
              while (result.Rows != null)
              {
                  //Add the rows to the final list
                  allRows.AddRange(result.Rows);
                  // We will know we are on the last page when the next page token is
                  // null.
                  // If this is the case, break.
                  if (result.NextLink == null)
                  {
                      break;
                  }
                  // Prepare the next page of results             
                  request.StartIndex = request.StartIndex + request.MaxResults;
                  // Execute and process the next page request
                  result = request.Execute();
              }
              GaData allData = result;
              allData.Rows = (List<IList>)allRows;
              return allData;
          }
          catch (Exception ex)
          {
              Console.WriteLine(ex.Message);
              return null;
          }

      }
  }

#endregion


}

If you have some red line show, just use ctrl + . to add the reference.
Now I create a google analytics service class file, so in my controller, I just need call that method.
And In my controller, I create a method:

private static GADATA.GaData GaReportingDatas(AdminStatsVM model)//I only allow my admin to see, here I pass my admin data over there, and once I got the data will asign to my adminStatsVM model
        {
            AnalyticsService gaService;            
            string email = "yourserviceaccountemail@developer.gserviceaccount.com";
            string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"bin\yourprivatekey.p12");
  //this is your download file put here, 
            gaService = GAAuthenticateHelper.AuthenticateServiceAccount(email, path);
            string profileId = "XXXXX";//this can find in google analytics
            string metricsStr = "ga:sessions,ga:users,ga:pageviews,ga:pageviewspersession,ga:avgsessionDuration,ga:bounces,ga:percentNewSessions";//google allow pass multiply metrics by separate by comma
            string startDate = model.StartDate.ToString("yyyy-MM-dd");
            string endDate =  model.EndDate.ToString("yyyy-MM-dd"); 
            var gaData = GAReportingHelper.Get(gaService, profileId, startDate, endDate, metricsStr, null);
            return gaData;
        }

Now you can use it anyway you like.
How to renter to the page?
here in my model I have one member

 public GaData GaDatas { get; set; }

so in my controller, I assign it to

 var record = new AdminStatsVM
            {
                ...
                GaDatas = GaReportingDatas(model);//call that method above

            };

here in the view:

@foreach (var item in Model.GaDatas.Rows)
                        {
                                                        
                            foreach (string col in item)
                            {@col.FormatDigit()

} }@Model.GoogleAnalyticsUrl

What is FormatDigit(),

 public static String FormatDigit(this String input)
        {
            decimal myNum = decimal.Parse(input);           
            return  String.Format((Math.Round(myNum,2) == myNum) ? "{0:0.00}" : "{0:0}",myNum);
        }

I was following

http://www.daimto.com/google-analytics-api-v3-with-c/#Google_Analytics_API_8211_Introduction

Anything don’t understand it, could have view this link first.

very helpful.

Have fun!