ASP.NET MVC C# - Pass dynamic parameter using URL ACTION - c#

How can I pass the value of my textbox "R_endDate" from my VIEW to my controller ExportToExcel function using Url.Action ?
On my View: Index.cshtml
I have this textbox with value of date.
<div class="uk-form-row">
<label class="uk-form-label" for="R_endDate">Ending Date:</label>
<div class="uk-form-controls">
#Html.TextBoxFor(m => m.R_endDate, new { #class = "uk-form-small uk-text-left required", #maxlength = 12, #data_uk_datepicker = "{format: 'MM/DD/YYYY'}" })
</div>
</div>
I have this anchor tag with url action.
Export
On my Controller: MISReportController.cs
public FileContentResult ExportToExcel()
{
byte[] filecontent = ExcelExportHelper.ExportExcel(list, "Technology", true, strAddtional);
return File(filecontent, ExcelExportHelper.ExcelContentType, strTitle);
}
my scripts
error1

You can easily handle this using javascript/jquery.
UI:
<a id="aExportToExcel" href="#" class="uk-button uk-button-small uk-text-center uk-text-small ">Export</a>
Script:
<script type="text/javascript">
$(document).ready(function () {
$("#aExportToExcel").click(function () {
var param = $("input[name='R_endDate']").val();
var _url = '#Url.Action("ExportToExcel", "MISReportController", new { param = "XXX" })'; // Param is the example parameter name. Change as needed.
_url = _url.replace("XXX", param); // _url will contain your url string so you can just play with it as needed for your requirement.
window.open(_url, "_blank");
});
});
</script>

try using html helper beginform()
in index.cshtml
#using (Html.BeginForm("ExportToExcel", "MISReport")) {<div class="uk-form-row">
<label class="uk-form-label" for="R_endDate">Ending Date:</label>
<div class="uk-form-controls">
#Html.TextBoxFor(m => m.R_endDate, new { #class = "uk-form-small uk-text-left required", #maxlength = 12, #data_uk_datepicker = "{format: 'MM/DD/YYYY'},#name="date" })</div></div>}
in the controller
[HttpPost]public FileContentResult ExportToExcel(Datetime date){ .......
}

Related

MVCGrid.NET - How to reload the grid?

I am using MVCGrid.NET http://mvcgrid.net/
And I created a Non-Fluent grid http://mvcgrid.net/gettingstarted see Non-Fluent Example
GridDefinition<YourModelItem> def = new GridDefinition<YourModelItem>();
GridColumn<YourModelItem> column = new GridColumn<YourModelItem>();
column.ColumnName = "UniqueColumnName";
column.HeaderText = "Any Header";
column.ValueExpression = (i, c) => i.YourProperty;
def.AddColumn(column);
def.RetrieveData = (options) =>
{
return new QueryResult<YourModelItem>()
{
Items = new List<YourModelItem>(),
TotalRecords = 0
};
};
MVCGridDefinitionTable.Add("NonFluentUsageExample", def);
Now I have my grid appear when you submit a form, but when I submit the form again, I am expecting new data, but the grid does not reload or refresh or anything. It does't even reset when I refresh the page, I have to do a full reload of the page to reset it, which is lame, does anyone know how to refresh or reload the grid when I want to show new data?
I have even tried this: http://mvcgrid.net/demo/NoQueryOnPageLoad
But it did not reload or refresh.
PLEASE HELP!
It reloads, try this,
//model class
public class YourModelItem
{
public int Id { get; set; }
public string YourProperty { get; set; }
}
//controller
public class HomeController : Controller
{
private static List<YourModelItem> _modelItems = new List<YourModelItem>();
public ActionResult Index()
{
GridDefinition<YourModelItem> def = new GridDefinition<YourModelItem>();
GridColumn<YourModelItem> column = new GridColumn<YourModelItem>();
column.ColumnName = "UniqueColumnName";
column.HeaderText = "Any Header";
column.ValueExpression = (i, c) => i.YourProperty;
def.AddColumn(column);
def.RetrieveData = (options) => new QueryResult<YourModelItem>()
{
Items = _modelItems,
TotalRecords = 0
};
MVCGridDefinitionTable.Add("NonFluentUsageExample", def);
return View();
}
[HttpPost]
public JsonResult Add(YourModelItem item)
{
_modelItems.Add(item);
return Json(true, JsonRequestBehavior.AllowGet);
}
}
index.cshtml
#{
ViewBag.Title = "Home Page";
}
#using MVCGrid.Web
<div class="jumbotron">
<div id="form1">
<div class="form-group">
<label for="Id">ID</label>
<input type="number" class="form-control" id="Id" aria-describedby="Id" placeholder="Enter Id">
</div>
<div class="form-group">
<label for="YourProperty">YourProperty</label>
<input type="text" class="form-control" id="YourProperty" placeholder="Enter Your Property">
</div>
<button id="addItem">Submit</button>
</div>
<br />
#Html.MVCGrid("NonFluentUsageExample")
</div>
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
$("#addItem").click(function () {
var formData = { Id: $('#Id').val(), YourProperty: $('#YourProperty').val() };
$.ajax({
type: "POST",
url: "/Home/add",
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function(data) {
if (data) {
MVCGrid.reloadGrid('NonFluentUsageExample');
}
}
});
});
});
</script>
}
_layout.cshtml -> body
<body>
<div class="container body-content">
#RenderBody()
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<script src="~/MVCGridHandler.axd/script.js"></script>
#RenderSection("scripts", required: false)
</body>
It adds item and reloads after "Submit".
Just have installed MVCGrid in new asp.net mvc - Install-Package MVCGrid.Net
Put these lines as above

