Calling web methods through jquery AJAX and nesting AJAX - c#

I have a problem in updating sql database table with jQuery ajax.
here is my scenario. I am working on privileges table to assign a teacher some kind of privilege/rights to perform some required functionality of the website.
1) I call a webmethod and pass teacher's id to retrive all privileges assigned to that particular teacher using jQuery ajax
2) in the success function of step 1 I call another web method using jQuery ajax and bind a click event on checkbox (on/of toggle button -- its input type was checkbox) present against every privilege listed.
3) when I click on that on/off toggle checkbox I want to update a row in sql database table in privileges table if it is on and user turns it off then that particular privilege will be unassigned to that teacher.
here is my code
public void UpdatePrivileges(string _columnName, byte _value, int _teacherid)
{
JavaScriptSerializer objserializer = new JavaScriptSerializer();
myDatabase.CreateConnection();
myDatabase.InitializeSQLCommandObject(myDatabase.GetCurrentConnection, "update tbl_privileges set " + _columnName + " = #val where teacher_id = #tid");
myDatabase.obj_sqlcommand.Parameters.AddWithValue("#tid", _teacherid);
myDatabase.obj_sqlcommand.Parameters.AddWithValue("#val", Convert.ToByte(_value));
try
{
myDatabase.OpenConnection();
myDatabase.obj_sqlcommand.ExecuteNonQuery();
}
finally
{
myDatabase.CloseConnection();
myDatabase.obj_sqlcommand.Dispose();
}
HttpContext.Current.Response.Write(objserializer.Serialize("Updated"));
}
This code is for retrieving teacher's privileges and show them on webForm.
function GetTeacherPrivileges() {
var teacherid = $('#<%=txtTeacherIDToPopulatePrivileges.ClientID%>').val();
$.ajax({
url: 'source/WebServices/GetAllTeachers.asmx/GetPrivileges',
method: 'post',
data: { _teacherID: teacherid},
datatype: 'json',
success: function (data) {
var obj = JSON.stringify(data);
var arrayjson = $.parseJSON(obj);
var actualarray = $.parseJSON(arrayjson);
$.each(actualarray, function (i, v) {
$('#tablebody').append('<tr class="table-row"> <td class="col-3"><span>Events</span></td><td class="col-2">is this teacher eligible to making events?</td><td class="col-3"><label class="switch centerbuttion "><input id="check_event" class="switch-input" type="checkbox" /><span class="switch-label" data-on="Yes" data-off="No"></span><span class="switch-handle"></span></label></td></tr><tr class="table-row"> <td class="col-3"><span>Attendance</span></td><td class="col-2">Do you want this teacher can mark attendance?</td><td class="col-3"><label class="switch centerbuttion "><input id="check_attendance" class="switch-input" type="checkbox" /><span class="switch-label" data-on="Yes" data-off="NO"></span><span class="switch-handle"></span></label></td></tr><tr class="table-row"><td class="col-3"><span>Homework</span></td><td class="col-2">Teacher will be able to upload homework with their respective classes.</td><td class="col-3"><label class="switch centerbuttion "><input id="check_homework" class="switch-input" type="checkbox" /><span class="switch-label" data-on="Yes" data-off="NO"></span><span class="switch-handle"></span></label></td></tr><tr class="table-row"><td class="col-3"><span>Reports</span></td><td class="col-2">Do you want this teacher to generate reports?</td><td class="col-3"><label class="switch centerbuttion "><input id="check_reports" class="switch-input" type="checkbox" /><span class="switch-label" data-on="Yes" data-off="NO"></span><span class="switch-handle"></span></label></td></tr><tr class="table-row"><td class="col-3"><span>Timetable</span></td><td class="col-2">Can this teacher make time table(s)?</td><td class="col-3"><label class="switch centerbuttion "><input id="check_timetable" class="switch-input" type="checkbox" /><span class="switch-label" data-on="Yes" data-off="NO"></span><span class="switch-handle"></span></label></td></tr><tr class="table-row"><td class="col-3"><span>Datesheet</span></td><td class="col-2">Can this teacher make Date Sheet(s)?</td><td class="col-3"><label class="switch centerbuttion "><input id="check_datesheets" class="switch-input" type="checkbox" /><span class="switch-label" data-on="Yes" data-off="NO"></span><span class="switch-handle"></span></label></td></tr>');
var event = v.Event;
var attendance = v.Attendance;
var homework = v.Homework;
var reports = v.Reports;
var timetable = v.TimeTable;
var datesheet = v.DateSheet;
if (event == 1) {
$('#check_event').trigger('click');
}
if (attendance == 1) {
$('#check_attendence').trigger('click');
}
if (homework == 1) {
$('#check_homework').trigger('click');
}
if (reports == 1) {
$('#check_reports').trigger('click');
}
if (timetable == 1) {
$('#check_timetable').trigger('click');
}
if (datesheet == 1) {
$('#check_datesheets').trigger('click');
}
$('#check_event').bind({
click: function () {
var privilegevalue = columnvalue('#check_event');
UpdatePrivilege('event', privilegevalue);
}
});
});
},
error: function (error) {
alert("Error: " + error);
}
});
This is the second AJAX code which I call in the success function of above AJAX for binding the click event.
function UpdatePrivilege(column,value) {
var teacherid = $('#<%=txtTeacherIDToPopulatePrivileges.ClientID%>').val();
$.ajax({
url: 'source/WebServices/GetAllTeachers.asmx/UpdatePrivileges',
data: { _columnName: "'"+column+"'" , _value: value , _teacherid:teacherid },
dataType: 'json',
dataContent: 'application/json; charset=utf-8',
success: function (data) {
alert('privilege updated'+data);
},
error: function(data) {
alert('Error in updating privilege' + data);
}
});
}
When I run my aspx page and input teacher's id to GetAllTeachers() function all works good and it binds the click event on checkbox against event privilege but when I click on that it gives me error from AJAX function of UpdatePrivilege() function.

If you are wanting to send json you need to stringify the data yourself. Also you don't need the extra quotes wrapping "'"+column+"'"
Try:
function UpdatePrivilege(column,value) {
// I assume you are running this within Razor context and not in a javascript file
var teacherid = $('#<%=txtTeacherIDToPopulatePrivileges.ClientID%>').val();
// create data object
var dataObj={ _columnName: column , _value: value , _teacherid:teacherid };
// stringify it
var postData = JSON.stringify(dataObj);
$.ajax({
url: 'source/WebServices/GetAllTeachers.asmx/UpdatePrivileges',
data: postData ,// stringified data
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
console.log('privilege updated', data);
},
error: function(data) {
console.log('Error in updating privilege' , data);
}
});
}

