How do I use ACE with my ASP.NET MVC application? - javascript

I want to use the ACE online code editor in my project. How do I use it in ASP.NET MVC?
I'd like to save whatever edits are made with that editor in the database. How do I do that?

Let's assume you have a strong typed model with a property called Editor with the data in it. Now use a normal <div> to load the data:
<div id="editor"><%=Model.Editor %></div>
Now you can create an ace editor in place of the div with javascript:
<script src="src/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
window.onload = function() {
var editor = ace.edit("editor");
};
</script>
Now when you want to save the data, for instance via a form post, use something like this to bind it back to the Editor property of the model:
<%=Html.HiddenFor(m=>m.Editor, new { #id = "hidden_editor" }) %>
<!-- this is jQuery, but you can use any JS framework for this -->
<script>
$("form").submit(function () {
$("#hidden_editor").val(editor.getSession().getValue());
});
</script>
In your controller you can now save the data to the database
[HttpPost]
public ActionResult Index (IndexModel model) {
var data = model.Editor;
// save data in database
}

Here is a solution using most recent technologies (Razor/MVC/Ajax) :
$(document).ready(function() {
$("#btnSave").on("click", function () {
$.ajax({
url: '#Url.Action("YourAction", "YourController")',
type: 'POST',
data: { id: #Model.ID,
html: ace.edit("editor").getValue() },
cache: false,
success: function (response) {
alert("Changes saved.");
}
});
});
});
In Controller :
[AjaxAuthorize]
[HttpPost, ValidateInput(false)]
public ActionResult YourAction(string id, string html)
{
if (id == null || String.IsNullOrEmpty(id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
// do you stuff
}

This is how I ended up doing it in Razor Views
#model OfficeGx.Cms.Model.ClassName
<div class="form-group row">
<div class="col-lg-11">
#Html.HiddenFor(x => x.CascadingStylesHdn, new { #id = "hidden_cssEditor" })
#Html.LabelFor(x=>x.CascadingStyles)
<div id="cssEditor">#Model.CascadingStyles</div>
</div>
</div>
<div class="form-group row">
<div class="col-lg-11">
#Html.HiddenFor(x => x.JavaScriptHdn, new { #id = "hidden_jsEditor" })
#Html.LabelFor(x => x.JavaScript)
<div id="jsEditor">#Model.JavaScript</div>
</div>
</div>
<script>
var cssEditor;
var jsEditor;
window.onload = function() {
cssEditor = ace.edit("cssEditor");
cssEditor.getSession().setMode("ace/mode/css");
cssEditor.setTheme("ace/theme/twilight");
jsEditor = ace.edit("jsEditor");
jsEditor.getSession().setMode("ace/mode/javascript");
jsEditor.setTheme("ace/theme/xcode");
};
$("form").submit(function () {
$("#hidden_cssEditor").val(window.cssEditor.getSession().getValue());
$("#hidden_jsEditor").val(window.jsEditor.getSession().getValue());
});
</script>
<style>
#cssEditor, #jsEditor {
position: relative;
height: 400px
}
#Model.CascadingStyles
</style>
In my Controller Add/Edit Method
[HttpPost]
[ValidateInput(false)]
public ActionResult AddEdit(Article article, FormCollection formCollection)
{
article.CompanyId = OperatingUser.CompanyId;
article.CascadingStyles = article.CascadingStylesHdn;
article.JavaScript = article.JavaScriptHdn;

Related

ASP.Net MVC File Upload via Bootstrap Modal Dialog results redirect browser

I'm having a basic form with few text fields and a file upload controller on a bootstrap modal dialog (Bootstrap 4). below is my code:
Model:
public class DemoContent
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[RegularExpression("([0-9]+)",ErrorMessage = "Age must be numbers only")]
public int Age { get; set; }
[EmailAddress]
public string Email { get; set; }
[DataType(DataType.Upload)]
[Display(Name = "Image")]
public HttpPostedFileBase ImageUrl { get; set; }
}
JavaScript
$(function() {
$("a[data-modal=demoPopup]").on("click", function () {
$("#demoModalContent").load(this.href, function () {
$("#demoModal").modal({ keyboard: true }, "show");
$("#demoForm").submit(function () {
if ($("#demoForm").valid()) {
var files = $("ImageUrl").get(0).files;
var data = $(this).serialize();
data.append("ImageUrl", files[0]);
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$("#demoModal").modal("hide");
location.reload();
} else {
$("#MessageToClient").text(result.message);
}
},
error: function () {
$("#MessageToClient").text("The web server had an error.");
}
});
return false;
}
});
});
return false;
});
Controller:
[HttpPost]
public ActionResult Create(DemoContent model)
{
if (model.Age > 55)
{
var file = model.ImageUrl;
return Json(new { success = true });
}
else
{
return Json(new { success = false,message="Invalid Data" });
}
}
Now when i open the popup it works also when i submit the form it goes to the controller along with the file. but the problem is once the server returns the success message the popup shows that message in a blank page instead of capturing it and refreshing the current page or showing the messages. any idea why is this happening.
link to source files : https://drive.google.com/open?id=1W3H3kFEpHJWfaf7_UnJI3O5I900GxyC7
May be you wrote your javascripts function in document.ready() function,That is why it again refreshing.
Write your JavaScript code as follows:
$(function() {
$("a[data-modal=demoPopup]").on("click", function () {
$("#demoModalContent").load(this.href, function () {
$("#demoModal").modal({ keyboard: true }, "show");
$("#demoForm").submit(function (event) { // Pass the event as parameter to the function.
event.preventDefault(); // I have added these two lines
event.stopImmediatePropagation();
if ($("#demoForm").valid()) {
var files = $("ImageUrl").get(0).files;
var data = $(this).serialize();
data.append("ImageUrl", files[0]);
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$("#demoModal").modal("hide");
location.reload();
} else {
$("#MessageToClient").text(result.message);
}
},
error: function () {
$("#MessageToClient").text("The web server had an error.");
}
});
return false;
}
});
});
return false;
});
I think you should install and use Microsoft.Unobtrusive.Validation and *.Ajax, if you want your modal to be updated (I get your question like that...). With this, you can use code like the following example, which can update your modal (used this in a project a few days ago):
Modal:
#using (Ajax.BeginForm("Login", new { Controller = "Home", area = "" }, new AjaxOptions() { OnSuccess = "onSuccessLogin", HttpMethod = "POST", UpdateTargetId = "loginmodalbody"}, new { id = "loginForm" }))
{
<div class="modal-body" id="loginmodalbody">
<div class="text-danger loginfailed"></div>
<div class="container">
<div class="card border-primary mb-3" style="margin: 0 auto;">
<div class="card-body">
#Html.Partial("~/Views/Shared/Modals/LoginModalBody.cshtml")
</div>
</div>
<div class="container">
<span><a onclick="alert('Leads to pw info')" href="#">Forgot password?</a></span>
</div>
<br />
<button class="btn btn-primary btn-block buttonlogin">Login</button>
</div>
<br />
</div>
}
Modal Body:
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-lg-12 col-12">
#Html.EditorFor(model => model.EMail, new { htmlAttributes = new { #class = "form-control", placeholder = "EMail", #id = "inputemail" } })
#Html.ValidationMessageFor(model => model.EMail, "", new { #class = "text-danger", #id = "dangeremail" })
</div>
</div>
<div class="form-group">
<div class="col-lg-12 col-12">
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control", placeholder = "Passwort", #id = "inputpassword" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger", #id = "dangerpassword" })
</div>
</div>
</div>
Thus, it updates your modal body after getting data from the posting of the form - you define the id to be updated within the AjaxOptions, as shown in the above snippet.

