jQuery UI autocomplete is not displaying results fetched via AJAX - asp.net

I am trying to use the jQuery UI autocomplete feature in my web application. What I have set up is a page called SearchPreload.aspx. This page checks for a value (term) to come in along with another parameter. The page validates the values that are incoming, and then it pulls some data from the database and prints out a javascript array (ex: ["item1","item2"]) on the page. Code:
protected void Page_Load(object sender, EventArgs e)
{
string curVal;
string type ="";
if (Request.QueryString["term"] != null)
{
curVal = Request.QueryString["term"].ToString();
curVal = curVal.ToLower();
if (Request.QueryString["Type"] != null)
type = Request.QueryString["Type"].ToString();
SwitchType(type,curVal);
}
}
public string PreLoadStrings(List<string> PreLoadValues, string curVal)
{
StringBuilder sb = new StringBuilder();
if (PreLoadValues.Any())
{
sb.Append("[\"");
foreach (string str in PreLoadValues)
{
if (!string.IsNullOrEmpty(str))
{
if (str.ToLower().Contains(curVal))
sb.Append(str).Append("\",\"");
}
}
sb.Append("\"];");
Response.Write(sb.ToString());
return sb.ToString();
}
}
The db part is working fine and printing out the correct data on the screen of the page if I navigate to it via browser.
The jQuery ui autocomplete is written as follows:
$(".searchBox").autocomplete({
source: "SearchPreload.aspx?Type=rbChoice",
minLength: 1
});
Now if my understanding is correct, every time I type in the search box, it should act as a keypress and fire my source to limit the data correct? When I through a debug statement in SearchPreload.aspx code behind, it appears that the page is not being hit at all.
If I wrap the autocomplete function in a .keypress function, then I get into the search preload page but still I do not get any results. I just want to show the results under the search box just like the default functionality example on the jQuery website. What am I doing wrong?

autocomplete will NOT display suggestions if the JSON returned by the server is invalid. So copy the following URL (or the returned JSON data) and paste it on JSONLint. See if your JSON is valid.
http://yourwebsite.com/path/to/Searchpreload.aspx?Type=rbChoice&term=Something
PS: I do not see that you're calling the PreLoadStrings function. I hope this is normal.

A couple of things to check.
Make sure that the path to the page is correct. If you are at http://mysite.com/subfolder/PageWithAutoComplete.aspx, and your searchpreload.aspx page is in another directory such as http://mysite.com/anotherFolder/searchpreload.aspx the url that you are using as the source would be incorrect, it would need to be
source: "/anotherFolder/Searchpreload.aspx?Type=rbChoice"
One other thing that you could try is to make the method that you are calling a page method on the searchpreload.aspx page. Typically when working with javascript, I try to use page methods to handle ajax reqeusts and send back it's data. More on page methods can be found here: http://www.singingeels.com/Articles/Using_Page_Methods_in_ASPNET_AJAX.aspx
HTH.

Related

How to display save confirmation message on my Web form when user saves new form by clicking Save button

I am very new to ASP.NET. I am working on some other developer's Web form. I have been asked to fix a bug which says:
No success message is displayed when user clicks Save button after
adding information to the form (first time or while updating)
There is a Label at the top of the page with ID lblMsgs
<asp:Label ID="lblMsgs" runat="server">
I have added this to the Code behind in the appropriate place:
lblMsgs.Text = "Message Text";
Now, my question is how do I modify the HTML or code behind to make sure that when Save button is clicked, the code checks that the data is saved to the database and displays save successful message on the Web form.
Can you please help by giving example of the code using my label ID above?
Thank you in advance.
That's a pretty vague question, but if your looking for data validation you should look at the built in ASP.NET Validators. This can do client/server side data validation. As for returning a message to the user based on a successful update to the DB, that is going to be solution specific depending on what type of data layer your using.
On your Save button handler, you can add validation logic if whether the data is valid or not.
protected void ValidateSave(object o, EventArgs e){
if (Page.IsValid) {
// Save to DB and notify of update status
var success = SomeDBMethod.Update...
if (success){
DoAlert("Saved Successfully!");
}
}
else { lblMsgs.Text = "Failed"; }
}
// Call client-side alert
private void DoAlert(string message) {
ClientScriptManager cs = Page.ClientScript;
var x = "alertScript";
if (!cs.IsStartupScriptRegistered(cstype, x))
{
String script = string.Format"alert('{0}', message);";
cs.RegisterStartupScript(cstype, x, script, true);
}
}