How to get autocompletet textbox Locations from google API in mvc?

I am using MVC and in View i want to bind a textbox to google API to get auto complete address, How to do this in MVC??
Note: I dont want to display google maps. just textbox show suggestions .. I Did something like this
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAacPaT9YiOu-8leoacd1RDbRfx7an1u74&libraries=places&callback=initMap"
async defer></script>
<script>
google.maps.event.addDomListener(AddNewJob, 'load', function () {
var options = {
types: ['(cities)'],
componentRestrictions: { country: "in" }
};
});
autocomplete = new google.maps.places.Autocomplete(document.getElementById('FromAddress'));
autocomplete.addListener();
</script>
}
And in textBox
<div class="form-group">
#Html.LabelFor(model => model.FromAddress, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<input type="text" id="FromAddress" />
#Html.ValidationMessageFor(model => model.FromAddress, "", new { #class = "text-danger" })
</div>
</div>
var input = document.getElementById('your input tag id');
var autocomplete = new google.maps.places.Autocomplete(input);
Use javascript to do it. Follow api documentation
Check it out on jsfiddle
To do this, you'll need a Maps API Key which you can obtain here : https://developers.google.com/maps/documentation/embed/get-api-key.
Replace YOUR_API_KEY in the scripts url with the api key you obtain from the link above.
Change the id to match the id of the input element you want to attach this to. In the example below, the input element's id is "FromAddress".
And you might want to change options or remove it entirely depending on your needs as the current setting limits the auto-completion to cities in India.
#section Scripts {
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap" async="" defer=""></script>
<script>
function initMap() {
google.maps.event.addDomListener(window, 'load', function () {
var options = {
types: ['(cities)'],
componentRestrictions: { country: "in" }
};
var input = document.getElementById('FromAddress');
var places = new google.maps.places.Autocomplete(input, options);
});
}
</script>
}

Add Validation Rules Dynamically to MVC3

All,
I need to add validation rules to dynamic form input text elements added by the user.
I am accomplishing this by cloning a chunk of HTML, providing unique ids and adding to the DOM
I researched the syntax for this, which I believe is correct yet I am getting the following JS error when I try to access the .rules method:
TypeError: $(...).rules is not a function
Caused by this:
$("input[type=text].validateRequired").each(function () {
$(this).rules("add", { required: true, messages: { required: "Data is missing" }
});
});
When I examine $(this) in FireBug, I do not see a .rules method yet it exists in the validation scripts and all of the documentation shows that the method should be available globally. Not sure how to get it in scope.
Here are the code pieces in the View related to this problem:
JS Includes
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
JS Method that creates the dynamic form elements
<script type="text/javascript">
$(document).ready(function() {
var uniqueId = 1;
var ctr = 1;
$(function() {
$('.js-add-cosponsor-hyperlink').click(function() {
var copy = $("#cosponsorsTemplate").clone(true).appendTo("#addCosponsorSection").hide().fadeIn('slow');
var cosponsorDivId = 'cosponsors_' + uniqueId;
var copyText = copy.html();
copyText = copyText.replace(/Guitar1/g, 'Guitar' + ctr);
copyText = copyText.replace('Guitar_1', 'Guitar_' + ctr);
copy.html(copyText);
$('#cosponsorsTemplate').attr('id', cosponsorDivId);
var deleteLink = copy.find("a.icon.delete");
deleteLink.on('click', function() {
copy.fadeOut(300, function() { $(this).remove(); }); //fade out the removal
});
$.validator.unobtrusive.parse(form);
$("input[type=text].validateRequired").each(function () {
var t = $(this);
$(this).rules("add", { required: true, messages: { required: "Data is missing" } });
});
uniqueId++;
ctr++;
});
});
});
</script>
*The Form*
#using (Html.BeginForm())
{
[...]
<!-- Template used to do the Clone: These need dynamic validation -->
<div style="display:none">
<div id="cosponsorsTemplate">
<div class="formColumn1"><label>Guitar</label></div>
<div class="formColumn2">#Html.TextBoxFor(model => model.Guitar1.Make, new { Placeholder = "Make", Class = "validateRequired" })
<div class="messageBottom">
#Html.ValidationMessageFor(model => model.Guitar1.Make)
</div>
</div>
<div class="formColumn3">#Html.TextBoxFor(model => model.Guitar1.Model, new { Placeholder = "Model" , Class = "validateRequired"})
<div class="messageBottom">
#Html.ValidationMessageFor(model => model.Guitar1.Model)
</div>
</div>
<div class="formColumn4">#Html.TextBoxFor(model => model.Guitar1.ProductionYear, new { Placeholder = "Production Year", Class = "validateRequired" })
<div class="messageBottom">
#Html.ValidationMessageFor(model => model.Guitar1.ProductionYear)
</div><a class="icon delete">Delete</a>
</div>
</div>
</div>
<!-- End Add Co-Sponsor Row Template -->
}
You are cloning a chunk of HTML so every time you do a clone you need to parse the whole form
by using $.validator.unobtrusive.parse

