how to bind the list to dropdownlist in javascript? - javascript

I am calling a web method from a JavaScript function
function loadstatecity() {
alert(document.getElementById("CountryList").value);
// PageMethods.username_availability(document.getElementById("CountryList").value, OnSuccess, OnFailure);
PageMethods.loadstatecity(document.getElementById("CountryList").value, OnSuccess,OnFailure);
}
Web method is returning a list of strings:
[System.Web.Services.WebMethod]
public static List<string> loadstatecity(string countrycode)
{
utilityFunc.loadstatecity(countrycode);
return utilityFunc.state;
}
loadstatecity function Code:
public static void loadstatecity(string CountryCode)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Mag_SDK"].ConnectionString))
{
con.Open();
using (SqlCommand com = con.CreateCommand())
{
com.CommandText = "Select ProvinceName from Province where CountryCode=#Country ;";
com.Parameters.AddWithValue("#country", CountryCode);
SqlDataReader dr = com.ExecuteReader();
while (!dr.Read())
{
state.Add(dr["ProvinceName"].ToString());
}
com.Connection.Close();
com.Connection.Dispose();
}
con.Close();
}
}
Now I want to bind this list to a DropDownList.
How can I do this?
Thank you for your help.

The List of strings type returned in your C# method will be serialized into a JavaScript array and will be accessible in a JavaScript callback. You'll then need to loop through all of the strings in the serialized array converting each one to an HTML 'option' element and then attach each element to the HTML 'state' select element produced by your ASP.NET. Here's some code which should accomplish that:
// The function to run on success, adds options to the state select.
function success(response) {
var select = document.getElementById('id-of-your-state-select-element'),
index = 0,
option = ''
value = '';
if (select) {
for (index; index < response.length; index++) {
value = response[index];
option = '<option>' + value + '</option>';
select.insertAdjacentHTML('beforeend', option);
}
}
}
// Shows an error in an alert box, should be improved before
// production deployment.
function error(response) {
alert(response);
}
These two functions are then used in your 'loadstatecity' method as success / failure callbacks.
PageMethods.loadstatecity(document.getElementById("CountryList").value, success, error);

Related

Javascript receiving Resource object containing chars instead of String

