How to determine the origin of a button in a view? - c#

There is a button on the page.
I do not see this button in the page code.
 
Question: how to determine the origin of a button in a view?
 
The project is used - ImportExportExcelASPNetCore // talkingdotnet // github.com
 
After starting the application, a page will appear.
 
Where in the page code is the Выберите файл button?
Code
#page
#model ImportExportExcelASPNetCore.Pages.ImportExportModel
#{
ViewData["Title"] = "ImportExport";
}
<h2>Import Export using NPOI</h2>
<form method="post" enctype="multipart/form-data">
<br/>
<div class="row">
<div class="col-md-4">
<input type="file" id="fUpload" name="files" class="form-control" />
</div>
<div class="col-md-8">
<input type="button" id="btnUpload" value="Upload" />
</div>
</div>
<div class="row">
<div class="col-md-8" style="padding-top:10px;">
<button asp-page-handler="Export">Export</button>
</div>
</div>
<br/>
<div id="dvData"></div>
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript" language="JavaScript">
$(document).ready(function ()
{
$('#btnUpload').on('click', function ()
{
var fileExtension = ['xls', 'xlsx']; // Расширение файла
var filename = $('#fUpload').val(); // Имя файла
if (filename.length == 0)
{
alert("Please select a file.");
return false;
}
else
{
var extension = filename.replace(/^.*\./, '');
if ($.inArray(extension, fileExtension) == -1)
{
alert("Please select only excel files.");
return false;
}
}
var fdata = new FormData();
var fileUpload = $("#fUpload").get(0);
var files = fileUpload.files;
fdata.append(files[0].name, files[0]);
$.ajax(
{
type: "POST",
url: "/ImportExport?handler=Import",
beforeSend: function (xhr)
{
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
data: fdata,
contentType: false,
processData: false,
success: function (response)
{
if (response.length == 0)
alert('Some error occured while uploading');
else
{
$('#dvData').html(response);
}
},
error: function (e)
{
$('#dvData').html(e.responseText);
}
});
})
});
</script>
}

Related

Trying to upload a file and display the files in a view

