I can tell you where its going wrong!
its here:
cs.RegisterClientScriptInclude(this.GetType(), "jq", "/_layouts/js/jquery.js");
cs.RegisterClientScriptInclude(this.GetType(), "custom", "/_layouts/js/custom.js");
how do i know? well its simple! i presum as you said you have many instances of custom.js
now this is where it gets messy, to put it simple! i have created a webpart and it contains an ascx. The webpart is added 5 times to the page (its a textbox that moves up/down).
To move the textbox I added Javascript to it, now when i run the code i notice that all 5 textbox (webparts) move up and down at the same time even tho in my javascript it should be random! (each webpart is ment to move at random intervals from each other)
to explain whats going on! javascript doesnt know what control to move as what your passing is exactly the same! so if like in my exaple i have each textbox wraped in a div with its class or id as "moveme", in the js i said to find moveme and move it up/down. As the webparts are repeated 5 times that makes 5 divs with the same ID's "moveme" so that javascript code is moving all 5 divs with that id ;) , so do you get where im going?
to get around this issue and to target the selected webpart you need to assign a unqiue id or pass on the auto generated div to the js file!
http://forums.asp.net/t/1855866.aspx
in your case its passing the webparts id! what exactly are you doing in the js files? this is a common issue when it comes to multiple controls/webparts using the same JS file using the same ID/Class.
also make sure your controls that your setting have unique values;
you can use Random;
//call the random generator class
Random rnd = new Random();
//use the code below as the auto id generator for you
rnd.Next();
so the above code will be used in this sense:
Textbox tb = new Textbox();
tb.Id = rnd.Next();
leaving the controls without id set should be auto generated.
it looks like you have multiple controls for some reason with the same id! hence why your getting all the same controls being updated with the same content until you submit the page
you need to look at your js file to see what its doing client side that is putting in the same content though all other webparts. When you click the submit button that is different because the control ids are auto generated and the button is serverside and its related to that webpart not the others, so the button you click will only update the webpart it belongs to... the others loose the content as the event related to the other webparts are different!
so my conclusion is.... your js file is doing somthing it should. it just doesnt know what exact control to update on client side as its updating all the webparts indicating they all have the same class or id (could be a div, textbox ect).
one solution isto pass your id's to the correct place? like making a parent div. It would be unique for each webpart by incrementing by the value of 1 everytime a webpart is added. This value is then passed on to the js file to do what it needs todo! so it would look like this:
webpart 1
div Id="1"
webpart 2
div Id="2"
webpart 3
div Id="3"
in your create child controls you can add the div like so:
//create a varible to store your unique ids
private int ids;
protected override void CreateChildControls()
{
//add a div with an id
this.Controls.Add(new LiteralControl("<div id='" + ids + "'>"));
//do your normal code
//add other controls
TextBox tb = new TextBox();
tb.Text = "hell0" + ids;
this.Controls.Add(tb);
//close the div
this.Controls.Add(new LiteralControl("</div>"));
}
so this webpart is adding a textbox surrounded by a div with a unique ID
now you need to remember ids for each new webparts thats repeating to page like so:
//save/get last known ID value to session state
public string ControlIds
{
get
{
return Page.Session["ControlIds"] as string;
}
set
{
Page.Session["ControlIds"] = value;
}
}
now ammend createchildcontrols to add it to session state:
add this first:
if (ControlIds != null)
{
ids = int.Parse(ControlIds);
}
this check to see if its NOT null, null is when it first loads, if its not than populate the value from session state into the varible
//create a random number
Random rndID = new Random();
//check if script value is already registered (needs to be unique)
if (!Page.ClientScript.IsStartupScriptRegistered(this.GetType(), "test" + rndID.Next().ToString()))
{
//register the js script: here im calling MoveImage in my JS file that takes a varible ID
Page.ClientScript.RegisterStartupScript(this.GetType(), "test" + rndID.Next().ToString(), "MoveImage(" + ids + ");", true);
//increment the id
ids++;
//add the current ID to session state
ControlIds = ids.ToString();
}
so the full .cs code will be:
//save/get last known ID value to session state
public string ControlIds
{
get
{
return Page.Session["ControlIds"] as string;
}
set
{
Page.Session["ControlIds"] = value;
}
}
protected override void CreateChildControls()
{
if (ControlIds != null)
{
ids = int.Parse(ControlIds);
}
//add a div with an id
this.Controls.Add(new LiteralControl("<div id='" + ids + "'>"));
//do your normal code
//add other controls
TextBox tb = new TextBox();
tb.Text = "hell0" + ids;
this.Controls.Add(tb);
//close the div
this.Controls.Add(new LiteralControl("</div>"));
//create a random number
Random rndID = new Random();
//check if script value is already registered (needs to be unique)
if (!Page.ClientScript.IsStartupScriptRegistered(this.GetType(), "test" + rndID.Next().ToString()))
{
//register the js script: here im calling MoveImage in my JS file that takes a varible ID
Page.ClientScript.RegisterStartupScript(this.GetType(), "test" + rndID.Next().ToString(), "MoveImage(" + ids + ");", true);
//increment the id
ids++;
//add the current ID to session state
ControlIds = ids.ToString();
}
}
in your js file you can see that its passing the value by doing this:
function MoveImage(arg)
{
alert("this controls ID is "+arg);
}
within the js file you can now do what you want by going through the parent (div ID) to its siblings (only to that specific webpart)
sorry for the long winded code!