Reloading partial page after jQuery ajax command

I am very new to both JQuery and Asp.net MVC 3 (C#), so I apologize if this is trivial. I have an MVC partial view (Index.cshtml) that has a list of tasks. These tasks are contained within indivudal divs that I have in a list style layout. I have a button called "add task" that opens a dialog. This dialog will save the added task to the database via an AJAX Json call to the controller.
This is where I am having trouble - after the dialog closes I would like the list of tasks to reload with the task i just added. I have found examples where the entire page is reloaded, and I found examples where the controller is supposed to return a rendered view. My problem is that the dialog is being opened from the partial I want to reload. Is there a way to accomplish what I am trying to do.
Index.cshtml
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
#foreach(var task in item.Tasks) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
</div>
</div>
}
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">All form fields are required.</p>
<form>
<fieldset>
<label for="TaskName">Task Name</label>
<input type="text" name="TaskName" id="name" class="text ui-widget-content ui-corner-all" />
<label for="TaskDescription">Task Description</label>
<input type="text" name="TaskDescription" id="description" value="" class="text ui-widget-content ui-corner-all" />
<input type="hidden" name="TaskID" id="ID" />
<input type="hidden" name="ProjectID" id="ProjectID" />
</fieldset>
</form>
</div>
Partial Javascript
function GetTask(id) {
if (id.length > 0) {
$.ajax({
url: '/Project/GetTaskFromID',
type: "POST",
data: { "id": id },
success: PopulateDialogFields,
error: HandleError
});
}
}
function PopulateDialogFields(data) {
$("#name").val(data.TaskName);
$("#description").val(data.TaskDescription);
$("#ID").val(data.TaskID);
}
function HandleError(data) {
alert(data.error);
var foo = data;
}
function SaveTask() {
var taskName = $("#name").val();
var taskDescription = $("#description").val();
var id = $("#ID").val();
var projectID = $("#ProjectID").val();
if (id.length > 0) {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
});
}
else {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "projectID": projectID }
});
}
}
$("#dialog-form").dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function () {
SaveTask();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
},
close: function () {
allFields.val("").removeClass("ui-state-error");
window.location.reload(true);
},
open: function () {
var id = $(this).data("id");
var projectID = $(this).data("projectID");
$("#ProjectID").val(projectID);
var button = $("#" + id);
GetTask(id);
}
});
$(".editTaskButton")
.button()
.click(function () {
$("#dialog-form").data('id', this.id).dialog("open");
});
$(".createTaskButton")
.button()
.click(function () {
$("#dialog-form").data('projectID', this.id).dialog("open");
});
I am relatively new to jQuery and ASP.NET MVC as well, however, here's what first comes to mind.
In order to maintain the AJAX-y aspect of the page, I suggest that you create a method that handles a POST which returns a JSON formatted set of TaskManagementApplication.Models.Project. This method can optionally return filtered results.
The markup would look like this,
<div id="ProjectAccordionWrapper">
<div id="ProjectWrapperTemplate" class="ProjectWrapper" style="display: none;">
<h3 id="itemName"></h3>
<div class="column">
<button class="createTaskButton" id="itemProjectID">Create New Task</button>
<div id="portletTemplate" class="portlet">
<div class="portlet-header" id="taskName"></div>
<div class="portlet-content" id="taskDescription"></div>
<button class="editTaskButton" id="taskID">Edit Task</button>
</div>
</div>
</div>
</div>
Next, you would have jQuery clone the ProjectWrapperTemplate element, and set all of the corresponding fields.
$(function () {
$.ajax({
url: '/Project/GetTasks',
type: "POST",
data: { }
}).done(function (data) {
data.forEach(function (element) {
AppendProjectWrapper(element);
});
});
function AppendProjectWrapper(data) {
var projectAccordionWrapper = $('#ProjectAccordionWrapper');
var projectWrapper = $('#ProjectWrapperTemplate').clone(true, true);
projectWrapper.id = nothing; // remove the id, so as to not have duplicates
projectWrapper.style.display = nothing; // remove the style "display: none"
var itemName = projectWrapper.children('#itemName'); // h3
itemName.id = nothing;
itemName.text(data.ItemName);
var itemProjectID = projectWrapper.children('#itemProjectID'); // button Create New Task
itemProjectID.id = data.ItemProjectID;
var portletTemplate = projectWrapper.children('#portletTemplate'); // div
data.Tasks.forEach(function (element) {
var portlet = portletTemplate.clone();
portlet.id = nothing;
var taskName = portlet.children('#taskName');
taskName.id = nothing;
taskName.text(element.TaskName);
var taskDescription = portlet.children('#taskDescription');
taskDescription.id = nothing;
taskDescription.text(element.TaskDescription);
var editTaskButton = portlet.children('#taskID');
editTaskButton.id = element.TaskID;
portlet.appendTo(projectWrapper);
});
portletTemplate.remove(); // remove the portlet template element
projectWrapper.appendTo(projectAccordionWrapper);
}
}
Finally, have '/Project/SaveTask' return a JSON formatted TaskManagementApplication.Models.Project of the currently saved task.
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
}).done(function (data) {
AppendProjectWrapper(data);
});
The return data for '/Project/GetTasks' should look as follows:
[
{
ItemName: '#item.Name',
ItemProjectID: '#item.ProjectID',
Tasks: [
TaskName: '#task.TaskName',
TaskDescription: '#task.TaskDescription',
TaskID: '#task.TaskID'
]
}
]
The return data from '/Project/SaveTask' should follow the same format, except or the outer-most array.
Please note that a lot of this code is untested.
It may be easiest to refactor the list into another action+view. Then, you can call this in both the original Index.cshtml view, and via the .load() method in jQuery. So, assuming this:
Projects controller
[HttpGet]
[ChildActionOnly]
public ActionResult Tasks(int id)
{
// create the appropriate model object as an IEnumerable of your Task type
return View(model);
}
Tasks.cshtml
#foreach(var task in Model) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
You would adjust Index.cshtml like so:
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
<div id="tasks-#item.ProjectID">
#Html.Action("Tasks", "Project", new { id = item.ProjectID })
</div>
</div>
</div>
}
</div>
//... the rest of the view
And finally,
// this should happen inside the callback of your .ajax() method
$('#tasks-'+projectID).load('/project/tasks/'+ projectID);

