Select2 drop down not producing results - asp.net-mvc

I'm using Select2 3.x in an MVC C# build. I'm 99% certain we're getting a JSON object delivered to the page. But it's producing nothing. No alerts. Can't get a console event. Nothing.
Here's the JS:
$('#component-ajax').select2({
minimumInputLength: 2,
ajax: {
url: '#Url.Action("AjaxComponents")',
dataType: 'json',
type: "GET",
delay: 250, // wait 250 milliseconds before triggering the request
data: function (params) {
var query = {
search: params
//,page: page
}
return query;
}
, results: function (obj, page) {
alert('hi');
return {results: obj};
}
},
placeholder: 'Component number'
});
The "HTML":
<div class="form-group">
<label class="control-label col-sm-3">Item Number</label>
<div class="col-sm-9">
#Html.HiddenFor(m => m.NewProductBOMComponent.ItemKey, new { #class = "js-data-component-ajax form-control", placeholder = "Search for customer", id = "component-ajax" })
</div>
</div>
The Controller:
public ContentResult AjaxComponents(string search)
{
var json = Services.FourthShiftItemService.FindComponents_jqs2(search);
return Content(json, "application/json");
}
And a JSON sample:
{"results":[{17825:"550-02"},{6495:"550-11"}],"pagination":{"more":false}}

Related

MVC partial in modal posting wrong model

My partial view which is loaded into a bootstrap partial on my Index page, should be posting type Announcement but is posting type AnnouncementViewModel of the Index page model to the Create controller.
The #modal-container is specified in my _Layout, which is working as expected.
Unsure about the controllers - they appear correct, the problem is stemming from my ajax post I believe but I don't know what's the issue. I get the error after POST, however the database does update with the model correctly, but afterwards I get the below error.
I have specified $('#create-container')/$('form') as the form in which to serialize and send back to the controller.
Why is it doing this?
Error:
The model item passed into the dictionary is of type 'AnnouncementsViewModel', but this dictionary requires a model item of type 'Announcement'.
Index:
#model AnnouncementsViewModel
<h2>Announcements</h2>
<div>
#Html.ActionLink("Create", "Create", "Announcements", null, new { #class = "modal-link btn btn-sm" })
<div class="announcementTable">
<div id="announcementList">
#{Html.RenderPartial("List", Model.AnnouncementList);}
</div>
</div>
</div>
Partial:
#model Announcement
#section Scripts {
<script type="text/javascript">
$(function () {
$('#btn-create').click(function () {
$.ajax({
url: '#Url.Action("Create","Announcements")',
type: 'POST',
contentType: 'application/json',
data: $('#create-container').serialize(),
success: function (data) {
if (data.success == true) {
$('#modal-container').modal('hide');
location.reload(false)
} else {
$('#modal-container').html(data);
}
}
})
});
$('#btn-close').click(function () {
$('#modal-container').modal('hide');
});
});
</script>
}
<div class="create-container">
#using (Html.BeginForm())
{
<div class="newAnnouncementTableRow1">
<div>#Html.LabelFor(m => m.Title)</div>
<div>#Html.EditorFor(m => m.Title)</div>
<div>#Html.LabelFor(m => m.Details)</div>
<div>#Html.EditorFor(m => m.Details)</div>
</div>
<div class="newAnnouncementTableRow2">
<div>#Html.LabelFor(m => m.StartDT)</div>
<div>#Html.EditorFor(m => m.StartDT)</div>
<div>#Html.LabelFor(m => m.ExpiryDT)</div>
<div>#Html.EditorFor(m => m.ExpiryDT)</div>
<div>#Html.LabelFor(m => m.Enabled)</div>
<div>
#Html.RadioButtonFor(m => m.Enabled, 1)Yes
#Html.RadioButtonFor(m => m.Enabled, 0, new { #checked = "checked" })No
</div>
</div>
<div>
<button type="submit" id="btn-create" class="btn btn-sm">Save</button>
<button type="button" class="btn btn-default modal-close-btn" data-dissmiss="modal">Cancel</button>
</div>
}
</div>
Controller:
[HttpGet]
public ActionResult Index()
{
var avm = new AnnouncementsViewModel
{
AnnouncementList = new List<Announcement>()
};
avm.AnnouncementList = GetAnnouncementList();
return View(avm);
}
[HttpGet]
public ActionResult Create()
{
return PartialView("Create");
}
[HttpPost]
public ActionResult Create(Announcement a)
{
db.DbAnnouncement.Add(a);
db.SaveChanges();
return Index();
}
You set contentType: 'application/json' it your .ajax() call but returning View from Controller. Either change contentType to html or change controller to return JsonResult and return Json("yourData");
I recommend you to change your ajax call:
$.ajax({
/* other data */
dataType : "html",
contentType: "application/json; charset=utf-8",
/* other data */
success: function (data) {
$('#modal-container').modal('hide');
location.reload(false)
},
error: function (jqXHR, textStatus, errorThrown )
{
$('#modal-container').html(data);
}
/* other data */
});
Thing is response from server in your case always success but it returns html rather than json so you just don't have data.success at all.
The other issue as mentioned in the comments was that the controller was redirecting to an action method that it could not.
Changing return Index(); to return RedirectToAction("Index", "Announcements"); solved the error and the redirecting to the Create partial page caused by using return View();.

