Showing posts with label Tweeting-Code. Show all posts
Showing posts with label Tweeting-Code. Show all posts

Saturday, December 15, 2012

Localizing date

For July 16, 2012, and giving it a format of d in SSRS

  • Formatted in German as: 16.07.2012
  • Formatted in English as: 7/16/2012


Had the d format in English formatted July as 07 (i.e. double digits), we won't need special handling for English

Here's how to handle the special case, special cases are always evaluated first(pardon my captain-obviousness) on the conditions

=IIF(Parameters!NeutralLanguageCode.Value = "en", "MM/dd/yyyy", "d")


Here's the customized output for English: 07/16/2012



Likewise with date time (g format), we have to handle the special case, July 16 2012 6:00 PM


  • Formatted in German as: 16.07.2012 18:00
  • Formatted in English as: 7/16/2012 6:00 PM


=IIF(Parameters!NeutralLanguageCode.Value = "en", "MM/dd/yyyy hh:mm tt", "g")

Here's the customized output for English: 07/12/2012 06:00 PM

General formatting: http://msdn.microsoft.com/en-us/library/ms157406(v=sql.90).aspx

Granular formatting: http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.71).aspx

Wednesday, November 28, 2012

Linq's syntax symmetry with Postgres

Can't help but notice, Linq multiple condition has more affinity with Postgres flexible syntax:


from c in Customers
join o in Orders on new {c.CompanyID, c.CustomerID} equals new {o.CompanyID, o.CustomerID}


Postgresql:


from Customers as c 
join Orders as o on (c.CompanyID,c.CustomerID) = (o.CompanyID,o.CustomerID)

Tuesday, August 21, 2012

ORM navigation differences between Entity Framework and NHibernate

Given this model:

public class Person
{
 public virtual int PersonId { get; set; }
 public virtual string PersonName { get; set; }
}


public class Question
{
 public virtual int QuestionId { get; set; }
 public virtual string QuestionText { get; set; }
 public virtual Person AskedBy { get; set; }
}


And this schema:

create table Person
(
PersonId int identity(1,1) primary key,
PersonName nvarchar(100) not null
);

create table Question
(
QuestionId int identity(1,1) primary key,
QuestionText nvarchar(100) not null,
AskedBy_PersonId int not null references Person(PersonId)
);



While this incur two database roundtrip on Entity Framework:

Console.WriteLine("{0}", q.QuestionText);
Console.WriteLine("{0}", q.AskedBy.PersonId);


NHibernate doesn't, it incurs one database roundtrip only

Sunday, July 29, 2012

From raw parameters to structured data

To avoid stringly-typed processing, convert string-based parameters to structured data. Then do further processing on that internal data structure, where the information can be easily processed.


public class Node
{
    public Node ChildOf { get; set; }
    public string Path { get; set; }

    public IList<Node> Children { get; set; }

}



public static class Helper
{

    public static Node ArrayToTree(params string[] paths)
    {
        Node root = new Node
        {
            ChildOf = null,
            Path = null,
            Children = new List<Node>()
        };

        

        foreach (string path in paths)
        {
            string[] subPaths = path.Split('.');

            Node addTo = root;

            foreach (string subPath in subPaths)
            {
                Node child = addTo.Children.FirstOrDefault(x => x.Path == subPath);

                if (child == null)
                {
                    child = new Node
                    {
                        ChildOf = addTo,
                        Path = subPath,
                        Children = new List<Node>()
                    };

                    addTo.Children.Add(child);
                }//if

                addTo = child;
            }//foreach

        }//foreach


        return root;
    }
}


Unit test:


public void TestStructuredData()
{
    Node n = Helper.ArrayToTree(
        new[]
        { 
            "Answers", 
            "Answers.Comments", 
            "Answers.Greats", 
            "Answers.Balls.Of.Fire", 
            "Comments" 
        
        });


    Assert.AreEqual(2, n.Children.Count);
    Assert.AreEqual(3, n.Children[0].Children.Count);


    Assert.AreEqual("Answers", n.Children[0].Path);

    Assert.AreEqual("Comments", n.Children[0].Children[0].Path);
    Assert.AreEqual("Greats", n.Children[0].Children[1].Path);
    Assert.AreEqual("Balls", n.Children[0].Children[2].Path);
    Assert.AreEqual("Of", n.Children[0].Children[2].Children[0].Path);
    Assert.AreEqual("Fire", n.Children[0].Children[2].Children[0].Children[0].Path);

    Assert.AreEqual("Comments", n.Children[1].Path);
}


