I'm developing a function on my website where a user should be able to edit his or hers own topic using ckeditor 5 and a textarea. The textarea is placed inside a modal. However, when I try to prefill the textarea when a user pushes a button, nothing goes inside the textarea. I have tried the following:
var editor;
ClassicEditor
.create(document.querySelector('#edit-reply-modal'))
.then(editor => {
editor = editor;
})
$(".toggle-edit-modal").click(function(e) {
e.preventDefault();
editor.setData("<p>Testing</p>"));
$("#edit-reply-modal").html("<p>Testing</p>");
});
Any help is appreciated.
I see you have one ')' more than needed editor.data.set("<p>Testing</p>"));
If you still can't set data, than try to set data like this :
editor.data.set("<p>Testing</p>");
Html :
<!-- The editable element in the editor's DOM structure. -->
<div class="... ck-editor__editable ..." contenteditable="true">
<!-- Editable content. -->
</div>
vanilla Javascript :
// A reference to the editor editable element in the DOM.
const domEditableElement = document.querySelector( '.ck-editor__editable' );
// Get the editor instance from the editable element.
const editorInstance = domEditableElement.ckeditorInstance;
// Use the editor instance API.
editorInstance.setData( '<p>Hello world!<p>' );
Docs : https://ckeditor.com/docs/ckeditor5/latest/builds/guides/faq.html
HTML Code:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.ckeditor.com/ckeditor5/24.0.0/classic/ckeditor.js"></script>
<textarea id="edit-reply-modal"><p>Old Data</p></textarea>
<button id="toggle-edit-modal">Fill New Data</button>
JAVASCRIPT Code:
let YourEditor;
ClassicEditor
.create(document.querySelector('#edit-reply-modal'))
.then(editor => {
window.editor = editor;
YourEditor = editor;
})
$('#toggle-edit-modal').on('click', function() {
YourEditor.setData('<p>This is the new Data!</p>');
})
let YourEditor;
ClassicEditor
.create(document.querySelector('#edit-reply-modal'))
.then(editor => {
window.editor = editor;
YourEditor = editor;
})
$('#toggle-edit-modal').on('click', function() {
YourEditor.setData('<p>This is the new Data!</p>');
})
button{
margin-top:20px;
padding: 5px;
color: white;
background: #00F;
border-radius: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.ckeditor.com/ckeditor5/24.0.0/classic/ckeditor.js"></script>
<textarea id="edit-reply-modal"><p>Old Data</p></textarea>
<button id="toggle-edit-modal">Fill New Data</button>
According to the documentation unlike ckeditor4 there is not any CKEDITOR.instances, so if you want to update your editor content, you can create a global instance of yor editor and then use setData() in order to update content by ajax.
Sample Code:
let myEditor;
ClassicEditor
.create(document.querySelector('#menuContent'), {
language: {
// The UI will be English.
ui: 'fa',
// But the content will be edited in Arabic.
content: 'fa'
},
placeholder: 'متن منو را وارد نمایید...'
})
.then(editor => {
window.editor = editor;
myEditor = editor;
})
.catch(err => {
console.error(err.stack);
});
function ShowMenuDetails(id) {
$.ajax({
url: '#Url.Action("MenuDetails", "Admin")',
type: 'POST',
data: JSON.stringify({ id: id }),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
cache: false,
success: function (data) {
$("#menuTitle").val(data.MenuTitle);
$("#order").val(data.MenuOrder);
myEditor.setData(data.MenuContent);
$("#myModal").modal();
},
error: function (err) {
alert(err);
},
statusCode: {
404: function (content) { alert(content); },
500: function (content) { alert(content); }
}
});
}
Related
I am playing around with React and Rails and I am working on a function to submit a post to the server, which works as intended, but then re-renders the DOM elements without refreshing the page.
I am aware I am missing a function that would get the new JSON object and map it over the DOM again but am unsure how to properly formulate this.
From my research, I would have to do a new $.ajax request on the '/posts' route, which is already set up as a JSON only render pulling all posts.
My code is below:
var New = React.createClass ({
handleClick(e) {
e.preventDefault();
let text = this.refs.text.value;
$.ajax({
url: '/new',
type: 'POST',
data: { post: { text: text} },
success: (post) => {
this.handleSubmit(post);
}
});
},
handleSubmit(post) {
console.log(post);
this.refs.text.value = ""
},
render: function() {
return( <div>
<div className="post-div">
<form>
<input className="form-control" ref='text' placeholder='Post Something' />
<button className="btn btn-primary" onClick={this.handleClick}>Submit</button>
</form>
</div>
</div>
)
}
})
and the other react file:
var Post = React.createClass ({
render: function() {
return
<div className="text-box">
<p className="text">{this.props.text}</p>
<div className="text-stamps">{this.props.timestamps}</div>
</div>;
}
})
Any help would be appreciated. Thank you.
The ReactJS introductory tutorial has exactly the same functionality explained in a great detail.
I'd definitely direct you to look at it here. And here's the section that directly does what you want. POSTing a comment to the server and re-rendering it back to the client. And it also shows how to optimistically render the new comment in the UI.
Update: Here is how you can do it. The comments are the place where you will add hooks into the server call.
var posts = [
{id: 1, text: "iPhone 7 release date"},
{id: 2, text: "Samsung 7 release date"}
];
var Post = React.createClass({
render: function(){
return (<p>{this.props.text}</p>);
}
});
var PostList = React.createClass({
render: function() {
var response = this.props.posts.map(function(post){
return (<Post text={post.text}></Post>);
});
return (<div>
{response}
</div>);
}
});
var PostForm = React.createClass({
getInitialState: function() {
return {newPost: ""};
},
handleTextChange: function(e){
this.setState({newPost: e.target.value});
},
onSubmit: function(e) {
e.preventDefault();
var newPost = this.state.newPost.trim();
if(!newPost) {
return ;
}
this.props.onAddition(newPost);
this.setState({newPost: ""})
},
render: function() {
return (
<form onSubmit={this.onSubmit}>
<h4>Add some post here</h4>
<input type="text" value={this.state.newPost} onChange={this.handleTextChange}></input>
<input type="submit" value="Add Post" />
</form>
);
}
});
var Page = React.createClass({
getInitialState: function() {
return {posts: posts};
},
onAddition: function(newPost) {
console.log("Adding new: ",newPost);
posts.push({id: Date.now(), text:newPost});
//POST to the server here and set the state if successful
this.setState({posts: posts});
},
componentDidMount: function() {
//Load from there server here
//And keep reloading it from the server every few seconds
},
render: function() {
return (
<div>
<PostForm onAddition={this.onAddition}/>
<PostList posts={this.state.posts}/>
</div>
);
}
});
var div = document.getElementById("app");
ReactDOM.render(<Page/>, div);
And here's a JSBin for this. https://jsbin.com/pokoja/edit?html,js,output
A slight modification to Kumar's answer because his solution mutates state and might be difficult for people who do not use the getInitialState function.
onAddition = (newPost) => {
const posts = [...this.state.posts]
posts.push({
_id: Date.now,
text: newPost.post
})
this.setState({
posts: posts,
postForm: {
post: ''
}
})}
In this instance, the contents of posts in state are copied (using the spread operator) and assigned to a posts constant. Then the new data is pushed into the constant, which is then set as the new state (along with the copied contents of the existing state).
I'm working through the official React tutorial and having a little trouble. When I add a comment I expect the comment to appear in the view, and for a split second it does, but then the page refreshes and the comment's gone.
On a related matter (and really just a request for a little FYI as I'm still learning AJAX), the code is supposed to add the comment to the JSON. I'm presuming that this wouldn't work on the Plunker but is there enough code there to actually update a JSON if the page is live?
Thanks for any help! Plunker link and code follows:
https://plnkr.co/edit/p76jB1W4Pizo0rDFYIwq?p=preview
<script type="text/babel">
// To get started with this tutorial running your own code, simply remove
// the script tag loading scripts/example.js and start writing code here.
var CommentBox = React.createClass({
loadCommentsFromServer: function() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
handleCommentSubmit: function(comment) {
var comments = this.state.data;
// Optimistically set an id on the new comment. It will be replaced by an
// id generated by the server. In a production application you would likely
// not use Date.now() for this and would have a more robust system in place.
comment.id = Date.now();
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: this.props.url,
dataType: 'json',
type: 'POST',
data: comment,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
},
render: function() {
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm onCommentSubmit={this.handleCommentSubmit} />
</div>
);
}
});
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function(comment) {
return (
<Comment author={comment.author} key={comment.id}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
var CommentForm = React.createClass({
getInitialState: function() {
return {author: '', text: ''};
},
handleAuthorChange: function(e) {
this.setState({author: e.target.value});
},
handleTextChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var author = this.state.author.trim();
var text = this.state.text.trim();
if (!text || !author) {
return;
}
this.props.onCommentSubmit({author: author, text: text});
this.setState({author: '', text: ''});
},
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input
type="text"
placeholder="Your name"
value={this.state.author}
onChange={this.handleAuthorChange}
/>
<input
type="text"
placeholder="Say something..."
value={this.state.text}
onChange={this.handleTextChange}
/>
<input type="submit" value="Post" />
</form>
);
}
});
var Comment = React.createClass({
rawMarkup: function() {
var md = new Remarkable();
var rawMarkup = md.render(this.props.children.toString());
return { __html: rawMarkup };
},
render: function() {
return (
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
<span dangerouslySetInnerHTML={this.rawMarkup()} />
</div>
);
}
});
ReactDOM.render(
<CommentBox url="comments.json" pollInterval={2000} />,
document.getElementById('content')
);
</script>
As you said, your problem is that the information in the json file is static (see last paragraph), so every time the comments are refreshed, you lose the new one. The way you could handle it is using the json file during the first load and then just prevent refreshing them, just adding the new ones to the comment box state (after all this is just a example and you just want to see some eye candy, don't you?).
Checking the browser's console you can see that your AJAX request to store the new file is failing, you cannot update it on Plunker, that file is immutable.
i am calling the ajax function on click of button it returns the json data and i am passing the data to the main.js script file(controller) its getting the data and binding the data to the ng-grid, the question here is whne i put the ng-grid in the from tag it does not dispaly the data
<script type="text/javascript">
$(document).ready(function () {
$("#mybutton").click(function () {
var scope = angular.element(document.getElementById("wrap")).scope(); // to get access all the varibales defined in the contoller
scope.$apply(function () {
$.ajax({
type: "POST",
url: "Website/Nggrid.asmx/GetDataForNgGrid",
success: function (result) {
// console.log(result);
var fd = JSON.parse(result); //parsing the json string
scope.updateMessage(fd);
alert("hi");
},
error: function (xmlhttprequest, Status, thrownError) {
alert(thrownError.toString());
alert(thrownError);
}
});
});
});
});
</script>
this is the function i am calling when the user clicks on button
<body ng-controller="MyCtrl">
<%--<form id="form1" runat="server">--%>
<div id="wrap" class="gridStyle" ng-grid="gridOptions">
</div>
<button id="mybutton">
Try it</button>
<%-- </form>--%>
</body>
this is the main.js
var app = angular.module('myApp', ['ngGrid']);
app.controller('MyCtrl', function ($scope) {
$scope.myData = [];
$scope.updateMessage = function (_s) {
$scope.myData = _s;
// $scope.Enable = true;
};
$scope.gridOptions = {
data: 'myData',
columnDefs: [
{ field: 'Status', displayName: 'Status', width: "*" }
]
};
});
my question is here that when i put ng-grid in the from tag it wont show the data, please give the suggestion on this
<form id="form1" runat="server">
<div id="wrap" class="gridStyle" ng-grid="gridOptions">
</div>
<button id="mybutton">
Try it</button>
</form>
I have a Kendo Grid declared inside of a Kendo Splitter like this in my partial view.
#(Html.Kendo().Splitter()
.Name("adminSplitter")
.Orientation(SplitterOrientation.Horizontal)
.Panes(p =>
{
p.Add()
.HtmlAttributes(new
{
id = "adminLeftHandPane"
})
.Resizable(false)
.Size("150px")
.Content(#<text>
#(Html.Kendo().Grid<AdministrativeTask>()
.Name("grdAdminTasks")
.ClientRowTemplate("<tr class=\"gridRow\"><td style=\"cursor:pointer\"><img src=\"#=ImageUrl#\" style=\"height: 16px; width: 16px;\" /> #=Title#</td></tr>")
.Columns(c => c.Bound(i => i.Action)
.Title("Administrative Tasks"))
.Selectable(s => s.Mode(GridSelectionMode.Single))
.DataSource(ds => ds.Ajax().Read("LoadAdministrativeTasks", "Admin").ServerOperation(false))
.Events(e => e.Change("change"))
)
</text>);
p.Add()
.HtmlAttributes(new
{
id = "adminRightHandPane"
})
.Content(#<text>
<div id="adminRightHandPaneContent"></div>
</text>)
;
}
)
)
and in this same partial view my script looks like this
<script>
function change() {
var row = this.select();
var item = this.dataItem(row);
$.ajax({
url: '/' + item.Controller + '/' + item.Action,
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
cache: false,
})
.success(function (result) {
// Display the section contents.
$('#adminRightHandPaneContent').html(result);
})
.error(function (xhr) {
$('#adminRightHandPaneContent').html("ERROR: <br><br>" + xhr.responseText);
//alert(xhr.responseText);
});
}
$(document).ready(function () {
alert($('.gridRow'));
$(".gridRow").hover(
function () {
alert("hit");
$(this).addClass("highlightRow");
},
function() {
$(this).removeClass("highlightRow");
}
);
});
When the partial view loads I get the alert "[object Object]" which tells me that Jquery found the row. However, when I hover over the row in question I do not get the "hit" alert message so at this point I am at a loss on how to proceed.
I am trying to get the row highlighted when the user hovers over the row. What am I doing wrong?
If you just want to change the styling of a row when the cursor is over the row of table, you can simply define a CSS style as:
#grid tbody tr:hover {
background: #ff0000;
}
Where grid is the id of the grid.
See if running here http://jsfiddle.net/OnaBai/uN2W5/
So you don't even need to add a CSS classes, hover function handlers,...
in generic form:
.k-grid table tr:hover td {
background :rgb(107, 188, 242) !important;
cursor: pointer !important;
}
in Q1 2016
kendo ui has in the css this line
.k-grid tr:hover{background-image:url(textures/highlight.png);background-image:none,-webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,.45)),to(rgba(255,255,255,0)));background-image:none,-webkit-linear-gradient(top,rgba(255,255,255,.45) 0,rgba(255,255,255,0) 100%);background-image:none,linear-gradient(to bottom,rgba(255,255,255,.45) 0,rgba(255,255,255,0) 100%);background-color:#88c5e0}
so it should work out of the box
.k-grid table tr.k-state-selected{background: red;color: black; }
I have a toggle button which works perfectly. The javascript and view is below:
jQuery:
$('.list-delist-link').delegate("a", "click", function (e) {
var obj = $(this);
if ($(this).hasClass('delist-property')) {
// Post to controller
e.preventDefault();
} else {
// Post to controller
e.preventDefault();
}
});
View:
<div class="list-delist-link">
#if(item.IsPropertyDisabled) {
#Html.ActionLink("List", "Enable", "Property", new { id = item.PropertyId }, new { #class="list-property other-button" })
} else {
#Html.ActionLink("Delist", "Disable", "Property", new { id = item.PropertyId }, new { #class="delist-property other-button" })
}
</div>
However, now I want to add a confirmation dialog box before the ajax action. However, everything breaks up when I am try to do that ... I am not sure why. I have the jQuery and css files on the layout page
The changes I made are listed below:
Changes to jQUery:
var obj;
$('.list-delist-link').delegate("a", "click", function (e) {
obj = $(this);
$("#dialog-confirm").dialog(open):
e.preventDefault();
});
Additional jQuery for modal confirmation:
$(function() {
$( "#dialog-confirm" ).dialog({
resizable: false, height:140, modal: true,
buttons: {
"Delete all items": function() {
if (obj.hasClass('delist-property')) {
// Post to controller
} else {
// Post to controller
}
$(this).dialog("close");
},
Cancel: function() {
$(this).dialog("close");
}
}
});
});
Additional div in View:
<div id="dialog-confirm" title="Are you sure?">
<p><span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>These items will be permanently deleted and cannot be recovered. Are you sure?</p>
</div>
Can you please tell me what is wrong?
You must add autoOpen: false, look this
$( "#dialog-confirm" ).dialog({
autoOpen : false,
resizable: false, height:140, modal: true,
buttons: {......