JQuery, ASCX and webmethods not seems to be working - c#

I have a cascading dropdown (3 of them) Type, Categories and Sub Categories. Type loads first and upon selection of Type, Category load and selection of Category, Sub Category loads.
Also i have 2 buttons, "Add Category" and "Add Sub Category" Upon clicking on these buttons, i call a JQuery Modal Form to add them. I use Webmethod in code behind to add them to database
This works perfectly in ASPX page.
Since I need use this in 3-4 pages, i thought of making the above as User control (ASCX). When i try to use this in a webpage, the webmethods in ASCX don't get called.
Is my approach correct? what should be done for my scenario
lOoking forward for your suggestions.
Thanks in advance
Karthik

i dont think you can have a WebMethod within a ASCX Control.
I solved it for my Problem like this:
AJAXBridge:
namespace Demo{
public partial class AjaxBridge : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod(EnableSession = true)]
public static string Control_GetTest()
{
return Control.GetTest();
}
}}
Control.ascx.cs
namespace Demo{
public partial class Control : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
HttpContext.Current.Session["test"] = DateTime.Now.ToString();
}
// ALMOST A WEB METHOD
public static string GetTest()
{
return " is " + HttpContext.Current.Session["test"];
}
}}
Control.ascx
<script type="text/javascript">
var dataSend = {};
$.ajax({
type: "POST",
url: "AjaxBridge.aspx/Control_GetTest",
data: dataSend,
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function(data) {
alert("before");
},
success: function(data) {
alert("Page Load Time from Session " + data.d);
},
fail: function() {
alert("fail");
}
}); </script>
So you have one ASPX which acts basically like a Interface for all AJAX Methods in all your Web Controls. There also some advantages like having overview and control of all exposed WebMethods, which makes it a lot easier to handle security matters (eg. with Annotations).

Was your web method was a static method in the code behind that was marked with WebMethod attribute as described in the "Calling Static Methods in an ASP.NET Web Page" section here before you moved it? If so this type of webmethod only works at the page level and cannot be used in a usercontrol. For an alternative read the first two sections of this page.

Related

Render a new partial view on existing partial view

I am trying to do a drill down report. I am using MVC and Devexpress Gridviews. I render my view and the partial view and display my gridview with the result.
Now what I need to accomplished is when I double click on the gridview I need to render a new/different partial view in the place off the existing gridview - The one I double clicked on.
Is this possible?
Here is what I have:
public ActionResult MainPartial()
{
using (var Context = new DataContext())
{
ViewBag.Level = 0;
return PartialView("MainPartial",SomeData);
}
}
public ActionResult FirstDrilldownPartial(int Param)
{
using (var Context = new DataContext())
{
ViewBag.Level = 1;
return PartialView("FirstDrilldownPartial",SomeNewData(Param));
}
}
My Gridview RowDblClick event
function onDoubleClick(s, e) {
$.ajax({
type: 'POST',
url: '/Controler/FirstDrilldownPartial',
dataType: 'json',
async: false,
//cache: false,
data: {
Param: 1
}
});
}
At the moment everything is working but when I call the function "function onDoubleClick(s, e)" the Main grid stay on the view and the new grid is not rendered.
Can someone please help with suggestions.
Thanks
You can render both partials in different divs and hide or show in your js function a div, for example
<div id="mydiv1">
#Html.Partial("Partial1")
<div>
<div id="mydiv2">
#Html.Partial("Partial2")
</div>
and in your onDoubleClick ( I assume that you are using jQuery)
$("#mydiv1").hide();
$("#mydiv2").show();
and to hide (on page load) the second div first just add
$(function () {
$("#mydiv2").hide();
});
or use
<div id="mydiv2" style="display:none;">
This code is not tested, but it should work.

Doing a postback without AutoPostBack