Avoid stringly-typed programming, use proper data structure.

http://www.google.com/search?q=stringly-typed+programming+-strongly

Sunday, June 10, 2012

Avoid stringly-typed, do the .NET proper, use strongly-typed

When you want to do this during run-time...
System.Collections.Generic.IList<Product> products = new System.Collections.Generic.List<Product>();



...instead of doing this:

...
Type elemType = ...
IList clonedList = (IList)Common.Create("System.Collections.Generic.List", elemType);
...

static class Common
{
    internal static object Create(string name, params Type[] types)
    {
        string t = name + "`" + types.Length;
        Type generic = Type.GetType(t).MakeGenericType(types);
        return Activator.CreateInstance(generic);
    }
}


Do this:
Type elemType = ...
IList clonedList = (IList) Activator.CreateInstance(typeof(System.Collections.Generic.List<>).MakeGenericType(elemType));




Happy Coding! ツ

Saturday, September 24, 2011

Task-based Asynchronous Pattern

Here's a simple implementation of task-based asynchronous pattern

using System;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;

namespace TestAsync
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // inherently synchrononous operation
        public int ComputeSomething(int n)
        {
            // Problem is O(N)

            while (n-- > 0)
                Thread.Sleep(1000);

            return 7;
        }

        // Wrap the synchronous operation on Task-based Async Pattern to make the operation operate asynchronously
        Task<int> ComputeSomethingAsync(int n)
        {
            Task<int> t = new Task<int>(() =>
                {
                    return ComputeSomething(n);
                });

            t.Start();
            return t;
        }



        private void button1_Click(object sender, EventArgs e)
        {
            // instead of doing things synchronously
            if (false)
            {
                int n = ComputeSomething(10);
                MessageBox.Show("Returned value is " + n.ToString());
            }

            // do things asynchronously instead
            if (true)
            {
                Task<int> t = ComputeSomethingAsync(10);
                t.ContinueWith(x =>
                {
                    if (x.IsFaulted)
                    {
                        MessageBox.Show(x.Exception.Message);
                    }
                    else
                    {
                        MessageBox.Show("Returned value is " + x.Result.ToString());
                    }

                });
            }

        }//button1_Click


    }//class Form1
}

For asynchronous operation, TAP asynchronous design pattern is easier to use than BeginXXX, EndXXX, IAsyncResult combo async pattern

On next C# version(C# 5), making routines asynchronous will be a lot easier with its built-in await and async functionality

Sunday, August 21, 2011

NHibernate Session's Transaction cannot detect other transactions' commit status

[TestMethod]
public void Nh_SessionTransaction_cannot_detect_transaction_commitness()
{
    // Arrange
    NHibernate.ISession sess = NhModelsMapper.GetSession(connectionString);
    Assert.IsFalse(sess.Transaction.IsActive);
    
    using(var tx = sess.BeginTransaction())
    {
        Assert.IsTrue(sess.Transaction.IsActive);
        Assert.IsTrue(tx.IsActive);

        tx.Commit();

        Assert.IsFalse(sess.Transaction.WasCommitted);
        Assert.IsTrue(tx.WasCommitted);

        Assert.IsFalse(sess.Transaction.IsActive);
        Assert.IsFalse(tx.IsActive);

    }

}

Further unit tests:
[TestMethod]
public void Nh_SessionTransaction_can_detect_its_own_transaction_commitness_only()
{
    // Arrange
    NHibernate.ISession sess = NhModelsMapper.GetSession(connectionString);
    Assert.IsFalse(sess.Transaction.IsActive);

    sess.Transaction.Begin();
    Assert.IsTrue(sess.Transaction.IsActive);
    
    Assert.IsFalse(sess.Transaction.WasCommitted);
    
}

NHibernate non-support for nested transactions, and how to tackle it

We cannot do nested transaction in NHibernate, but we can detect if there's an active transaction and adjust our code's transaction accordingly

