i have a page where on click of a button, a javascript function runs. It then aggregates some data and places the data on a hidden field in this page. It then opens a new window. This new window picks up this aggregated data like so :-
$('#accepted').val(window.opener.$('#accepted').val());
where accepted is the hidden field in both parent and child window (no runat="server" was used). The issue now is that i require this data to databind two grids. Currently I've done a doPostback on both grids, but what i really want to do is doPostback for the form once and handle the databinding the PageLoad event. So two questions :-
1) How do i doPostback the form?
2) How do i do this while still being able to differentiate from the actual form submission?
To post the form you should just be able to add a call to __doPostback in your javascript, after the accepted field is set. You can use the EventTarget and EventArgument parameters of the __doPostback to control the binding in your grid.
So, you could put this in your js:
__doPostback('rebindGrid', '');
and then this in your page load event:
if (Request.Form["__EVENTTARGET"] == "rebindGrid")
{
//....Do so stuff
}
In order to tie it in more directly with the postback model I wrap mine with some C#
C# Extension Method
public static string GetPostBackLink (this Control c, string argument = "") {
return c.Page.ClientScript.GetPostBackEventReference(ctl, argument, true) + ";";
}
ASPX
<asp:LinkButton id="lnkDoThis" runat="server" onclick="lnkDoThis_Click"
style="display: none;"></asp:LinkButton>
<asp:HiddenField id="hdnParamHolder" runat="server" />
JS
function DoSomething(param) {
$("[id$='hdnDealTemp']").val(param);
<%= lnkDoThis.GetPostBackLink() %>
}
CodeBehind
protected void lnkDoThis_Click (object sender, EventArgs e) {
var myParam = hdnParamHolder.Value;
// Do server actions here
}
As for the opening in a second window ... I am not sure I follow when you want this to happen? If it is after the postback you will need to read from the hdnParamHolder control when the page reloads.
Related
I have 2 pages : PageListAnimals and PageEditAnimal.
In PageListAnimals, there is a gridview with animals information. I can click on each animal to open the PageEditAnimal : that opens another page, in a new window.
When i finished editing animal information, i would like to save and close the window PageEditAnimal, and after that, the other window PageListAnimals will be refreshed, or the grid view inside updated.
I know solutions exist in javascript, but i would like to implement it server-side.
I think it's possible to have something like Observer pattern for example. When the PageEditAnimal is closed, that notifies the PageListAnimals to update himself.
Please give me a clue or something to help to solve that problem.
EDIT - RESOLVED :
The solution was to call the refresh of the parent from the child, but i just managed to do this in javascript :
window.onbeforeunload = function () {
window.opener.refresh();
}
Then in the parent, the javascript function method() has to update the gridview inside.
Why do you need to open another page do do the edit?
Instead open in the same page, and after the edit is done, redirect to the PageListAnimals page.
Response.Redirect("PageListAnimals.aspx");
If you insist to keep the PageListAnimals open, then I think the only way to do it is with javascript. Just create a call to a server side function that contains GridView.Databind() method.
You can do it this way:
add this script in the head of your page
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(window).focus(function () {
document.getElementById('<%= Button3.ClientID %>').click();
});
</script>
Add this button, to call the code behind that should update the GridView
<asp:Button ID="Button3" style="display:none"; runat="server" Text="Button" onclick="Button3_Click" />
And code behind should look like this:
protected void Button3_Click(object sender, EventArgs e)
{
//This is how your data should be bind in GridView
GridView1.DataBind(); //GridView1 -> name whatever your gridview is named
}
Caution
This code is called whenever you go to the page PageListAnimals, so use it with careful.
I have a custom control which is basically a Gridview and its first column is a TemplateField with a checkbox in the header and a checkbox for each of the rows. Clicking on the header checkbox should call some javascript to toggle each of the checkboxes in every row on display... it's a common requirement as we know.
My problem is (I'll go into more detail later) that when I have 2 of these controls on the same page, and I click the checkbox that selects all the chkboxes, the page calls the wrong bit of javascript (which only appears once on the rendered html page) and checks all the checkboxes on the wrong grid !
Here's my code:
<asp:TemplateField>
<HeaderTemplate>
<input type="checkbox" ID="chkSelectAll" onclick="SelectAllCheckboxes(this)"/>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkSelected"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>
Javascript:
<script>
function SelectAllCheckboxes(chk) {
$('#<%=gridPublishers.ClientID%>').find("input:checkbox").each(function ()
{
if (this != chk) { this.checked = chk.checked; }
});
}
</script>
So, the parent page has 2 of these controls on it. The first grid shows All the publishers and the other shows the publishers that have been selected from the first...
<h2>Selected Publishers</h2>
<cac:GridPublishers id="GridSelectedPublishers" runat="server" CssClass="GridSelectedPublishers" BindSource="DynamicFromSession" ShowMultiSelectCol="true" ShowFilterControls="false" NoRecordsMessage="No Publishers have been selected yet." />
<br /><br />
<h2>All Publishers</h2>
<cac:GridPublishers id="GridPublishers" runat="server" ShowMultiSelectCol="true" CssClass="GridPublishers" />
As I said earlier, the javascript only appears once on the rendered html page (and I understand why) but how can I get each instance of the custom control calling it's own javascript (or an alternative method) so that it only toggles its own checkboxes ??
...
I've also tried adding 2 javascript events and on grid bind trying to find the master checkbox and assign it the correct JS function, but I've searched each cell of the header row, and col 0 (where the control should be) holds 0 controls.
...
I've also tried adding a hidden button that on page load, I can assign it the correct javascript function (that will affect the correct gridview) and then the master checkbox fires the hidden button onClientClick event, but as the page reloads, it gets confused and fires the click event twice and from both grids apparently !
Please help !!
So I guess you realise that this line of code is causing the root problem of selecting the checkboxes in the wrong datagrid:
#<%=gridPublishers.ClientID%>').find
It's always going to pickup gridPublishers, and not GridSelectedPublishers.
So this is the area to fix. What you need to do is make this function a bit more abstract:
<input type="checkbox" ID="chkSelectAll" onclick="SelectAllCheckboxes(this)"/>
The onclick event passes 'this', but that's only a reference to the checkbox which isn't much help.
I'd suggest you try and make it something like this:
<input type="checkbox" ID="chkSelectAll" onclick="SelectAllCheckboxes(this,'GridSelectedPublishers')"/>
And then use the 2nd argument in the javascript function to grab the right datagrid.
Your problem now, is how to get that 2nd argument in there....you may be able to think of your own solution for this, but I would be tempted to make that checkbox an ASP checkbox, and find it during datagrid render and assign it the onClick with Attribute.Add
Making sense?
I've already marked "ben_the_builder's" answer as correct because it got me along the right line.
When I bind my grids I call this function:
private void Register_CheckAllControl_JScript()
{
// THIS IS A WORKAROUND FOR WHEN TWO OF THE SAME CUSTOM CONTROL LIVE ON THE SAME PAGE, EACH CONTROL'S JAVASCRIPT MUST SPECIFY THE ID OF THE CONTROL TO AFFECT
if (gridPublishers.HeaderRow != null)
{
CheckBox chkAll = gridPublishers.HeaderRow.FindControl("chkSelectAll") as CheckBox;
if (chkAll != null)
{
if (this.BindSource == Enumerators.BindSource.DynamicFromSession)
{
chkAll.Attributes.Add("onclick", "SelectAllCheckboxes(this,'GridSelectedPublishers');");
}
else
{
chkAll.Attributes.Add("onclick", "SelectAllCheckboxes(this,'GridPublishers');");
}
}
}
}
To access the "master" checkbox from code behind - it had to be an ASP control. an input control just wasn't recognised when iterating through the header cell collection.
My Javascript needed a little tweaking for the IDs to be correct. The control name I'm passing had to be name it was given on the parent page which belongs in the middle of the three tier final html output name (see the example, it'll make sense...)
My Javascript looks like this now:
<script>
function SelectAllCheckboxes(chk, ctrlName) {
//if ctrlName = "
$("#MainContent_" + ctrlName + "_gridPublishers").find("input:checkbox").each(function () {
if (this != chk) { this.checked = chk.checked; }
});
}
</script>
You want to use parameters. Instead of hard coding #<%=gridPublishers.ClientID%> into your javascript function, use the this parameter you pass to the function to determine the name of the grid view that contains the checkbox, then check everything inside that grid view.
I have a Update Panel inside a User Control i use on 2 pages in my website
Both pages use the same MasterPage, ScriptManger is declared in the MasterPage.
Both pages call the UC the same way:
<uc:SearchCube runat="server" ID="searchCube" />
in the Update panel i have many RadioButtons that on change generate a server side event that fill dropdown in the update panel and update the panel
protected void SearchCategoryChanged(object sender, EventArgs e)
{
FillDropdowns();
SearchOptions.Update();
}
Update Panel is set like this:
<asp:UpdatePanel ID="SearchOptions" runat="server" UpdateMode="Conditional"
hildrenAsTriggers="true"/>
Each RadioButton is set like this:
<asp:RadioButton ID="RadioButton1" GroupName="SearchCategory" runat="server"
AutoPostBack="true" OnCheckedChanged="SearchCategoryChanged" Text="Text"/>
I also have an AsyncPostBackTrigger on each Radio Button Controller
The problem i have is that on one page when i call the Update() function the panel is updated and Page_Load is triggered which causes the UC to refresh and reload the default settings of the UC
I can see in DEBUG mode that on the working page Update() does not generate Page_Load.
Can anyone explain to me why this is happening?
Everytime a request goes to the server, it executes the Page_Load event.
What you need to do is make sure you have a PostBack validation on all your pages:
protectec void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
//Not a postBack: Normal page load
//Init your page here
}
else
{
//It's a PostBack (from a command).
//Do nothing or init stuff your all your commands.
}
}
If you put some breakpoints in your Page Load and your SearchCategoryChanged method, you'll be able to see what the pipeline looks like.
Fixed my problem.
the problematic page is an index page that takes a few parameters in.
I have a Response.Redirect() on the page to avoid duplication of pages.
Apparently when the PostBack() is made it calls the page without any parameters and i was forcing it to be redirected into a default view since no parameters were sent to the page.
i found a lead to my problem in a Microsoft help forum that stated:
By calling Response.Write() directly you are bypassing the normal
rendering mechanism of ASP.NET controls. The bits you write are going
straight out to the client without further processing (well,
mostly...). This means that UpdatePanel can't encode the data in its
special format.
Anyway the page was reloading every time which caused it to reload the User Control with it's default values.
I have a web form that allows the user to modify data in certain fields (mostly TextBox controls, with a couple of CheckBox, DropDownList, and one RadioButtonList control) with a submit button to save the changes. Pretty standard stuff. The catch is, I need to keep track of which fields they modified. So I'm using ASP.NET HiddenField controls to store the original value and then on submit comparing that to the value of the corresponding TextBox (for example) control to determine which fields have been modified.
However, when I submit the form and do the comparison, the value of the TextBox control in the code behind still reflects the original value, even though I have changed the contents of the TextBox, so it isn't registering the change. Here is an example of a set of TextBox/HiddenField pairings (in this case last, first, middle names) in my ASP.NET form:
<div id="editName" class="editField" style="display: none">
<asp:TextBox ID="tbxLName" runat="server" class="editable"></asp:TextBox>,
<asp:TextBox ID="tbxFName" runat="server" class="editable"></asp:TextBox>
<asp:TextBox ID="tbxMName" runat="server" class="editable"></asp:TextBox>
<asp:HiddenField ID="hdnLName" runat="server" />
<asp:HiddenField ID="hdnFName" runat="server" />
<asp:HiddenField ID="hdnMName" runat="server" />
</div>
I'm setting the original values of all these controls (".Text" for the TextBox controls, ".Value" for the HiddenField controls) on PageLoad in the code behind.
Here's an example of where I'm doing the comparison when I submit the form (I'm adding the field name, old value, and new value to List<string> objects if the values differ):
if (tbxLName.Text != hdnLName.Value)
{
changes.Add("ConsumerLastName");
oldVal.Add(hdnLName.Value);
newVal.Add(tbxLName.Text);
}
But when I enter a new value into the TextBox control and click Submit:
then step through the code in the debugger, it shows me that the value of the control is still the old value:
Why is the comparison happening against the original value of the TextBox even though the new value is there when I click the submit button?
Update: #David gets the credit for this, even though he didn't post it as an answer -- I was forgetting to enclose the method for pre-filling the original values of the controls in a check for IsPostBack; I really should have known better, I've been doing this for quite a while!
Are you checking for IsPostback in Page_Load so you don't overwrite the values sent in the Postback?
Make sure that you are not overwriting your values in the Page_Load method:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
someTextField = "Some Value";
}
}
It took a while for me to get that the Page_Load method works as an "before anything goes" method and not only a method that is being ran when you visit the page with GET.
Make sure you're not overwriting the value for the textbox somewhere in page init or load without checking for the IsPostback flag.
It may happen due to postback. If you code for set textbox not in !isPostBack then put it.
i.e.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
tbxLName.Text="anything";
}
}
I am creating a custom user control that will act as a search feature. I want to easily be able to add this to multiple pages without having to modify much code.
I thought the best method to do this would be to create a simple user control that I can inject anywhere with one line of code and then have this control postback to a different URL. So wherever the search function is, it will always post back to the same page. My control looks like this:
<asp:TextBox ID="searchTextBox" runat="server" MaxLength="350"></asp:TextBox>
<asp:Button ID="submit" runat="server" Text="Search" PostBackUrl="~/myPostBackPage.aspx" />
myPostBackPage.aspx.cs looks like this, but it isn't grabbing the text.
protected void Page_Load(object sender, EventArgs e)
{
content.InnerHtml = ((TextBox)PreviousPage.FindControl("searchTextBox")).Text;
}
But it isn't pulling anything from the searchTextBox field and I get:
Object reference not set to an instance of an object.
Is there a better way to do this or how should I fix my code? Thanks!
I don't know where the TextBox is declared, if you for example use MasterPages the NamingContainer of it would be the ContentPlaceHolder of the master instead of the Page. Therefore just cast the PreviousPage property to the correct type:
YourPageType page = PreviousPage as YourPageType;
if(page != null)
{
content.InnerHtml = page.SearchText;
}
You have to provide a public property since the TextBox is protected(best-practise anyway):
public string SearchText
{
get { return searchTextBox.Text; }
}
I tested your code and PreviousPage is null. Try switch to Page.