CKEditor Raw data to controller

I am using CKeditor in MVC 3 app.
Right now i am in need of saving text with HTML tags to DB, problem is that Ckeditors GetData() method returns raw format of data (http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#getData)
I need a way to make that raw format to normal string with Html tags
View :
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>TextEditionViewModel</legend>
#Html.DropDownListFor(model=>model.Id, Model.Texts)
<div class="editor-label">
#Html.LabelFor(model => model.Text)
</div>
<div class="editor-field">
#Html.TextAreaFor((model => model.Text), new { #Id = "editor1" })
#Html.ValidationMessageFor(model => model.Text)
</div>
<script type="text/javascript">
CKEDITOR.replace('editor1');
</script>
<script type="text/javascript">
var editor_data = CKEDITOR.instances['editor1'].getData();
var url = '#Url.Action("EditText1", "Admin")';
var data = { CommentText: editor_data };
function Save() {
alert(editor_data);
$.post(url, { CommentText: editor_data }, function (result) {
});
};
$('#Id').change(function () {
var selectedText = $(this).val();
if (selectedText != null && selectedText != '') {
$.getJSON('#Url.Action("Text","Admin")', { Id: selectedText }, function (text) {
CKEDITOR.instances['editor1'].setData(text);
});
}
});
</script>
</fieldset>
<p>
<input type="button" value="Save" onclick="Save()"/>
</p>
}
If editor_data is set to Normal "Text" string everything works!
Controller
public ActionResult EditText1(String CommentText)
{
return null;
}
You could decorate your controller action with the [ValidateInput] attribute to allow POSTing HTML tags which is not authorized by ASP.NET by default:
[HttpPost]
[ValidateInput(false)]
public ActionResult EditText1(string commentText)
{
return null;
}
UPDATE:
The problem is related to the fact that the editor_data variable is not accessible in the Save method.
You could do this:
<script type="text/javascript">
function Save() {
var editor_data = CKEDITOR.instances['editor1'].getData();
var url = '#Url.Action("EditText1", "Admin")';
var data = { CommentText: editor_data };
$.post(url, data, function (result) {
});
}
...
</script>

Categories

Resources