Button click data-bind is not working with knockout - asp.net-mvc

I cannot get the following piece of code to fire the button click to call save. I am using ASP.Net MVC with Knockoutjs. I am new to knockout and mvc. What am I missing here? Thanks in advance.
cshtml
#section scripts
{
<script src="~/Scripts/knockout-3.4.0.js"></script>
<script src="~/Scripts/knockout.mapping-latest.js"></script>
<script src="~/CustomScripts/bookingviewmodel.js"></script>
<script type="text/javascript">
var bookingViewModel = new BookingViewModel(#Html.Raw(data));
ko.applyBindings(bookingViewModel);
</script>
}
<div class="content">
<button class="btn btn-primary pull-right" data-bind="click: save"><i class="fa fa-check"></i> Save Booking</button>
</div>
bookingviewmodel.js
BookingViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.save = function () {
$.ajax({
url: "/Booking/Save",
type: "POST",
data: ko.toJSON(self),
contentType: "application/json",
success: function (data) {
if (data.bookingViewModel != null) {
ko.mapping.fromJS(data.bookingViewModel, {}, self);
}
}
});
}
}

Related

List<IFormFile> files gets nothing from dropzone post mvc

I'm trying to send images from dropzone to my controller mvc project by httpPost
The forms are calling correctly the IActionResult but the files count are always 0
When the forms load I get
but I'm already giving a URL. Don't know what's the error.
Here is my cshtml script of dropzone config
#section Scripts
{
<link rel="stylesheet" href="~/css/basic.css" />
<link rel="stylesheet" href="~/css/dropzone.css" />
<script type="text/javascript" src="~/js/dropzone.js"></script>
<script type="text/javascript" src="~/js/dropzone-amd-module.js"></script>
<script>
Dropzone.autoDiscover = false;
$(document).ready(function () {
$('#myDropzone').dropzone({
url:"/Aprovacoes/SaveUploadedFile",
method: "post",
//parameter name value
paramName: function () { "files" },
//clickable div id
clickable: '#previews',
//preview files container Id
previewsContainer: "#previews",
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 100,
maxFiles: 100,
// url:"/", // url here to save file
maxFilesize: 100,//max file size in MB,
addRemoveLinks: true,
dictResponseError: 'Server not Configured',
acceptedFiles: ".png,.jpg,.gif,.bmp,.jpeg,.pdf",// use this to restrict file type
init: function () {
var self = this;
// config
self.options.addRemoveLinks = true;
self.options.dictRemoveFile = "Delete";
//New file added
self.on("addedfile", function (file) {
console.log('new file added ', file);
$('.dz-success-mark').hide();
$('.dz-error-mark').hide();
});
// Send file starts
self.on("sending", function (file) {
console.log('upload started', file);
$('.meter').show();
});
// File upload Progress
self.on("totaluploadprogress", function (progress) {
console.log("progress ", progress);
$('.roller').width(progress + '%');
});
self.on("queuecomplete", function (progress) {
$('.meter').delay(999).slideUp(999);
});
// On removing file
self.on("removedfile", function (file) {
console.log(file);
});
$('#Submit').on("click", function (e) {
e.preventDefault();
e.stopPropagation();
// Validate form here if needed
if (self.getQueuedFiles().length > 0) {
self.processQueue();
} else {
self.uploadFiles([]);
$('#myDropzone').submit();
}
});
self.on("successmultiple", function (files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
});
}
});
})
</script>
And here is the form
#using (Html.BeginForm("SaveUploadedFile", "Aprovacoes", FormMethod.Post, new { #name = "myDropzone", id = "myDropzone", #enctype = "multipart/form-data" }))
{
<br />
<div>
<div id="previews" class="dz-default dz-message box__input dropzone">
<div style="text-align:center">
<i class="fa fa-cloud-upload" style="font-size:23px;position:relative;top:4px;"></i> <span style="margin-left:20px">Drop files to attach or browse</span>
</div>
</div>
</div>
<br />
<div>
<input type="submit" id="Submit" name="Submit" class="btn btn-success m-t-5" value="Submit" />
</div>
}
My controller httpPost method
[HttpPost]
public IActionResult SaveUploadedFile(List<IFormFile> files)
{
//do stuff
}
always come 0
This is my working solution:
View Part
#using (Ajax.BeginForm("YourAction", "YourController", FormMethod.Post, new AjaxOptions { HttpMethod = "POST", OnBegin = "OnBegin", OnSuccess = "OnSuccess", OnFailure = "OnFailure" }, new { #id = "ajaxForm", #enctype = "multipart/form-data" }))
{
<div class="card">
<div class="card-body">
#Html.AntiForgeryToken()
<div class="col-md-12 dropzone">
<div class="dropzone-previews" id="dropzonePreview">
<i class="icon-file-upload icon-5x absolute-center text-muted"></i>
</div>
</div>
</div>
<div class="row form-group mt-3">
<div class="col-md-12">
<input class="btn btn-inverse btn-primary" id="btnSubmit" name="inputSubmit" type="submit" value="Save" />
</div>
</div>
</div>
</div>
}
Script Part
Dropzone.autoDiscover = false;
var options = {
paramName: "PhotoFiles",
addRemoveLinks: true,
autoDiscover: false,
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 5,
thumbnailWidth: 250,
thumbnailHeight: 250,
dictRemoveFile: 'Delete',
previewsContainer: '#dropzonePreview',
clickable: '.dropzone',
acceptedFiles: ".jpeg,.jpg,.png",
};
var dropZone = new Dropzone("form#ajaxForm", options);
dropZone.element.querySelector("input[type=submit]").addEventListener("click", function (e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
// if dropzone has file process them, if not send empty array
if (dropZone.getQueuedFiles().length > 0) {
dropZone.processQueue();
} else {
$("#ajaxForm").submit();
}
});
dropZone.on("successmultiple", function (files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
OnSuccess(response);
});
dropZone.on("errormultiple", function (files, response) {
// Gets triggered when there was an error sending the files.
// Maybe show form again, and notify user of error
OnFailure(response);
});
Controller Part
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult InsertPhotos()
{
if (Request.Files.Count > 0)
{
for (int i = 0; i < Request.Files.Count; i++)
{
//process files
}
}
//return some result
return Json(result, JsonRequestBehavior.AllowGet);
}
Hope it helps.

HttpPostedFileBase could not be found Visual studio 2019

hi,
i'm working on a asp.net core mvc with visual studio 2019,
(see attached for the mvc version (3.1.8).
i want to use HttpPostedFileBase, but getting error could not be found,
i've seen a solution suggesting to add using system.Web, and i did, but still getting this error,
Any ideas?
Edit:
Created the html :
<div class="col-md-6">
<div>
<input id="CSVFile" type="file">
</div>
<button onclick="Submit()">submit</button>
</div>
and javascript:
<script type="text/javascript">
function Submit() {
var pdata = new FormData();
var files = $("#CSVFile").get(0).files;
window.alert(files.Length);
pdata.append('CSVFile', files[0]);
$.ajax({
url: "Index",
type: "POST",
data: pdata,
processData: false,
contentType: false,
success: function (data) {
var input = $("#CSVFile");
input.replaceWith(input.val('').clone(true));
}
});
}
</script>
but the controller is not being called (it is defined HttpPost)
public ActionResult Index(IFormFile CSVFile)
{
return View();
}
.net core 3.1 doesn't contain HttpPostedFileBase.If you want to upload files,you can use IFormFile,here is an official tutorial.
Here is a simple demo to use IFormFile(from view to controller):
view:
<div class="row">
<div class="col-md-6">
<div>
<input id="CertImageFile" type="file">
</div>
<button onclick="Submit()">submit</button>
</div>
</div>
#section scripts{
<script type="text/javascript">
function Submit() {
var pdata = new FormData();
var files = $("#CertImageFile").get(0).files;
pdata.append('CertImageFile', files[0]);
$.ajax({
url: "Submit",
type: "POST",
data: pdata,
processData: false,
contentType: false,
success: function (data) {
var input = $("#CertImageFile");
input.replaceWith(input.val('').clone(true));
}
});
}
</script>
}
Controller:
[HttpGet]
public IActionResult TestIFormFile()
{
return View();
}
[HttpPost]
public IActionResult Submit(IFormFile CertImageFile)
{
return Ok();
}
result:

Quick Search Form Not Submitting MVC

I currently have a partial view that renders at the top of every page on the site. The point of this partial view is to provide a form that lets the user do a quick search. I have set the partial view form up as follows:
#using (Html.BeginForm())
{
<div class="col-md-7" style="text-align: right">
<div class="input-group input-group-sm col-sm-6 pull-right">
#Html.TextBox("caseReference")
<button type="submit">
<i class="fa fa-search"></i>
</button>
</div>
</div>
}
#Html.Partial("_MainNavigation")
</div>
</div>
</nav>
<script type="text/javascript">
$(function () {
$("form").on("submit", function (event) {
event.preventDefault();
var request = { caseReference: $('#caseReference').val() };
submitForm(request, '#Url.Action("CaseSearch", "QuickSearch", new { area = "Search" })');
});
});
</script>
However under the page source the form action renders as a request to the home page with a post action. I have read numerous examples and this task seems very straight forward. Would it be a better idea to use the parameters on the #html.BeginForm() method?
So after spending a few hours researching, I have finally got the quick search functionality to work on the home page of my site. In the razorview I have the following code:
<div class="input-group input-group-sm col-sm-6 pull-right">
#Html.Kendo().MaskedTextBox().Name("name").Mask("000000/0000").Deferred()
<button id="search" type="submit">
<i class="fa fa-search"></i>
</button>
<script type="text/javascript">
$(function () {
$("#search").on("click", function (event) {
event.preventDefault();
var value = $('#name').val();
value = value.replace(/[/]/g, "_");
var refVal = value;
var url = '#Url.Action("Action", "Contoller", new { area = "Area" })' + '//' + refVal;
$.ajax({
type: 'GET',
url: url,
cache: false,
dataType: 'json',
contentType: "application/json;",
success: function (result) {
if (result.success) {
window.location.href = result.url;
}
else {
bootbox.alert(result.message);
}
}
});
});
});
However in regards to the following line:
var url = '#Url.Action("Action", "Contoller", new { area = "Area" })' + '//' + refVal;
If I hard code the url and append the search term it works on the Home page because we are at the root directory but from other pages it fails, To get around this I tried to use #Url.Action. However this is producing the following result in the html soure code:
var url = '' + '//' + refVal;
Is there a certain way to use the URL.Action method from withing JS?

Jquery sortable index change to ASP.NET MVC controller

I am trying to get the model binder to recognize the change. I am not sure what I am missing here. Basically the initial page population pulls the page number from the database. I then have the sortable working, the raw HTML in Firebug shows the change in order. But when I post back to the model first off it is not figuring out to go the post method and the other issue is Survey. Pages does not seem to have the change in order.
View
#for (var i = 0; i < Model.Pages.Count; i++)
{
var page = Model.Pages.ElementAt(i);
#Html.Hidden("Pages[" + i + "].PageId", page.PageId, new { #class = "page_index" })
#Html.Hidden("Pages[" + i + "].PageNumber", page.PageNumber)
<li id="#page.PageId" class="sortable-item text-center ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s">
</span>#page.PageNumber</li>
}
</ul>
JavaScript
<script type="text/javascript">
$(document).ready(function () {
$('.sortable').sortable({
stop: function (event, ui) {
var formData = $('#editSurveryForm').serialize();
$.ajax({
url: "#Url.Action("Edit")",
data: formData,
type: 'POST',
traditional: true,
success: function () {
alert("success");
},
error: function () {
alert("fail");
}
}
);
}
});
});
</script>
Controller
[HttpPost]
public ActionResult Edit(Survey survey)
{
if (!ModelState.IsValid)
{
return View("EditSurvey", survey);
}
surveyRepository.UpdateSurvey(survey);
return RedirectToAction("Index", "Administration");
}
Ok, I figure this one out. I had the hidden fields outside of the <li></li> tag. Once I moved them inside I did all my logic as I would have.
<div class="span9">
<div class="span4">
<ul class="sortable_page_list">
#for (var i = 0; i < Model.Pages.Count; i++)
{
<li class="sortable-item text-center ui-state-default">
#Html.HiddenFor(model => model.Pages[i].PageId)
#Html.HiddenFor(model => model.Pages[i].PageNumber)
<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>#Model.Pages[i].PageNumber
</li>
}
</ul>
<div class="span1 pull-right internal-wrapper">
#Html.ActionLink("Add", "AddPage", new { id = Model.SurveyId }, new { #class = "add_survey_icon common_icon_settings" })
</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('.sortable_page_list').sortable({
update: function (event, ui) {
var counter = 1;
$("[id*='PageNumber']").each(function() {
$(this).attr("value", counter);
counter++;
});
//var surveyToUpdate = $('#editSurveyForm');
$.ajax({
url: '#Url.Action("Edit","Administration")',
contentType: "application/json; charset=utf-8",
data: $('#editSurveyForm').serialize(),
type: 'POST'
});
}
});
});
Last thing to figure out is why the ajax post is not posting to the Post method with the survey form data