So I'm trying to build an virtual file storage, im stuck at the part where I have to upload files and after that display them in a File-s view so that the user can download, delete or see them. The form input together with the file upload is in a modal box. To process the modal form I have used #Html.BeginForm and to process the file upload I have used ajax. What I have achieved until now is that I can upload the files to the server folder, but I dont konw how I can save the file name and the file path to the database of file-s table. And I also need help on how to display these files in a specific view. Thank you in advance.
Html
<div class="modal-body">
#using (Html.BeginForm("SaveRecord", "NgarkoDokument", FormMethod.Post, new { enctype = "mulptiple/form-data" }))
{
<div class="form-group">
<label for="exampleFormControlSelect1">Lloji i dokumentit</label><br />
<select title="Lloji i dokumentit" name="lloji" class="form-control col-md-3 box" id="tipiDropdown"> </select>
<input type="button" title="Ngarko dokument" name="ngarko" value="Ngarko" id="uploadPop" class="btn btn-info col-md-3" onclick="document.getElementById('file').click();" />
<input type="file" onchange="javascript: updateList()" multiple="multiple" style="display:none;" id="file" name="postedFiles"/>
<div id="fileList"></div>
</div>
<br /><br />
<div class="form-group">
<label for="formGroupExampleInput">Fusha indeksimi</label> <br />
#*<input title="Indeksimi dokumentit" id="indeksimi" class="form-control col-md-3" type="text" name="indeksimi" placeholder="indeksimi" required />*#
#Html.TextBoxFor(a => a.Fusha_Indeksimit.Emri_Indeksimit, new { #class = "form-control", #placeholder = "indeksimi" })
#* <button title="Shto indeksim" id="modalPlus" type="submit" class="btn btn-info"><i class="glyphicon glyphicon-plus"></i></button>*#
</div>
<label for="formGroupExampleInput">Vendndodhja fizike e dokumentit</label><br>
<div id="zyraModal" class="form-group col-md-4">
#*<input title="Zyra fizike" id="zyra" class="form-control" type="text" name="zyra" placeholder="Zyra" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Zyra, new { #class = "form-control", #placeholder
= "Zyra" })
</div>
<div class="form-group col-md-4">
#* <input title="Kutia fizike" id="kutia" class="form-control" type="number" name="kutia" placeholder="Nr i kutisë" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Nr_Kutise, new { #class = "form-control", #placeholder = "Nr i kutisë" })
</div>
<div class="form-group col-md-4">
#* <input title="Rafti fizik" id="rafti" class="form-control" type="text" name="rafti" placeholder="Rafti" />*#
#Html.TextBoxFor(a => a.Vendndodhja_fizike.Rafti, new { #class = "form-control", #placeholder = "Rafti" })
</div>
<br /><br />
<div class="row" id="ruaj">
<button title="Ruaj dokumentin" type="submit" class="btn btn-success">Ruaj</button>
</div>
}
</div>
Ajax script
<script type="text/javascript">
$(document).ready(function () {
$("#file").change(function () {
console.log("Image selected!");
var formData = new FormData();
var totalFiles = document.getElementById("file").files.length;
for (var i = 0; i < totalFiles; i++) {
var file = document.getElementById("file").files[i];
formData.append("file", file);
}
$.ajax({
type: "POST",
url: '/UploadFile/Upload',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (response) {
alert('succes!!');
}
});
});
});
</script>
Controller
public ActionResult Dokument()
{
return View();
}
[HttpPost]
public void Upload()
{
Dokumenti dok = new Dokumenti();
for (int i = 0; i < Request.Files.Count; i++)
{
var file = Request.Files[i];
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/File/"), fileName);
file.SaveAs(path);
}
}
public ActionResult SaveRecord(NgarkoDokument model)
{
try
{
Vendndodhja_Fizike vendndodhja = new Vendndodhja_Fizike();
vendndodhja.Zyra = model.Vendndodhja_fizike.Zyra;
vendndodhja.Rafti = model.Vendndodhja_fizike.Rafti;
vendndodhja.Nr_Kutise = model.Vendndodhja_fizike.Nr_Kutise;
db.Vendndodhja_Fizike.Add(vendndodhja);
Fusha_Indeksimit indeksimi = new Fusha_Indeksimit();
indeksimi.Emri_Indeksimit = model.Fusha_Indeksimit.Emri_Indeksimit;
db.Fusha_Indeksimit.Add(indeksimi);
Dokumenti dok = new Dokumenti();
dok.Emer = model.Dokumenti.Emer;
db.Dokumenti.Add(dok);
db.SaveChanges();
//int lastUserId = dok.UserID;
}
catch(Exception ex)
{
throw ex;
}
return RedirectToAction("Dokument");
}
}
First of all, you may need to specify this because you send FormData to your controller. For example:
public async Task CreateAsync([FromForm] CreateBookDto input)
{
...
}
I care about a lot of things while uploading the file so my js file is a bit long but you can get what works for you:
$(function () {
var fileInput = document.getElementById('Book_CoverImageFile');
var file;
fileInput.addEventListener('change', function () {
var showModal = true;
file = fileInput.files[0];
document.getElementById("choose-cover-image").innerHTML = file.name;
var permittedExtensions = ["jpg", "jpeg", "png"]
var fileExtension = $(this).val().split('.').pop();
if (permittedExtensions.indexOf(fileExtension) === -1) {
showModal = false;
alert('This extension is not allowed')
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
else if(file.size > 5*1024*1024) {
showModal = false;
alert('The file is too large');
}
var img = new Image();
img.onload = function() {
var sizes = {
width:this.width,
height: this.height
};
URL.revokeObjectURL(this.src);
if (sizes.width > 1920 && sizes.height > 1080){
alert('Height and Width must not exceed 1920*1080.')
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
var aspectRatio = sizes.width / sizes.height;
aspectRatio = Number (aspectRatio.toFixed(1));
if (aspectRatio !== 1.8){
alert("The picture you uploaded is not in 16:9 aspect ratio!")
$('#Book_CoverImageFile').val('');
$("#choose-cover-image").html("Choose a cover image...");
}
}
if(showModal === true) {
readURL(this);
$('#myModal').modal('show');
}
var objectURL = URL.createObjectURL(file);
img.src = objectURL;
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img-upload').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$('form#CreateBookForm').submit(function (e) {
e.preventDefault();
var title = $('#Book_Title').val().trim();
var formData = new FormData();
formData.append("Title", title);
formData.append("CoverImageFile", file);
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
percentComplete = parseInt(percentComplete * 100);
if(percentComplete !== 100){
$( '#Book_CoverImageFile' ).prop( "disabled", true );
$( '#Book_Title' ).prop( "disabled", true );
$( '#btnSubmit' ).prop( "disabled", true );
}
}
}, false);
return xhr;
},
url: app.appPath + `api/app/Book`,
data: formData,
type: 'POST',
contentType: false,
processData: false,
success: function(data){
alert("The Book has been successfully submitted. It will be published after a review from the site admin.");
window.location.href = "/books";
},
error: function (data) {
alert(data.responseJSON.error.message);
}
});
});
This does many things, for example; file permitted extension control, control of file size, checking whether the file is more than 1920 * 1080 pixels, whether the file has 16:9 aspect ratio, disabling form elements while sending the file, etc...
And if you really care about security, you should;
To only accept permitted extensions:
public class AllowedExtensionsAttribute : ValidationAttribute
{
private readonly string[] _extensions;
public AllowedExtensionsAttribute(string[] extensions)
{
_extensions = extensions;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
if (value == null) // If uploading a file is optional on the form screen, it should be added == CanBeNul
{
return ValidationResult.Success;
}
var file = value as IFormFile;
var extension = Path.GetExtension(file.FileName);
if (file.Length > 0 && file != null)
{
if (!_extensions.Contains(extension.ToLower()))
{
return new ValidationResult(GetErrorMessage());
}
}
return ValidationResult.Success;
}
public string GetErrorMessage()
{
return $"This extension is not allowed!";
}
}
To limit the uploaded file size:
public class MaxFileSizeAttribute : ValidationAttribute
{
private readonly int _maxFileSize;
public MaxFileSizeAttribute(int maxFileSize)
{
_maxFileSize = maxFileSize;
}
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
if (value == null) // If uploading a file is optional on the form screen, it should be added == CanBeNull
{
return ValidationResult.Success;
}
var file = value as IFormFile;
if (file.Length > 0)
{
if (file.Length > _maxFileSize)
{
return new ValidationResult(GetErrorMessage());
}
}
return ValidationResult.Success;
}
public string GetErrorMessage()
{
return $"Maximum allowed file size is { _maxFileSize} bytes.";
}
}
And you must add them to Dto:
public class CreateBookDto
{
[Required]
[StringLength(64)]
public string Title { get; set; }
[CanBeNull]
[DataType(DataType.Upload)]
[MaxFileSize(5*1024*1024)] // 5mb
[AllowedExtensions(new string[] { ".jpg", ".png", ".jpeg" })]
public IFormFile CoverImageFile { get; set; }
}
Finally, your HTML file should look like this:
<form method="post" id="CreateBookForm" asp-page="/Book/Create" enctype="multipart/form-data">
<div class="form-group">
<div class="custom-file">
<input asp-for="Book.CoverImageFile" type="file" name="file" class="custom-file-input" id="Book_CoverImageFile"
required="required">
<label id="choose-cover-image" class="custom-file-label" for="customFile">Choose a cover image...</label>
<small class="form-text text-muted">#L["CreateBookCoverInfo"].Value</small>
</div>
</div>
...
<button id="btnSubmit" type="submit" class="btn btn-primary btn-block">Submit</button>
</form>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<img class="img-fluid" id="img-upload" alt=""/>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary btn-block" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