My Java code should return user login as a String, but on Javascript side I'm receiving a strange Resource object whose numbered attributes each contains one char.
Here is my Java code:
#PostMapping(path = "/account/reset_password/finish", produces = MediaType.TEXT_PLAIN_VALUE)
#Timed
public ResponseEntity<String> finishPasswordReset(#RequestBody KeyAndPasswordVM keyAndPassword) {
if (!checkPasswordLength(keyAndPassword.getNewPassword())) {
return new ResponseEntity<>("Incorrect password", HttpStatus.BAD_REQUEST);
}
return userService.completePasswordReset(keyAndPassword.getNewPassword(), keyAndPassword.getKey()).map(
user -> new ResponseEntity<String>(user.getLogin(), HttpStatus.OK)).orElse(
new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
}
Javascript controller code:
Auth.resetPasswordFinish({key: $stateParams.key, newPassword: vm.resetAccount.password}).then(function (userLogin) {
vm.success = 'OK';
console.log("userLogin="+userLogin);
}).catch(function () {
vm.success = null;
vm.error = 'ERROR';
});
The console prints:
userLogin=[object Object]
which is not very interesting.
Inspecting the received object gives:
One can see that each char of the String is a numbered attribute of the Resource object.
Javascript Auth code:
function resetPasswordFinish (keyAndPassword, callback) {
var cb = callback || angular.noop;
return PasswordResetFinish.save(keyAndPassword, function (userLogin) {
return cb(userLogin);
}, function (err) {
return cb(err);
}).$promise;
}
This one is just passing the parameter to the callback function.
Do you know how to receive a plain String instead of this Resource object? I apologize if this is a trivial question.
I know that doing this will work in order to retrieve the user login:
var i = 0;
var userLoginToString = "";
while (typeof userLogin[String(i)] !== 'undefined') {
userLoginToString += String(userLogin[String(i)]);
i += 1;
}
however I don't think that this is the intended way to use this Resource object.

.NET AJAX asynchronous calls

I've been tasked with including asynchronous calls to my webpage and I'm not sure where to start. Currently, my webpage takes user input from a drop down list, converts it into a list of CodeDesc objects, serializes it all into JSON and then deserializes it back so it can be displayed in a GridView on the screen. (I could just make it spit out the CodeDesc object back to the GridView but this is the way my manager wanted it so..).
In any case, now I need the results to be displayed without reloading the page and after some research I read that AJAX was a good way to do it. Unfortunately, I'm confused how I can connect it all and actually use it. My attempts are below but I could really use some guidance on the matter.
HTML (partial):
<script>
$("#Button1").on("click", function () {
$.ajax({
type: ??'GET'??,
contentType: ??
success: function (?? Call deserializeJSONResults function ??) {
$('#GridView2').html("");
for (var i = 0; i < deserializedProduct.length; i++) {
$("#GridView2").append(deserializedProduct.id, deserializedProduct.code, deserializedProduct.);
}
}
});
});</script>
Without using AJAX my code is below:
CS:
protected void Button1_Click(object sender, EventArgs e)
{
DataConnector dc = new DataConnector();
GridView2.DataSource = dc.deserializeJSONResults(DropDownList1.SelectedValue);
GridView2.DataBind();
}
Backend:
//Return results to GridView2 as list of CodeDesc objects
public List<CodeDesc> getQueryResults(string searchTerm)
{
try
{
List<CodeDesc> L = new List<CodeDesc>();
string query = "select id, code, descr from code_desc where code_type_id = (select id from code_desc where descr = :searchTerm)";
// Create the OracleCommand
using (OracleCommand cmd = new OracleCommand(query, con))
{
cmd.Parameters.Add(new OracleParameter("searchTerm", searchTerm));
con.Open();
// Execute command, create OracleDataReader object
using (OracleDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
CodeDesc c = new CodeDesc
{
id = reader.GetInt32(0),
code = reader.GetString(1),
description = reader.GetString(2)
};
L.Add(c);
}
}
}
return L;
}
//catch clause here
}
//Convert to JSON and parse
public List<CodeDesc> deserializeJSONResults(string searchTerm)
{
List<CodeDesc> L = getQueryResults(searchTerm);
string json = JsonConvert.SerializeObject(L, Formatting.Indented);
//deserialize object
List<CodeDesc> deserializedProduct = JsonConvert.DeserializeObject<List<CodeDesc>>(json);
return deserializedProduct;
}
}
Any help would be appreciated. I have little development experience and this is my first time with web/.NET development

Razor - Converting Json result from controller to a complex object