How to pass selected files in Kendo Upload as parameter in ajax request

After much of struggle im posing this question. Im using a Kendo Upload on a page. Am able to post the selected files on the asyn mode with whe the page has Html.BeginForm. But I'm not able to send file details as HttpPostedFileBase when I use ajax request to send data to the controller.
Following is my html
<form class="form-horizontal" role="form">
<div class="form-group">
#Html.Label("Complaint Name", new { #class = "col-sm-3 control-label" })
<div class="col-sm-4">
#Html.TextBoxFor(
m => m.ComplaintName,
new
{
#TabIndex = "1",
#class = "form-control input-sm",
disabled = true
})
</div>
</div>
<div class="form-group">
#Html.Label("Complaint Details", new { #class = "col-sm-3 control-label" })
<div class="col-sm-4">
#Html.TextBoxFor(
m => m.ComplaintDetails,
new
{
#TabIndex = "2",
#class = "form-control input-sm",
disabled = true
})
</div>
</div>
<div class="form-group">
#Html.Label("Choose files to upload", new { #class = "col-sm-3 control-label" })
<div class="col-sm-9 nopaddingforTextArea">
<input name="files" id="files" type="file" />
</div>
</div>
<div class="form-group">
<div>
<input id="btnSubmit" class="btn btn-primary pull-right" type="button" />
</div>
</div>
</form>
Following is my action
public ActionResult SaveComplaintDetails(string complaintName, string complaintDetails, IEnumerable<HttpPostedFileBase> files)
{
}
Following is my js
$("#files").kendoUpload({
async: {
saveUrl: '#Url.Action("EsuperfundCommentsBind", ClientInboxConstants.NewQuery)',
autoUpload: false
},
multiple: true
});
$("#btnSubmit").click(function () {
//Ajax call from the server side
$.ajax({
//The Url action is for the Method FilterTable and the Controller PensionApplicationList
url: '#Url.Action("SaveComplaintDetails", "Complaints")',
//The text from the drop down and the corresponding flag are passed.
//Flag represents the Index of the value in the dropdown
data: {
complaintName: document.getElementById("ComplaintName").value,
complaintDetails: document.getElementById("ComplaintDetails").value,
files: //What to pass here??
},
contentType: "application/json; charset=utf-8",
//Json data
datatype: 'json',
//Specify if the method is GET or POST
type: 'GET',
//Error function gets called if there is an error in the ajax request
error: function () {
},
//Gets called on success of the Ajax Call
success: function (data) {
}
});
});
My question is how to pass the selected files in Kendo Upload in ajax as a parameter?
Any help in this aspect would be really appreciated.
If your view is based on a model and you have generated the controls inside <form> tags, then you can serialize the model to FormData using:
<script>
var formdata = new FormData($('form').get(0));
</script>
This will also include any files generated with: <input type="file" name="myImage" .../> and post it back using:
<script>
$.ajax({
url: '#Url.Action("YourActionName", "YourControllerName")',
type: 'POST',
data: formdata,
processData: false,
contentType: false,
});
</script>
and in your controller:
[HttpPost]
public ActionResult YourActionName(YourModelType model)
{
}
or (if your model does not include a property for HttpPostedFileBase)
[HttpPost]
public ActionResult YourActionName(YourModelType model,
HttpPostedFileBase myImage)
{
}
If you want to add additional information that is not in the form, then you can append it using
<script>
formdata.append('someProperty', 'SomeValue');
</script>
**Example Usage :**
View :
#using (Html.BeginForm("Create", "Issue", FormMethod.Post,
new { id = "frmCreate", enctype = "multipart/form-data" }))
{
#Html.LabelFor(m => m.FileAttachments, new { #class = "editor-label" })
#(Html.Kendo().Upload()
.HtmlAttributes(new { #class = "editor-field" })
.Name("files")
)
}
<script>
$(function () {
$('form').submit(function (event) {
event.preventDefault();
var formdata = new FormData($('#frmCreate').get(0));
$.ajax({
type: "POST",
url: '#Url.Action("Create", "Issue")',
data: formdata,
dataType: "json",
processData: false,
contentType: false,
success: function (response) {
//code omitted for brevity
}
});
});
});
</script>
*Controller :*
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Exclude = null)] Model viewModel, IEnumerable<HttpPostedFileBase> files)
{
//code omitted for brevity
return Json(new { success = false, message = "Max. file size 10MB" }, JsonRequestBehavior.AllowGet);
}
<script>
$(function () {
$('form').submit(function (event) {
event.preventDefault();
var formdata = new FormData($('#createDetail').get(0));
$.ajax(
{
type: 'POST',
url: '#Url.Action("Detail_Create", "Product")',
data: formdata,
processData: false,
success: function (result) {
if (result.success == false) {
$("#divErr").html(result.responseText);
} else {
parent.$('#CreateWindowDetail').data('kendoWindow').close();
}
},
error: function (xhr, ajaxOptions, thrownError) {
$("#divErr").html(xhr.responseText);
}
});
});
});
#using (Html.BeginForm("Detail_Create", "Product", FormMethod.Post, new { id = "createDetail", enctype="multipart/form-data"}))
{
<div id="divErr" class="validation-summary-errors"></div>
<fieldset>
<ol>
<li>
#Html.LabelFor(m => m.Price)
#(Html.Kendo().NumericTextBoxFor(m => m.Price).Name("Price").Format("{0:0}")
.HtmlAttributes(new { style = "width:100%" })
)
</li>
<li>
#Html.LabelFor(m => m.Description)
#Html.TextBoxFor(model => model.Description, new { #class = "k-textbox", id = "Description", style = "width:100%;" })
</li>
<li>
#Html.LabelFor(m => m.Group)
#(Html.Kendo().ComboBox()
.Name("Group")
.Placeholder("Введите группу детали")
.DataTextField("Name")
.DataValueField("Id")
.HtmlAttributes(new { style = "width:100%;" })
.Filter("contains")
.MinLength(1)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Group_Read_ComboBox", "Product");
})
.ServerFiltering(true);
})
)
</li>
<li>
#Html.LabelFor(m => m.Image)
#(Html.Kendo().Upload()
.Name("files")
)
</li>
</ol>
</fieldset>
<button type="submit" id="get" class="k-button">Добавить</button>
}
[HttpPost]
public ActionResult Detail_Create(DetailModel model, IEnumerable<HttpPostedFileBase> files)
{
string error = string.Empty;
if (ModelState.IsValid)
{
.....
}
IEnumerable<System.Web.Mvc.ModelError> modelerrors = ModelState.SelectMany(r => r.Value.Errors);
foreach (var modelerror in modelerrors)
{
error += "• " + modelerror.ErrorMessage + "<br>";
}
return Json(new { success = false, responseText = error }, JsonRequestBehavior.AllowGet);
}
after pressing the button, the controller null comes to how to fix. 2 days already sitting, and the time comes to an end

