CKEditor not showing in MVC - asp.net-mvc

I am unable to show the CKEditor UI, for reasons unknown at some places. In one view, it works great.. in another it does not, but uses the exact same code as the one that works. Allow me to clarify:
I am going database first, and connecting an ADO.NET Entity Data Model to a database I have running. Then I made a controller, lets call it "news" with the MVC CRUD template, linking it to my model (database). From here the views are compiled for me, and under the "Create" view I would introduce:
<div class="editor-field">
#Html.TextAreaFor(model => model.content, new { #class="ckeditor", #id="ckeditorbox"})
#Html.ValidationMessageFor(model => model.content)
</div>
where model.content is the column name in the database (read/write to DB works, so this isn't really the issue anyway). This appears as a blank space in my browser. Inspecting the page with Google Chrome I see that it gets a visibility:hidden attribute for some reason.
Now
If I were to make a new controller with no template (Empty MVC controller) and post the exact same code from the Create.cshtml view into my newly created Index.cshtml then CKEditor would display just fine. Anyone got an idea as to why this is?
I was thinking this was an issue with the ckeditor.js script not being initialized, because the initializing is placed in _Layout.cshtml as:
<script src="#Url.Content("addons/ckeditor/ckeditor.js")" type="text/javascript"></script>
However placing this in the Create.cshtml view does not work either.
Suggestions are greatly appreciated

As to why CKEditor did not appear on particular pages, I am not sure. The fix for me however was to set:
<script type="text/javascript">
CKEDITOR.replace('x');
CKEDITOR.editorConfig = function (config) {
ignoreEmptyParagraph = true;
};
in the view

Related

KendoUI ASP.Net MVC Grid - How to add row client side?

I am trying to implement a very simple grid with ability to add a new row via a toolbar button. None of the samples provided in the documentation seem to work as expected.
#model Models.MyModel
#{
ViewBag.Title = "Simple Grid";
}
<div class="container-fluid">
<div class="row"></div>
<div class="row">
<div class="col-xs-11">
#(Html.Kendo().Grid<Models.MyModel>()
.Name("myGrid")
.ToolBar(toolbar => {
toolbar.Create().Text("Add New Row");
})
.Columns(columns => {
columns.Bound(p => p.Name).Width(200);
columns.Bound(p => p.Header1).Width(100);
columns.Bound(p => p.Header2).Width(100);
})
.Scrollable()
.Editable(ed => ed.Mode(GridEditMode.InLine).CreateAt(GridInsertRowPosition.Bottom))
.HtmlAttributes(new { style = "height:350px;" })
.DataSource(ds => ds
.Custom()
.Schema(schema => schema
.Model(model => {
model.Id("Id");
model.Field("Name", typeof(string));
model.Field("Header1", typeof(string));
model.Field("Header2", typeof(string));
})
)
)
)
</div>
</div>
</div>
The above is in a simple index.chtml page which uses a layout page and injects all the jQuery and KendoUI scripts.
When the page is loaded get a JS error Unable to get property 'nodeName' of undefined or null reference
Not sure why that happens, but hitting continue, displays an empty grid as expected.
Clicking the "Add new Row" toolbar button results in another JS error (same as above)
Question:
Am I missing a configuration option on the grid? Per documentation, this is supposed to work "out of the box". All I want to achieve is a simple grid which adds a new empty row everytime I click the "Add" button.
While it can be a bit tough to see at first, using the Custom() configuration requires more than just setting the .Schema() configuration. You can refer to samples in in the Custom DataSource documentation article for references to this. Every sample has at least the Transport field defined with a read configuration set so that the DataSource knows where to read the data.
Since you're doing CRUD operations here I also recommend that you set the other transport fields (Create, Read, Update, Destroy) to ensure that you can work with your controller and communicate with your backend properly.
As a quick note, if you search around the Telerik site for the error unable to get property 'nodeName' of undefined or null reference you start to get the hint that this error is due to an incorrect configuration of a component. It's not specific to the Grid, but it does pop up from time-to-time and the issue almost always boils down to configuration options.
Now, to fix this particular issue I'd recommend working with Ajax binding rather than custom binding. Ajax binding is super simple to work with and is perfect for this kind of scenario where you want a simple Grid added to the page without the more advanced configuration that comes from working with a more advanced feature. Plus you can work with your client-side model to set up validation etc., for your server-side (no need to set the schema manually).
Or, alternatively just set the transport field configuration to valid ActionResults or URLs to push information back and forth properly.
When first implementing any new product I always recommend following documentation closely and starting off with the smaller examples and building form there. If you're looking to work with a custom data source then I say start with a bigger configuration and remove pieces until you get the minimal piece that you're looking for.

Angular.js in ASP.Net MVC -- need to reload page twice