AJAX not updating partial view

I'm currently having difficulty using Ajax to update a partial view without having to refresh the whole page. I'm using MVC and entity framework to scaffold views.
I'll try and include as much as possible to help explain myself:
I have a div which is going to be used to hold a list view of all my comments
<div id="ContainAnnouncementComments"> </div>
This div gets populated using the following:
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Custom_Scripts/BuildAnnouncement.js"></script>
#Scripts.Render("~/bundles/jqueryval")
$(document).ready(function () {
$.ajax({
url: '/Comments/BuildAnnouncementComment',
data: { AnnouncementId: #Model.AnnouncementId},
success: function (result) {
$('#ContainAnnouncementComments').html(result);
}
});
});
Which calls the BuildAnnouncementComment() method in my controller:
public ActionResult BuildAnnouncementComment(int? AnnouncementId)
{
return PartialView("_AnnouncementComment", db.Comments.ToList().Where(x => x.AnnouncementId == AnnouncementId));
}
I then have a second div container which is used to hold a text box for a user to enter some information which 'should' then update the ContainAnnouncementComments using Ajax replace call:
<div id="ContainAnnouncementCommentCreate">
#using (Ajax.BeginForm("AJAXCreate", "Comments", new { announcementId = Model.AnnouncementId }, new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "ContainAnnouncementComments"
}))
{
<div class="form-group">
#Html.AntiForgeryToken()
<div class="col-md-10">
#Html.EditorFor(model => model.Message, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Message, "", new { #class = "text-danger" })
</div>
</div>
}
</div>
The Ajax method calls the AJAXCreate method in the controller:
public ActionResult AJAXCreate(int announcementId, [Bind(Include = "CommentId, Message")] Comment comment)
{
if (ModelState.IsValid)
{
comment.UserId = User.Identity.GetUserId();
comment.AnnouncementId = announcementId;
db.Comments.Add(comment);
db.SaveChanges();
}
return PartialView("_AnnouncementComment", db.Comments.ToList());
}
From here, when running, I try to create a new comment, but when submitted, instead of the partialView being updated, all that is being displayed is the partialview.
Not sure if I've explained this properly so if i'm missing any information please let me know and i'll update accordingly.
After 3 hours of staring at my code I realised that nothing was actually wrong with the implementation and all that was wrong was I hadn't installed AJAX through the NuGet manager.
Joys.

