How to make a .cshtml pop window in ASP .NET Core MVC web application - razor

I am a newbie to programming & I am trying to make a ASP .NET Core MVC web application. There I have to upload a user profile image. To do this I should make a pop up window like in Facebook. (As an example, when user clicked on camera icon instead of going to another page, a pop window to upload image has to be appeared.)
Following is the line in the Profile.cshtml page that redirects to the UploadUserImage.cshtml page that should appear as a popup window. (that file is very large that is why I thought to publish only this line)
<a asp-action="UploadUserImage" asp-controller="UserImages"><i class="fas fa-camera camera-icon-profile"></i></a>
And following is the .cshtml file that has to be appear as popup upon clicking the above link.
UploadUserImage.cshtml
#model IEnumerable<WebApp.Models.User>
#{
Layout = "/Views/Shared/_Profile.cshtml";
ViewData["Title"] = "Upload your photo";
}
<div class="container">
<div class="row">
#using (Html.BeginForm("UploadProfilePicture", "UserImageUpload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">Upload your picture</h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<input type="file" name="file" />
<input type="submit" class="btn btn-primary form-control" value="Save Photo" />
</div>
</div>
</div>
</div>
}
</div>
}
</div>
</div>
I got to know that by a front end jQuery can be used to make the popup window appear. but I do not know how to apply it. Can please somebody let me know how to do it?
Thank you very much for your time.

Create a PartialView to your UploadPage
Search and install Magnific-Popup packages
Create a Function to call the Popup Window in the Html
<script>
function ShowPopup(idUserProfile) {
$.ajax({
type: 'POST',
url: "#Url.Action("Method", "Controller")",
data: { idUserProfile },
success: function (response) {
$.magnificPopup.open({
items: {
src: response
},
type: 'inline',
modal: true,
closeOnBgClick: false,
focus: '#btnDismiss'
});
},
error: function (xhr, ajaxOptions, thrownError) {
}
});
}
</script>
maybe you donĀ“t use the idUserProfile
In the Controller class call the partial View
public ActionResult Upload()
{
return PartialView("_UploadPage");
}
In Html to call the Function
<button class="btn btn-primary" onclick="ShowPopup()">Show Upload</button>

Related

Razor (not MVC) Modal search form

Ive seen a few examples but none that meet my requirements. I have a field called "Empno" on a form with a lookup button. I want to show a modal dialog search form to populate it. The modal itself has search fields such as company, employee name, and cost center. These modal fields are used to limit results. to get the result they click a submit button which causes a postback where the data is returned from a DB and then displayed in a table. The table has a "Select" button. I want the modal to remain open on its trip to the database and only close then the user presses select or close. I used to be able to achieve this with scriptmanager which is not available. I am using bootstrap 5.1 in a razor project on AspNetCore 5.x.
The modal needs return the company and empno(employee number) of the row which "Select" is pressed. I have the following which does work to display the webpage in a modal.
<button id="btnEmpSearch" class="btn btn-dark" data-toggle="ajax-modal" data-bs-target="#modalEmployeeSearchForm" title="Search" data-url="#Url.Page("ModalContent")"><i class="fas fa-search"></i>Search</button>
<input type="hidden" id="hfDisplayModal" asp-for="DisplayModal" />
#*Modal search forms*#
<!-- Modal -->
<div class="modal fade" id="modalEmployeeSearchForm" tabindex="-1" aria-labelledby="modalTitle" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modelTitle">Employee Search</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- pagfe will be placed here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
#section scripts {
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript">
$(function () {
$('button[data-toggle="ajax-modal"]').click(function (event) {
/*alert('button clicked');*/
event.preventDefault();//dont close when clicking search button
// url to Razor Pages handler which returns modal HTML(data-url)
var url = $(this).data('url');
$.get(url).done(function (data) {
// append HTML to document, find modal and show it
$("#modalEmployeeSearchForm").find(".modal-body").append(data);
$("#modalEmployeeSearchForm").modal({ "backdrop": "static", keyboard: false });
$("#modalEmployeeSearchForm").modal('show');
});
});
});
</script>
}
I have this partially figured out. I changed my modal as follows (Added Iframe):
Employee Search
Cancel
And I changed my script as follows:
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
/*Prevent postback on btnEmpSearch button click*/
$("#btnEmpSearch").click(function (event) {
event.preventDefault();
});
/*Show modal Dialog and load URL in it*/
$('button[data-toggle="ajax-modal"]').click(function (event) {
/*url to Razor Pages handler which returns modal HTML(data-url)*/
var url = $(this).data('url');
$.get(url).done(function (data) {
// append HTML to document, find modal and show it
/* $("#modalEmployeeSearchForm").find(".modal-body").append(data);*/
$("#RemoteContentFrame").attr("src", url);
$("#modalEmployeeSearchForm").modal({ "backdrop": "static", keyboard: false });
$("#modalEmployeeSearchForm").modal('show');
/*$("#modalEmployeeSearchForm").find("#searchEmployee").preventDefault();*/
});
});
});
</script>
}
Now I just need to figure out how to pass the selected employee number and company

