views:

63

answers:

4

As it stands right now, I have a literal control on my page. In my code-behind, I'm using StringBuilder to generate some JavaScript. Also on that page I have a item collection. What I want to do is for each item in my item collection, generate my literal which will in essence generate my JavaScript. Here is an example of my code-behind now. I'm ok with doing something different, but I just need to generate said JavaScript for every item in the collection and I'm not sure how to do it.

System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<script type='text/javascript'>");
sb.Append("mboxCreate(\"product_productpage_rec\",");
sb.Append("\"entity.id=" + _prodID + "\",");
sb.Append("\"entity.categoryId=" + _categoryID + "\",");
sb.Append("\"entity.name=" + _prod.Title + "\",");
sb.Append("\"entity.pageURL=" + Request.Url.ToString() + "\",");
//The following value has been taken from the productImageControl code behind.
//Might have to refactor in future as a property of the image control.
string filename = AppSettingsManager.Current.ProductImagePathLarge + _prod.ActiveProductItemCollection[0].Sku + AppSettingsManager.Current.ProductImageExtension;
sb.Append("\"entity.thumbnailURL=" + filename + "\",");
sb.Append("\"entity.inventory=" + _prod.ActiveProductItemCollection.Count + "\",");
sb.Append("\"entity.value=" + _prod.ActiveProductItemCollection[0].ActualPrice + "\",");
sb.Append("\"entity.ProductItemID=" + prodItem.Id + "\",");
sb.Append("\"entity.addToCartImg=~/Images/Buttons/btn_AddToCartFlat.gif\");<");
//The last line has to be /script. < inserted on prev line. do not change it or bad things will happen.            
sb.Append("/script>");
//add script to page
this.LiteralMBoxScript.Text = sb.ToString();
A: 

You should be serializing collection to JSON using JavaScriptSerializer. Using LiteralControl and StringBUilder to generate javascript smells...

Jakub Konecki
how does creating json help here??
jimplode
@jimplode - you don't have to generate js with *every* request. Just write a function that will accept your JSON object in .js file that can be cached by the browser, and pass to it the serialized collection.
Jakub Konecki
I like the idea of passing a JSON array but effectively that's what he's doing. You're just suggesting he serialize the object of data and insert that as a string, but the manual way he's written it here, while not as portable as JSON, is sufficient. I wouldn't push to rewrite it to use JSON.
drachenstern
@Jakub: I agree JSON objects are lightweight and nice, but is not what was asked in the question. So the problem here is not how to do it using JSON, but how to add seperate javascript blocks to the page. I do like JSON though.
jimplode
@drachenstern - I'm serializing only data - the logic can be nicely written in proper js file, reused and doesn't have to be regenerated for every request. It also helps with maintenance and allows for getting data using AJAX.
Jakub Konecki
@jimplode - I understood the question - I just believe you are trying to solve a problem in a not-optimal way.
Jakub Konecki
A: 

What you want to do is something like this:(this is not actual working code)

StringBuilder sb = new StringBuilder("");
foreach(item in collection)
{
    sb.Append("<script type=\"text/javascript\">");
    //do your javascript stuff here
    sb.Append("</script>");
}

literal.Text = sb.ToString();
jimplode
I've tried that method but it doesn't work how I need it to. I need to generate a separate javascript block for each item. This puts them all into one.
tking
not if you add the script tag in each itteration!! Have amended code to demonstrate
jimplode
Ok, I see what you are saying. Sorry. I'll try it.
tking
A: 

I realize that @jimplode suggested wrapping around with a foreach, and that's a good suggestion. I'm going to tackle a different part of the problem.

Injecting Client-Side Script from an ASP.NET Server Control

and try this block on for readability: (note that there's no appending because it's not creating a string and repeatedly adding to it. So it's my understanding that this works as well as a StringBuilder.Append()

string myScript = @"
<script type='text/javascript'>
    mboxCreate(
        'product_productpage_rec',
        'entity.id=" + _prodID + @"',
        'entity.categoryId=" + _categoryID + @"',
        'entity.name=" + _prod.Title + @"',
        'entity.pageURL=" + Request.Url.ToString() + @"',
        'entity.thumbnailURL=" + filename + @"',
        'entity.inventory=" + _prod.ActiveProductItemCollection.Count + @"',
        'entity.value=" + _prod.ActiveProductItemCollection[0].ActualPrice + @"',
        'entity.ProductItemID=" + prodItem.Id + @"',
        'entity.addToCartImg=~/Images/Buttons/btn_AddToCartFlat.gif'
    );
</script>"  
drachenstern
Ok, so you are saying declare the string like so above, then doing a foreach Console.Writeline(myscript); ?
tking
something like that ... yes. Do you understand what the above code does? The `@` in particular
drachenstern
no, not the @. sorry, I'm kind of new to .NET development.
tking
Hence I drew your attention to it. It means take all the characters in this string, _including newlines and carriage returns_ as part of the string.
drachenstern
oh ok. Thank you.
tking
+2  A: 

I think you should not do that in the code behind since it is purely client side code, you should do that in your aspx page using server tags

I'm symplifying your example but the idea is there:

Assuming you have declared the collection in your code behind:

 protected List<Person> persons = new List<Person>();

protected void Page_Load(object sender, EventArgs e)
        {
            persons.Add(new Person() { Name = "Toto", Firstname="Bobo" });
            persons.Add(new Person() { Name = "Titi", Firstname = "Bibi" });
        }

You put that in your aspx

<% foreach (var person in persons)
   { %>
<script type="text/javascript">
    mboxCreate("person.name=" + "<%=person.Name%>", "person.firstname=" + "<%=person.Firstname%>");
</script>
<%} %>

This will generate the following html:

 <script type="text/javascript">
 mboxCreate("person.name=" + "Toto", "person.firstname=" + "Bobo");
 </script>

 <script type="text/javascript">
 mboxCreate("person.name=" + "Titi", "person.firstname=" + "Bibi");
 </script> 

The huge advantage is that you dont have to do anymore those ugly string concatenation in your code behind. And it is a lot easier to read/maintain.

Sigo
Good call there @sigo. Additionally, he could use a ASP:REPEATER control and do something similar. Then he could get all the benefits of databinding (in this case, not so much, but that's why I suggest the repeater, the lightest of the bunch)
drachenstern