Using jquery to check if POST is successful

I am trying to write jquery function that will pop up and say Post was successful! and if not, Post was not successful! How could I use a try catch with inputting some jquery?
#using (Html.BeginForm("Admin", "Home", "POST"))
{
<div class="well">
<section>
<br>
<span style="font-weight:bold">Text File Destination:   </span>
<input type="text" name="txt_file_dest" value="#ViewBag.GetTextPath">
<span style="color:black">   Example:</span><span style="color:blue"> \\invincible\\chemistry$\\</span>
<br>
<br>
<span style="font-weight:bold">SQL Connection String:</span>
<input type="text" name="sql_Connection" value="#ViewBag.GetSqlConnection">
<span style="color:black">   Example:</span> <span style="color:blue"> Server=-</span>
<br>
<br>
<button class="btn btn-success" type="submit" >Save Changes</button>
</section>
</div>
}
So I figured out my answer. Just for future reference to anybody that tries this, below is what I did. I placed it above #using (Html.BeginForm("Admin", "Home", "POST")). #Andrew I did try yours, but I could not get it to work. Thanks to everyone for tyring to help me.
<script language="javascript" type="text/javascript">
$(function() {
$("form").submit(function(e) {
$.post($(this).attr("action"), // url
$(this).serialize(), // data
function (data) { //success callback function
alert("Edit successful");
}).error(function () {
alert('failure');
});
e.preventDefault();
});
});
</script>
You'll want to change your HtmlHelper BeginForm declaration slightly, so that an id attribute will be rendered with the element, like this:
#using (Html.BeginForm("Admin", "Home", FormMethod.Post, new { id = "well-form" }))
Now you can add a script above the declaration which traps-and-submits the form and handles the response (success or error).
<script>
$(function() {
// Find the form with id='well-form'
$('#well-form').submit(function() {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function(result) {
alert('Post was successful!');
},
error: function(result) {
alert('Post was not successful!');
}
});
// return false to cancel the form post
// since javascript will perform it with ajax
return false;
});
});
</script>
$.ajax({
url: 'post.html',
success: function(){
alert('success');
},
error: function(){
alert('failure');
}
});
Compounding to Sonu's answer, I have found similar questions regarding this hard to accomplish as the HTML form submit has no callback and it seems that it is recommended to use ajax() when you want a postback confirmation of your form submission.
Please see this Stackoverflow Link.
Could you use the Ajax Events? such as $.ajaxSuccess
http://api.jquery.com/category/ajax/global-ajax-event-handlers/

Resources