Reputation: 147
I have a DropDownList
where onChange
sets the content of the TextArea
which is my CKEditor
control.
When the editor is not in use I run this bit of code for onChange
:
$(".setBody").change(function() {
//
var className = "." + $(this).attr("sExternalId");
var text = $(this).val();
//
$(className).val(text);
});
I'm not very experienced with Javascript/JQuery and I just can't figure out how to perform the same using CKEditor's setData()
function. This is what I've tried:
$(".setCKBody").change(function() {
//
var className = "." + $(this).attr("sExternalId");
var text = $(this).val();
//
var editor = $(className).ckeditorGet();
editor.setData(text, function() {
alert("The content was set");
});
});
$(".setCKBody").change(function() {
//
var className = "." + $(this).attr("sExternalId");
var text = $(this).val();
//
CKEDITOR.instances[$(className)].setData(text, function() {
alert("The content was set");
});
});
Am I close? I think one of the main limitations is that I have multiple editor controls with the same id and name, only the class can tell them apart which is why I'm using that with the JQuery. I've tried working through some examples online, but I'm not sure how to apply them to this scenario - that's probably my inexperience coming through there...
Thanks.
EDIT
This is how my textarea
and dropdownlist
appears in view source:
<textarea class="editArea M3" cols="20" id="Body" name="Body" rows="5">
*some text*
</textarea>
<select class="setCKBody" id="Templates" name="Templates" sExternalId="M3">
<option value="some value">Option 1</option>
<option value="some value">Option 2</option>
</select>
The onChange
event above is triggered from the dropDownList
changing and is linked to the textArea
via the "sExternalId" attribute. I realised I used "id" as the attribute name in the example above which was in error, so I changed that.
I use this to set it as a CKEditor control:
<script>CKEDITOR.replaceAll('editArea');</script>
I have between 2 to 6 textarea
controls on the same page, created with razor like this:
@Html.TextAreaFor(m => m.Body, new { @class = "span12 editArea " + Model.ExternalId, rows = 5 })
They are contained within a partial view that is used like this:
@foreach (MailTemplateModel oTemplate in Model.Templates)
{
@Html.Partial("_MailPartial", oTemplate)
}
This is why each text area has "Body" set as the id
and name
. I think this is the heart of the problem, with there being multiple elements with the same id and name CKEditor is not able to select the correct one. I've tried to do CKEDITOR.instances["className"] but that was undefined, whereas doing CKEDITOR.instances.Body did work, but would only ever return the same value.
I'm going to restructure the way the page is created to avoid this, hopefully my issues will be solved at the same time.
Upvotes: 1
Views: 9634
Reputation: 147
My original approach to this scenario was all wrong, I had a model that contained multiple mail templates and so I rendered each one via a partial view within the same page so that the user could click to edit any one of them and the details would appear in a modal popup - within the same window. What I wanted to avoid was forcing the user to navigate to another window to edit a mail template, but this lead to multiple elements having the same id
and name
attributes which prevented me from accessing them correctly.
I've now added a list box where the user can select a template to edit, the selected template is rendered underneath and so avoids the multiple name
and id
issue. Now I know there is only ever 1 CKEditor control so I can access it in my js like this:
var editor = CKEDITOR.instances.SelectedTemplate_Body;
SelectedTemplate_Body
is the name
and id
of the element I made into a CKEditor control. The onChange
function I wrote for the dropdownlist
is now written like this:
$(document).ready(function() {
//
$(".setBody").change(function() {
//
var templateId = $(this).val();
//
$.ajax({
type: "GET",
url: msHost + "MailTemplates/UpdateBody",
data: { "templateId": templateId },
cache: false,
dataType: "text",
success: function (data) {
CKEDITOR.instances.SelectedTemplate_Body.setData(data);
}
})
});
});
The tempalteId
attribute is the value associated to the dropdownlist
selection, this lets me know which template to use for setting the content of my editor control.
MailTemplates/UpdateBody
points to a public
method in my MailTemplates
controller which runs a search on available mail templates and matches against the template Id passed in, the method then returns the body of the template as a string.
public string UpdateBody(string tempalteId)
{
TemplateQuery oQuery;
//
oQuery = new TemplateQuery();
oQuery.Execute();
foreach (MailTemplate oTemplate in oQuery.Results)
if (oTemplate.Id.Equals(templateId))
return oTemplate.Body;
//
return string.Empty;
}
This line replaces the contents of the CKEditor control with the response from the controller method.
CKEDITOR.instances.SelectedTemplate_Body.setData(data);
Thanks @Nenotlep for trying to help out, you gave me a few things to think about there.
Upvotes: 0
Reputation: 13402
Here's a few pointers.
class="foo"
if you have many things that you refer to as a group, like like here it looks like you would have many setCKBody elements you listen to for change events.id="foo"
if you have one single specific thing.CKEDITOR.instances[xxx]
<-- xxx should be a string, not a jquery object - so CKEDITOR.instances[className]
might work better (I can't say not having seen your HTML).It would help if we saw your HTML; textarea definitions and setCKBody definitions. Do you have many ckeditors and many setCKBody elements?
Upvotes: 2