bind kendo.data.DataSource to combo using MVVM

Again next question , this time a tricky one,
Datasource:
var dsCountryList =
new kendo.data.DataSource({
transport: {
read: {
dataType: "jsonp",
url: "/Masters/GetCountries"
}
},
schema: {
model: {
id: "CountryID",
fields: {
"CountryDesc": {
}
}
}
}
});
Observable object
function Set_MVVMSupplier() {
vmSupplier = kendo.observable({
SupplierID: 0,
SupplierName: "",
AccountNo: "",
CountryList: dsCountryList,
});
kendo.bind($("#supplierForm"), vmSupplier);
}
here is the html which is bind to observable object , but i am not getting combobox filled, also each time i clicked the combo request goes to server and bring data in json format for countryID, CountryDesc
<div class="span6">
<div class="control-group">
<label class="control-label" for="txtCountryId">Country</label>
<div class="row-fluid controls">
#*<input class="input-large" type="text" id="txtCountryId" placeholder="CountryId" data-bind="value: CountryId">*#
<select id="txtCountryId" data-role="dropdownlist"
data-text-field="CountryDesc" data-value-field="CountryID" , data-skip="true"
data-bind="source: CountryList, value: CountryDesc">
</select>
</div>
</div>
</div>
I didn't get the answer , so i found an alternate working ice of code. just have a look and if it helps then please vote.
created model for ddl in js file
ddl = kendo.data.Model.define({
fields: {
CountryId: { type: "int" },
ConfigurationID: { type: "int" }
}
});
added var ddl to MVVM js file
vmSupplier = kendo.observable({
CountryId: new ddl({ CountryId: 0 }),
ConfigurationID: new ddl({ ConfigurationID: 0 }),});
added code in controller
using (CountriesManager objCountriesManager = new CountriesManager())
{
ViewBag.Countries = new SelectList(
objCountriesManager.GetCountries().Select(p => new { p.CountryID, p.CountryDesc })
, "CountryID", "CountryDesc"); ;
}
added code in cshtml
<div class="span4">
<label class="control-label" for="txtCountryId">Country</label>
#Html.DropDownList("Countries", null,
new System.Collections.Generic.Dictionary<string, object> {
{"id", "txtCountryId" },
{ "data-bind","value: CountryId"} })
</div>
this way i got solved the problem