How to use Jquery/Ajax with asp.net MVC 4 with partial view and action with model

I am new to both asp.net MVC and JQuery so be gentle.
I am trying to use a HTTP Post to update my contact form, used to send an email, using AJAX. I have seen lots of posts but what I want seems specific and I cant seem to find anything relevant.
The down low: I have a layout page which has the header, renders the body and has my footer in. My footer contains the form I want to submit. I want to submit this form without refreshing the whole page. The layout page:
<div id="footer">
#{Html.RenderAction("Footer", "Basic");}
</div>
<p id="p"></p>
I have a model for this form to send an email.
namespace SimpleMemberShip.Models
{
public class EmailModel
{
[Required, Display(Name = "Your name")]
public string FromName { get; set; }
[Required, Display(Name = "Your email"), EmailAddress]
[StringLength(100, ErrorMessage = "The email address entered is not valid")]
public string FromEmail { get; set; }
[Required]
public string Message { get; set; }
}
The footer:
<h2> footer yo !</h2>
#Html.ValidationSummary()
<fieldset>
<legend>Contact Me!</legend>
<ol>
<li>
#Html.LabelFor(m => m.FromEmail)
#Html.TextBoxFor(m => m.FromEmail)
</li>
<li>
#Html.LabelFor(m => m.FromName)
#Html.TextBoxFor(m => m.FromName)
</li>
<li>
#Html.LabelFor(m => m.Message)
#Html.TextBoxFor(m => m.Message)
</li>
</ol>
<button id="submit"> Submit </button>
</fieldset>
controller:
[ChildActionOnly]
public ActionResult Footer()
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
[HttpPost]
public ActionResult Footer(EmailModel model)
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
I want to use the model validation and everything to be the same or similar as if the form was posted normally through the server.
Edit:
My new code, which works great! but it only works once, when the button is clicked again nothing happens. Anyone know why?
<script type="text/javascript">
$("#submit").click(function () {
$("#footer").html();
var url = '#Url.Action("Footer", "Basic")';
$.post(url, { FromName: $("[name=FromName]").val(), FromEmail: $(" [name=FromEmail]").val(), Message: $("[name=Message]").val() }, function (data) {
$("#footer").html(data);
});
var name = $("[name=FromName]").val();
$("#p").text(name);
});
</script>
new Edit:
did some research and using
$("#submit").live("click",function () {
instead of
$("#submit").click(function () {
seemed to do the trick.
<script type="text/javascript">
$("#submit").live("click",function () {
$('.validation-summary-errors').remove();
var url = '#Url.Action("Footer", "Basic")';
$.post(url, { FromName: $("[name=FromName]").val(), FromEmail: $("[name=FromEmail]").val(), Message: $("[name=Message]").val() }, function (data) {
$("#footer").html(data);
});
});
</script>
ended up with this but will try the "serialize()" option next time.
controller was changed to this without the [ChildActionOnly] and works perfect now
[HttpPost]
public ActionResult Footer(EmailModel model)
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
Thank you everyone that helped!
Change the [ChildActionOnly] to [HttpGet] in the controller
You can pass model data to controller by doing the following steps
1. Get the input values on click of submit and sent to the Footer action in controller
$("#submit").click(function () {
var FromEmailValue = $('#FromEmail').val();
var FromNameValue = $('#FromName').val();
var MessageValue = $('#Message').val();
var url = '#Url.Action("Footer", "Basic")';
$.ajax({
url: urlmodel,
data: { FromName: FromNameValue, FromEmail: FromEmailValue, Message: MessageValue},
cache: false,
type: "POST",
success: function (data) {
do something here
}
error: function (reponse) {
do something here
}
});
});
In the controller
``
[HttpGet]
public ActionResult Footer()
{
return PartialView("~/Views/Shared/_Footer.cshtml");
}
[HttpPost]
public ActionResult Footer(string FromName = "", string FromEmail = "", string Message = "")
{
//for ajax request
if (Request.IsAjaxRequest())
{
do your stuff
}
}

ASP.Net MVC Scripts not working with controller's default action url. Same is working with controller/action url

When mvc application is queried with controller name alone in the url without specifying action, the page is rendered but ajax/scripts are not working, whereas the same page when queried with action in the url, is working as expected.
Not working url: http://localhost:port/Search --> Page rendering is fine but scripts are not working - Search results are not showing up
Working url: http://localhost:port/Search/Index --> Page and scripts are working as expected - Search results are showing up
C#:
public class SearchController : Controller
{
private readonly List<string> _cars;
public SearchController()
{
_cars = new List<string>{"Corolla","Camry","Civic","Land Rover","Range Rover","Polo"};
}
public ActionResult Index()
{
return View();
}
public async Task<JsonResult> GetMatchingResults(string filter)
{
var results = await Task.Run(() => GetSearchResults(filter));
return new JsonResult() { Data = results,JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
private List<string> GetSearchResults(string filter)
{
var results = _cars.Where(car => car.Contains(filter));
return results.ToList();
}
}
HTML:
<html>
<head>
#using System.Web.Optimization
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<meta name="viewport" content="width=device-width" />
<script src="~/Scripts/ApplicationScripts/SearchViewJS.js" type="text/javascript"></script>
<title>SearchView</title>
</head>
<body>
<div>
<input class="searchText" type="search" />
</div>
<div>
<input class="searchResults" type="text" />
</div>
</body>
</html>
JS:
$(document).ready(function () {
$(".searchText").on('input', function (event) {
var filter = $(event.currentTarget).val();
search(filter).then(display);
});
function search(filter) {
return $.getJSON('GetMatchingResults/', { 'filter': filter });
}
function display(result) {
$(".searchResults").val(result);
}
})
It is because of the context of
$.getJSON('GetMatchingResults/', { 'filter': filter });
In the first case that will be trying to hit /GetMatchingResults the second tries to hit /search/GetMatchingResults. A fix could be to use
$.getJSON('/search/GetMatchingResults/', { 'filter': filter });
Or even better would be to generate the path from a HTML helper that will route correctly if you update your routing rules. This would look something like
$.getJSON('#Url.Action("GetMatchingResults", "Search")', { 'filter': filter });

MVC update partial view onchange drop down list

I want to update a partial view when user changes the current value of my drop down list.
With my onchange submit, the partial view does not load in div but replaces the whole page.
How can I fix it?
view:
#using (Ajax.BeginForm("GetEnvironment", new RouteValueDictionary { { "Environment", Model.Environnements } }, new AjaxOptions() { UpdateTargetId = "ExportDiv" }))
{
#Html.DropDownListForEnum(x => x.Environnements, new { onchange = "this.form.submit();" })
}
<div id="ExportDiv">
#Html.Partial("Export")
</div>
Controller :
public PartialViewResult GetEnvironment(ExampleDto model)
{
return PartialView("Export", model);
}
Export.cshtml
It looks like triggering submit on the form causes whole page to be posted instead of AJAX behavior. Try this:
#using (Ajax.BeginForm("GetEnvironment", new RouteValueDictionary { { "Environment", Model.Environnements } }, new AjaxOptions() { UpdateTargetId = "ExportDiv" },new {id = "ajaxForm"))
{
#Html.DropDownListForEnum(x => x.Environnements, new { onchange = "submitAjaxForm()" })
}
<div id="ExportDiv">
#Html.Partial("Export")
</div>
<script type="text/javascript">
$('form#ajaxForm').submit(function(event) {
eval($(this).attr('onsubmit')); return false;
});
window.submitAjaxForm = function(){
$('form#ajaxForm').submit();
}
</script>
You need to include the scripts in thier own section if you are using it.
The result should be the same than what Ufuk suggested, but did you try simply adding return false; after this.form.submit(); ?

Categories

Resources