It is my PartialView:
.......
<div class="form-group">
#Html.LabelFor(model => model.securities, htmlAttributes: new { #class = "control-label col-md-2"})
<div class="col-md-10">
#(Html.Kendo().MultiSelect()
.Name("productMultiSelect")
.DataTextField("label")
.DataValueField("value")Product to be used by the multiselect as a value.
.HtmlAttributes(new { style = "width:350px; height:350px", #id = "prd" })
.Filter(FilterType.Contains)
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetLogin", "IT_Inventory");
})
.ServerFiltering(false);
})
.Value(ViewBag.SelectedItem2)
.ItemTemplate("<span><h3 style=\"font-size: 1.2em;font-weight: normal;margin: 0 0 1px 0;padding: 0;\">#: data.label #</h3><p style=\"margin:0;padding:0;font-size: .8em; \">#: data.desc #</p></span>")
)
</div>
</div>
My button:
<button type="button" id="btnSave" class="btn btn-success btn-lg">Save </button>
My JS:
<script>
$("#btnSave").click(function (e) {
e.preventdefault();
$.ajax({
type: 'POST',
url: '#Url.Action("SignIT", "IT_Inventory")',
data: JSON.stringify({ productMultiSelect: $("#productMultiSelect").data("kendoMultiSelect").value(), id: $("#id").val(), SomeBooleanProperty: false }),
dataType: 'json',
contentType: 'application/json',
success: function (data) {
if (data == true) {
$("#onInsert").data("kendoWindow").close();
}
else {
alert("Error!");
}
},
error: function () {
alert("An error has occured!!!");
}
});
});
</script>
When I try post to controller I am getting Uncaught TypeError: Cannot read property 'value' of undefined. For id and SomeBooleanProperty is ok.
When I use submit form is ok.
I should post data to controller list of productMultiSelect?
Looks like you havn't initialize you kendoMultiSelect, or it's in another div;
Check to see it:
console.log($("#productMultiSelect").length); //should be at least 1, if 0, then you initialized kendo in come other div
and
console.log($("#productMultiSelect").data("kendoMultiSelect")); //should be an object - if undefined, then you have not initialized kendo
console.log($("#productMultiSelect").length); - 0
console.log($("#productMultiSelect").data("kendoMultiSelect")); - undefined
very interesting and strange.
This PartialView is in KendoWindow.
Related
I am getting autocomplete item list from javascript autocomplete but when I select that autocomplete item list at that time it shows the error i.e. Uncaught TypeError: n.item is undefined
Here is my code,
<div class="form-group">
<div class="col-md-3">
<nop-label asp-for="Name" />
</div>
<div class="col-md-9">
#Html.TextBoxFor(model => Model.Name, new { #class = "form-control" })
#Html.HiddenFor(model => Model.Name)
</div>
</div>
$(document).ready(function () {
$("#Name").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("AutoComplete", "Product")',
datatype: "json",
data: {
term: request.term
},
success: function (data) {
response($.map(data, function (val) {
return {
label: val.Name,
value: val.Name
}
}))
}
})
},
select: function (ui) {
$("#Name").val(ui.item.Name);
}
});
});
Here is the controller
public JsonResult AutoComplete(string term = "")
{
var objCustomerlist = (from product in _productMasterRepository.Table
where product.Name.StartsWith(term)
select new
{
Name = product.Name,
ID = product.Name
}).ToList();
return Json(objCustomerlist);
}
Your select signature is incorrect:
select: function (ui) {
$("#Name").val(ui.item.Name);
}
Change it into:
select: function (event, ui) {
$("#Name").val(ui.item.Name);
}
And that should work fine.
I'm trying to send a post request to the Action with the Model data after the value of some of it's properties is changed :
#{
JsonSerializerSettings jss = new JsonSerializerSettings {
ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
}
<div id="contents">
<!--Lead Stage-->
#if (Model.LeadStagesNav != null)
{
for (int i = 0; i < Model.LeadStagesNav.Count; i++)
{
#Html.HiddenFor(a => a.LeadStagesNav[i].PermissionId)
<div class="form-group" style="margin-bottom:10px">
#Html.Label("Lead Stage", new { #class = "col-md-2" })
<div style="display:inline-block;position:relative">
#Html.DropDownListFor(model => model.LeadStagesNav[i].Name, null, new { #class = "form-control", #style = "width:200px", onchange = "ChangeValue()" })
</div>
#if (ViewData["LeadStagesNav[" + i + "].LeadStatus"] != null)
{
<!--Lead Status-->
#Html.Label("Lead Status", new { #style = "margin-left:15px;margin-right:15px" })
<div style="display:inline-block;position:relative">
#Html.DropDownListFor(model => model.LeadStagesNav[i].LeadStatus, null, new { #class = "form-control", #style = "width:200px", onchange = "ChangeValue()" })
</div>
if (ViewData["LeadStagesNav[" + i + "].LeadSubStatus"] != null)
{
#Html.Label("Lead Sub Status", new { #style = "margin-left:15px;margin-right:15px" })
<div style="display:inline-block;position:relative">
<!--Lead Sub Status-->
#Html.DropDownListFor(model => model.LeadStagesNav[i].LeadSubStatus, null, new { #class = "form-control", #style = "width:200px" })
</div>
}
}
</div>
<!--Delete Button-->
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Delete Lead Stage"
onclick="document.getElementById('index').value = #i"
name="submit" class="btn btn-default" />
<input type="hidden" id="index" name="index" />
</div>
</div>
}
}
</div>
<script type="text/javascript">
window.ChangeValue = function () {
var model = #Html.Raw(JsonConvert.SerializeObject(Model, Formatting.Indented, jss));
$.ajax({
method: "POST",
url: "/CmsPermissions/Edit",
data: { permission: model },
success: function (data) {
$("#contents").html(data);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
}
});
};
the thing is the The problem is that I get the old model data
posted to the Action instead of the
new data after the dropdown selected value has changed,
Anyone has any idea ?
that is because you are passing the old model as data
var model = #Html.Raw(JsonConvert.SerializeObject(Model, Formatting.Indented, jss));
you need to serialize your form and pass it an example is
function SubmitForm() {
var data = $("#YourFormID").serialize();
var url = "/YourURL/ACtion"
var form = $('#policyForm')[0]
var formdata = false;
if (window.FormData) {
formdata = new FormData(form);
}
return $.ajax({
url: url,
type: 'POST',
dataType: 'json',
data: formdata ? formdata : data,
cache: false,
contentType: false,
enctype: 'multipart/form-data',
processData: false,
error: function () {
$('#imgLoadingForPortal').modal('hide');
Lobibox.notify('error', {
size: 'mini',
rounded: true,
delay: false,
position: 'center top', //or 'center bottom'
msg: 'Something went wrong..please try again later',
sound: false,
delay: 5000,
});
}
})
}
I'm sure it's something simple, but I can't get this to work. I've read the documentation and other sources, but I am just not understanding. I simply want to pass data that I retrieve with ajax to an empty array. I've ensured that the data is indeed successfully coming from the server, but it does not appear to get assigned to UserArticles, and does not update the DOM. What am I missing. Here's my code:
Component:
Vue.component('article-selection', {
props: ['articles'],
template: '<div> <p>{{articles.title}}</p> </div>'
})
Vue:
var Article = {};
var UserArticles = [];
var vm = new Vue({
el: '#createNewArticle',
data: {
Article: Article,
UserArticles: UserArticles
},
computed: {
isNewArticle: function () {
return this.Article.ArticleIdentification.Id.length < 5
}
},
created: function(){
this.getUserArticles();
},
methods: {
setUserId: function (id) {
//code
},
createNewArticle: function (msg) {
//code},
getUserArticles: function () {
$.ajax({
method: "GET",
url: "/api/Article/GetUserArticles"
}).done(function (rData, status, jq) {
UserArticles = rData;
toastr.success('', 'Retrieved User Articles');
}).fail(function (rData, status, error) {
var result = $.parseJSON(rData.responseText);
toastr.warning(result.messages, 'Retrieve User Articles')
});
}
}
})
HTML:
<div class="row" id="createNewArticle" >
<div class="col-sm-12">
<!--Create Initial article-->
<div class="row" v-if="true">
<div class="col-sm-12 text-center">
<div>Passed: {{Article.UserId}}</div>
<div class="form" style="display: inline-block;" id="newArticleForm">
<div class="form-group">
<label for="ArticleName">Article Title</label>
<input type="text" class="form-control" id="ArticleTitle"
name="ArticleTitle" v-model="Article.ArticleIdentification.Title" /><br />
<p>{{Article.ArticleIdentification.Title}}</p>
<button class="btn btn-sm" v-on:click="createNewArticle('hey hey')">
Create New Article
</button>
</div>
</div>
</div>
<div class="col-sm-12">
<!--COMPONENT HERE--!>
<article-selection v-for="(artId, index) in UserArticles"
v-bind:key="artId.id"
v-bind:index="index"
v-bind:articles="artId"></article-selection>
</div>
</div>
</div>
Try writing the method like this
$.ajax({
method: "GET",
url: "/api/Article/GetUserArticles"
success: function (data) {
UserArticles = data;
},
error: function (error) {
alert(JSON.stringify(error));
}
})
}
I had to use an arrow function in my ajax code inside of the done function as well as add the this keyword. Note the difference:
getUserArticles: function () {
$.ajax({
method: "GET",
url: "/api/Article/GetUserArticles"
}).done((rData, status, jq) => {
this.UserArticles = rData;
toastr.success('', 'Retrieved User Articles');
}).fail(function (rData, status, error) {
var result = $.parseJSON(rData.responseText);
toastr.warning(result.messages, 'Retrieve User Articles')
});
}
I have this button on the UI where the customer will open a modal. The modal will load a partial view retrieved by Ajax.
$('#btnfeedback').on('click', function(e) {
e.preventDefault();
var debateModal;
$.get('#Url.Action("LoadFeedbackModal", "Home")', function() {
}).done(function(info) {
debateModal = bootbox.dialog(
{
message: info,
title: '<span class="fa fa-wechat"></span> Leave Feedback',
closeButton: true
});
debateModal.find('.modal-header').removeClass('modal-header').addClass('modal-header-info');
}).fail(function() {
debateModal = bootbox.alert({ message: "Problem try later", size: 'small' });
});
});
And this is my Controller:
[HttpGet]
public ActionResult LoadFeedbackModal()
{
return PartialView("Partials/_FeedbackModal", new FeedbackVm());
}
[HttpPost]
public ActionResult LoadFeedbackModal(FeedbackVm feedback)
{
try
{
var fb = Mapper.Map<Feedback>(feedback);
Db.Feedbacks.Add(fb);
Db.SaveChanges();
return Json(new { Mensaje = "Thanks for your feedback", Status = true }, JsonRequestBehavior.AllowGet);
}
catch (Exception exception)
{
return Json(new { Mensaje = "HUbo un problema :( Intenta luego", Status = false }, JsonRequestBehavior.AllowGet);
}
}
And this is my partial view:
#model TuGrietaLive.ViewModels.Admin.Index.FeedbackVm
#using (Html.BeginForm("LoadFeedbackModal", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<p>
Muchas gracias por tu Feedback. Para nosotros es muy importante.
<small>Si nos dejas tu correo te podemos contestar :)</small></p>
<div class="form-group">
#Html.LabelFor(m => m.FeedbackType, new { #class = "control-label col-md-2 col-xs-12" })
<div class="col-md-10 col-xs-12">
#Html.EnumDropDownListFor(model => model.FeedbackType, "Selecciona una Categoria", new { #class = "form-control", name = "FeedbackType" })
#Html.ValidationMessageFor(model => model.FeedbackType)
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2 col-xs-12">Email <small>(Opcional)</small></label>
<div class="col-md-10 col-xs-12">
#Html.EditorFor(model => model.Email, new { htmlAttributes = new { #class = "form-control"} })
#Html.ValidationMessageFor(model => model.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Comment, new { #class = "control-label col-md-2 col-xs-12" })
<div class="col-xs-12 col-md-10 ">
#Html.EditorFor(model => model.Comment, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Comment, "", new { #class = "text-danger", rows = 10 })
</div>
</div>
<button type="submit" id="btnsendFeedback" autofocus class="btn btn-block btn-success">
<span class="glyphicon glyphicon-envelope"></span>Enviar
</button>
</div>
}
I can successfully get the view and the modal draws the partial. Now I want to get the response of the server after submitting the form.
How can I get post action message? This code opens a new window with JSON object. I want to capture that and open a modal. This is killing me.
You should change button type of btnsendFeedback in your feedback dialog to button instead of submit:
<button type="button" id="btnsendFeedback" autofocus class="btn btn-block btn-success">
<span class="glyphicon glyphicon-envelope"></span>Enviar
</button>
and handle click event of btnsendFeedback upon receiving dialog content:
$('#btnfeedback').on('click', function (e) {
e.preventDefault();
var debateModal;
$.ajax({
url: '#Url.Action("LoadFeedbackModal", "Home")',
type: 'GET'
}).done(function (info) {
debateModal = bootbox.dialog(
{
message: info,
title: '<span class="fa fa-wechat"></span> Leave Feedback',
closeButton: true
});
debateModal.find('.modal-header').removeClass('modal-header').addClass('modal-header-info');
$('#btnsendFeedback').on('click', function (e) {
$.ajax({
url: '#Url.Action("LoadFeedbackModal")',
type: 'POST',
dataType: 'json'
}).done(function (result) {
console.log(result.Mensaje);
});
});
}).fail(function (xhr, status, error) {
debateModal = bootbox.alert({ message: "Problem try later", size: 'small' });
});
});
To begin, add an ID or class to your form so that we can hook into it's submit event:
#using (Html.BeginForm("LoadFeedbackModal", "Home", FormMethod.Post, new { #id="feedback-form" }))
Then you can use that selector to get the form:
var form = $('#feedback-form');
Alternatively, you could use find() to get the form from the modal:
var form = debateModal.find('form');
Next, add an event handler for the form's submit event:
form.on('submit', function(e){
});
You'll want to cancel the native event, and then use serialize() to prepare your AJAX data:
form.on('submit', function(e){
e.preventDefault();
var data = form.serialize();
});
Once you've done that, you can use $.post to submit the form data, handling it as you see fit:
form.on('submit', function(e){
e.preventDefault();
var url = form.attr('action');
var data = form.serialize();
$.post(url, data)
.done(function(response, status, jqxhr){
})
.fail(function(jqxhr, status, error){
});
});
Finally, put this all together in the shown.bs.modal event, so that it gets wired up once the dialog is visible:
debateModal.on('shown.bs.modal', function(){
var form = debateModal.find('form');
form.on('submit', function(e){
// prevent/cancel the native submit
e.preventDefault();
var url = form.attr('action'); // or use #Url.Action(), if you prefer
var data = form.serialize();
$.post(url, data)
.done(function(response, status, jqxhr){
/* Do what you need to with the response, and then close the modal */
debateModal.modal('hide');
})
.fail(function(jqxhr, status, error){
});
});
}
$.getJSON('#Url.Action("LoadFeedbackModal", "Home")').done(function(info) {
debateModal = bootbox.dialog(
{
message: info,
title: '<span class="fa fa-wechat"></span> Leave Feedback',
closeButton: true
});
debateModal.find('.modal-header').removeClass('modal-header').addClass('modal-header-info');
}).fail(function() {
debateModal = bootbox.alert({ message: "Problem try later", size: 'small' });
});
Suggest use getJSON instead of get, any question let me know.
I'm working with .NET Framework / MVC 4 / C#. I have a View that contains a Partial View which I update/refresh depending on user actions which include clicking a SAVE or CANCEL button. An Ajax request calls a Controller method which returns a Partial View with a blank model to refresh the View. THE PROBLEM is that when returning to the Ajax call from the Controller method, the HTML that the Ajax call presents is the OLD HTML from the Partial View that I am trying to replace??? The model returned by the Controller method is definitely blank, but the Ajax request is not getting it for some strange reason.
After the user clicks either button:
A javascript function is triggered.
The Form inside the Partial View is serialized (hidden inputs, text boxes, and dropdowns).
The serialized Form data is passed into an Ajax request which calls a Controller method and passes in the data.
//Submit a New Payment
$('#paymentpartial').on("click", ".savepayment", function () {
event.preventDefault();
var $form = $('form');
if ($form.valid()) {
var form = $form.serialize();
//Save
$.ajax({
url: '/Payments/SavePayment',
datatype: "json",
traditional: true,
data: form,
cache: false,
success: function (html) {
$("#paymentpartial").html(html);
oTable.fnDraw();
},
//AJAX call failed
error: function (data, status, errorThrown) { alert(status + ", " + errorThrown); }
});
}
return false;
});
Controller method does stuff and returns a Partial View with a blank model.
public ActionResult SavePayment(PaymentSummaryVM model)
{
try
{
//Save Stuff Here
//Build a brand new model for the Partial View
PaymentSummaryVM newModel = new PaymentSummaryVM();
newModel.ParticipantId = model.ParticipantId;
List<PaymentType> pTypes = db.PaymentTypes.Where(pt => pt.Active == true).OrderBy(pt => pt.ord).ToList();
newModel.PaymentTypeList = new SelectList(pTypes, "PaymentTypeId", "Name");
return PartialView("_AddEditPayment", newModel);
}
catch (Exception ex)
{
TempData["Error"] = "There were errors while saving your changes. " + ex.Message;
return RedirectToAction("Index", new { id = model.ParticipantId });
}
return RedirectToAction("Index", new { id = model.ParticipantId });
}
On success, Ajax returns the HTML of the Partial View and injects it in a DIV using the jQuery .html() function.
$.ajax({
url: '/Payments/SavePayment',
datatype: "json",
traditional: true,
data: form,
cache: false,
success: function (html) {
$("#paymentpartial").html(html);
}
THE PROBLEM is that the HTML returned by the Controller method, as seen in the Ajax call, is the OLD HTML from the previous Partial View that I'm trying to replace. I'm so confused. Here's the Partial View HTML:
#using BeyondThemes.BeyondAdmin.Models
#model PaymentSummaryVM
#if (Model.PaymentId == 0)
{
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">New Payment</span>
</div>
}
else
{
<div class="widget-header bordered-bottom bordered-blue">
<span class="widget-caption">Edit Payment</span>
</div>
}
<div class="widget-body" style="margin-bottom:20px">
#Html.HiddenFor(m => m.ParticipantId)
#Html.HiddenFor(m => m.PaymentId)
<div class="row">
#Html.Bootstrap().LabelFor(m => m.PaymentDate).LabelText("Date:").HtmlAttributes(new { #class = "col-md-1 control-label" })
<div class="form-group col-md-3">
#Html.Bootstrap().TextBoxFor(m => m.PaymentDate).Placeholder("Payment Date").HtmlAttributes(new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.PaymentDate)
</div>
#Html.Bootstrap().LabelFor(m => m.PaymentTypeId).LabelText("Type:").HtmlAttributes(new { #class = "col-md-1 control-label" })
<div class="form-group col-md-3">
#Html.Bootstrap().DropDownListFor(m => m.PaymentTypeId, Model.PaymentTypeList).OptionLabel("Select a Payment Type").HtmlAttributes(new { #class = "form-control", #id = "creditcard" })
#Html.ValidationMessageFor(m => m.PaymentTypeId)
</div>
#Html.Bootstrap().LabelFor(m => m.Notes).LabelText("Notes:").HtmlAttributes(new { #class = "col-md-1 control-label", #maxlength = "250" })
<div class="form-group col-md-3">
#Html.Bootstrap().TextAreaFor(m => m.Notes).HtmlAttributes(new { #class = "form-control", #maxlength = "250" })
#Html.ValidationMessageFor(m => m.Notes)
</div>
</div>
<div class="form-group col-md-offset-1">
<div class="row">
<div class="col-md-1">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-success savepayment" style="width:100%">Save</button>
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default cancelpayment" style="width:100%">Cancel</button>
</div>
<div class="col-md-9">
</div>
</div>
</div>
</div>
And it's being injected from the main View like this:
#using (var form = Html.Bootstrap().Begin(new Form().Type(FormType.Horizontal).HtmlAttributes(new { #id = "paymentpartial" })))
{
Html.RenderPartial("_AddEditPayment", Model);
}
UPDATE:
I just got it to do what I wanted. I had to make the following change, that is, NOT SERIALIZING the form. Just passed in the specific value..Really no clue why this worked but hey..
var pid = $("#ParticipantId").val();
$.ajax({
url: '/Payments/GetAddPaymentPartial',
datatype: "json",
//traditional: true,
data: { participantid: pid },
Try triggering a reset/clear on your success.
$.ajax({
url: '/Payments/SavePayment',
datatype: "json",
traditional: true,
data: form,
cache: false,
success: function (html) {
$("#paymentpartial").html(html);
$("#paymentpartial").find('form')[0].reset();
}