[TestMethod]
public void Nh_Can_Detect_Transaction_From_Session_Begin_Transaction() 
{
	// Arrange
	NHibernate.ISession sess = NhModelsMapper.GetSession(connectionString);
	Assert.IsNotNull(sess.Transaction);
	Assert.IsFalse(sess.Transaction.IsActive);


	// Act
	var tx = sess.BeginTransaction();
	
	
	// Assert
	Assert.IsTrue(sess.Transaction.IsActive);
	Assert.AreEqual(sess.Transaction.IsActive, tx.IsActive);

	Assert.IsNotNull(tx);
	Assert.IsNotNull(sess.Transaction);
	Assert.AreSame(sess.Transaction, tx);

	tx.Commit();
	Assert.IsFalse(sess.Transaction.IsActive);
	Assert.AreEqual(sess.Transaction.IsActive, tx.IsActive);

}

Saturday, August 13, 2011

ProxyCreationEnabled = false; can not load the collections

When using

this.Configuration.ProxyCreationEnabled = false;

You will not be able to load all child collections of an entity

var query = questionRep.All.Where(x => x.QuestionId == questionId);
retrievedQuestion = query.Single();
Assert.AreEqual(expectedCount, retrievedQuestion.Answers.Count);


The retrievedQuestion.Answers is left null when you set ProxyCreationEnabled to false. That assertion will throw an exception.


If you want then to populate the collections of an entity yet you don't want proxy creations, you need to eager load the collections manually.

var query = questionRep.All.Where(x => x.QuestionId == questionId);

query = query.Include("Answers");
query = query.Include("Comments");
query = query.Include("Answers.Comments");

retrievedQuestion = query.Single();

Assert.AreEqual(expectedCount, retrievedQuestion.Answers.Count);


retrievedQuestion.Answers will not be null anymore, Assert.AreEqual can now do its job.

Friday, August 12, 2011

NHibernate and Entity Framework error details

Sometimes, NHibernate produces clearer error message than Entity Framework.

Entity Framework, level of error detail is sounding like an alibi:

Test method TestProject.TestTheIRepository.Ef_CanUpdate threw exception: 
System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details. ---> System.Data.UpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name 'Product_ProductId'.

While NHibernate is very spot-on from where the error came from:

Test method TestProject.TestTheIRepository.Nh_CanUpdate threw exception: 
NHibernate.Exceptions.GenericADOException: could not insert: [TestProject.SampleModel.ProductPrice][SQL: INSERT INTO [ProductPrice] (EffectiveDate, Price, Product_ProductId) VALUES (?, ?, ?); select SCOPE_IDENTITY()] ---> System.Data.SqlClient.SqlException: Invalid column name 'Product_ProductId'.

Check your Entity Framework mapping or your database, e.g. see if the mapped column on your Entity Framework class' property is existing on your database table.

Tuesday, August 2, 2011

Entity Framework 4.1's NHibernate session.Evict(entity);

If you encountered this error..

System.InvalidOperationException: An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

..you may want to evict your object. You can use this routine, granted that the program can access the old entity memory reference.

// (dbContext as IObjectContextAdapter).ObjectContext.Detach(entity);  // old EF of yore
dbContext.Entry(entity).State = System.Data.EntityState.Detached;


However, if you won't be able to reference the old entity, you can use the following helper to force-evict an entity based on its primary key:


Another approach for force-evicting object that already exists in the ObjectStateManager

private static void Evict(DbContext ctx, Type t, 
    string primaryKeyName, object id)
{            
    var cachedEnt =
        ctx.ChangeTracker.Entries().Where(x =>   
            ObjectContext.GetObjectType(x.Entity.GetType()) == t)
            .SingleOrDefault(x =>
        {
            Type entType = x.Entity.GetType();
            object value = entType.InvokeMember(primaryKeyName, 
                                System.Reflection.BindingFlags.GetProperty, null, 
                                x.Entity, new object[] { });

            return value.Equals(id);
        });

    if (cachedEnt != null)
        ctx.Entry(cachedEnt.Entity).State = EntityState.Detached;
}


Sample use:

Evict(yourDbContextHere, typeof(Product), "ProductId", 1);

Monday, August 1, 2011

Razor tag nuances

Instead of doing this:

@{
    int i = 2;
    if (i == 2)
    {
        <text>Whatever great @i</text>
    }
}

You can do this:
@{
    
    int can = 3;
    if (can == 3) {
        @:Whatever great @can  
    }
}