MS MVC (razor) Access view data for serializartion

I have a view within a MS MVC [razor] project where I want to submit view data back to a controller via a JSON post operation. I have looked around and I cannot find how to retrieve and package the view data for submission back to the controller. I was under the assumption that the JSON serialize operation would package the data when called but this does not seem to be happening. For example:
MVC View ------------------------------
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<center>
<fieldset id="UserCreateFieldset">
<div class="editor-label">
#Html.LabelFor(model => model.FirstName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.FirstName)
#Html.ValidationMessageFor(model => model.FirstName)
</div>
<p>
<input type="button" name="CreateButton" value="Create" onclick="CreateUser()" />
</p>
</fieldset>
</center>
}
<script>
function CreateUser()
{
var infoForm = $("#UserCreateFieldset");
var entries = infoForm.serializer.Serialize(Model);
$.ajax(
{
url: '#Url.Action("CreateUser", "User")',
data: entries,
type: "POST",
dataType: "json",
success: function (data)
{
$.event.trigger({
type: "CreateUserCompleted",
NewUserID: 1,
});
}
});
}
</script>
Just to note; when the controller is called via the post it receives back the model -- but it contains the original values used to load the view.
Peter
Use the .serialize() method from jquery:
function CreateUser()
{
var data = $('form').serialize();
$.ajax({
url: '#Url.Action("CreateUser", "User")',
data: data,
type: "POST",
dataType: "json",
success: function (data)
{
$.event.trigger({
type: "CreateUserCompleted",
NewUserID: 1,
});
}
});
}
You can instead of using Html.BeginForm use Ajax.BeginForm to not mess with the internals if you are doing the same thing as a the Html.BeginForm without anything special. you could change your code to:
#using(Ajax.BeginForm("MyAction", "MyController",
new AjaxOptions
{
HttpMethod = "POST"
}))
{
// Same form
}
It even has OnSuccess method which can be used in the AjaxOptions declaration:
#using(Ajax.BeginForm("MyAction", "MyController",
new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "TriggerEvent"
}))
{
// Same form
}
And you set a function in the javascript to be called on success:
function TriggerEvent() {
$.event.trigger({
type: "CreateUserCompleted",
NewUserID: 1,
});
}