I've got a WebForm with two drop down lists, where the contents of the second one depend on the first.
So if the user changes the category, the second dropdown needs to be filled with the list of subcategories.
This sounds like a typical job for AutoPostBack.
However, there's a bit of a problem with AutoPostBack: if the list isn't dropped open, and the user uses the keyboard to make the choice, the postback happens right after the first keystroke. This prevents the user from scrolling down the list with the down arrow, or typing the name of the category.
This happens in Chrome and IE and Opera, but not in Firefox. Firefox fires the onchange event only when leaving the control (tabbing to the next control), just like it would when the list was dropped open, and that's what I want the other browsers to do too.
Any solutions how I can achieve this?
I tried to remove the AutoPostBack attribute and use onblur, but apparently the page works differently with AutoPostBack than without, because the browsers start complaining about Javascript errors.
Now since we're all so fond of jsFiddle, here's one. It doesn't actually do anything, but it can demonstrate the problem. Click on the first dropdown, then click again to close the list. (This is what happens when you navigate through the form with the tab key: dropdown lists don't open up.) Now type a letter or the down arrow. Firefox changes the current selection and waits for you to do anything else, but Chrome and IE and Opera all attempt to submit the form immediately, with drastic results.
So how can I avoid that? And note that simply changing the fiddle may not be enough, it must be translatable back to an ASP.NET solution.
Ok here is how I'd do it by using ajax and avoiding the use of AutoPostback all together to populate my sub category.
Create an object that represents the select list json object to send back.
public class SelectItem
{
public string Id { get; set; }
public string Text { get; set; }
}
Then create a PageMethod:
[WebMethod]
public static List<SelectItem> GetSubCategories(string Id)
{
// Returning dummy data for demo purposes
var subCats = new List<SelectItem>();
if (Id == "1")
{
subCats.Add(new SelectItem { Id = "1", Text = "1 Subs"});
}
else if (Id == "2")
{
subCats.Add(new SelectItem { Id = "2", Text = "2 Subs"});
}
return subCats;
}
Add a script manager and EnablePageMethods i.e.
<asp:ScriptManager runat="server" EnablePageMethods="true">
</asp:ScriptManager>
Change your dropdown lists to use ClientIDMode="Static"
<asp:DropDownList Id="ddlCategory" runat="server" ClientIDMode="Static">
<asp:ListItem Value ="1" Text ="One"></asp:ListItem>
<asp:ListItem Value ="2" Text ="Two"></asp:ListItem>
</asp:DropDownList>
<asp:DropDownList Id="ddlSubCategory" runat="server" ClientIDMode="Static">
</asp:DropDownList>
Then use the following jQuery:
<script type="text/javascript">
$(function () {
var $cat = $('#ddlCategory');
$cat.click(function () {
var catId = $cat.val();
$.ajax({
type: "POST",
url: "Default.aspx/GetSubCategories",
data: "{ Id: " + catId + " }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
var subs = msg.d;
// empty selection
var $ddlSubCategory = $('#ddlSubCategory');
$ddlSubCategory.empty();
$.each(subs, function (index, sub) {
$ddlSubCategory.append($('<option/>', {
value: sub.Id,
text: sub.Text
}));
});
}
});
});
});
</script>

Getting the messages/notifications instantly without refreshing the page in asp.net

I have a label which I show numbers in and numbers are the count of data from database. Whenever new data is saved in DB, the number in label should increase. It increases when i refresh the page, because I call the method on page_load in codebehind.
What in my mind is that:
I should call the method periodically without refreshing the page.
For this purpose, I know that I should use AJAX, but I couldnt find appropriate usage for me.
Can you direct me to a solution?
This is the label on aspx page:
<div id="panoramCouponBarLittleTalep">
<asp:Label ID="LabelTalepSayisiSag" ClientIDMode="Static" Text="" runat="server" />
</div>
This is the page_load :
protected void Page_Load(object sender, EventArgs e)
{
if (Session["user"] != null)
{
if (!IsPostBack)
{
SonBesGunTalepSayisi();
}
}
}
And the method I use:
private void SonBesGunTalepSayisi()
{
RequestProvider rP = new RequestProvider();
int talepSayisi = rP.LastFiveDaysRequestCount();
if (talepSayisi > 0)
{
LabelTalepSayisiSag.Text = talepSayisi.ToString();
}
else
{
LabelTalepSayisi.Text = "";
}
}
I would use an ASP.NET AJAX Page Method to be the server endpoint that your JavaScript AJAX will call, based upon a timer; like this:
Code-behind:
[WebMethod]
public static string GetRequestCount()
{
RequestProvider rP = new RequestProvider();
int talepSayisi = rP.LastFiveDaysRequestCount();
if (talepSayisi > 0)
{
return talepSayisi.ToString();
}
return "";
}
I would add a CssClass value to your Label control as that will make it easier to use in a jQuery selector, like this:
Markup:
<div id="panoramCouponBarLittleTalep">
<asp:Label ID="LabelTalepSayisiSag" ClientIDMode="Static"
Text="" runat="server" CssClass="TheLabel" />
</div>
$(document).ready(function() {
setInterval(ajaxCall, 5000); // 5000 MS == 5 seconds
});
function ajaxCall() {
$.ajax({
type: "POST",
url: "PageName.aspx/GetRequestCount",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result) {
// Put result of call into label
$('.TheLabel').text(result);
}
});
}
Note: Obviously you can adjust the timer interval value to be larger or smaller, depending upon your needs and performance. Also, the CssClass value on the Label control avoids the name mangling issue that plagues ASP.NET server controls. Even though you are using the ClientIDMode="Static", I like to avoid using the ID of a server control in jQuery when possible, because a class name will not get mangled by ASP.NET.
You can use ASP Page Methods to do it:
http://www.geekzilla.co.uk/View7B75C93E-C8C9-4576-972B-2C3138DFC671.htm