ASP NET MVC RAZOR Upload Multiple Images FileList

I'm new in asp net and I have a List of images and I want to send through javascript to the controller.
I'm using FileList and here is an example.
.Create.cshtml
<div class="form-group">
#Html.LabelFor(model => model.description, "Escolha as Imagens", htmlAttributes: new { #class = "control-label col-md-2" })
<input id="files" type="file" name="files[]" />
<br>
<div id="preview"></div>
</div>
#section Scripts{
<script type="text/javascript">
function handleFileSelect(evt) {
var files = evt.target.files;
var f = files[0];
//kiem tra co fai file anh
if (f.type.match('image.*')) {
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var span = document.createElement('span');
span.innerHTML = [
'<img class="thumb" src="', e.target.result, '" title="', escape(theFile.name),
'"/><span class="remove_img_preview"></span>'
].join('');
document.getElementById('preview').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
}
$('#files').change(function(evt) {
handleFileSelect(evt);
});
$('#preview').on('click',
'.remove_img_preview',
function() {
$(this).parent('span').remove();
});
$('#btnSave').click(function() {
$.ajax({
url: '/Dishes/Create',
data: { files: files },
type: "POST",
cache: false,
datatype: "html",
success: function(data) {
console.log(data);
},
error: function(jqXhr, textStatus, errorThrown) {
//do your own thing
alert("fail");
}
});
});
</script>
}
</fieldset>
<div class="form-group">
<div class="footer text-center">
<button class="btn btn-fill btn-info" name="btnSave" id="btnSave">Inserir novo</button>
</div>
</div>
Controller.cs
public ActionResult Create()
{
ViewBag.idTypeDish = new SelectList(db.TypeDish, "idTypeDish", "name");
return View();
}
// POST: Dishes/Create
[HttpPost]
public ActionResult Create(IEnumerable<HttpPostedFileBase> files)
{
return View();
}
In the controller, files are always null.
I'm using that example, http://jsfiddle.net/Lwczca6p/1/, I just adapt to my project.
You've got a few problems. First, you're trying to use files with your AJAX, but that variable was defined in the scope of another function (i.e. you don't have access to it here). Second, when using jQuery's $.ajax to do a file upload, you need to set the processData option to false. Here's how I would handle it:
$('#MyForm').on('submit', function (e) {
e.preventDefault();
var formData = new FormData(this); // `this` is the form instance
$.ajax({
url: '/path/to/handler',
type: 'POST',
data: formData,
processData: false,
contentType: 'multipart/form-data',
success: function (data, textStatus, jqXHR) {
// do something on success
},
error: function (jqXHR, textStatus, errorThrown) {
// do something on error
}
});
});
Try this, first create a model for your view:
public class FileModel
{
[Required(ErrorMessage ="Please select file.")]
[Display(Name ="Browse File")]
public HttpPostedFileBase[] files { get; set; }
}
Then, edit your view to this (to enable upload many files you need to put multiple="multiple" in your element):
#model Models.FileModel
#using (Html.BeginForm("Create", "YourController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.files, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.files, "", new { #type = "file", #multiple = "multiple" })
#Html.ValidationMessageFor(model => model.files, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Upload" class="btn btn-primary" />
</div>
</div>
</div>
}