i have a partial view "_SearchPanel" that has year list dropdown, a classes multiselect control, (some other drop downs - ommitted) and a search button.
I want that when i change selection in year list drop down, only my classes list is refreshed/updated, and not the whole partial view on page.
So i use a JsonResult action in my controller (as opposed to the first time load)
public JsonResult BindClasses(int yearId)
{
ClassRepository repClass = new ClassRepository("name=ge");
YearRepository repYear = new YearRepository("name=ge");
var dataClass = repClass.GetClassesByYear(yearId);
var groupedClassOptions = dataClass.GroupBy(x => x.grade).Select(x => new OptionGroupVM()
{
GroupName = "Grade " + x.Key.ToString(),
Options = x.Select(y => new OptionVM()
{
Value = y.classID.ToString(),
Text = y.classname
})
});
return Json(groupedClassOptions);
}
My javascript
var dropDownYear = $('#ddlYear');
dropDownYear.change(function(){
$("#classList").load(url, {yearId: $(this).val()}, function(result){
setOptions($('#classList'), #Html.Raw(Json.Encode(new List<int>(){})), result);
});
});
now the problem is this result is not considered as an object as was the first time (onpageload) here:
jQuery(function ($) {
setOptions($('#classList'), #Html.Raw(Json.Encode(Model.SelectedClasses)), #Html.Raw(Json.Encode(Model.ClassOptions)));
}
How do i correct/cast it to be considered as Model.ClassOptions(type: GroupOptionsVM List) object instead of a Json
What I have tried
var url = '#Url.Action("BindClasses", "Maps")';
var dropDownYear = $('#ddlYear');
dropDownYear.change(function(){
$("#classList").load(url, {yearId: $(this).val()}, function(result){
#{var x = new List<OptionGroupVM>();}
x = result;
setOptions($('#classList'), #Html.Raw(Json.Encode(new List<int>(){})), x);
});
});
this gives me some syntax errors!!
UPDATE
[Referring to the previous question Stephen linked in comments]
Since i had to do it for two dropdown lists with slight difference i had created setOptions function in my script
function setOptions(listBox, selected, groups) {
// Generate options
createGroupedOptions(listBox, selected, groups);
// Attach plug-in
listBox.multiselect({ enableClickableOptGroups: true, onChange: function(){
var selectedClassItems = this.$select.val();
} });
}
function createGroupedOptions(element, selected, groups) {
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
var groupElement = $('<optgroup></optgroup>').attr('label', group.GroupName);
for (var j = 0; j < group.Options.length; j++) {
var option = group.Options[j];
var optionElement = $('<option></option>').val(option.Value).text(option.Text);
if (selected) {
if (selected.toString().indexOf(option.Value) >= 0) {
optionElement.attr('selected', 'selected')
}
} else {
if (option.IsSelected) {
optionElement.attr('selected', 'selected')
}
}
$(groupElement).append(optionElement);
}
$(element).append(groupElement);
}
}
CALLING setOptions function
setOptions($('#classList'), #Html.Raw(Json.Encode(Model.SelectedClasses)), #Html.Raw(Json.Encode(Model.ClassOptions)));
setOptions($('#indicatorList'), #Html.Raw(Json.Encode(Model.SelectedIndicators)), #Html.Raw(Json.Encode(Model.IndicatorOptions)));
Your returning json, so using .load() makes no sense (you would typically use that when the method your calling returns a partial view).
Change your script to create the <optgroup> and <option> elements based on your data your method returns
var url = '#Url.Action("BindClasses", "Maps")';
var dropDownYear = $('#ddlYear');
dropDownYear.change(function() {
$.post(url, { yearId: $(this).val() }, function(data) {
$.each(data, function(index, item) {
var group = item.GroupName;
// use the above to build your <optgroup> element
$.each(item.Options, function(index, item) {
var value = item.Value;
var text = item.Text;
// use the above to build your <option> elements and append to the <optgroup> element
});
// append the <optgroup> to the <select id="classList"> element
});
});
});
Note the details of the code for generating the elements are in the answer to your previous question
You are trying to mix client side code (jQuery) with server side code (.NET) and it won't work. #Html.Raw and JsonEncode are server side methods. You can't use them after the page loads.
In essence, you need to either use jQuery for all of your page interaction and manage the state of the page on the client side or use full MVC (postback) and do everything on the server.
There are technically other options but I just wanted to address the fundamental issue with what you have tried so far.

CRM Javascript Automatically Populated a Look-up Value with a specific field

I'm trying to write a javascript on CRM Phone Call page. We have a custom look-up field called new_department, and we want to automatically populate the field with value "IT" (there should be one) when the form is opened.
The thing is we have a separate Dev and Production CRM link therefore I cannot just assign a hard-coded GUID value into this field. So first I wrote a Rest Retrieve Multiple to get the correct department.
Then my problem is I'm not sure about the result returned from this Retrieve Multiple. How do I grab just the GUID from Rest? I'm seeing that this is a type of {Object}. Then lastly how do I go about setting the lookup value after retrieving the {Object}? Any help is greatly appreciated.
Here is my code.
function phonecall() {
var formType = Xrm.Page.ui.getFormType();
if (formType == 1) //create
{
//RetrieveMultiple function
var DepartmentId = getITDepartment();
//set the lookup value
var ID = DepartmentId.id;
var departmentValue = new Array();
departmentValue[0] = new Object();
departmentValue[0].id = DepartmentId;
departmentValue[0].name = 'IT';
userValue[0].entityType = "new_department";
Xrm.Page.getAttribute("new_department").setValue(departmentValue);
}
}
function getITDepartment()
{
XrmServiceToolkit.Rest.RetrieveMultiple("new_departmentSet", "$select=new_departmentId&$filter=new_name eq 'IT'",
function (results) {
if (results.length > 0)
resultList = results;
}, function (error) { alert(error); }, function onComplete() { }, false);
return resultList;
}
Thanks much.
I'm not familiar with XrmServiceToolkit but here how code could look like to work properly - I replaced only assigning part:
var DepartmentId = getITDepartment();
if (DepartmentId != null && DepartmentId.length > 0){
Xrm.Page.getAttribute("new_department").setValue([{
id: DepartmentId[0].new_departmentId,
name: "IT",
entityType: "new_department"
}]);
}
You are setting the lookup value correctly, you just need to get the Id correctly. The results variable is an array of new_department records, so try something like this:
var resultId = null;
XrmServiceToolkit.Rest.RetrieveMultiple("new_departmentSet", "$select=new_departmentId&$filter=new_name eq 'IT'",
function (results) {
if (results.length > 0)
resultId = results[0].new_departmentId; //gets the first record's Id
}, function (error) { alert(error); }, function onComplete() { }, false);
return resultId;

SharePoint TextField ClientID changes?

I'm trying to use some javascript on a page layout, and I'm encountering a strange issue where the ClientID of a Sharepoint.WebControls.TextField seems to change between OnLoad and the page being displayed.
In the OnLoad event, TextField3.ClientID resolves to "ctl00_PlaceHolderMain_TextField3", but if look to see why my js doesn't work, the page source reveals that the control id to be "ctl00_PlaceHolderMain_TextField3_ctl00_TextField".
Any ideas what's going on?
Here's the code I'm using:
public class PostingTemplate : Microsoft.SharePoint.Publishing.PublishingLayoutPage
{
protected DropDownList author;
protected TextField TextField3;
private List<string> _authorNames;
public List<string> AuthorName
{
get { return _authorNames; }
set { _authorNames = value; }
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
author.AutoPostBack = false;
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"fillInAuthorText", getQuery(), true);
author.Attributes.Add("onChange", "fillInAuthorText()");
if (!Page.IsPostBack)
{
_authorNames = new List<string>();
_authorNames = Utilities.GetAuthorList(SPContext.Current.Site);
author.DataSource = _authorNames;
author.DataBind();
}
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (author.Items.Count > 0)
{
author.SelectedIndex = 0;
TextField3.Text = ((ListItem)author.Items[author.SelectedIndex]).Text;
}
}
private string getQuery()
{
string query = #" function fillInAuthorText() {
var IndexValue = document.getElementById('";
query += author.ClientID;
query += #"').selectedIndex;
var SelectedVal = document.getElementById('";
query += author.ClientID;
query += #"').options[IndexValue].value;
document.getElementById('";
query += TextField3.ClientID;
query += #"').value = SelectedVal;
}";
return query;
}
}
You need to include the client ID of the parent control as well.
// Replace:
query += author.ClientID;
// With:
query += base.ClientID + "_" + author.ClientID;
(Note that I've only ever done this with a web part so there may be some tweaking you need to do for it to work in a page layout.)
Another option is to resolve this client side. See Eric Shupp's blog for most info.
With help form Alex Angas, Here is what I discovered:
The TexField renders out some literals that end up surrounding a textbox, and it's really the textbox that you're interested in. Here's the modified section of code:
private string getQuery()
{
string query = #" function fillInAuthorText() {
var IndexValue = document.getElementById('";
query += author.ClientID;
query += #"').selectedIndex;
var SelectedVal = document.getElementById('";
query += author.ClientID;
query += #"').options[IndexValue].value;
document.getElementById('";
query += getTextFieldID(TextField3);
query += #"').value = SelectedVal;
}";
return query;
}
private string getTextFieldID(Control txt)
{
foreach (Control c in txt.Controls)
{
if (c.HasControls())
{
foreach (Control con in c.Controls)
if (con is TextBox)
return con.ClientID;
}
}
return "";
}
Keep in mind, this is specific to my application, your mileage my vary.

Categories