Related

How to implement select2.js c# ajax call is not working

Hello I want to load country state and city using select2.js how can i achieve this? i make ajax call to load details of country state and city... i am facing problem when trying to make ajax call to load data using webmethod. BindCountryData and BidnStateData are never called please suggest me solution for that what changes should i do to make call.
$(document).ready(function){
country();
}
function country(){
$(".autosuggest").select2({
minimumInputLength: 1,
placeholder: "Select Item",
allowClear: true,
ajax: {
type: "POST",
url: 'country.aspx/BindCountryData',
async : false,
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: function(term) {
return {
country: term
};
},
results: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.completeName,
slug: item.slug,
id: item.id
}})};}}});}}
$('.autosuggest').change(function () {
searchState();
});
function searchState(){
$(".State").select2({
minimumInputLength: 1,
placeholder: "Select State",
allowClear: true,
ajax: {
type: "POST",
url: 'state.aspx/BidnStateData',
async : false,
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: function(term) {
return {
state: term,
countryId : $('.autosuggest').val()
};
},
results: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.completeName,
slug: item.slug,
id: item.id
}
})
};
}
}
});
}}
I've been using the following approach in my projects:
1) Load select elements at initial stage, and bind onChange action:
<select class="selectcombusca" name="zone_id" onChange="carregacidades($('option:selected',this).val());">
<option value="#">Select State</option>
<option value="1">State 1</option>
<option value="2">State 2</option>
</select>
<select class="selectcombusca" name="cidade_id">
<option value="#">Select City</option>
<option value="1">City 1</option>
<option value="2">City 2</option>
</select>
2) Apply select2 to initial elements:
$(".selectcombusca").select2();
3) Function to load cities based on the selected state, triggered on the select change:
function carregacidades(zone_id) {
$.ajax({
url: your-url,
type: 'post',
dataType: 'json',
data: 'zone_id=' + zone_id, //from the selected option
beforeSend: function() {
$('select[name=\'cidade_id\']').hide();
$('select[name=\'cidade_id\'] + .select2').hide();
//I like to hide the inital element so the user can undestand there's a call being made, avoiding multiple changes on the element.
$('select[name=\'cidade_id\']').after('<span class="loading">Loading Indicator<span>'); //I also like to put some kind of loading indicator, like a spinner
},
complete: function() {
$('.loading').remove(); //remove the loading indicator
$('select[name=\'cidade_id\']').show(); //show DOM element
$("select[name=\'cidade_id\']").select2().val('#'); //rerender select2 and set initial option
$('select[name=\'cidade_id\'] + .select2').show(); //show select2 element
},
success: function(json) {
//create the new options based on the call return
html = '<option value="#">Cidade</option>';
if (json['cidade'] && json['cidade'] != '') {
for (i = 0; i < json['cidade'].length; i++) {
html += '<option value="' + json['cidade'][i]['cityId'] + '">' + json['cidade'][i]['cityName'] + '</option>';
}
}
$('select[name=\'cidade_id\']').html(html); //replace select options on DOM
},
error: function(xhr, ajaxOptions, thrownError) {
//handle error
}
});
};
In short: by changing the select element, I hide the element that will receive the new information, make the call, add then add the information to DOM (still hidden). Finally, rerender the select2 element with the new options and then show it.
I hope this helps you.