What code do I type in next page after passing gridview button clicked rowindex

I pass the row index value into next page when gridview button clicked using this code
if(e.CommandName=="select")
{
int Id = int.Parse(e.CommandArgument.ToString());
//Label1.Text = Id.ToString();
Response.Redirect("~/manclothes1.aspx?Id=" + e.CommandArgument.ToString());
}
but i don't know what code i write in next page to display row data
please can anyone help me
In ASP.NET you don't actually pass code to a new page. Instead you modify the controls on the current page and the ASP.NET framework re-renders the page for you. Instead of the Response.Redirect line you want something like
DataGrid1.EditItemIndex = Id;
In the page_load of manclothes1.aspx you can try
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["Id"] != null)
{
var id = Request.QueryString["Id"];
// do something with id variable
...
}
}
You'll probably want to reference whatever code on the current page populates the gridview with data in the first place. Essentially, where the code on the current page gets many rows to populate a gridview, the code on the manclothes1.aspx page will get one row. If it's data from a database, the query will likely be very much the same but with an additional WHERE clause to filter by (I'm assuming) an ID value, which is probably a primary key (or the primary key, if we're talking about only one table).
To put this into context, what the call to Response.Redirect() is doing is telling the client (browser) to issue an entirely new request (a GET request, that is) for an entirely new resource (manclothes.aspx with a query string parameter). So understand that "the next page" knows nothing of the gridview on the current page. Nor should it, really. The request should be handled entirely separate from the current page.

Maintaining GridView current page index after navigating away from Gridview page

I have a GridView on ASP.NET web form which I have bound to a data source and set it to have 10 records per page.
I also have a hyper link column on the GridView, such that a user can navigate to another page (details page) from the list. On the details page, they have "Back" button to return to the GridView page
Edit
Just to clarify the query
I am looking for sample code snippet on the Server Side on how to specify the page index to set the GridView after data binding. The idea is to ensure the user navigates to the same page index they were on.
The three basic options at your disposal: query string, session, cookie. They each have their drawbacks and pluses:
Using the query string will require you to format all links leading to the page with the gridview to have the proper information in the query string (which could end up being more than just a page number).
Using a session would work if you're sure that each browser instance will want to go to the same gridview, otherwise you'll have to tag your session variable with some id key that is uniquely identifiable to each gridview page in question. This could result in the session management of a lot of variables that may be completely undesirable as most of them will have to expire by timeout only.
Using a cookie would require something similar where cookie data is stored in a key/data matrix (optimized hash table might work for this). It would not be recommended to have a separate cookie name for each gridview page you're tracking, but rather have a cookie with a common name that holds the data for all gridview pages being tracked and inside that have the key/value structure.
Edit: A small code snippet on setting the page index.
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
try
{
if(HttpContext.Current.Request["myGVPageId"] != null])
{
myGridview.PageIndex = Convert.ToInt32(HttpContext.Current.Request["myGVPageId"]);
}
}
catch(Exception ex)
{
// log it
}
}
}
I'm more of a fan of the Session approach, personally. Simply save your page index as a session variable, and, if this Session variable isn't null on page load, use it to fire your "OnPageIndexChanging" method, like so:
Set your current page number whenever the page number changes:
protected void GridViewIndexChanging(object sender, GridViewPageEventArgs e)
{
myGridView.PageIndex = e.NewPageIndex;
Session["pageNumber"] = e.NewPageIndex;
//whatever your page index changing does...
}
Then, on Page_Load do something like:
if (!IsPostBack)
{
if (Session["pageNumber"] != null)
{
GridViewIndexChanged(myGridView, new GridViewPageEventArgs((int)Session["pageNumber"]));
}
}
you can ues the Page Index Change Event of Gridview and Find out the Current Page Index for e:g
yourGridId.PageIndex=e.NewPageIndex;
ViewState["GridPageIndex"]=e.NewPageIndex;
on PageLoad Get the Viewstate Value
string pIndex=string.Empty;
pIndex=Convert.toInt32(ViewState["GridPageIndex"]);
if(!string.Empty(pIndex))
{
yourGridId.PageIndex =pIndex;
}
you must use query string and is recommended, otherwise you can use session object but don't use that for this as you may have grid view opening in different pages so use query string .
gridView1.CurrentPageIndex = (Request["pageNo"] != null) ? Request["pageNo"] as int : 0;
gridView1.DataSource = myDataSet;
gridView1.DataBind();
you can update your link on GridView_DataBound event