How can I refresh my razor view on AJAX post

Helo all,
I am able to post to controller using ajax.post, but on success how can I make my view refresh with new data.
Do I need to usn #Html.BeginForm to do this?
This is my view.
<div>
<p>Order lines allocates to <b>#Model.Name (#Model.Code) </b>
</div>
#if (Model.OrderLineAllocations.Any())
{
#grid.GetHtml(
columns: grid.Columns(
grid.Column(header: "Dispatched", style: "row-selector", format: #<text><input name="chkSelected" class="myCheckbox" onclick="expandableEvent(this)" type="checkbox" value="#item.IdAllocation" /></text>),
grid.Column(header: "Order Ref", format: item => item.OrderLineItem.OrderLine.Order.OrderRef)
),
tableStyle: "expandable-table",
rowStyle: "expandable-master-row",
htmlAttributes: new { id = "gridLineAllocations" })
<br />
<input type="hidden" id="hidUnselectedValues" name="hidUnselectedValues" />
<input type="submit" name="action" value="Dispacth" id="btnDispacth" />
<input type="submit" name="action" value="Revert" id="btnRevert" />
}
else
{
#Html.Raw("No records found....");
}
And this is my ajax post
$(document).ready(function() {
unSelected = [];
$("#btnDispacth").click(dipatchAllocations);
$("#btnRevert").click(revertAllocations);
});
function dipatchAllocations() {
var objInputEmail = $("#hidUnselectedValues");
if (objInputEmail != null) {
var id = objInputEmail.val();
if ((id != null) && (id != "")) {
$.ajax({
type: 'POST',
url: '/Batch/GetData',
data: '{ "allocationId" : "' + id + '","batchId" : "' + #Model.Id + '" }',
contentType: "application/json; charset=utf-8",
//contentType:"application/x-www-form-urlencoded",
traditional: true,
success: subscribed,
error: errorInSubscribing
});
} else {
alert('Please enter a valid email address in order to subscribe.');
}
}
};
This is my controller action
[HttpPost]
public ActionResult GetData(long[] allocationId,long batchId)
{
var model = context.GetData(batchId)
model.Name = "asdaksdjaksdj";
return View("Finalize", model);
}
I am having some idea, I have to do that on success call back. But I am not sure how to bind my updated model to the view at client side.
Thanks
There is no simple "rebind" method inside mvc, it's still html, css and js at the end.
I see 2 options to achieve desired behaviour.
option 1. Override rendered content with the result of POST
In this case your View will look similar to:
<div id="content">
<div>
<p>Order lines allocates to <b>#Model.Name (#Model.Code) </b>
</div>
...
else
{
#Html.Raw("No records found....");
}
</div>
On javascript:
$.ajax({
type: 'POST',
url: '/Batch/GetData',
dataType: "html",
success: function(data, textStatus, jqXHR){
$('#content').html(data);
}
});
option 2. Fill rendered html from javascript on every load
This will require to move Razor logic to javascript.
Your view will look like:
<div>
<p>Order lines allocates to <b id="NameAndCode"></b>
</div>
And javascript will fill the gaps:
$(function(){
var model = {
NameAndCode: "#Model.Name (#Model.Code)"
}
fillView(model);
})
var fillView = function(data){
$('#NameAndCode').html(data.NameAndCode)
}
$.ajax({
type: 'POST',
url: '/Batch/GetData',
dataType: "json",
success: function(data, textStatus, jqXHR){
fillView(data);
}
});
It's just a small piece just to show the idea.
It depends on case which option to choose.

Resources