C# MVC Bootstrap Add Record Popup Form

I have an existing form which relies on a category being selected, if a category does not exist for the user the company belongs too, the user must be able to create one.
I believe jQuery and JSON is the route forward, but I cannot generate a true popup above the current Bootstrap form, nor can I get the popup form to post without posting the main form.
If possible I'd like the jQuery function getCategories to open a popup form only if no data is returned, then the popup form using validation, once a record has been successfully added to the database, the popup form close and then recall the jQuery function getCategories and select the newly added record.
HomeController.cs
public JsonResult GetCategories(int companyId)
{
var categories = _repository.GetCategories(companyId);
return Json(categories, JsonRequestBehavior.AllowGet);
}
_Layout.cshtml
#using Documents
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="" />
<meta name="author" content="#ViewBag.LenderName" />
<title>#ViewBag.Title - #ViewBag.LenderName</title>
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/dataTablesCss")
#Styles.Render("~/Content/blue")
<!--[if lt IE 9]>
#Scripts.Render("~/bundles/ie8")
<![endif]-->
</head>
<body class="has-navbar-fixed-top page-index">
#Scripts.Render("~/bundles/jquery")
<!--[if lt IE 9]>
#Scripts.Render("~/bundles/jqueryvalidate")
<![endif]-->
#RenderSection("featusearch", required: false)
#RenderBody()
<footer id="footer" class="text-center">
<div class="container">
<div class="row">
<div class="col-lg-12">
<p> </p>
<p>
Copyright © 2015 - #ViewBag.CompanyName
</p>
</div>
</div>
</div>
</footer>
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/dataTables")
#Scripts.Render("~/bundles/money")
#Scripts.Render("~/bundles/tooltip")
#Scripts.Render("~/bundles/jquery-ui")
<script type="text/javascript" language="javascript">
$("#menu-close").click(function (e) {
e.preventDefault();
$("#sidebar-wrapper").toggleClass("active");
});
$("#menu-toggle").click(function (e) {
e.preventDefault();
$("#sidebar-wrapper").toggleClass("active");
});
$(function () {
$('a[href*=#]:not([href=#])').click(function () {
if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') || location.hostname === this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
</script>
<script type="text/javascript" charset="utf-8">
$(function () {
$('.validation-summary-errors').each(function () {
$(this).addClass('alert');
$(this).addClass('alert-danger');
});
$('form').each(function () {
$(this).find('div.form-group-individual').each(function () {
if ($(this).find('span.field-validation-error').length > 0) {
$(this).addClass('has-error');
$(this).find('span.field-validation-error').removeClass('field-validation-error');
}
});
});
});
</script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
var oTable = $('#orders').dataTable({
responsive: true,
"pagingType": "full",
"iDisplayLength": 5,
"aLengthMenu": [[5, 10, 25, -1], [5, 10, 25, "All"]],
columnDefs: [{ type: 'date-euro', targets: 4 }],
"aoColumns": [
{ "visible": false },
{ "bSortable": true, "bSearchable": true },
{ "bSortable": true, "bSearchable": true },
{ "bSortable": true, "bSearchable": true },
{ "bSortable": true, "bSearchable": true },
null,
null,
null
],
"order": [[0, "desc"]]
});
$('#Form').find('select').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
$('#Form').find('input').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
$('#Form').find('button').each(function () {
$(this).tooltip({
placement: "top",
trigger: "hover",
container: "body"
});
});
});
</script>
#RenderSection("scripts", false)
</body>
</html>
$(document).ready(function () {
var companyId = parseInt($('#CompanyId').val(), 0);
function getCategories() {
$.getJSON('/Home/GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].CategoryName + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].CategoryName + '</option>');
}
}
if (data.length > 0) {
// We Have Date
} else {
// No Data
// Create Dialog Popup
alert('Error getting Categories, please add a Category');
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
$('#Categories').change(function () {
var selected = $(this).find('option:selected');
categoryId = selected.val();
$('#CategoryId').val(categoryId);
});
});
Index.cshtml
#using WebApplication1
#using WebApplication1.Helpers
#model WebApplication1.Models.Order
#{
ViewBag.Title = "Test";
}
<div id="navigation" class="wrapper">
<div class="navbar navbar-fixed-top" id="top">
<div class="navbar-inner">
<div class="inner">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle btn btn-navbar" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/" title="Home"><h1>Test</h1><span>#ViewBag.CompanyName</span></a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-right" id="main-menu">
#Html.MenuLink("Logout", "Login", "Logout", "", "Logout")
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="highlighted">
<div class="container">
<div class="header">
<h2 class="page-title">
<span>Test</span> <small>This is a test page.</small>
</h2>
<p></p>
</div>
</div>
</div>
<div id="content">
<div class="container">
<div class="row">
<div class="col-sm-12">
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form", #Id = "Form" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.CategoryId, new { #Value = #ViewBag.CategoryId, #Id = "CategoryId" })
<fieldset>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Title</span>
#Html.DropDownListExt("SalutationId", ViewBag.SalutationList as SelectList, "Title")
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.SalutationId)</p>
</div>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Forename</span>
#Html.TextBoxForExt(m => m.Forename, new Dictionary<string, object> { { "Value", #ViewBag.Forename } })
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.Forename)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Middle Name</span>
#Html.TextBoxForExt(m => m.MiddleName, new Dictionary<string, object> { { "Value", #ViewBag.MiddleName } })
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.MiddleName)</p>
</div>
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Surname</span>
#Html.TextBoxForExt(m => m.Surname, new Dictionary<string, object> { { "Value", #ViewBag.Surname } })
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.Surname)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-6">
<div class="input-group">
<span class="input-group-addon">Categories</span>
<select id="Categories" name="Categories" class="form-control" data-toggle="tooltip" title="Categories">
<option></option>
</select>
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.CategoryId)</p>
</div>
<div class="col-sm-1">
<button type="submit" class="btn btn-primary" name="Submit" value="Submit" title="Click to Submit">Submit</button>
</div>
</div>
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
<script type="text/javascript" src="/Scripts/form.js"></script>
form.js
$(document).ready(function () {
var companyId = parseInt($('#CompanyId').val(), 0);
var categoryId = parseInt($('#CategoryId').val(), 0);
getCategories();
function getCategories() {
$.getJSON('/Home/GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].Category + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].Category + '</option>');
}
}
if (data.length > 0) {
// We Have Data
} else {
// No Data
// Create Dialog Popup
alert('Error getting Categories, please add a Category');
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
$('#Categories').change(function () {
var selected = $(this).find('option:selected');
categoryId = selected.val();
$('#CategoryId').val(categoryId);
});
});
Add.cshtml
#using WebApplication1.Helpers
#model WebApplication1.Models.Category
<div id="content">
<div class="container">
<div class="row">
<div class="col-sm-4">
#using (Html.BeginForm("Add", "Home", FormMethod.Post, new { #class = "form-horizontal", role = "form", #Id = "AddForm" }))
{
#Html.HiddenFor(m => m.CompanyId, new { #Value = #ViewBag.CompanyId, #Id = "CompanyId" })
<fieldset>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-4">
<div class="input-group">
<span class="input-group-addon">Category Name</span>
#Html.TextBoxForExt(m => m.CategoryName)
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.CategoryName)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-1">
<button type="submit" class="btn btn-primary" name="Add" value="Add" title="Click to Add a Category">Add</button>
</div>
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
BundleConfig.cs
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.IgnoreList.Clear();
bundles.UseCdn = true;
BundleTable.EnableOptimizations = false;
bundles.Add(new ScriptBundle("~/bundles/ie8").Include(
"~/Scripts/html5shiv.js",
"~/Scripts/respond.js"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js"));
var jquery = new ScriptBundle("~/bundles/jquery", "~/Scripts/jquery-2.1.4.js").Include(
"~/Scripts/Compatibility/jquery-1.11.3.js");
jquery.CdnFallbackExpression = "window.jQuery";
bundles.Add(jquery);
bundles.Add(new ScriptBundle("~/bundles/jqueryvalidate").Include(
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.unobtrusive.js",
"~/Scripts/_extensions.js"));
bundles.Add(new ScriptBundle("~/bundles/money").Include(
"~/Scripts/jquery.price_format.2.0.js"));
bundles.Add(new ScriptBundle("~/bundles/tooltip").Include(
"~/Scripts/tooltip.js"));
bundles.Add(new ScriptBundle("~/bundles/dataTables").Include(
"~/Scripts/DataTables-1.10.9/jquery.dataTables.js",
"~/Scripts/DataTables-1.10.9/dataTables.bootstrap.js",
"~/Scripts/DataTables-1.10.9/date-euro.js"));
bundles.Add(new ScriptBundle("~/bundles/awesomeMvc").Include(
"~/Scripts/AwesomeMvc.js"));
bundles.Add(new ScriptBundle("~/bundles/jquery-ui").Include(
"~/Scripts/jquery-ui.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/Site.css"));
bundles.Add(new StyleBundle("~/Content/blue").Include(
"~/Content/colour-blue.css"));
bundles.Add(new StyleBundle("~/Content/red").Include(
"~/Content/colour-red.css"));
bundles.Add(new StyleBundle("~/Content/dataTablesCss").Include(
"~/Content/DataTables-1.10.9/dataTables.bootstrap.css",
"~/Content/DataTables-1.10.9/Buttons-1.0.3/buttons.bootstrap.css"));
}
}
Any help would be much appreciated :-)
It sounds like you might be looking for a Modal popup. Bootstrap already has this built in. You can learn about it here: http://www.w3schools.com/bootstrap/bootstrap_modal.asp
You can also pull what to show in the modal from another view using the Html.RenderPartial(view)
Following on from Drew Rochon's suggestion, I have researched and resolved my issue.
The following code is either replacement or addition where specified.
_Add.cshtml (Replacement for Add.cshtml)
#using WebApplication1.Helpers
#model WebApplication1.Models.Category
<div class="modal fade" id="AddCategoryModal" tabindex="-1" role="dialog" aria-labelledby="Add" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h5 class="modal-title">Add Category</h5>
</div>
<div class="modal-body">
#using (Html.BeginForm(null, null, FormMethod.Post, new { #Id = "AddCategoryForm" }))
{
#Html.HiddenFor(m => m.CompanyId, new { #Id = "CompanyId" })
<fieldset>
<div class="form-group">
<div class="form-group-individual">
<div class="col-sm-12">
<div class="input-group">
<span class="input-group-addon">Category Name</span>
#Html.TextBoxForExt(m => m.CategoryName)
</div>
<p class="help-block">#Html.ValidationMessageFor(m => m.CategoryName)</p>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<button type="submit" class="btn btn-primary">Add</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
</div>
</fieldset>
}
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
var path = $("#Path").val();
var companyId = parseInt($('#CompanyId').val(), 0);
var categoryId = parseInt($('#CategoryId').val(), 0);
var abort = false;
$("#AddCategoryModal").modal('show');
$('#AddCategoryModal').off("hidden.bs.modal").on('hidden.bs.modal', modalClose);
function modalClose() {
$("#AddAdvisoryModal").remove();
$('.modal-backdrop').remove();
}
$('#AddCategoryForm').formValidation({
framework: 'bootstrap',
excluded: ':disabled',
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
CategoryName: {
validators: {
notEmpty: {
message: 'Category Name is required'
}
}
}
}
}).on('success.form.fv', function (e) {
e.preventDefault();
var companyId = $("#CompanyId").val();
var categoryName = $("#CategoryName").val();
var model = {
CompanyId: companyId,
CategoryName: categoryName
};
$.ajax({
url: "/Home/_Add/",
type: "POST",
contentType: "application/json;charset=utf-8;",
dataType: "html",
data: JSON.stringify(model),
success: function (markup) {
categoryId = parseInt(markup, 0);
if (categoryId > 0) {
$('#Categories').val(categoryId);
getCategories();
alert("Category added successfully.");
modalClose();
}
},
error: function () {
alert('Ajax request not recieved!');
}
});
});
function getCategories() {
$.getJSON(path + 'GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
$('#Categories').append('<option value="9999999">Add a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].CategoryName + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].CategoryName + '</option>');
}
}
if (data.length > 0) {
if (categoryId > 0) {
$('#Categories').val(categoryId);
}
} else {
alert('Error getting Categories, please add a Category');
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
$('#AddCategoryForm').find('select').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
$('#AddCategoryForm').find('input').each(function () {
$(this).tooltip({
placement: "top",
trigger: "focus"
});
});
});
</script>
form.js (Replacement)
$(document).ready(function () {
var companyId = parseInt($('#CompanyId').val(), 0);
var categoryId = parseInt($('#CategoryId').val(), 0);
getCategories();
$('#Categories').change(function () {
var selected = $(this).find('option:selected');
categoryId = selected.val();
if (categoryId == 9999999) {
openModal();
}
$('#CategoryId').val(categoryId);
});
function getCategories() {
$.getJSON(path + 'GetCategories', { companyId: companyId }, function (data) {
$('#Categories option').remove();
$('#Categories').append('<option value="0">Please select a Category</option>');
$('#Categories').append('<option value="9999999">Add a Category</option>');
for (var i = 0; i < data.length; i++) {
if (data[i].Id != categoryId) {
$('#Categories').append('<option value="' + data[i].Id + '">' + data[i].CategoryName + '</option>');
} else {
$('#Categories').append('<option value="' + data[i].Id + '" selected>' + data[i].CategoryName + '</option>');
}
}
if (data.length > 0) {
if (categoryId > 0) {
$('#Categories').val(categoryId);
}
} else {
alert('Error getting Categories, please add a Category');
openModal();
}
}).fail(function () {
debugger;
alert('Error getting Categories, please add a Category');
});
}
function openModal() {
var companyId = $("#CompanyId").val();
var model = { CompanyId: companyId };
$.ajax({
url: "/Home/_Add/",
type: "POST",
contentType: "application/json;charset=utf-8;",
dataType: "html",
data: JSON.stringify(model),
success: function (markup) {
if (isNaN(markup) || markup == "0") {
$(document.body).append(markup);
}
}
});
}
});
BundleConfig.cs (Addition)
bundles.Add(new StyleBundle("~/Content/formValidationCss").Include(
"~/Content/formValidation.css"));
bundles.Add(new ScriptBundle("~/bundles/formValidation").Include(
"~/Scripts/formValidation.min.js",
"~/Scripts/foundationBootstrap.min.js",
"~/Scripts/foundation.min.js"));
_Layout.cshtml (Addition)
#Styles.Render("~/Content/formValidationCss")
#Scripts.Render("~/bundles/formValidation")
HomeController.cs (Addition)
public ActionResult _Add(WebApplication1.Models.Category model)
{
int id;
if (ModelState.IsValid)
{
id = _documentsRepository.SetCategory(model);
}
else
{
ModelState.Clear();
return PartialView(model);
}
return Content(id.ToString());
}
Hope this proves useful to others.