Thursday, July 28, 2011

Sort the version number stored in string type

Read some question on stackoverflow on how to get the latest version number, the version number is of string type though. Here's one of my answer (aside from multiplying each digit group ):


with a as
(
 select * from ( values('2.1.4 '), ('2.1.12'), ('2.1.5'), ('2.2.1') ) as b(c)     
),
x as
(
 select c, 
  Ranking = RANK() 
   over(order by 
    convert(int,PARSENAME(c,3)), 
    convert(int,PARSENAME(c,2)), 
    convert(int,PARSENAME(c,1))) 
 from a
)
select * 
from x;

-- PARSENAME usage is inspired by http://www.sql-server-helper.com/tips/sort-ip-address.aspx

Output:
c      Ranking
2.1.4  1
2.1.5  2
2.1.12 3
2.2.1  4


To get the latest version, just sort the query in descending order then get the row with the ranking of 1:

with a as
(
 select * from ( values('2.1.4 '), ('2.1.12'), ('2.1.5'), ('2.2.1') ) as b(c)     
),
x as
(
 select c, 
  Ranking = RANK() 
   over(order by 
    convert(int,PARSENAME(c,3)) desc, 
    convert(int,PARSENAME(c,2)) desc, 
    convert(int,PARSENAME(c,1)) desc) 
 from a
)
select * 
from x 
where Ranking = 1

Output
c     Ranking
2.2.1 1

Sunday, July 17, 2011

Compelling reason to abandon ADO.NET and use Linq-capable ORM instead

Many scratch their head with this innocent question:

How to pass "Philippines,China,Canada" as parameter @list to IN clause? This isn't working: SELECT * FROM Country WHERE CountryName IN (@list)

Using Linq, that problem can be easily solved. There's no method on scalar type that can test against a list, a good Linq provider (used Linq-to-NHibernate here) don't have a problem translating this(list against scalar) though:

var countryList = 
 from c in s.Query<Country>()
 where new[]{ "Philippines", "China" }.Contains(c.CountryName)
 select c;

The generated query:

exec sp_executesql N'select country0_.CountryId as CountryId1_, country0_.CountryName as CountryN2_1_, country0_.Population as Population1_ 
from [Country] country0_ 
where country0_.CountryName in (@p0 , @p1)',N'@p0 nvarchar(4000),@p1 nvarchar(4000)',@p0=N'Philippines',@p1=N'China'

Linq can accept variable list too:

Console.Write("Input list: ");
string[] list = Console.ReadLine().Split(','); // example input is Philippines,Canada,China

var countryList =
 from c in s.Query<Country>()
 where list.Contains(c.CountryName)
 select c;


The generated query:

exec sp_executesql N'select country0_.CountryId as CountryId1_, country0_.CountryName as CountryN2_1_, country0_.Population as Population1_ 
from [Country] country0_ 
where country0_.CountryName in (@p0 , @p1 , @p2)',N'@p0 nvarchar(4000),@p1 nvarchar(4000),@p2 nvarchar(4000)',@p0=N'Philippines',@p1=N'Canada',@p2=N'China'

Saturday, July 16, 2011

NHibernate equivalent of Entity Framework's MapLeftKey and MapRightKey

Fluent NHibernate equivalent of Entity Framework's MapLeftKey and MapRightKey


.Override<Movie>(x => x.HasManyToMany(y => y.Genres).Table("MovieAssocGenre")        
    .ParentKeyColumn("z_MovieId").ChildKeyColumn("z_GenreId"))
.Override<Genre>(x => x.HasManyToMany(y => y.Movies).Table("MovieAssocGenre")
    .ParentKeyColumn("z_GenreId").ChildKeyColumn("z_MovieId"))


And EntityFramework equivalent of NHibernate's ParentKeyColumn and ChildKeyColumn

// You can either do this:
modelBuilder.Entity<Movie>().HasMany(x => x.Genres).WithMany(x => x.Movies).Map(x =>
 {
  x.ToTable("MovieAssocGenre");
  x.MapLeftKey("z_MovieId");
  x.MapRightKey("z_GenreId");
 });

// Or this:
modelBuilder.Entity<Genre>().HasMany(x => x.Movies).WithMany(x => x.Genres).Map(x =>
 {
  x.ToTable("MovieAssocGenre");
  x.MapLeftKey("z_GenreId");
  x.MapRightKey("z_MovieId");
 });