Event not firing on button click event

This is a problem I haven't come across before.
I'm working on an MVC4 project. I'm using an asp button control because there isn't a Html Helper that can be used for a button (re: There's no #Html.Button !). My button code is:
<td><asp:Button ID="ButtonUndo" runat="server" Text="Undo"
OnClick="ButtonUndo_Click" AutoPostBack="true"/></td>
I went to the Designer tab and clicked on this button which produced the event handler:
protected void ButtonUndo_Click(object sender, EventArgs e)
{
RRSPSqlEntities db = new RRSPSqlEntities();
int id = (int)ViewData["ClientId"];
var updateAddress = (from a in db.Address
where a.PersonId == id
select a).SingleOrDefault();
updateAddress.Deleted = false;
db.SaveChanges();
}
I should add that this code was added to the same .aspx page wrapped in a script tag. Also within this section is the Page_Load method. The eventhandler is not within Page_Load.
The problem was found when I set a breakpoint and stepped through the code. Clicking my button shows that it doesn't hit my event handler at all. I don't know why this is, particularly as ASP created the event from clicking the button in Design mode.
Clicking my button shows that it doesn't hit my event handler at all.
This isn't all that surprising. ASP.NET MVC uses a completely different event model (i.e. it doesn't have one like web forms). However, what you're trying to do is very straight forward. In your controller build a new method, let's call it Undo:
public ActionResult Undo(int id)
{
RRSPSqlEntities db = new RRSPSqlEntities();
var updateAddress = (from a in db.Address
where a.PersonId == id
select a).SingleOrDefault();
updateAddress.Deleted = false;
db.SaveChanges();
return View("{insert the original action name here}");
}
and then in your markup, simply markup the input like this:
<form method="POST" action="/ControllerName/Undo">
#Html.HiddenFor(Model.Id)
<input type="submit" value="Undo" />
</form>
where the Model for the View you're on contains a property, I've called it Id, that is the id you want passed into Undo.
I usually prefer to make ajax calls. You can try:
<button type="button" class="button" onclick="ButtonUndo();" />
In the form:
<script>
function ButtonUndo() {
$.ajax({
type: 'POST',
url: '/controller/action',
data: 'PersonID=' + ID,
dataType: 'json',
cache: false,
success: function (result) {
//do stuff here
},
error: function () {
//do error stuff here
}
});
}
</script>
Controller:
[HttpPost]
public ActionResult Action(int PersonID)
{
//Do your stuff here
return new JsonResult { result = "something" };
}
(Sorry for any typos or syntax errors...I pulled from existing code that we use in a project.)

Google map not showing after Partial postback

I have a google map in a page (Using the Javascript API v3)
the map is loaded like this:
In the Default.aspx page:
(This is the div where I will load the map)
The scripts I am using:
<script src="http://maps.google.com/maps/api/js?sensor=false&" type="text/javascript </script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript" src="Scripts/MapScript.js"></script>
The MapScript.j file which contains the javascript code for loading the map and all the other thing I need (markers, animations, mouse events...)
In the MapScript.js I load the map with this script
var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
The "MapScript.js" contains lots of function that i use in the map.
Untill now everything works fine the map is loaded and all the functions works correctly.
But what I want to do is this:
I put the map in an Update Panel.
In the code behind
at page load the MapPanel is not visible
protected void Page_Load(object sender, EventArgs e)
{
MapPanel.Visible = false;
}
the on the click of a button I do a partial post back on the update panel and change the visibility of the map to true.
But the problem is that after the partial postback, the map stops showing.
I tried to use RegisterStartupScript to register all 3 of the javascript sources I am using. (I put it in the PageLoad event)
string scr;
scr = "<script src='/Scripts/MapScript.js'></script>";
Page.ClientScript.RegisterStartupScript(Page.GetType(), "key", scr, false);
But it did not work.
Any help is greatly appreciated. Hope I was clear enough.
Thanks a lot
You need to initialize the map after the partial post back of your updatepanel like this.
<script>
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
function InitializeRequest(sender, args) {
}
// fires after the partial update of UpdatePanel
function EndRequest(sender, args) {
LoadMap();
}
var map = null;
function LoadMap()
{
map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
}
</script>
You can also dynamically load the javascript, if you do not won to loaded if not the map displayed using ajax. Here is an example, that I load only one js. Modified it to load them all.
var map = null;
function LoadMap()
{
LoadScript("http://maps.google.com/maps/api/js?sensor=false&", function() {
map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
});
}
function LoadScript(url, callback)
{
jQuery.ajax({
type: "GET",
url: url,
success: callback,
dataType: "script",
cache: true
});
};

Categories