I want to refresh the checkboxes when I am selecting another item from the dropdown

Basically I am assigning roles to the users. I want to automatically show the pre-asssigned roles. I am able to render that on the first time, but the checkboxes remains same when value is changed in dropdown:
type: "POST",
dataType: "json",
url: "/UserRoles/myaction",
data: { "userid": DropDownSelectedVal },
success: function (data) {
$.each(data, function (i, val) {
var a = (data[i]);
$("#" + a).attr('checked', true);
});
},
error: function (error) {
alert('error; ' + eval(error));
}
})
First try to clear all check boxes using the below code on selection change event of dropdown.
$('input:checkbox').removeAttr('checked');
Then run your ajax code for selecting new user roles.
type: "POST",
dataType: "json",
url: "/UserRoles/myaction",
data: { "userid": DropDownSelectedVal },
success: function (data) {
$.each(data, function (i, val) {
$("#" + val).prop('checked', true);
});
},
error: function (error) {
alert('error; ' + eval(error));
}
})
You should control all checkbox. You can try this.
url: "/UserRoles/myaction",
data: { "userid": DropDownSelectedVal },
success: function (data) {
$.each(data, function (i, val) {
var a = (data[i]);
if(!$("#" + a).is(":checked")) {
$("#" + a).attr("checked", true);
}else{
$("#" + a).attr("checked", false);
}
});
},
The elegant solution that I can suggest is to maintain a hidden input to store all your permission that is selected.
Your HTML
<input type="hidden" id="_hiddenSelectedPermissions" value="2, 1" />
<input class="permissions" type="checkbox" value="1">Default Permission 1
<input class="permissions" type="checkbox" value="2">Default Permission 2
<input class="permissions" type="checkbox" value="3">Permission 3
<input class="permissions" type="checkbox" value="4">Permission 4
<input class="permissions" type="checkbox" value="5">Permission 5
Set the hidden control value after ajax results and call below function to reassign all the checked check boxes
function refreshSelectedPermissions() {
$('input:checkbox.permissions').prop('checked', false);
var selected = $('#_hiddenSelectedPermissions').val().split(",") || [];
$('input:checkbox.permissions').each(function() {
var value = $(this).val();
if($.inArray(value, selected) === -1){
$(this).prop('checked', false);
}
else{
$(this).prop('checked', true);
}
});
}

Fetching Cities dynamically in Asp.net HTML control

I have a HTML dropdown list for countries. Now I want to populate the City dropdown accordingly using ajax
<select class="form-control" id="ddCountry" runat="server" tabindex="8"></select>
<select class="form-control" id="ddCity" runat="server" tabindex="9"></select>
<script type="text/javascript">
$('#ddCountry').on('change', function () {
var storeData = { countryId: this.value }
$.ajax({
type: "POST",
url: "UserRegistration.aspx/GetCities",
data: JSON.stringify(storeData),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert("The data in list is "+data);
},
error: error
});
});
</script>
My method on .cs page is as follows:
[WebMethod]
public static List<CityBO> GetCities(string countryId)
{
//returning cities
}
The problem is I am able to fetch the data in GetCities method but not able to show it in the ddCity list because it is a HTML control and the method is static, so
ddCity.Items.AddRange(list_of_countries) is not working as ddCity is not being recognized in static method. Please tell how to fill the dropdown list.
You cannot access controls in static method. You need to return list of cities from webmethod and fill dropdown using javascript.In success method of ajax write code like this.
success: function (data) {
fillDropDown(data.d);
}
function fillDropDown(data){
var html = "";
for (var i = 0; i < data.length; i++)
{
html += "<option value='" + data[i].ValueField+ "'>" +
data[i].TextField+ "</option>";
}
$("select[id$=ddlCity]").html(html);
}
You can use ajax success function given below.
success: function (data)
{
var lankanListArray = JSON.parse(data.d);
// running a loop
$.each(lankanListArray, function (index, value)
{
$("#ddlCity").append($("<option></option>").val(this.name).html(this.value));
});
}