MVC 5 DIV acting a widget (using Url.Action) to post form values

I'm in a bit of a quandary at the moment, to set the scene there is a dropdown list at the top of the page followed by a bunch of "clickable" DIV elements and I've made them clickable by wrapping an Action around them.
However, the issue is that none of them POST values to the controller so i cannnot read the contents of the dropdownlist. Further reading suggests it is because I am using Action which do not normally post values.
However, all examples I have found so far seem to include having a "submit" input type button but I would prefer if the DIV element can act as a button but also post values.
I guess the question is, before I ditch what I'm trying to do - is such a thing possible? Any help appreciated!
Within Form (DropDown)
<div class="row">
<span class="label label-primary">Reporting Period </span> #Html.DropDownListFor(x => x.ReportQuarterID, new SelectList(Model.ReportingQuarters, "Id", "Name", new { #class = "dropdown" }), new { #id = "ddlReportingQuarter" })
</div>
Within Form (Clickable Div)
<a href="#Url.Action("QuarterlySpendBySite", "Reports")">
<div class="col-lg-4 col-md-6 col-sm-12 col-xs-12 hvr-grow">
<div class="ibox float-e-margins">
<div class="ibox-title y-bgc-s1">
<h5>Quarterly Spend By Site</h5>
</div>
<div class="ibox-content no-padding">
</div>
</div>
</div>
</a>
Within Controller
[HttpPost]
public ActionResult QuarterlySpendBySite()
{
return View(new Test.Models.TestReporting_BL());
}
Above routine is ignored, if I remove HTTPPost it will work fine but if I try Request.Form["ddlReportingQuarter"] - it returns null.
<script type="text/javascript">
$(function() {
$('#ActionLinkId').click(function() {
var selectedVal=$("#ddlReportingQuarter option:selected").val();
$.post({
url: $('#ActionLinkId').attr('href'),
type: 'post',
data: {selectVal: selectedVal}
success: function(data) {
}
});
// prevent the default action, If not it'll redirect
return false;
});
}
</script>
And in controller make this change.
[HttpPost]
public ActionResult QuarterlySpendBySite(string selectVal)
{
return View(new Test.Models.TestReporting_BL());
}

Ajax.BeginForm rendered outside of Kendo Grid column

I face strange problem with Kendo Grid Columns.Template and Ajax.BeginForm.
I have such code
#(Html.Kendo().Grid(Model)
.Name("Monitoring")
.Columns(columns =>
{
columns.Template(#<text>
#using (Ajax.BeginForm("HardReboot", "Admin", new { id = item.Id }, new AjaxOptions
{
OnSuccess = "Loaded",
OnFailure = "Failure"
}))
{
<input class="btn btn-default" type="submit" value="Hard Reboot" />
}
</text>).Width(30);
}
))
When page is rendered the Form html tag is rendered outside column like this
<form action="/admin/hardreboot?id=1185158" data-ajax="true" data-ajax-failure="Failure" data-ajax-success="Loaded" id="form0" method="post"></form>
<div class="k-widget k-grid" id="Monitoring"><table><colgroup><col style="width:30px" /></colgroup><thead class="k-grid-header"><tr><th class="k-header" scope="col"><span class="k-link"> </span></th></tr></thead><tbody><tr><td>
<input class="btn btn-default" type="submit" value="Hard Reboot" />
</td></tr></tbody></table></div>
Any idea why?
Do a manual ajax request with jQuery.ajax() instead of putting a form because nested forms cause a problem
No idea but you can use custom commands for this.
http://demos.telerik.com/kendo-ui/grid/custom-command
A custom command renders a button (you can add styles) and calls a javascript function when pressed. In this function you can do your ajax request.