Asp.Net single control render for AJAX calls

I'm trying to implement something similar to this or this.
I've created a user control, a web service and a web method to return the rendered html of the control, executing the ajax calls via jQuery.
All works fine, but if I put something in the user control that uses a relative path (in my case an HyperLink with NavigateUrl="~/mypage.aspx") the resolution of relative path fails in my developing server.
I'm expecting:
http://localhost:999/MyApp/mypage.aspx
But I get:
http://localhost:999/mypage.aspx
Missing 'MyApp'...
I think the problem is on the creation of the Page used to load the control:
Page page = new Page();
Control control = page.LoadControl(userControlVirtualPath);
page.Controls.Add(control);
...
But I can't figure out why....
EDIT
Just for clarity
My user control is located at ~/ascx/mycontrol.ascx
and contains a really simple structure: by now just an hyperlink with NavigateUrl like "~/mypage.aspx".
And "mypage.aspx" really resides on the root.
Then I've made up a web service to return to ajax the partial rendered control:
[ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class wsAsynch : System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
public string GetControl(int parma1, int param2)
{
/* ...do some stuff with params... */
Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl("~/ascx/mycontrol.ascx");
Type viewControlType = viewControl.GetType();
/* ...set control properties with reflection... */
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
}
}
The html is correctly rendered, but the relative path in the NavigateUrl of hyperlink is incorrectly resolved, because when I execute the project from developing server of VS2008, the root of my application is
http://localhost:999/MyApp/
and it's fine, but the NavigateUrl is resolved as
http://localhost:999/mypage.aspx
losing /MyApp/ .
Of Course if I put my ascx in a real page, instead of the pageHolder instance used in the ws, all works fine.
Another strange thing is that if I set the hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx") I get the correct url of the page:
http://localhost:999/MyApp/mypage.aspx
And by now I'll do that, but I would understand WHY it doesn't work in the normal way.
Any idea?
The problem is that the Page-class is not intented for instantiating just like that. If we fire up Reflector we'll quickly see that the Asp.Net internals sets an important property after instantiating a Page class an returning it as a IHttpHandler. You would have to set AppRelativeTemplateSourceDirectory. This is a property that exists on the Control class and internally it sets the TemplateControlVirtualDirectory property which is used by for instance HyperLink to resolve the correct url for "~" in a link.
Its important that you set this value before calling the LoadControl method, since the value of AppRelativeTemplateSourceDirectory is passed on to the controls created by your "master" control.
How to obtain the correct value to set on your property? Use the static AppDomainAppVirtualPath on the HttpRuntime class. Soo, to sum it up... this should work;
[WebMethod(EnableSession = true)]
public string GetControl(int parma1, int param2)
{
/* ...do some stuff with params... */
var pageHolder = new Page() { AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath };
var viewControl = (UserControl)pageHolder.LoadControl("~/ascx/mycontrol.ascx");
var viewControlType = viewControl.GetType();
/* ...set control properties with reflection... */
pageHolder.Controls.Add(viewControl);
var output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
}
The tildy pust the path in the root of the app, so its going to produce a the results you are seeing. You will want to use:
NavigateUrl="./whatever.aspx"
EDIT:
Here is a link that may also prove helpful...http://msdn.microsoft.com/en-us/library/ms178116.aspx
I find the /MyApp/ root causes all sorts of issues. It doesn't really answer your question 'why is doesn't work the normal way', but do you realize you can get rid of the /MyApp/ and host your website at http:/localhost/...?
Just set Virtual Path in the website properties to '/'.
This clears everything up, unless of course you are trying to host multiple apps on the development PC at the same time.
It might be that the new page object does not have "MyApp" as root, so it is resolved to the server root as default.
My question is rather why it works with Page.ResolveUrl(...).
Maybe ResolveUrl does some more investigation about the location of the usercontrol, and resolves based on that.
Weird, I recreated the example. The hyperlink renders as <a id="ctl00_hlRawr" href="Default.aspx"></a> for a given navigation url of ~/Default.aspx. My guess is that it has something to do with the RequestMethod. On a regular page it is "GET" but on a webservice call it is a "POST".
I was unable to recreate your results with hl.NavigateUrl = Page.ResolveUrl("~/mypage.aspx")
The control always rendered as <a id="ctl00_hlRawr" href="Default.aspx"></a> given a virtual path. (Page.ResolveUrl gives me "~/Default.aspx")
I would suggest doing something like this to avoid the trouble in the future.
protected void Page_Load(object sender, EventArgs e)
{
hlRawr.NavigateUrl = FullyQualifiedApplicationPath + "/Default.aspx";
}
public static string FullyQualifiedApplicationPath
{
get
{
//Return variable declaration
string appPath = null;
//Getting the current context of HTTP request
HttpContext context = HttpContext.Current;
//Checking the current context content
if (context != null)
{
//Formatting the fully qualified website url/name
appPath = string.Format("{0}://{1}{2}{3}",
context.Request.Url.Scheme,
context.Request.Url.Host,
(context.Request.Url.Port == 80 ? string.Empty : ":" + context.Request.Url.Port),
context.Request.ApplicationPath);
}
return appPath;
}
}
Regards,
It is hard to tell what you are trying to achieve without posting the line that actually sets the Url on of the HyperLink, but I think I understand your directory structure.
However, I have never run into a situation that couldn't be solved one way or another with the ResolveUrl() method. String parsing for a temporary path that won't be used in production is not recommended because it will add more complexity to your project.
This code will resolve in any object that inherits from page (including a usercontrol):
Page page = (Page)Context.Handler;
string Url = page.ResolveUrl("~/Anything.aspx");
Another thing you could try is something like this:
Me.Parent.ResolveUrl("~/Anything.aspx");
If these aren't working, you may want to check your IIS settings to make sure your site is configured as an application.

