CKEditor and ASP.Net MVC 3 RequiredAttribute - asp.net-mvc

I've integrated CKEditor 3 (formerly FCKEditor) into my asp.net MVC (v3 to be specific) application. I have a RequiredAttribute in my model for the field that needs the editor but the client side validation doesn't work correctly with CKEditor. When I try to submit and I've entered data into CKEditor the required validation doesn't see the data. If I try resubmitting again, then it works. I've looked around online and can't find a solution. I am also using Jquery and using the Jquery adapter
http://docs.cksource.com/CKEditor_3.x/Developers_Guide/jQuery_Adapter

If someone is looking for a more generic way to do this you can add this javascript :
$(document).ready(function () {
if ($('.text-editor')) {
$('.text-editor').ckeditor();
$('input[type=submit]').bind('click', function() {
$('.text-editor').ckeditorGet().updateElement();
});
}
});
And use .text-editor css class on a textarea and it works just fine.
#Html.TextAreaFor(model => model.Description, new { #class = "text-editor" })
I find this solution eazyer than the other one, hope it can helps!

It is even simpler if you don't use the jQuery adapter:
$(function () {
$('input[type="submit"]').click(function () {
CKEDITOR.instances.Body.updateElement();
});
});
Where Body is the ID of the textarea.

For me this code does the trick, it could probably be optimized a bit but it works:
$('#newsForm').submit(function (event) {
var editor = $('#Body').ckeditorGet();
editor.updateElement();
$(this).validate().form();
});
Because I don't know in which order the eventhandlers for submit runs I make sure to both update the value and refresh the validation result.
EDIT: Updated solution
<script type="text/javascript">
//<![CDATA[
$(document).ready(function () {
$('#Body').ckeditor();
$('#newsForm').bind('submit', onFirstSubmit);
});
function onFirstSubmit(event) {
var editor = $('#Body').ckeditorGet();
editor.updateElement();
$(this).validate().form();
$(this).unbind('submit', onFirstSubmit).submit();
}
//]]>
</script>

I couldn't get it fixed with the above solutions, but this worked for me;
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Content/ckeditor/ckeditor.js")" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
CKEDITOR.replace("activiteit_details", { toolbar: 'Basic' });
CKEDITOR.replace("activiteit_verslag", { toolbar: 'Full' });
// Bind CKeditor fields on submit (To avoid problems with the RequiredAttribute)
$('input[type=submit]').bind('click', function () {
var CKactiviteit_details = CKEDITOR.instances.activiteit_details.getData();
$("#activiteit_details").val(CKactiviteit_details);
var CKactiviteit_verslag = CKEDITOR.instances.activiteit_verslag.getData();
$("#activiteit_verslag").val(CKactiviteit_verslag);
});
});
</script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
...
<div class="editor-label">
#Html.LabelFor(model => model.activiteit_details)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.activiteit_details)
#Html.ValidationMessageFor(model => model.activiteit_details)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.activiteit_verslag)
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.activiteit_verslag)
#Html.ValidationMessageFor(model => model.activiteit_verslag)
</div>
...
<p>
<input type="submit" value="Opslaan" />
</p>
</fieldset>

I also tried to use CKEditor but with no luck. I've been using CLEditor instead (along with the required attribute) and it works fine for me.
Ever thought of trying this instead?

Thanks for the answers.
Thanks to this post I've found my own solution which suits my case perfectly.
If you don't want to use click/mousedown event, but instead, want to trigger the validation on the right form-submit event you can use the following approach.
It doesn't use neither jQuery-Adapter CKEditor plugin nor click event.
And it's possible to apply it to all forms with ckeditor.
$('form').on('submit.ckeditorValidation', function () {
var $this = $(this);
var $ckeditor = $this.find('textarea.ckeditor');
// if no ckeditor for this form then do nothing
if (!$ckeditor || !$ckeditor.length) {
return true;
}
// update content from CKEditor to TextArea
var textAreaId = $ckeditor.attr('id');
CKEDITOR.instances[textAreaId].updateElement();
// trigger validation and check if the form is valid
if (!$this.valid()) {
return false;
}
// if form is valid then
// unsubscribe current event handler to avoid endless recursion
// and re-trigger form submit
$(this).off('submit.ckeditorValidation').submit();
return true;
});

i have been through the same issue and i was unable to resolve it because of one more issue that is related to it.
When ckeditor replaces the textarea, it makes it hidden and i found out that the default settings for jquery validator was to ignore the hidden elements with ":hidden" selector.
To resolve the issue, i have to update the hidden selector and update the element value. here is my code that does this in document ready event and is now working
$('#frmid').validate().settings.ignore = "input:hidden";
$('input[type="submit"]').click(function () {
$("#txtarea").val(CKEDITOR.instances["txtarea"].getData());
});