Pass $scope along with $location.Path() in AngularJS

I have two screens in my project, MemberList.HTML and EditMember.html.
MemberList.HTML displays all members with Edit link for each member.
When I click on Edit link, it calls the function ng-click="EditMember(member)" and code for EditMember(member) is
$scope.EditMember = function (member) {
var getData1 = angularService.GetMember(member.ID);
getData1.then(function (mem) {
$scope.Member = mem.data;
alert($scope.Member.FirstName);
$location.path('/members/editmember');
}, function (error)
{
alert('Error in getting Member record');
}
);
};
code for EditMember.Html
<div>
<div class="bottom-margin">
<div class="left-label">ID</div>
<div><input type="text" name="txtID" id="txtID" ng-model="Member.ID"/></div>
</div>
<div class="bottom-margin">
<div class="left-label">First Name</div>
<div><input type="text" name="txtFirstName" ng-model="Member.FirstName"/></div>
</div>
</div>
<div>
<div class="bottom-margin">
<div class="left-label"><input type="button" name="btnCancel" value="Cancel" /></div>
<div><input type="button" name="btnSave" value="Save" /></div>
</div>
</div>
Route configuration is
$routeProvider.when('/members/editmember',
{
templateUrl: '/Template/EditMember.html',
controller: 'myCntrl'
});
Now the problem is, in alert it is showing me the First Name but it is not displaying any data in EditMember.Html.
Everything is in same angular CONTROLLER, there is no different controller is used here.
How do I pass $scope with member data to EditMember.Html? What am I doing wrong?
Unlike services, controllers are not singletons in angular. When you changed the location, a new instance of that controller was created, and therefore a new scope.
Personally, I would pass a reference in the URL to the member you want to edit, e.g. /members/edit/1234, and load that data in when the controller loads, or during routing using $routerProvider resolve.
Personally, I would also consider using a different controller for editing vs viewing, and moving any shared functionality into services - just to keep things coherent.
#glennanthonyb, I did something like this....I am using the same controller here.
In route, I have added
$routeProvider.when('/members/editmember/:ID',
{
templateUrl: '/Template/EditMember.html',
controller: 'myCntrl'
});
and in the Controller I have added $routeParams parameter
if ($routeParams.ID != null) {
GetMember();
}
function GetMember() {
var getData = angularService.GetMember($routeParams.ID);
getData.then(function (mem) {
$scope.Member = mem.data;
}, function (error) {
alert('Error in getting records');
});
}
In MemberList.Html instead of calling a function, I am using href
Edit
I am not sure if it is the right way to do it or not but it is working.

MVC 5 prevent page refresh on form submit

