I use a select2 plugin my website. I can't set selected value in select2. Please see my code below.
Html
<input id="drpEditProvider" class="form-control" type="text" value="" tabindex="8" name="ProviderId" data-required="true" />
Script
var attendeeUrl = '#Url.Action("GetProvider", "Admin")';
var pageSize = 100;
$('#drpEditProvider').select2(
{
placeholder: 'Please Select Provider',
//Does the user have to enter any data before sending the ajax request
minimumInputLength: 0,
allowClear: true,
//tags:["red", "green", "blue"],
ajax: {
////How long the user has to pause their typing before sending the next request
//quietMillis: 150,
//The url of the json service
url: attendeeUrl,
dataType: 'jsonp',
//Our search term and what page we are on
data: function (term, page) {
return {
pageSize: pageSize,
pageNum: page,
searchTerm: term
};
},
results: function (data, page) {
//Used to determine whether or not there are more results available,
//and if requests for more data should be sent in the infinite scrolling
var more = (page * pageSize) < data.Total;
return { results: data.Results, more: more };
}
},
initSelection: function (element, callback) {
var data = [];
$(element.val().split(",")).each(function () {
data.push({ id: this, text: this });
});
callback(data);
},
});
Controller and model
public class Select2PagedResult
{
public int Total { get; set; }
public List<Select2Result> Results { get; set; }
}
public class Select2Result
{
public string id { get; set; }
public string text { get; set; }
}
public JsonResult GetProvider(string searchTerm, int pageSize, int pageNum)
{
int Count = 0;
List<Provider> provideres = ProviderHelper.GetAllProvider(searchTerm, out Count);
//Translate the attendees into a format the select2 dropdown expects
Select2PagedResult pagedProvider = new Select2PagedResult();
pagedProvider.Results = new List<Select2Result>();
//Loop through our attendees and translate it into a text value and an id for the select list
foreach (Provider a in provideres)
{
pagedProvider.Results.Add(new Select2Result { id = a.Id.ToString(), text = a.Name });
}
//Set the total count of the results from the query.
pagedProvider.Total = Count;
//Return the data as a jsonp result
return new JsonpResult
{
Data = pagedProvider,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
Finally I found the answer. You can set selected value in select2 plugin like below.
Select 2 Single selection
$("#drpselector").select2("data", { id: "1", text:"Test 1" });
Select 2 Multiple selection
var arrdata = "1:Test 1,2:Test 2"
var thdprdata = [];
$(arrdata.split(",")).each(function () {
thdprdata.push({ id: this.split(':')[0], text: this.split(':')[1] });});
$("#drpselector").select2("data", thdprdata);
I use this code in my application. It works fine for me.
Related
i have a razor project where i implemented DataTables. I'm trying to retrieve data from the database dynamically with ajax in this way:
$('#orariDipendenti').DataTable({
'orderMulti': false,
'stateSave': true,
'paging': true,
'pageLength': 10,
'filter': false,
'processing': true,
'serverSide': true,
'ajax': {
url: '?handler=LoadData',
type: 'POST',
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
},
});
my back code is this:
public JsonResult LoadTable()
{
try
{
var idDipendente = HttpContext.Session.GetInt32("IdDipendente");
var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
var length = Request.Form["length"].FirstOrDefault();
var start = Request.Form["start"].FirstOrDefault();
int pagesize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordstotal = 0;
var recordData = context.Pres_Orari.Where(x => x.IdDipendente == idDipendente).ToList();
recordstotal = recordData.Count;
var data = recordData.Skip(skip).Take(pagesize).ToList();
return new JsonResult(new { draw = draw, recordsFiltered = recordstotal, recordsTotal = recordstotal, data = data });
}
catch (Exception)
{
throw;
}
}
the error i get when i open the page is this:
DataTables warning: table id={id} - Invalid JSON response.
I know the broblem is with the returned json but i don't know where. somebody can help me?
Firstly,your handler name is LoadTable,your url in ajax is url: '?handler=LoadData'.You need to change url to url: '?handler=LoadTable'.And here is a working demo(I also change xhr.setRequestHeader("XSRF-TOKEN" to xhr.setRequestHeader("RequestVerificationToken",if your code can work,you don't need to changexhr.setRequestHeader("XSRF-TOKEN"):
cshtml:
#Html.AntiForgeryToken()
<table id="orariDipendenti" class="table table-striped table-bordered" style="width:100%">
<thead class="thead-dark">
<tr class="table-info">
<th>IdDipendente</th>
<th>Name</th>
</tr>
</thead>
</table>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
<script>
<script>
$(function () {
$('#orariDipendenti').DataTable({
'orderMulti': false,
'stateSave': true,
'paging': true,
'pageLength': 10,
'filter': false,
'processing': true,
'serverSide': true,
ajax: {
url: '?handler=LoadTable',
type: 'POST',
beforeSend: function (xhr) {
xhr.setRequestHeader("RequestVerificationToken",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
},
columns: [
{ data: 'idDipendente' },
{ data: 'name' },
]
});
});
</script>
Model:
public class MyModel1 {
public int IdDipendente { get; set; }
public string Name { get; set; }
}
cshtml.cs(I use fake data to test):
public static List<MyModel1> list = new List<MyModel1> { new MyModel1 { IdDipendente = 1, Name = "name1" }, new MyModel1 { IdDipendente = 2, Name = "name2" }, new MyModel1 { IdDipendente = 3, Name = "name3" } };
public JsonResult OnPostLoadTable()
{
try
{
var idDipendente = 1;
var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
var length = Request.Form["length"].FirstOrDefault();
var start = Request.Form["start"].FirstOrDefault();
int pagesize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordstotal = 0;
var recordData = list.Where(x => x.IdDipendente==idDipendente).ToList();
recordstotal = recordData.Count;
var data = recordData.Skip(skip).Take(pagesize).ToList();
return new JsonResult(new { draw = draw, recordsFiltered = recordstotal, recordsTotal = recordstotal, data = data });
}
catch (Exception)
{
throw;
}
}
}
result:
On my View I have a button I use to submit a [description] value to my Controller via JSON, which is then used to create a new Table record. For example:
[HttpPost]
public JsonResult createNewStatus(string description)
{
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
//var allErrors = ModelState.Values.SelectMany(x => x.Errors);
try
{
if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
}
What I'd like to do now (before saving the Status to the DB) is run a check to see if any other records in the INV_Statuses table have a [description] value matching the one submitted to the function for new creation. If there is a match, I want to return an error/validation? message and alert the user the submitted value already exists and to choose it from the DropDownList on the View.
Can anyone provide an example of how to go about this with LINQ in my MVC Controller?
EDIT: Added my View JS code for submitting the new Status:
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
},
error: function () {
alert("ERROR!");
}
});
});
EDIT2:
Adricadar's suggestion:
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
try
{
var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
var isDuplicateDescription = existingStatus != null;
if (isDuplicateDescription)
{
ModelState.AddModelError("Error", "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.");
}
else if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description }, JsonRequestBehavior.AllowGet);
I added a .ToUpper() in my comparison in Controller, but even though the match with .ToUpper() gets identified, the ModelState.AddModelError() code fires, then the code returns and no error message is issued?
The value (though duplicate) still gets added to the dropdownlist (visually, not in DB) via my current JS code:
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
},
error: function () {
alert("ERROR!");
}
});
});
Check for existing status and set status back as follows:
var existingStatus = db.INV_Statuses.FirstOrDefault(s => s.status_description == description);
if (existingStatus ==null)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
else
{
// set the status back to existing
status = existingStatus;
}
Set an existing flag in your response:
return Json(new { ID = status.Id, Text = status.status_description, AlreadyExists = (existingStatus != null) }, JsonRequestBehavior.AllowGet);
Then in your response JavaScript, simply parse out the returned data:
success: function (resp) {
if (resp.AlreadyExists != true)
{
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
}
else
{
alert(resp.status_description + " already exists");
$("#selectStatus").val(resp.Id);
}
}
You can query the database for a status with an existing description and if exists and an model state error.
Be aware that string comparison is case sensitive.
[HttpPost]
public JsonResult createNewStatus(string description)
{
INV_Statuses status = new INV_Statuses()
{
// ID auto-set during save
status_description = description,
created_date = DateTime.Now,
created_by = System.Environment.UserName
};
//var allErrors = ModelState.Values.SelectMany(x => x.Errors);
try
{
var existingStatus = db.INV_Statuses.FirstOrDefault(x => x.status_description.ToUpper() == status.status_description.ToUpper());
var isDuplicateDescription = existingStatus != null;
string error = String.Empty;
if (isDuplicateDescription)
{
error = "[" + status.status_description + "] already exists in the database. Please select from the DropDownList.";
}
else if (ModelState.IsValid)
{
db.INV_Statuses.Add(status);
db.SaveChanges();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = status.Id, Text = status.status_description, Error = error , IsDuplicate = isDuplicateDescription }, JsonRequestBehavior.AllowGet);
}
In javascript verify if response have IsDuplicate = true if is true you skip the part where you need to add an element in dropdown.
$('#createNewStatus').click(function () {
$('#createStatusFormContainer').show();
})
$('#cancelNewStatus').click(function () {
$('#createStatusFormContainer').hide();
})
$('#submitNewStatus').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewStatus').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewStatus", "INV_Assets")',
data: data,
success: function (resp) {
if(resp.IsDuplicate)
{
//display error from response
//display resp.Error
} else {
$('#selectStatus').append($('<option></option>').val(resp.ID).text(resp.Text));
form[0].reset();
$('#createStatusFormContainer').hide();
var count = $('#selectStatus option').size();
$("#selectStatus").prop('selectedIndex', count - 1);
}
},
error: function () {
alert("ERROR!");
}
});
});
I require some help with my JQuery autocomplete.
Im trying to autocomplete postalcodes filtered by countries but for this I need to send a country value along with the autocomplete term to my mvc controller.
The value of the var country should be send as an extra param towards the controller action but I can't seem to accomplish this.
Here is my setup without the extra param:
View:
#Html.TextBoxFor(j => j.MainAddressCountry, new { data_autocomplete_url = Url.Action("AutoCompletePostalCode", "Location")})
script:
var country = $("#MainAddressCountry");
$('*[data-autocomplete-url]')
.each(function() {
$(this).autocomplete({
source: $(this).data("autocomplete-url"),
messages: {
noResults: '',
results: function() {
}
},
focus: function() {
var menu = $(this).data("uiAutocomplete").menu.element;
var focused = menu.find("li:has(a.ui-state-focus)");
if (menu.parent().hasClass('scroll-wrapper')) {
setTimeout(function() {
var height = menu.parent().height();
if (focused.position().top + focused.height() > height) {
menu.scrollTop(menu.scrollTop() + parseInt(focused.position().top) + focused.height() - height);
}
}, 1);
}
},
"open": function() {
var menu = $(this).data("uiAutocomplete").menu.element;
menu.addClass('scrollbar-dynamic').addClass('autocomplete-scroll');
}
});
}
);
controller:
public ActionResult AutoCompletePostalCode(string term)
{
var items = new[] {"2220", "2222", "1800", "1900", "3541", "5214", "9000", "9002", "9006"};
var filteredItems = items.Where(
item => item.IndexOf(term, StringComparison.InvariantCultureIgnoreCase) >= 0
);
return Json(filteredItems, JsonRequestBehavior.AllowGet);
}
Anyone that might know how to do the trick?
Thanks in advance.
You need to change the way you build source property into something like this:
source: function(request, response) {
$.getJSON("url here", { parameter1: 'your first parameter', parameter2: 'your second parameter' },
response);
},
Controller action:
public JsonResult Test(string parameter1, string parameter2)
{
//code
}
I have a new development task , I am trying to do reports dashboard and my requirement is to
I will have a form and I need to select values from form and depending upon user selection I need to display high charts in the same page and tabular view of my data in same page. So my form content is static and my Highcharts data and tabular contains dynamic data.
Steps I have done so far:
Login form and if credentials are valid Displays my mainform.aspx
My mainform.aspx contians form with a submit button
<form id="StatsForm" name="StatsForm" action="../Stats/Index/" method="POST"
enctype="multipart/form-data">
<%= Html.AntiForgeryToken()%>
<% Html.RenderPartial("OptionalFields"); %>
</form>
On button click I am sending my form data to controller
//
$(document).ready(function () {
$("#GetReport").click(function () {
$("form[name=StatsForm]").submit();
});
});
//]]>
</script>
I am doing some repository functions from my form data in my controller action and I am adding form values to a model class.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection form)
{
var manufacturerId = Convert.ToInt32(form["manufacturerId"]);
var reportId = Convert.ToInt32(form["reportId"]);
var categoryId = Convert.ToInt32(form["categoryId"]);
var retailerId = Convert.ToInt32(form["retailerId"]);
var countryId = Convert.ToInt32(form["countryId"]);
var regionId = Convert.ToInt32(form["regionId"]);
var manufacturerWidgetId = (form["ManufacturerWidgetId"]);
var startDate = new DateTime(1, 1, 1, 0, 0, 0, 0);
var endDate = new DateTime(1, 1, 1, 0, 0, 0, 0);
if (!String.IsNullOrEmpty(form["StartDate"]))
{
startDate = Convert.ToDateTime(form["StartDate"]);
}
if (!String.IsNullOrEmpty(form["EndDate"]))
{
endDate = Convert.ToDateTime(form["EndDate"]);
}
var reportName = _reportRepository.GetReport(reportId);
var stats = new Stats
{
ManufacturerId = manufacturerId,
CountryId = countryId,
ReportName = reportName.ToString(),
StartDate = startDate,
EndDate = endDate
};
Now I am struck, I did below steps not sure if I am right. I thought because my mainform.aspx has to display dynamic partials I am trying to create partials foreach report and on selection of uservalue I am planning to inject corresponding partial in my mainform.aspx.
for that I am doing : (continuation of my Action method)
switch (reportName.Code)
{
case "INTER":
return RedirectToAction("InterStats",
new
{
manufacturerId = manufacturerId,
countryId = countryId,
startDate = "2013-01-01",
endDate = "2013-01-31"
});
break;
case "CUMLEADS":
return RedirectToAction("ParametersCumLeads",
new
{
manufacturerId = manufacturerId,
countryId = countryId,
categoryId = categoryId,
startDate = startDate.ToString("yyyy-MM-dd"),
endDate = endDate.ToString("yyyy-MM-dd")
});
break;
case "IMP":
break;
}
5.My partial view:
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public JsonResult InterStats(int manufacturerId, int countryId, DateTime startDate, DateTime endDate)
{
//Get all manufacturerwidgets for manufacturer
var manufacturerWidget = _manufacturerWidgetsRepository.GetManufacturerWidgetByManufacturerAndCountry(manufacturerId, countryId);
var interReport = new InterReport();
var interRecordList = new List<InterRecord>(); // a list of my anonymous type without the relationships
interReport.InterRecordList = new List<InterRecord>();
var count = 1;
foreach (var mw in manufacturerWidget)
{
var widgetName = mw.Description;
//Get the product stats data
var imps = _productStatsRepository.GetSumImpressionsProductStatsForManufacturerCountryDate(
mw.Id, countryId, startDate, endDate);
var clicks = _productStatsRepository.GetSumClicksProductStatsForManufacturerCountryDate(
mw.Id, countryId, startDate, endDate);
float ctr = 0;
if (imps != 0 && clicks != 0)
{
ctr = ((clicks / (float)imps) * 100);
}
// Create the data for the report
var interRecord = new InterRecord
{
WidgetName = widgetName,
Impressions = imps,
Interactions = clicks,
Ctr = ctr,
Count = count
};
interReport.InterRecordList.Add(interRecord);
count++;
}
interReport.Counter = count;
return Json(interReport, JsonRequestBehavior.AllowGet);
}
And I tried in my mainform.aspx to write a small ajax function to render partial data , but $("#GetReport").click(function () I am sending form back to controller dont know how it will again here ?
<script type="text/javascript" language="javascript">
//<![CDATA[
$(document).ready(function () {
$("#GetReport").click(function () {
$.ajax({
url: "/Stats/InterStats/<%: Model.ManufacturerId %>/<%: Model.CountryId %>/<%: Model.StartDate %>/<%: Model.EndDate %>",
type: 'get',
success: function (data) {
<% Html.RenderPartial("InterStats"); %>
}
});
$("form[name=StatsForm]").submit();
});
});
//]]>
</script>
So I ahve my partial views, my data ready and I am not able to display corresponding partial in my mianform.aspx .Please help how can I do this?
$.ajax({
url: "/Stats/InterStats/<%: Model.ManufacturerId %>/<%: Model.CountryId %>/<%: Model.StartDate %>/<%: Model.EndDate %>",
type: 'get',
success: function (data) {
<% Html.RenderPartial("InterStats"); %>
}
});
Instead of this, you need some javascript in the success function to handle the response. Probably something like:
success: function (data) {
$('#someDivId').html(data);
}
i have an ajax AutoCompleteExtender. I am able to bind the text only with my AutoCompleteExtender not image. So How can i bind the image and text in an ajax AutoCompleteExtender? Any help is greatly appreciated.
Add below mentioned files in your header section
<script type="text/javascript">
$(document).ready(function () {
$("#searchtext").autocomplete
({
source:
function (request, response) {
$.ajax
({
url: "../BeanService.asmx/GetCompletionList",
data: "{prefixText:'" + request.term + "'}", // term is the property that contains the entered text
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response(data["d"]); // property d contains list of names sent from service
//$("#dynamiccontainer").append(data["d"]);
},
error: function (xhr, callStatus, errorThrown) {
// alert(callStatus);
}
});
},
// Attempt to remove click/select functionality - may be a better way to do this
select: function (event, ui) {
var mylink = ui.item.value;
var doc = document.createElement("html");
doc.innerHTML = mylink;
var links = doc.getElementsByTagName("a")
var urls = [];
for (var i = 0; i < links.length; i++) {
urls.push(links[i].getAttribute("href"));
}
window.location.href = urls[0];
return false;
}
});
});
</script>
Below is the Textbox on which autocomplete will be applied
<asp:TextBox ID="searchtext" runat="server"></asp:TextBox>
This is your bean class which will be filled by webservice and returned to jquery method through ajax call
public class SearchBean
{
public int Id
{
get;
set;
}
public string Title
{
get;
set;
}
public string reUrl
{
get;
set;
}
public string stype
{
get;
set;
}
public string photoAdd
{
get;
set;
}
}
This is your webservice which will be called by your jquery automplete ajax method
public string[] GetCompletionList(string prefixText)
{
BDBEntities db = new BDBEntities();
List<SearchBean> lstfinaldata = new List<SearchBean>();
List<MaCatMaster> lstcatlist = db.MaCatMasters.Where(z => z.CatName.Contains(prefixText) && z.Status == true).ToList();
foreach (MaCatMaster obj in lstcatlist)
{
SearchBean objbean = new SearchBean();
objbean.Id = obj.Id;
objbean.Title = obj.CatName;
objbean.stype = "Category";
objbean.reUrl = www.demo.com + "/Pages/Coupons/" + obj.Id;
lstfinaldata.Add(objbean);
}
string[] st = new string[lstfinaldata.Count];
int i = 0;
foreach (SearchBean obj in lstfinaldata)
{
StringBuilder sb = new StringBuilder();
sb.Append("<html><body>");
sb.AppendFormat("<a href='{0}' name='urllink'>", obj.reUrl);
sb.Append("<table width='420px'>");
sb.AppendFormat("<tr><td width='60px'><img src='{0}' style='border:1px solid #eeeeee' width='60px' height='40px'></td><td align='left' width='300px'>{1}</td><td align='left' width='60px' style='font-size:14px;'>{2}</td></tr>", obj.photoAdd, obj.Title, obj.stype);
sb.Append("</table>");
sb.Append("</a>");
sb.Append("</body></html>");
st[i] = sb.ToString();
i++;
}
return st;
}
In your search method you can use AutoCompleteExtender.CreateAutoCompleteItem() method to create pairs of the text to display and the image path:
public static List<string> Search(string prefixText, int count)
{
var items = new List<string>();
// ...
items.Add(AjaxControlToolkit.AutoCompleteExtender.CreateAutoCompleteItem(
text,
imagePath));
// ...
return items;
}
Then create the img tags on the client side with a javascript:
function Items_Populated(sender, e) {
var items = sender.get_completionList().childNodes;
for (var i = 0; i < items.length; i++) {
var div = document.createElement(“div”);
div.innerHTML = ”<img src=' + items[i]._value + ’ /><br />”;
items[i].appendChild(div);
}
Here are some examples:
AJAX AutoComplete with prefix image
Auto Complete with images