Related

AS NET MVC How to keep track of checkbox value using a variable

I have a following situation.
I have a variable bOk into a HTML page. I'd like to update this variable every time a checkbox.checked property was changed.
I think the best way should be using jscript but I don't know how to start this.
That is the reason I did not put a code in this question.
Is there a way to somebody to help me?
Using the onclick event, you can get the state of the checkbox with jQuery whenever it is clicked.
document.getElementById("checkbox-id").onclick = function() {
var bOk = $("#checkbox-id").is(":checked")
}
document.getElementById("checkbox-id").onclick = function() {
var bOk = $("#checkbox-id").is(":checked")
alert(bOk);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="checkbox-id"/>
<input id="chkok" type="checkbox" />Tick
#{var BOK = "Hi..";}
<input type="hidden" value=#BOK id="hdnbok">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#chkok').click(function ()
{
alert($("#hdnbok").val());
})
});

Ajax.ActionLink alternative with mvc core

In MVC5 there is #Ajax.ActionLink that is useful to update just a partial view instead of reloading the whole View. Apparently in MVC6 is not supported anymore.
I have tried using #Html.ActionLink like the following but it doesn't update the form, it return just the partial view:
View:
#Html.ActionLink("Update", "GetEnvironment", "Environments", new { id = Model.Id }, new
{
data_ajax = "true",
data_ajax_method = "GET",
data_ajax_mode = "replace",
data_ajax_update = "environment-container",
#class = "btn btn-danger"
})
control:
public async Task<ActionResult> GetEnvironment(int? id)
{
var environments = await _context.Environments.SingleOrDefaultAsync(m => m.Id == id);
return PartialView("_Environment",environments);
}
Partial view:
#model PowerPhysics.Models.Environments
this is a partial view
Then I tried using ViewComponents. When the page loads the component works correctly but I don't understand how to refresh just the component afterward (for example with a button):
View:
#Component.InvokeAsync("Environments", new { id = Model.Id }).Result
component:
public class EnvironmentsViewComponent : ViewComponent
{
public EnvironmentsViewComponent(PowerPhysics_DataContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync(int? id)
{
var environments = await _context.Environments.SingleOrDefaultAsync(m => m.Id == id);
return View(environments);
}
}
How can I update just a part of a view by using PartialViews in MVC6?
You can use a tag as follows:
<a data-ajax="true"
data-ajax-loading="#loading"
data-ajax-mode="replace"
data-ajax-update="#editBid"
href='#Url.Action("_EditBid", "Bids", new { bidId = Model.BidId, bidType = Model.BidTypeName })'
class="TopIcons">Link
</a>
Make sure you have in your _Layout.cshtml page the following script tag at the end of the body tag:
<script src="~/lib/jquery/jquery.unobtrusive-ajax/jquery.unobtrusive-ajax.js"></script>
ViewComponent's are not replacement of ajaxified links. It works more like Html.Action calls to include child actions to your pages (Ex : Loading a menu bar). This will be executed when razor executes the page for the view.
As of this writing, there is no official support for ajax action link alternative in aspnet core.
But the good thing is that, we can do the ajaxified stuff with very little jQuery/javascript code. You can do this with the existing Anchor tag helper
<a asp-action="GetEnvironment" asp-route-id="#Model.Id" asp-controller="Environments"
data-target="environment-container" id="aUpdate">Update</a>
<div id="environment-container"></div>
In the javascript code, just listen to the link click and make the call and update the DOM.
$(function(){
$("#aUpdate").click(function(e){
e.preventDefault();
var _this=$(this);
$.get(_this.attr("href"),function(res){
$('#'+_this.data("target")).html(res);
});
});
});
Since you are passing the parameter in querystring, you can use the jQuery load method as well.
$(function(){
$("#aUpdate").click(function(e){
e.preventDefault();
$('#' + $(this).data("target")).load($(this).attr("href"));
});
});
I add ajax options for Anchor TagHelper in ASP.NET MVC Core
you can see complete sample in github link :
https://github.com/NevitFeridi/AJAX-TagHelper-For-ASP.NET-Core-MVC
after using this new tagHelper you can use ajax option in anchor very easy as shown below:
<a asp-action="create" asp-controller="sitemenu" asp-area="admin"
asp-ajax="true"
asp-ajax-method="get"
asp-ajax-mode="replace"
asp-ajax-loading="ajaxloading"
asp-ajax-update="modalContent"
asp-ajax-onBegin="showModal()"
asp-ajax-onComplete=""
class="btn btn-success btn-icon-split">
<span class="icon text-white-50"><i class="fas fa-plus"></i></span>
<span class="text"> Add Menu </span>
</a>
Use tag helpers instead and make sure to include _ViewImport in your views folder.
Note: Make sure to use document.getElementsByName if there are several links pointing to different pages that will update your DIV.
Example - Razor Page
<script type="text/javascript" language="javascript">
$(function () {
var myEl = document.getElementsByName('theName');
$(myEl).click(function (e) {
e.preventDefault();
var _this = $(this);
$.get(_this.attr("href"), function (res) {
$('#' + _this.data("target")).html(res);
});
});
});
</script>
<a asp-action="Index" asp-controller="Battle" data-target="divReplacable" name="theName" >Session</a>
<a asp-action="Index" asp-controller="Peace" data-target="divReplacable" name="theName" >Session</a>
<div id="divReplacable">
Some Default Content
</div>

Why can't I change page after submitting form?

I should see: "Hello" after hitting submit, but I don't. Why?
http://jsfiddle.net/GbfLG/1/
<div data-role="page" id="create">
<script type="text/javascript">
alert("HERE");
$('#form').submit(function() {
$.post("/").success(function(resp) {
alert("RET");
$.mobile.changePage($("#final"));
});
return false;
});
</script>
<div data-role="content">
<form id="form">
<input type="submit" name="g" value="Submit" id="g"/>
</form>
</div>
</div>
<div data-role="page" id="final">
Hello
</div>​
jQM has a different set of rules then the normal web page. You have used your java script in the wrong place. With jQM, if possible write all you js code in separate file/files.
This is a fix made to your jsFiddle code, it is working now, I have just put it in right context. Your js code was not changed a bit.
Example:
$('#create').live('pagebeforeshow',function(e,data){
$('#form').submit(function() {
$.post("/").success(function(resp) {
$.mobile.changePage($("#final"));
});
return false;
});
});
Your form is submiting - the return false; isn't working as it should.
Try..
$('#form').submit(function(e) {
e.preventDefault();
e.stopPropagation();
... stuff ...
});
Also in your fiddle you haven't defined $.changePage so it comes out as 'undefined'.

MVC3 using jquery.validate.unobtrusive.js and $("#form").submit() hijax not working

I have a basic form
#Html.ValidationSummary(true)
using (Html.BeginForm("Index", "Home", FormMethod.Post, new { #class = "form" }))
{
<div class="editor-label">
<label for="Name">#Html.LabelFor(model => model.Name)</label>
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
</div>
and so on. My Model is using data annotations and validation is turned on.
I'm hijaxing the form using some jquery:
<script type="text/javascript">
$("form[action='/']").submit(function () {
$.post($(this).attr("action"), $(this).serialize(), function (response) {
$("#contactForm").replaceWith($("#contactForm", response));
});
return false;
});
</script>
This works if I type the fields in correctly and submit. But the strange thing is if I enter an invalid value into one of the form fields and the validation code kicks in to highlight my mistake the submit event function I appended in the hijaxing script above is lost and a full post happens.
Any good ideas as to how I get around this?
I think when you add a submit handler to your form you are overwriting the submit handler that the jquery validation / data annotations adds.
To get around this you can add:
var theForm = $(this);
if ( theForm.valid() ) {
$.post($(this).attr("action"), $(this).serialize(), function (response) {
$("#contactForm").replaceWith($("#contactForm", response));
});
return false;
}
This will make sure the form is valid before making the POST.

Client side validation when using Ajax/jQuery to submit an ASP.NET MVC 3 form

I am having trouble with client side validation when using Ajax and jQuery to handle a form sumission when using ASP.NET MVC 3.
Checking if the model is valid on the server side works, however the following snippet does not trigger the client side valiation.
Am I missing something?
#model ViewModels.LeadDetailModelCore
#{using (Html.BeginForm("UpdateCore", "Leads", new { area = "Telesales" }, FormMethod.Post, new { id = "coreSave" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Lead_ID)
#Html.LabelFor(model => model.LeadStatus_ID)
#Html.DropDownListFor(model => model.LeadStatus_ID, new SelectList(Model.LeadStatuses, "LeadStatus_ID", "LeadStatus_Name"), "-- Please select a status --")
#Html.ValidationMessageFor(model => model.LeadSource_ID)
}}
<script type="text/javascript">
// NOTE ADD
$(function () {
$('#coreSave').die().live("submit", function (e) {
e.preventDefault();
var form = $(this);
var val = form.validate()
if (val.valid()) {
$("#ProgressDialog").dialog("open");
// post via ajax
}
return false;
});
});
</script>
Make sure that you have included the proper scripts:
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
and that you manually parse validation for all dynamic DOM elements. So everytime you update the DOM you should register client validation if this form was not part of the DOM when you initially loaded the page:
$.validator.unobtrusive.parse($('#coreSave'));
You might also find the following answer useful for using jQuery dialog with partial views.

Resources