// In Entity Framework, there's no need to do both statements, just choose one. Any of those statement fully describes the many-to-many on both ends

// Whereas in NHibernate, you need to do both

The DDL:

create table Movie
(
MovieId int identity(1,1) not null primary key,
MovieName varchar(100) not null unique,
MovieDescription varchar(100) not null unique,
YearReleased int not null,
Version rowversion
);

create table Genre
(
GenreId int identity(1,1) not null primary key,
GenreName varchar(100) not null unique
);


create table MovieAssocGenre
(
MovieAssocGenreId int identity(1,1) not null primary key,
z_MovieId int not null references Movie(MovieId),
z_GenreId int not null references Genre(GenreId),
constraint uk_MovieAssocGenre unique(z_MovieId, z_GenreId)
);

Tuesday, June 21, 2011

Non-validation on DateTime and other primitive types on ASP.NET MVC

Even you don't have any Required attribute on a value type property, i.e. primitive types and struct; ASP.NET MVC validation will still kick-in. You must make the field nullable

public class SalesFilterViewModel
{
    public int CompanyId { get; set; } // will be required, even there's no Required attribute
    public int? BranchId { get; set; } // will not be required
    
    public DateTime? StartingDate { get; set; } // nullable, will not be required
    public DateTime? EndDate { get; set; } // nullable, will not be required
}

// A true-false type of polling
public class Poll
{        
    public string QuestionId { get; set; }

    // When a default value of false(when you don't make the bool nullable, 
    // it will default to false on page load) doesn't make sense, 
    // but an answer(either true or false) is still required, make the 
    // property nullable and add a Required attribute.
    [Required]
    public bool? YourAnswer { get; set; }
}

Thursday, May 26, 2011

Dropdownlist callback using jQuery

@model TestDropdownList.Models.Person

<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>
@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>


@using (Html.BeginForm())
{
    @Html.LabelFor(x => x.CountryCode, "Country")

    @Html.DropDownListFor(x => x.CountryCode,
            new Dictionary<string, string>() { { "PH", "Philippines" }, { "CN", "China" }, { "CA", "Canada" }, { "JP", "Japan" } }
            .Select(x => new SelectListItem { Value = x.Key , Text = x.Value} ) )
}


<script type="text/javascript">
    $(function () {
        $('#CountryCode').change(function () {
            // alert('hello');
            alert($(this).val() + ": " + $('option:selected', $(this)).text());

        });
    });
</script>

Thursday, May 19, 2011

Entity Framework Code First Navigation

Entity Framework folks can't claim their ORM can implement things the POCO way, classess are tainted with attributes, it's hard to call it Plain Old CLR Object anymore. I think that's why they just settle with Code-First, whatever that mean :-)


The Objects
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;

namespace EfCodeFirstNavigation.Model
{


    public class Person
    {
        [Key]
        public int PersonID { get; set; }
        public string PersonName { get; set; }
        public int TheCountryID { get; set; }
        

        [ForeignKey("TheCountryID")]
        public virtual Country Country { get; set; }
    }

    public class Country
    {
        [Key]
        public int CountryID { get; set; }
        public string CountryName { get; set; }
        public int Population { get; set; }

        public virtual ICollection<Person> Persons { get; set; }
    }


}

The Relational Mapping and sample data(in comments)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;



namespace EfCodeFirstNavigation.Model
{
    public class CatalogContext : DbContext
    {

        public DbSet<Person> Persons { get; set; }
        public DbSet<Country> Countries { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();


            
        }
    }
}

/* DDL
 

create table Country
(
CountryID int identity(1,1) primary key,
CountryName varchar(100) not null,
Population int not null
);


create table Person
(
PersonID int identity(1,1) primary key,
PersonName varchar(100) not null,
TheCountryID int not null references Country(CountryID)
);


insert into Country(CountryName, Population) values('Philippines', 9)
insert into Country(CountryName, Population) values('China', 2)

insert into Person(PersonName, TheCountryID) values('Michael',1)
insert into Person(PersonName, TheCountryID) values('Jolin',2)
 
*/




Read database:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EfCodeFirstNavigation.Model;

using System.Data.SQLite;