Sending knockout viewmodel to controller is missing items from drop down box

Little by little I'm learning this...
In my C#/MVC4 demo build I've created a controller to send data to my view through JSON. In my view I am able to parse the response and populate a drop down list.
I'm using knockout similar to a cart to create additional lines (colors) for posting to the controller.
code:
MVC ViewModel:
function Color(data) {
this.ID = ko.observable(data.ID);
this.ColorName = ko.observable(data.ColorName);
this.Duration = ko.observable(data.Duration);
this.bNotPermanent = ko.observable(1);
}
function ViewModel() {
self = this;
self.CurrentColors = ko.observableArray([]);
self.AddColors = ko.observableArray([]);
self.AllColors = ko.observableArray([]);
$.ajax({
type: "POST",
url: '#Url.Action("GetUsersColors", "EditUser")',
data: { szUserRecID: RecID },
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
self.CurrentColors(colors);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
})
$.ajax({
type: "POST",
url: '#Url.Action("GetVisibleColors", "EditColor")',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {},
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
self.AllColors(colors);
},
error: function (err) {
alert(err.status + " - " + err.statusText);
}
})
self.removeLine = function (color) { self.AddColors.remove(color);
};
self.addColor = function (color) {
self.AddColors.push(new Color({ ColorName: "", ID: "", Duration: "Permanent" }))
};
self.save = function ()
{
// I've also tried data: ko.mapping.toJSON(this)
// based on my issues I've seen, I'm almost positive this is where my issue is
// I think the mapping is having an issue but I don't know what it should look like
// with an array of objects
$.ajax({
url: '#Url.Action("PostColors", "EditColor")',
type: "POST",
data: ko.mapping.toJSON(this.AddColors()),
async: true,
contentType: "application/json"
}).success(function (data) {
});
};
this does work...
View
<table>
<thead>
<tr data-bind =" visible: $root.AddColors().length > 0">
<th padding: 10px; >Color</th>
<!--<th padding: 10px; >Duration</th>-->
</tr>
</thead>
<tbody data-bind="foreach: AddColors">
<tr>
<!-- This works, it displays all the colors provided by the controller -->
<td><select data-bind="options: $root.AllColors, optionsText: 'ColorName', value: ID, optionsCaption: 'Select Color...'"></select></td>
<td>
<a href='#' data-bind='click: $parent.removeLine'>Remove</a>
</td>
</tr>
</tbody>
</table>
<button data-bind='click: addColor'>Add Color</button>
<button data-bind='click: save'>Submit Colors</button>
controller:
[HttpPost]
public void PostColors(List<ViewModels.ColorList> AddColors)
{
int t = 0; // to set a break point only
}
C# ViewModel
public class ColorList
{
public int? ID { get; set; }
public string ColorName { get; set; }
public string Duration{ get; set; }
public bool bNotPermanent { get; set; }
}
when I inspect AddColors in the above function, the Duration is set but the ColorName is null but I do have the correct number of elements coming through.
I can add lines(colors) over and over on the form and selecting them on the list. But why are they not showing in "AddColors" object list?
I did find another article on here referring to get; set; in the viewmodel and I did add that. Up until that point everything coming through was null.
Fiddler is showing this (and it doesn't look quite right...?)
[{"ID": {"ID":11,"ColorName":"Green","Duration":null,"bNotPermanent":1},"ColorName":"","Duration":"Permanent","bNotPermanent":1},{"ID": {"ID":17,"ColorName":"Red","Duration":null,"bNotPermanent":1},"ColorName":"","Duration":"Permanent","bNotPermanent":1}]
I really think my issue is with the data conversion / ajax post. Question is, what should it look like?
I'm guessing that you want the ID of the color to appear in the ID field on the added color entry. If so, what you need to do is that you need to set the optionsValue binding to select a single property from the selected item and use the value of that property to set the property you are binding to.
The Knockout documentation on the options binding states the following regarding the optionsValue binding.
Similar to optionsText, you can also pass an additional parameter called optionsValue to specify which of the objects’ properties should be used to set the value attribute on the elements that KO generates.
Since you don't want the whole object to be set into the ID property of your added color, you want Knockout to pick the ID property from the color. So just update your binding from:
<select data-bind="options: $root.AllColors,
optionsText: 'ColorName',
value: ID,
optionsCaption: 'Select Color...'">
</select>
to:
<select data-bind="options: $root.AllColors,
optionsText: 'ColorName',
optionsValue: ID,
value: ID,
optionsCaption: 'Select Color...'">
</select>

Adding an asp.net custom user control from JQuery

I am using following JQuery code from somewhere on the internet to load content on browser window scroll.
var pageIndex = 1;
var pageCount;
$(window).scroll(function () {
if ($(window).scrollTop() == $(document).height() - $(window).height()) {
GetRecords();
}
});
function GetRecords() {
pageIndex++;
if (pageIndex == 2 || pageIndex <= pageCount) {
$("#loader").show();
$.ajax({
type: "POST",
url: "CS.aspx/GetCustomers",
data: '{pageIndex: ' + pageIndex + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess,
failure: function (response) {
alert(response.d);
},
error: function (response) {
alert(response.d);
}
});
}
}
function OnSuccess(response) {
var xmlDoc = $.parseXML(response.d);
var xml = $(xmlDoc);
pageCount = parseInt(xml.find("PageCount").eq(0).find("PageCount").text());
var customers = xml.find("Customers");
customers.each(function () {
var customer = $(this);
var table = $("#dvCustomers table").eq(0).clone(true);
$(".name", table).html(customer.find("ContactName").text());
$(".city", table).html(customer.find("City").text());
$(".postal", table).html(customer.find("PostalCode").text());
$(".country", table).html(customer.find("Country").text());
$(".phone", table).html(customer.find("Phone").text());
$(".fax", table).html(customer.find("Fax").text());
$("#dvCustomers").append(table).append("<br />");
});
$("#loader").hide();
}
As you can see its adding HTML table on response success. But I have an asp.net user-control that I want to add instead of this HTML table when content scrolls (In short I want to add a server side control from JQuery). I can't add user-control's HTML in place of this HTML table because its code is too lengthy and complex and I don't know much JQuery. I am the beginner of the beginner concept of JQuery. Moreover I am a specialist in back-end programming. So, I can't code that business logic in JQuery. So any one please help me in doing so.
Like kintaro alerady suggested; render you html on server side (in a user control) and then load that control inside web method to return results in HTML to client side.
Here'a an example:
JavaScript code:
var pageIndex = 0;
var data = { "pageIndex": pageIndex };
$.ajax({
type: "POST",
url: "CS.aspx/GetCustomers",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8"
}).done(function (result) {
$("#dvCustomers").append(result.d);
});
and the PageMethod on server side:
[WebMethod]
public static string GetCustomers(int pageIndex)
{
Page pageHolder = new Page();
UserControl viewControl = (UserControl)pageHolder.LoadControl("_path_to_customers_usercontrol");
pageHolder.Controls.Add(viewControl);
StringWriter output = new StringWriter();
HttpContext.Current.Server.Execute(pageHolder, output, false);
return output.ToString();
}
You will also have to pass a pageIndex value to Customers user controls, you can to that by casting the result of LoadControl method to a class that represnts your customer user control and then set PageIndex property.
If you are developing your project as ASP.NET Web Site you'll have to use reflection to set property value. Here's an example:
Type viewControlType = viewControl.GetType();
PropertyInfo field = viewControlType.GetProperty("PageIndex");
if (field != null)
{
field.SetValue(viewControl, pageIndex, null);
}
You can switch the HTML of the control with url parameter:
$.ajax({
type: "POST",
url: "CS.aspx/GetCustomers",
data: '{pageIndex: ' + pageIndex + ', ajaxcall: true}',
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(function (data) {
$("#dvCustomers table").append(data);
});
And in the ascx control:
<%if (Page.Request.QueryString.Get("ajaxcall") == "true")
{%>
normal html control render.
<%}
else
{%>
<tr>
<td>All data of table only tr an tds</td>
</tr>
<%} %>
Create a div and put your user control in this div. then set the visibility:hidden and once it is success display it(set visibility to visible using jquery) :
<div style="visibility:hidden" id="dv1">
<uc1:usercontrol Visible="true" runat="server">...
</div>
Jquery :
$("#dv1").css("visibility","visible");

Categories

Resources