I minimized the problem to this simple reproduction. Create new Asp.net MVC app, add Angular.js via nugget.
_Layout.cshtml:
<head>
<!-- Other stuff -->
#RenderSection("JavascriptInHead", required: false)
</head>
_Index.cshtml
#section JavascriptInHead {
<script src="~/Scripts/angular.min.js"></script>
}
<div ng-app>
{{2 + 2}}
</div>
So this works (obviously), however when I click, say About or Contact menu to reload another view and then go back to Home, I get
{{2 + 2}}
Then I click page reload two times and I get
4
Please help me understand this..
Angular bootstraps when the document loads. So if you are loading html that contains angular into your page without doing a full page refresh, you'll need to bootstrap angular manually. Try adding this script to your partial page:
angular.element(document).ready(function() {
angular.bootstrap(document);
});
btw, I for one appreciate you posting a concise example rather than 100 lines of code from your actual project. If your actual project has an app name, however, like this...
<div ng-app="myApp">
then the js you put into your partial page should look like this...
angular.element(document).ready(function() {
angular.bootstrap(document, ['myApp']);
});
Documentation for manually bootstrapping Angular can be found here: https://docs.angularjs.org/guide/bootstrap

I need an explanation about how to use Grails (with different controllers)

I'm trying to create a little and basical Twitter-like site with Grails.
Here is the main part of my project arborescence (UserCwitter handles users, MessageCwitter handles messages and GroupCwitter handles groups like followers/followings) :
I'm trying to insert a text field to write a new message in the index (here it's index_final.gsp).
So I added this piece of code (in every controller my function to create a new user/message/groupe is called save()) :
<g:form action="save">
<fieldset class="form">
<g:render template="form"/>
</fieldset>
</g:form>
But I don't know why, the form that appears is the one to create a new user and not a message.
Why and what should I do ?
Thanks for your help. Sorry if this is something really easy or even stupid, I'm really new to Grails.
From render tag documentation, related to template attribute:
Note that if the value of the template attribute starts with a '/' it
will be resolved relative to the views directory. This is useful for
sharing templates between views. Without the leading '/' it will be
first be resolved relative to the current controller's view directory
then, failing that, the top level views directory.
So you should use
<g:render template="/messageCwitter/form"/>
if you want to render form template that is in messageCwitter folder.

Serving static content to my action using MVC's convention approach

I'm looking at outsourcing some in-page help on a large web application I am creating and would like to make it really easy for this content to added to our pages when we're ready for it.
So I was thinking I could create a system where I can add text files to the same folder where an action expects it's view to be and read out the content of that file the content in that file can be passed back to the view to display. Either that or create a helper that would do the same.
Example
Controllers
HomeController.cs
Views
Home
Index.aspx
Index.txt
Index.aspx would then have access to the content in Index.txt.
How would I start going about creating this system. Are there any built in classes in .NET MVC that I could take advantage of?
A similar question was asked yesterday: Including static html file from ~/Content into ASP.NET MVC view.
Basically you can read the text from the file and include it inside your view by using File.ReadAllText so you would have something like this inside your index.aspx file
<%= File.ReadAllText(Server.MapPath("~/Views/Home/index.txt")) %>
I'd create a parallel hierarchy in the Content folder and put the files there, probably as HTML. Then you can simply load them via AJAX in the view using the parallel hierarchy convention.
Content
Help
Home
index-help.html
about-help.html
Foo
index-help.html
bar-help.html
Then in your views
<div class="help">
<noscript>
<a href='#Url.Content( "~/content/help/home/index-help.html" )'>Click for Help</a>
</noscript>
</div>
<script type="text/javascript">
$(function() {
$('.help').load( '#Url.Content( "~/content/help/home/index-help.html" )' );
});
</script>
You may also be able to extract the controller/action from RouteData in the view if your routes are consistent and move this to your _Layout.cshtml file with the path being provided by route data.
#{
var controller = ViewContext.RouteData["controller"] as string;
var action = ViewContext.RouteData["action"] as string;
var url = Url.Content( string.Format( "~/content/help/{0}/{1}-help.html", controller, action ) );
<div class="help">
<noscript>
<a href="#url>Click for Help</a>
</noscript>
</div>
<script type="text/javascript">
$(function() {
$('.help').load( "#url" );
});
</script>
}
One possible solution would be to store them as xml file instead, that are serialized from the model the view is expecting. You could then create an Action Filter populate the model being returned with the data from the XML file. I hope that helps.

Symfony - Changing templates for embedded forms

I have made a form which embedded forms to add new records in a one-to-many relationship with ajax, my question is, where do I edit the template for the embedded form? because I would assume this would be in _form.php but it doesn't seem to use that template
Thanks in advance
If your are adding fields by ajax you can do the response of the ajax with some template. For example if you have a mail field you could do:
public function executeAddMailForm($request)
{
$this->forward404unless($request->isXmlHttpRequest());
$mail = new MailForm();
//action logic...
return $this->renderPartial('addMail',array('form' => $form));
}
and make a _addMail template:
<div class="form-ajax-item">
<div class="form-ajax-label">
<?=$form['mail']->renderLabel()?>
</div>
<div class="form-ajax-field">
<?=$form['mail']->render()?>
</div>
</div>
This way you can do the ajax response using templates.
In fact it does come from the same _form partial as the main form. Form elements in symfony by default render as a table row, so this might be what is causing your confusion. Could you please tell us what you're wanting to do.
There is documentation on how to do this and a very detailed example on the symfony website see here. It's pretty in depth and can look a bit daunting but I recommend you read through it and make sure you take the time to actually understand it.

Resources