Cannot Retrieve value from html input (autocomplete jquery ui)

I have a html autocomplete textbox,my problem is when i try and enter an address eg. "New York" and click on submit button.It does not retrieve the input value.(does not return any value)
Test.aspx
<!--Address-->
<div class="form-group">
<label class="col-sm-3 control-label no-padding-right">Address</label>
<div class="col-sm-7">
<input id="tb_address" type="text" class="form-control" placeholder="Type 'a' or 'h'" />
</div>
</div>
My javascript code in Test.aspx page
<script type="text/javascript">
jQuery(function ($) {
//custom autocomplete (category selection)
$.widget("custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function (ul, items) {
var that = this,
currentCategory = "";
$.each(items, function (index, item) {
if (item.category != currentCategory) {
ul.append("<li class='ui-autocomplete-category'>" + item.category + "</li>");
currentCategory = item.category;
}
that._renderItemData(ul, item);
});
}
});
var data = [
{ label: "New York", category: "North" },
{ label: "Rochester", category: "North" },
{ label: "California", category: "North" },
];
$("#tb_address").catcomplete({
delay: 0,
source: data
});
});
</script>
protected void bn_Submit_Click(object sender, EventArgs e)
{
string address = Request.Form["tb_address"];
lb_msg.Text = address;
}
I see that your input does not have a name, adapt the input tag as follows and try again:
<input id="tb_address" name="tb_address" type="text" class="form-control" placeholder="Type 'a' or 'h'" />