namespace EfCodeFirstNavigation
{
    class Program
    {
        static void Main(string[] args)
        {
            var db = new CatalogContext();
            
            // I don't know why the need to use Include(this is for eager loading, analogous to Fetch of NHibernate) 
            // I thought Entity Framework supported lazy loading already.
            // I'll just research next time why lazy loading doesn't work.
            foreach(var p in db.Persons.Include("Country"))
            {
                Console.WriteLine("{0} {1}", p.PersonName, p.Country.CountryName);
            }
        }
    }//Program
}



Here's the generated query of Entity Framework:
SELECT 
[Extent1].[PersonID] AS [PersonID], 
[Extent1].[PersonName] AS [PersonName], 
[Extent1].[TheCountryID] AS [TheCountryID], 
[Extent2].[CountryID] AS [CountryID], 
[Extent2].[CountryName] AS [CountryName], 
[Extent2].[Population] AS [Population]
FROM  [dbo].[Person] AS [Extent1]
INNER JOIN [dbo].[Country] AS [Extent2] ON [Extent1].[TheCountryID] = [Extent2].[CountryID]


UPDATE(an hour later)

When not including Include, this error happen...
There is already an open DataReader associated with this Command which must be closed first.

..., the solution is to add MultipleActiveResultSets=True to your connection string, rationale can be found from MSDN. You can now remove Include from your Linq. Entity Framework supports lazy loading.

jQuery's LINQ's Select

<script src="/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script>

<body>

@{
    var a = new[] { "The", "quick", "brown", "fox" };
    
    

    var b = a.Select(v => "www." + v + ".com");
    
    foreach(var t in b) {
        Response.Write(t + "<br/>");
    }

    int i = 0;
    var c = b.Select(v => new { v, i = ++i, m = i * 2 });
    
    foreach(var t in c) {
        Response.Write(t.v + " xxx " + t.i + " yyy " + t.m + "<br/>");
    }
    
}



<hr />


<script>

    // This evil code was sourced from http://stackoverflow.com/questions/761148/jquery-document-ready-and-document-write/761190#761190
    $(function () {
        document.write = function (evil) {            
            $('body').append(evil);            
        }
    });
    // ...evil :p mwahahah


    $(function () {
       
        a = ["jumps", "over", "lazy", "dog"];

        b = $.map(a, function (v) {
            return "www." + v + ".com";
        });

        $.each(b, function () {
            document.write(this + "<br/>");
        });


        i = 0;
        c = $.map(b, function (v) {
            return { v: v, i: ++i, m: i * 2 };
        });

        $.each(c, function () {
            document.write(this.v + " xxx " + this.i + ' yyy ' + this.m + "<br/>");
        });

    });
</script>


</body>


Output:

www.The.com
www.quick.com
www.brown.com
www.fox.com
www.The.com xxx 1 yyy 2
www.quick.com xxx 2 yyy 4
www.brown.com xxx 3 yyy 6
www.fox.com xxx 4 yyy 8

www.jumps.com
www.over.com
www.lazy.com
www.dog.com
www.jumps.com xxx 1 yyy 2
www.over.com xxx 2 yyy 4
www.lazy.com xxx 3 yyy 6
www.dog.com xxx 4 yyy 8

Sunday, April 24, 2011

Put prefix to a property

<script>


String.prototype.splice = function( idx, rem, s ) {
    // sourced from: http://stackoverflow.com/questions/4313841/javascript-how-can-i-insert-a-string-at-a-specific-index
    return (this.slice(0,idx) + s + this.slice(idx + Math.abs(rem)));
};

String.prototype.putPrefixToProperty = function(prefix) {
    ndx = -1;
    for(i = this.length - 1; i > 0; --i) {
        if (this[i] == '.') {
            ndx = i;
            break;
        }
    }    
    return this.splice(++ndx,0,prefix)        
}


alert("ProductId".putPrefixToProperty("txt_"));
alert("PurchasedDto.ProductId".putPrefixToProperty("txt_"));
alert("PurchasedDto.LineItem.ProductId".putPrefixToProperty("txt_"));

</script>

Output:
txt_ProductId
PurchasedDto.txt_ProductId
PurchasedDto.LineItem.txt_ProductId

Trivia: Did you know you can copy alert's text(or any dialog for that matter) by pressing Ctrl+C