Self explanatory question.
Between posts, the grid I have setup is retaining the HasSelection bit, even if the WebGrid has been re-loaded with new data. Therefore, the functionality I have wired into the physical selection of a WebGrid record runs, even though the user hasn't selected anything on the new resultset yet.
Thoughts?
WebGrid obtains the selected row thru the query string. by default, the query string field is row like http://localhost/grid?row=2
Ideally, you would remove that query string field before posting back like so http://localhost/grid
If it is not possible, set WebGrid.SelectedIndex to -1 instead.
Edit
Here are few ways to set WebGrid.SelectedIndex:
#{
WebGrid grid = new WebGrid(Model);
grid.SelectedIndex = ViewBag.SelectedIndex;
#grid.GetHtml(
columns: grid.Columns(
...
)
)
}
public ActionResult Index(int? row)
{
ViewBag.SelectedIndex = (IsKeepSelection() ? row.GetValueOrDefault() : 0) - 1; //TODO: add bound checking
return View(People.GetPeople());
}
Or (I prefer the previous one though since it's easier to understand):
#{
WebGrid grid = new WebGrid(Model);
if(ViewBag.ClearSelection) {
grid.SelectedIndex = -1;
}
#grid.GetHtml(
columns: grid.Columns(
...
)
)
}
public ActionResult Index(int? row)
{
ViewBag.ClearSelection = IsClearSelection();
return View(People.GetPeople());
}
The ultimate answer to this issue was to clear out the "action" on the form. Apparently, the WebGrid is tightly coupled to this value and therefore the makers of the WebGrid expected you to futz with the action attribute instead of the WebGrid itself.
I simply reset the querystring with document.forms[0].action = window.location.pathname; in my submission button. Since the form's action resolves to the querystring, this fixed it.
Related
When I use the code below, I remove the datatable values, but the data table structure still exists and displays empty fields (see pics) with the DOM explorer showing an empty table and table rows.
How can I clear the datatable values and the table itself? This way when I repopulate search again, the empty smaller table isn't present?
lvwOutput.Items.Clear();
lvwOutput.DataSource = null;
lvwOutput.DataBind();
Before
After items.clear and datasource = null
This is ridiculous and I believe there is a better way to do this, but the never ending server/client battle makes this harder than it should be. My listview binded to a datatable is called lvwOutput.
In my btnClear I had to put the following. You cannot hide the element or clear the items in the server side asp code for this to work
ScriptManager.RegisterStartupScript(Page, GetType(), "emptyTable", "javascript:emptyTableRows(); ", true);
In my javascript code I had to put the following, this clears the client code
function emptyTableRows(){
var tableHeaderRowCount = 0;
var table = document.getElementById('lvwOutputTable');
var rowCount = table.rows.length;
for (var i = tableHeaderRowCount; i < rowCount; i++) {
table.deleteRow(tableHeaderRowCount);
}
}
And then in the portion of my code that would display the listview and datatable when the user initiates another sql search. This clears the server side.
lvwOutput.Items.Clear();
lvwOutput.DataSource = null;
lvwOutput.DataBind();
You can create a property the stores the data table in session that way you can access it during the click event.
DataTable dtbleDataSource
{
get
{
return Session["dataSource"] as DataTable
}
set
{
Session["dataSource"] = value;
}
}
In your click event you can say:
dtbleDataSource.Reset();
I have ajax function like this to run on HTML select list
$.ajax({
type: "POST",
url: urlemp,
success: function (returndata) {
if (returndata.ok) {
// var data = eval("" + returndata.data + "");
select.empty();
select.append($('<option>' + "" + '</option>'));
$.each(returndata.data, function (rec) {
select.append($('<option>' + returndata.data[rec].Name + '</option>'));
});
select.show('slow');
select.change();
}
else {
window.alert(' error : ' + returndata.message);
}
}
}
);
and this is the HTML element
<select id="cmbDept"></select>
How can i get the value of the selected item in the controller using MVC 3 ?
you have 4 ways to do that
1. the you can bind ti the change event of the select $(select).change(function(){}) and send an ajax request again wrapping the selected value which you will be able to get in the controller
2. you can keep a hidden input in your view binded to a property in the view's model now bind to the change of the select and fill the input with the value this way whenever your form is posted back it will have the values properly binded to the model
3. #Don saved me from writing the third way so read his ans.
4. if you have a model that this view is binded to then simple keep a property in the model with the name cmbDept and selected value would be automatically posted back
Us FormCollection as parameter in your controller. And assign name to the select
<select id="cmbDept" name="cmbDept"></select>
Now the FormCollection has this posted value.
public ActionResult Index(FormCollection form)
{
string val = "";
foreach (var key in form.AllKeys)
{
if (key.Contains("cmbDept"))
{
val = form.Get(key);
}
}
--your code here with the posted values
return View();
}
To get the value of the select element on the client, just use $("#cmbDept").val().
To get the value of the element once it's submitted to the server, add a name="cmbDept" to your select and simply create a parameter named cmbDept in the controller action your $.ajax call is is posting to.
I have encountered a problem and I didn't manage to find any soultions yet. Let me simplify things a bit.
I have 2 forms, the first contains an ASP ListBox with multi select mode enabled. I submit the form and in the other form I use just for testing purposes this snippet of code:
protected void Page_Load(object sender, EventArgs e)
{
foreach (string formKey in Request.Form.AllKeys)
{
if (formKey != null)
{
if (formKey.Equals("ctl00$MainContent$ListBox1"))
Label1.Text = Request.Form[formKey];
}
}
}
The problems is that the values that come from the listbox (the values that i selected in the previous form) are separated by "," for ex. "test1,test2,test3". How can i change this separator to "$" for example? I need to change it because the actual values may contain "," and i don't manualy feed them to the listbox.
I can't use any other mode of transfering this values between the form because the entire application uses this model. The values that i get are then sent to a workflow where there will be manipulated and in the workflow i need to know where each listbox item starts and ends so it must be an unique separator.
Any help is apreciated! Thank you very much
Thank you MatteKarla but unfortunately this does not solve my problem. Yes, this is a good way of transfering the values from one form to another.
However i must use the method I described above with Request form keys because the listbox is one of many others "parameters" that are generated at runtime and have their values sent to a workflow method that takes this values. And i can't afford to change that in my application.
My problem is that coma (",") separator is used by default with a multiselect listbox.
I thought that there maybe is a method to change that separator from coma to another char because the coma can also be included in the value itself and this will create confusion.
As i said if i select three values test1, test2 and test3, the result with my method will be a string looking like "test1,test2,test3". However a "test1$test2$test3" would be much better.
But I'm affraid that changing this default separator is not possbile. I must think at a method to overcome this problem like replacing before feeding the listbox all the intended coma from the values with some other char not to create confusion. But this is not a great way of doing it.
On your first page/form (First.aspx.cs) create a public property with the listbox:
public ListBox PostedListBox { get { return ListBox1; } }
Set the postback-url for the button to Second.aspx
Second page in the aspx-file after the #Page-directive add:
<%# PreviousPageType VirtualPath="~/First.aspx" %>
Then in Form_Load on Second.aspx.cs you can extract the values:
if (PreviousPage != null)
{
ListBox postedListbox = PreviousPage.PostedListBox;
foreach (var index in postedListbox.GetSelectedIndices())
{
var itemText = postedListbox.Items[index].Text;
}
}
Or you could just try to locate the control by using:
if (PreviousPage != null)
{
var control = PreviousPage.FindControl("ListBox1") as ListBox;
}
Third Edit:
You could use GetValues:
Request.Form.GetValues("ctl00$MainContent$ListBox1");
returns a string array containing each of the selected items.
I have a webpage which includes a telerik grid in ajax mode. The data for the grid is constructed in the controller action used to serve the view, and then stored in the session. 90% of the time its available to the ajax method used to populate the grid. And sometimes its not, which is odd. Some sort of race condition ?
public ActionResult EditImage(int productModelId, int revision)
{
ViewBag.Current = "Edit";
//Unit of work and repo generation removed from brevity
var modelToEdit = prodModelRepo.Where(p => p.ProductModelID == productModelId && p.Revision == revision).FirstOrDefault();
var vmie = new VMImageEdit(modelToEdit)
{
//init some other stuff
};
Session["vmie"] = vmie;
return View(vmie);
}
Now the telerik contorol will post back to _EISelect in order to populate its grid
// Ajax Actions for EditImage
[GridAction]
public ActionResult _EISelect()
{
var vmie = (VMImageEdit) Session["vmie"];
return View(new GridModel(vmie.Colours));
}
So if my session object is null, how can I recover - I guess I need the productModelId and Revision parameters from the original EditImage call. Are they available in the _EISelect in any way - its posted to, and the post contains nothing useful.
Oh to make this possibly harder, this page will be displayed via an inline frame.
The answer lies in the telerik ajax databinding - this can be used to pass arbitrary data in the querystring
.Select("_EISelect", "AdminProduct", new { productModelId = Model.ProductModelId, revision = Model.Revision})
which can be recovered in _EISelect as parameters. Simples.
Using ASP.NET 3.5 ListView control.
I would like to capture the value of my table id from the currently edited row of a ListView.
A ItemEditing event has been added to the ListView.
The only value available in this event is e.NewItemIndex.
This returns 0 if the first row of the current page of the ListView is being edited.
How do I convert this 0 into the actual table id (label control value)?
I have tried:
table_id = Convert.ToString(ListView1.Items[e.NewEditIndex].FindControl("table_idLabel1"));
Can you use the DataKeyNames property instead of a label? Set the property to the name of the database field that is the key for the table, then do something like this:
table_id = ListView1.DataKeys[e.NewEditIndex].Value.ToString();
Are you sure table_idLabel1 is the correct id?
Also, you may need to look recursively as in Chris's answer. Plus, it looks like your casting the control to a string. You probably want the ID property and not the control itself.
Use FindControlRecursive (from Recursive Page.FindControl). The problem with FindControl is that it only search one layer deep.
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}
return null;
}