yBrowser: IE9
Technologies: MVC5
I am mainly using Angular for everything on my page. (Single Page App).
But because I am working with IE9, I can't use FileAPI.. So, I decided to go with MVC's Form Actions to get HttpPostedFileBase in my controller methods to handle fileupload.
Html Code: (Is present in a modal)
#using (Html.BeginForm("UploadTempFileToServer", "Attachment", FormMethod.Post, new { enctype = "multipart/form-data", id = "attachmentForm" }))
{
<div>
<span id="addFiles" class="btn btn-success fileinput-button" ng-class="{disabled: disabled}" onclick="$('#fileUpload').click();">
<span>Add files...</span>
</span>
<input id="fileUpload" type="file" name="files" class="fileInput" onchange="angular.element(this).scope().fileAdded(this)" />
</div>
<div>
<span class="control-label bold">{{currentFilePath}}</span>
<input name="fileUniqueName" value="{{fileUniqueName}}" />
<input id="attachmentSubmit" type="submit" value="Upload File" />
</div>
}
MVC Controller:
public void UploadTempFileToServer(IEnumerable<HttpPostedFileBase> files, string fileUniqueName)
{
var folderPath = fileStorageFolder;
foreach (var file in files)
{
if (file.ContentLength > 0)
{
file.SaveAs(folderPath + fileUniqueName);
}
}
}
Question #1: Does anyone know of a way to send the HttpPostedFileBase data to the controller, without using form's submit action?
I don't mind using Jquery if need be. I have tried hijacking the form's submit action and that didn't work.
I tried sending the file control's data using non submit button event, but no luck there either.
If not:
Question #2 How do I prevent the page from going to /Attachment/UploadTempFileToServer after the execution of submit is completed?
To answer #2 (and assuming you're using jQuery):
$(document).on('submit', '#attachmentForm', function(event){
event.preventDefault();
// everything else you want to do on submit
});
For #1, unfortunately, unless a browser supports XMLHttpRequest2 objects (which I don't believe IE9 does), you can't send file data via ajax. There are plugins that let you submit the form to a hidden iframe, though. I think Mike Alsup's Form plugin has that ability: http://malsup.com/jquery/form/#file-upload
So, after much research and attempts. This is my solution:
Using https://github.com/blueimp/jQuery-File-Upload/wiki
HTML:
Earlier I was using a hidden file upload control and triggering its click via a span. But because of security issues a file input which is opened by javascript can't be submitted by javascript too.
<div class="col-md-7">
<div class="fileupload-buttonbar">
<label class="upload-button">
<span class="btn btn-success btnHover">
<i class="glyphicon glyphicon-plus"></i>
<span>Add files...</span>
<input id="fileUpload" type="file" name="files"/>
</span>
</label>
</div>
</div>
Javascript:
$('#fileUpload').fileupload({
autoUpload: true,
url: '/Attachment/UploadTempFileToServer/',
dataType: 'json',
add: function (e, data) {
var fileName = data.files[0].name;
var ext = fileName.substr(fileName.lastIndexOf('.'), fileName.length);
var attachment = {
AttachmentName: fileName,
Extension: ext
}
var fileUniqueName = id + ext;
//Sending the custom attribute to C#
data.formData = {
fileUniqueName: fileUniqueName
}
data.submit().success(function (submitData, jqXhr) {
attachment.Path = submitData.path;
//Add the attachment to the list of attached files to show in the table.
$scope.attachmentControl.files.push(attachment);
//Since this is not a direct angular event.. Apply needs to be called for this to be bound to the view.
$scope.$apply();
}).error(function (errorData, textStatus, errorThrown) {
});
},
fail: function (data, textStatus, errorThrown) {
}
});
C#:
public virtual ActionResult UploadTempFileToServer(string fileUniqueName)
{
//Getting these values from the web.config.
var folderPath = fileStorageServer + fileStorageFolder + "\\" + tempFileFolder + "\\";
var httpPostedFileBase = this.Request.Files[0];
if (httpPostedFileBase != null)
{
httpPostedFileBase.SaveAs(folderPath + fileUniqueName);
}
return Json(new
{
path = folderPath + fileUniqueName
},
"text/html"
);
}