Partial View not refreshing

I have a partial view on a cshtml page as follows :-
#model MvcCommons.ViewModels.CompositeViewModel
#{
ViewBag.Title = "Edit";
}
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
#Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID)
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.CategoryID, "Category")
</div>
<div class="editor-field">
#Html.DropDownListFor(model => model.ArticleViewModel.Article.CategoryID, (SelectList)ViewBag.CategoryID)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.CategoryID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleTitle)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ArticleViewModel.Article.ArticleDate)
#Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
#Html.HiddenFor(model => model.PageViewModel.Page.PageTitle, new { id = "PageTitle" })
#Html.HiddenFor(model => model.PageViewModel.Page.PageAction, new { id = "PageAction" })
#Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID, new { id = "ArticleID" })
<div class="ImageGallery">
#Html.Partial("~/Views/Shared/ImageGallery.cshtml", Model)
</div>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
The ImageGallery.cshtml Partial View is as follows :-
#model MvcCommons.ViewModels.CompositeViewModel
#{
ViewBag.Title = "Modal image uploader";
}
<script type="text/javascript">
var pageTitle = $('#PageTitle').val();
var pageAction = $('#PageAction').val();
var id = $('#ArticleID').val();
$(document).ready(function () {
$('.modal_block').click(function (e) {
$('#tn_select').empty();
$('.modal_part').hide();
});
$('#modal_link').click(function (e) {
$('.modal_part').show();
var context = $('#tn_select').load('/Upload/UploadImage?Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id, function () {
initSelect(context);
});
e.preventDefault();
return false;
});
$('#delete_images').click(function (e) {
var sList = "";
$('input[type=checkbox]').each(function () {
var sThisVal = (this.checked ? this.value : "");
sList += (sList == "" ? sThisVal : "," + sThisVal);
});
$.ajax({
url: "/Upload/DeleteImages?IDs=" + sList + '&Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id,
data: sList,
cache: false,
type: "POST",
dataType: "json"
});
reloadGallery();
return false;
});
function reloadGallery() {
$.ajax({
type: "GET",
url: '/Upload/Index/',
data: "{}",
cache: false,
dataType: "html",
success: function (data)
{ $().html(data); }
})
}
});
</script>
<div class="modal_block modal_part"></div>
<div class="modal_dialog modal_part" id="tn_select"></div>
<h2>List of images</h2>
<p>
This page contains the list of all uploaded images.
</p>
#if (Model.ImageViewModel.Images.Count > 0)
{
<div class="imageContainer">
<div class="div-table">
<div class="div-table-row-title">
<div class="div-table-col">Image</div>
<div class="div-table-col">Image Name</div>
</div>
</div>
}
</div>
<div class="DeleteImages">
Delete Selected Images.
</div>
}
else
{
<div class="imageCenter">
No images have been uploaded so far.
</div>
}
<p>
Click here to open modal dialog.
</p>
<div class="clear"></div>
Here is the code in the Controller to delete the images:-
[HttpPost]
public ActionResult DeleteImages(string IDs)
{
_Page = Request.QueryString["Page"];
_Action = Request.QueryString["Action"];
_ItemID = Convert.ToInt32(Request.QueryString["id"]);
Generics.PageIDS currentPage = (Generics.PageIDS)Enum.Parse(typeof(Generics.PageIDS), _Page);
_PageID = Convert.ToInt32(currentPage);
string[] sepImageIds = IDs.Split(',');
foreach (string strImageId in sepImageIds)
{
imageViewModel.DeleteFromXML(strImageId);
}
return RedirectToAction(_Action, _Page, new { id = _ItemID });
}
Everything works fine in this Partial View, except for when I delete an image, the deletion is done correctly, however when the code is passed back to the View, the Partial View is not refreshed.
Is there something I am missing?
Thanks for your help and time!
------------------UPDATE---------------------------------------------
This is the Edit Controller Action after the Delete has finished :-
public ActionResult Edit(int id = 0)
{
articleViewModel.Article = unitOfWork.ArticleRepository.GetByID(id);
pageViewModel.Page.PageTitle = "Article";
pageViewModel.Page.PageAction = "Edit";
if (articleViewModel.Article == null)
{
return HttpNotFound();
}
PopulateDropDownList(articleViewModel.Article.CategoryID);
viewModel.ArticleViewModel = articleViewModel;
int ImageCount = 0;
imageViewModel.Images = imageViewModel.PopulateFromXML(pageViewModel.GetPageID(_PageName), id, out ImageCount).ToList();
viewModel.ImageViewModel = imageViewModel;
viewModel.PageViewModel = pageViewModel;
return View(viewModel);
//return Json(viewModel, JsonRequestBehavior.AllowGet);
}
I think it is because all partial views are cached by default, what I would do is to create a method in the controller to return an ActionResult like so, with the output cache attribute of 0, so it does not cache
[OutputCache(Duration = 0)]
public ActionResult ImageGalleryAction()
{
// do return your cshtml name here
return PartialView("ImageGallery");
}
I would give an id to your imageGalleryDiv, change your reloadGallery method to load the partial view on onload event as well and remove the #Html.Partial like so
<script>
function reloadGallery(){
$('#myImageGallery').load("ImageGalleryAction");
}
</script>
<div id="myImageGallery" class="ImageGallery" onload="reloadGallery()">
</div>
That way, your partial view will be manually injected/refreshed via jquery and it won't be cached.
Cheers
You need to call the reloadGallery function once your DELETE ajax call succeeds, which is inside the success callback:
$.ajax({
url: '/Upload/DeleteImages?IDs=' + sList + '&Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id,
data: sList,
cache: false,
type: 'POST',
success: function(data) {
reloadGallery();
}
});
Not to mention that your DeleteImages action doesn't return any JSON, so you should remove the dataType: 'json' switch. You seem to be redirecting at the end of the DeleteImages action. Are you sure that you are redirecting to a controller action that returns a partial?
Also instead of firing yet another AJAX request in your reloadGallery method why not simply have your DeleteImages action return the partial and inside the success call update the corresponding section of your DOM using the .html method?
I think it might be in your ajax call
function reloadGallery() {
$.ajax({
type: "GET",
url: '/Upload/Index/',
data: "{}",
cache: false,
dataType: "html",
success: function (data)
{ $().html(data); }
})
}
remove the data: "{}" or replace it with data: {}

Categories