Passing flash variables to asp.net

I don't know much about Flash but we are working on a site that has a flash form and when the users pick an option, like selecting a value from a drop down list, we need the value to be passed to asp.net server-side code. What's the easiest way to do this?
Flash can invoke server side service. So use GET or POST to pass data
You could explore these options:
1) Communicate between the SWF and the containing page through JavaScript
2) Communicate via asp.net webservices from the SWF directly to the webservice.
3) Not sure but could probably do a POST to a processing aspx page?
HTH
I think a good option is to use the XML class so consider this:
var xmlRequest = new XML();
xmlRequest.onLoad = parseXMLResponse;
xmlRequest.load("http://yourpathtoyourserver/file.aspx?listselectedvalue=something");
function parseXMLRequest(loaded)
{
trace("hi");
}
You can also have the page give you data back this way so it's not just one way communication.
Assuming you are using Action Script 2.
Read the important notes at the bottom of each codes pertain to sending and retrieving data from flash to .net page. Explanation of the code is in the comment inside the code.
Flash Part (Action Script 2)
//function to send collected form data to asp.net page
//use other control/button to call this function
//important: in order for the 'onLoad' event to work correctly, this function has to be 'Void'
function sendForm():Void
{
//create LoadVars object
var lv_in:LoadVars = new LoadVars();
var lv_out:LoadVars = new LoadVars();
//set onLoad event
lv_in.onLoad = function(success:Boolean)
{
//if success, meaning data has received from .net page, run this code
if (success)
{
//lv_in.status is use to get the posted data from .Net page
statusMsg.text = "Thank you for filling up the form!" + lv_in.status;
}
//if fail, run this code
else
{
statusMsg.text = "The form you are trying to fill up has an error!";
}
}
//this is the collected data from the form
lv_out.userName = txtUserName.text;
lv_out.userAddress = txtUserAddress.text;
lv_out.userBirthday = txtUserBirthday.text;
//begin invoke .net page
lv_out.sendAndLoad("ProcessDataForm.aspx", lv_in, "POST");
}
Important note:
The function that contain onLoad event, in this case sendForm function, has to be Void function, meaning it's not returning value. If this function return value, what happen is the function will be executed all the way without waiting for the returned data from .net page, thus the onLoad event will not be set properly.
.Net Part
public void ProcessData
{
//process the data here
Response.Write("status=processed&");
}
Important note:
To send data/message back to flash, you can use Response.Write. However, if you want Action Script to parse the posted message/data from .Net page keep in mind you have to include & symbol at the end of the message. When parsing data/message, Action Script will stop at & symbol, thus leave the rest of the message alone and only get the message under sent variable.

Resources