CKEditor cannot remove toolbar until I click it - javascript

I'm currently using CKEditor and I'm having some trouble removing my toolbar when I click away. Currently I want to create CKEditor instances dynamically as users click on it.
However the trouble comes up when I try to click away without clicking on the toolbar. When I try to click away on the toolbar stays there and it does not run any of my onBlur code. It's only when I click on a button the toolbar or click away and then click back to the text area will it remove the toolbar and run my onBlur code.
Right here is a small snippet of code that I wrote to create the instance when clicked. Am I doing something wrong here or am I missing a piece of focus code?
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="ckeditor\ckeditor.js"></script>
<script>
$(document).ready(function(){
CKEDITOR.disableAutoInline = true;
$("#abc").on('click', function(){
var ck = CKEDITOR.inline(CKEDITOR.document.getById('abc'));
});
});
</script>
</head>
<body>
<div id="abc" contenteditable="true" >
Edit this
</div>
</body>
</html>

Try removing the jquery on click and simply allow ckeditor to handle it
$(document).ready(function () {
CKEDITOR.disableAutoInline = true;
CKEDITOR.inline('abc');
});
OR
var abcEditor = CKEDITOR.inline('abc');

So instead of making it on click I did it so that on page load it will find all content editable areas and create ckeditor instances.
Originally I wanted to use on click to create an instance dynamically as I will be populating things dynamically. However, I found it easier to just create a ckeditor instance as I create the dynamic content.
Using this function I am able to create new ckeditor instance as the dynamic content is created and also use the onblur function to write everything to my database.
If any one has any solutions to getting the raw html from ckediter, please let me know. This method has to get the parent and then find the element and then save it, which to me doesnt sound right. So if you have any suggestions on how to do this I'm all open ears! thanks!
if(CKEDITOR.instances[this.id] == undefined){
console.log("creating new instance");
var ck = CKEDITOR.inline(CKEDITOR.document.getById( this.id ));
ck.on('blur', function(e){
var id = e.editor.name;
var html = $("#"+id).parent()[0].outerHTML;
console.log(html);
$.ajax({
type: 'POST',
url: "saveHtml",
data: { content : html}
}).done(function(data) {
console.log(data);
console.log("finished sending data");
});
});
}else{
console.log("no instance created");
}

Related

I need to update my page using Anchor (#) in URL

index.php
<html>
<head>
<title>My Title</title>
<script type="text/javascript">
function getLink(data) {
document.getElementById("box").innerHTML="This is "+data;
}
</script>
</head>
<body>
Home<br />
Profile<br />
Message<br />
Setting<br />
<hr />
<div id="box"></div>
</body>
</html>
Output
Home
Profile
Message
Setting
This is Home
As the code says my Div contents updated when i click any of the link but the problem is that when user goes back by clicking Back Button of Browser the content of my Div donot changes.
I want that either user Goes Back, Goes Forward or he directly puts the path in the address bar www.*****/index.php#profile the content of my Div should be change.
Note
I used document.location.hash to get the value of hash like this :
<head>
<script>
var hashValue=document.location.hash;
alert(hashValue);
</script>
</head>
but it works only when user goes back and then refresh the page
Plz help me how can i achieve this :(
You need to use hashchange event:
function hash_changed() {
var data = document.location.hash.substr(1);
var box = document.getElementById("box");
if (data) {
// inner page
box.innerHTML="This is " + data;
}
else {
// homepage
box.innerHTML = "";
}
}
window.onhashchange = function () {
hash_changed();
};
window.onload = function () {
hash_changed();
};
Also when you are using hashchange event, there is
no need to set onclick for your links:
Home
Profile
Message
Setting
When user click on a link, the hash automatically changes (with href attribute of link),
and hashchange event get fired.
Check DEMO here.
First Time
When a user come to your page for the first time with a hash:
http://fiddle.jshell.net/B8C8s/9/show/#message
We must show the wanted page (message here), so we must run hash_changed() function
we declare above, at first time. For this, we must wait for DOM ready or window.onload.
Check the HTML5 history API. It allows you to work with the browser history
HTML5 history api
$(window).on('hashchange', function() {
alert(location.hash);
});
or window.onhashchange event if you don't want to use jQuery
If you're going to be using AJAX, you'll really want to look into using jQuery instead of raw javascript unless your intention is educational. jQuery is just a mainstay of the web now.
If you must use those hashes...
Use jQuery Special Events, and use the hashchange event:
<a href='#home'>Home</a>
Script:
$(window).on('hashchange', function() {
$('#box').html("This is "+event.fragment);
});
However, for your scenario...
You don't need to use those # values at all as you're passing the values in your function arguments anyway according to the code you provided, just do this:
Home<br />
Alternatively (and preferably, as you're using AJAX according to the tags) you can use jQuery and its builtin selector click events which use Event Listeners:
<a href='javascript:void();' class='divLink' id='home'>Home</a><br/>
Script is this easy:
$('.divLink').click(function(){
$('#box').html("This is "+$(this).id());
}

.removeClass not functioning within .replaceWith

I'm trying to make a button that will hide a specific -- and then replace it with another hidden . However, when I test the code, everything fires correctly except for the .removeClass which contains the "display: none."
Here is the code:
<script type="text/javascript">
$(document).ready(function(){
var webform = document.getElementById('block-webform-client-block-18');
var unmarriedbutton = document.getElementById('unmarried');
var buyingblock = document.getElementById('block-block-10');
$(unmarriedbutton).click(function () {
$(buyingblock).fadeOut('slow', function() {
$(this).replaceWith(function () {
$(webform).removeClass('hiddenbox')
});
});
});
});
</script>
The CSS on 'hiddenbox' is nothing more than "display: none.'
There is a with the id of unmarried, which when clicked fades out a div and replaces it with a hidden div that removes the class to reveal it. However, the last part doesn't fire -- everything else does and functions properly. When I look at in the console too, it shows no errors.
Can someone please tell me where the error is? Thanks!
Edit: I may be using the wrong function to replace the div with, so here's the site: http://drjohncurtis.com/happily-un-married. If you click the "download the book" button, the the div disappears and is replaced correctly with the div#block-webform-client-block-18. However, it remains hidden.
The function you pass to replaceWith has to return the content you want to replace it with. You have to actually return the content.
I don't know exactly what you're trying to accomplish, but you could use this if the goal is to replace it with the webform object:
$(this).replaceWith(function () {
return($(webform).removeClass('hiddenbox'));
});
NB, use jquery !
var webform = $('#block-webform-client-block-18');
var unmarriedbutton = $('#unmarried');
var buyingblock =$('#block-block-10');
unmarriedbutton.click(function () {
buyingblock.fadeOut('slow', function() {
$(this).replaceWith( webform.removeClass('hiddenbox'));
});
});
Was too fast, i believe it's the way you select your object (getelementbyid) then you create a jquery object from it... -> use jquery API

How to update bootstrap popover text?

I am using bootstrap-popover to show a message beside an element.
If I want to show different text in the popover after the first time, the text does not change. Re instantiating the popover with new text does not overwrite.
See this js fiddle for a live example:
http://jsfiddle.net/RFzvp/1/
(The message in the alert and the message in the dom is inconsistent after the first click)
The documentation is a bit light on how to unbind: http://twitter.github.com/bootstrap/javascript.html#popovers
Am I using this wrong? The Any suggestions on how to work around?
Thanks
You can access the options directly using the jquery data closure dictionary like this:
$('a#test').data('bs.popover').options.content = 'new content';
This code should work fine even after first initializing the popover.
Hiya please see working demo here: http://jsfiddle.net/4g3Py/1/
I have made the changes to get your desired outcome. :)
I reckon you already know what you are doing but some example recommendations from my end as follows for sample: http://dl.dropbox.com/u/74874/test_scripts/popover/index.html# - sharing this link to give you idea for different link with different pop-over if you will see the source notice attribute data-content but what you wanted is working by the following changes.
Have a nice one and hope this helps. D'uh don't forget to up vote and accept the answer :)
Jquery Code
var i = 0;
$('a#test').click(function() {
i += 1;
$('a#test').popover({
trigger: 'manual',
placement: 'right',
content: function() {
var message = "Count is" + i;
return message;
}
});
$('a#test').popover("show");
});​
HTML
<a id="test">Click me</a>
​
just in-case anyone's looking for a solution that doesn't involve re-instantiating the popover and just want to change the content html, have a look at this:
$('a#test').data('popover').$tip.find(".popover-content").html("<div>some new content yo</div>")
Update: At some point between this answer being written and Bootstrap 3.2.0 (I suspect at 3.0?) this changed a little, to:
$('a#test').data('bs.popover').tip().find ............
Old question, but since I notice that the no answer provides the correct way and this is a common question, I'd like to update it.
Use the $("a#test").popover("destroy");-method. Fiddle here.
This will destroy the old popover and enable you to connect a new one again the regular way.
Here's an example where you can click a button to set a new popover on an object that already has a popover attached. See fiddle for more detail.
$("button.setNewPopoverContent").on("click", function(e) {
e.preventDefault();
$(".popoverObject").popover("destroy").popover({
title: "New title"
content: "New content"
);
});
The question is more than one year old, but maybe this would be usefull for others.
If the content is only changed while the popover is hidden, the easiest way I've found is using a function and a bit of JS code.
Specifically, my HTML looks like:
<input id="test" data-toggle="popover"
data-placement="bottom" data-trigger="focus" />
<div id="popover-content" style="display: none">
<!-- Hidden div with the popover content -->
<p>This is the popover content</p>
</div>
Please note no data-content is specified. In JS, when the popover is created, a function is used for the content:
$('test').popover({
html: true,
content: function() { return $('#popover-content').html(); }
});
And now you can change anywhere the popover-content div and the popover will be updated the next time is shown:
$('#popover-content').html("<p>New content</p>");
I guess this idea will also work using plain text instead of HTML.
On Boostrap 4 it is just one line:
$("#your-element").attr("data-content", "your new popover content")
You can always directly modify the DOM:
$('a#test').next(".popover").find(".popover-content").html("Content");
For example, if you want a popover that will load some data from an API and display that in the popover's content on hover:
$("#myPopover").popover({
trigger: 'hover'
}).on('shown.bs.popover', function () {
var popover = $(this);
var contentEl = popover.next(".popover").find(".popover-content");
// Show spinner while waiting for data to be fetched
contentEl.html("<i class='fa fa-spinner fa-pulse fa-2x fa-fw'></i>");
var myParameter = popover.data('api-parameter');
$.getJSON("http://ipinfo.io/" + myParameter)
.done(function (data) {
var result = '';
if (data.org) {
result += data.org + '<br>';
}
if (data.city) {
result += data.city + ', ';
}
if (data.region) {
result += data.region + ' ';
}
if (data.country) {
result += data.country;
}
if (result == '') {
result = "No info found.";
}
contentEl.html(result);
}).fail(function (data) {
result = "No info found.";
contentEl.html(result);
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
Hover here for details on IP 151.101.1.69
This assumes that you trust the data supplied by the API. If not, you will need to escape the data returned to mitigate XSS attacks.
Learn't from previous answers
let popOverOptions = {
trigger: 'click',
...
};
// save popOver instance
let popOver = $(`#popover-unique-id`).popover(popOverOptions);
// get its data
let popOverData = popOver.data('bs.popover');
// load data dynamically (may be with AJAX call)
$(`#popover-unique-id`).on('shown.bs.popover', () => {
setTimeout(() => {
// set content, title etc...
popOverData.config.content = 'content/////////';
// updata the popup in realtime or else this will be shown next time opens
popOverData.setContent();
// Can add this if necessary for position correction:
popOver._popper.update();
}, 2000);
});
This way we can update popover content easily.
There's another way using destroy method.
http://jsfiddle.net/bj5ryvop/5/
Bootstrap 5.0 update
let popoverInstance = new bootstrap.Popover($('#element'));
And then:
popoverInstance._config.content = "Hello world";
popoverInstance.setContent();
(Caution: it will update popover content globally, so if you have multiple open popovers then they all will be updated with "Hello world")
I found Bootstrap popover content cannot changed dynamically which introduces the setContent function. My code (hopefully helpful to someone) is therefore:
(Noting that jquery data() isn't so good at setting as it is getting)
// Update basket
current = $('#basketPopover').data('content');
newbasket = current.replace(/\d+/i,parseInt(data));
$('#basketPopover').attr('data-content',newbasket);
$('#basketPopover').setContent();
$('#basketPopover').$tip.addClass(popover.options.placement);
if jQuery > 4.1 use
$("#popoverId").popover("dispose").popover({
title: "Your new title"
content: "Your new content"
);
Bootstrap 5.1
I tried about 8 different ways to change the content for my Bootstrap 5.1 project, but none worked. I could see the values in the underlying popover object and could change them, but they didn't show on the page.
I got it going by first using the Bootstrap Popover's selector option, which the docs don't explain that well, but basically amounts to putting a watch on the page, so if new popover elements are added to the page (with the selector) they will become popovers automatically.
$(function() {
// set up all popovers
new bootstrap.Popover(document.body, {selector: 'has-popover');
})
then in my ajax call where some different content has been fetched, I remove the existing popover div, change the attribute with the text, and add it again:
var $pop = $('#pop_id1234')
var html = $pop[0].outerHTML // save the HTML
$pop.remove()
var $new = $(html).attr('data-bs-content',popoverText) // data('bs-content') becomes bsContent which won't work
$('#pop-container').append($new)

ASP MVC view added with ajax - isn't visible in browser page source

This problem drive me nuts for two days.
I have strongly typed view with text area. User can write comment in that area. After button click I save comment and return view from action method with comment id and comment text. Returned view I add to div called "messages" and it works. Comments saved, View returned, Display fine but when I right click in browser for page source div "Messages" is empty.
This thing makes me problem. Each comment has edit button and if there is 5 comments in messages div when I click edit I got edit function called 5 times. But when I hard code HTML with comments in div messages it works. But when I ajaxify page nothing works as it should.
Here is the code:
<script>
$(function () {
$('#addMessageForm').submit(function () {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#messages').prepend($(result).fadeIn('slow'));
}
});
return false;
});
});
</script>
#using (Html.BeginForm("AddMessage", "Comment", FormMethod.Post, new { id = "addMessageForm" }))
{
#Html.TextAreaFor(a => a.CommentText);
<input type="submit" value="Submit Comment" />
}
<div id="messages">
</div>
This is add comment Action Method:
[HttpPost]
public ActionResult AddMessage(CommentModel model)
{
model.Author = "Vlada Vucetic";
Random r = new Random();
int n = r.Next(1, 1000000);
model.CommentId = n;
return View("CommentView", model);
}
This is what happen when I click edit button. But as I said when I add hard code comment div in div messages and click edit it called only once. I have no idea what is happen here? Why page source doesn't display anything in browser...
This is comment view. This is what I add to div messages.
#model Demo_AjaxPosting.Models.CommentModel
#{
Layout = null;
}
<script src="../../json2.js" type="text/javascript"></script>
<script>
$('.editButton').live('click', function (e) {
e.preventDefault();
var container = $(this).closest('div'); //$(this).closest('.commentWrap');
var itemId = container.attr('id');
alert(itemId);
var nestId = '#' + itemId;
var txt = $(nestId + ' #commentTextValue').text();
$(nestId + ' #commentTextValue').remove();
$(nestId + ' #editButton').remove();
$(nestId).prepend('<textarea id="editArea">' + txt + '</textarea>');
$(nestId).append('<input type="submit" value="Ok" class="btnOk" />');
})
</script>
<div style="border: 1px solid #dddddd;">
#Html.ActionLink(#Model.Author, "SomeAction") #Model.CommentId
<div class="commentWrap" id="#Model.CommentId">
<p id="commentTextValue">#Model.CommentText</p>
<a class="editButton" href="#">Edit</a>
</div>
</div>
The page source shows the page as it is initially received from the server. The DOM is created from the source and displayed. If you later add comments to the DOM (using jQuery), it will be displayed but the page source isn't updated. So far, that's expected behavior.
If you want to inspect the HTML after comments have been added, use a tool like Firebug. It works on the DOM and nicely handles dynamic parts.
The reason your event handler is executed several times is that you add it several times. Every time a comment is added, the Ajax answer transmits (and the browser executes) a script with the following line:
$('.editButton').live('click', function (e) {
As a result, you end up having several event handlers installed. They might have identical code. But that doesn't matter. They are installed several times. So if you click the "Edit" link, several of them are executed and you get several text boxes.
The solution is to move the Javascript code (including the SCRIPT tags) out of the CommentView and into the view of the main page.

How can I dynamically create a tweet button?

I'm currently trying to create a tweet button with the horizontal count feature dynamically:
JavaScript
var twitter = document.createElement('a');
twitter.setAttribute('href', 'http://twitter.com/share');
twitter.setAttribute('class', 'twitter-share-button twitter-tweet');
twitter.setAttribute('data-url','http://mindcloud.co.uk/idea/?idea=' + this.id);
twitter.setAttribute('data-count', 'horizontal');
twitter.setAttribute('data-via', 'jtbrowncouk');
twitter.style.top = '20px';
twitter.style.left = '300px';
twitter.innerHTML = "Tweet";
The problem i'm having is that the button is being displayed as a text link, not as a button with the horizontal count box.
I've created a facebook button in the same way, which works correctly, however to make it work I use the following:
JavaScript
var facebook = document.createElement('fb:like');
facebook.setAttribute('id', 'like'+this.id);
facebook.setAttribute('href', 'http://mindcloud.co.uk/idea/?idea=' + this.id);
facebook.setAttribute('layout', 'button_count');
facebook.setAttribute('send', 'false');
facebook.setAttribute('width' , '300');
facebook.setAttribute('font', '');
facebook.setAttribute('show_faces', 'true');
facebook.style.top = '0px';
facebook.style.left = '300px';
using the following:
FB.XFBML.parse();
to parse and draw the button. FB.XFBML.parse() comes from
http://connect.facebook.net/en_US/all.js
When I create the Tweet button statically inside a .html file it works correctly. I'm including the following script within my index page where the tweet button should be created dynamically:
<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
If you can see what i'm doing incorrectly please inform me!
The following screenshot gives a visual explanation to what is going wrong with the tweet button!
Solution:
I've now managed to solve the problem. The problem i'd imagine is that the twitter script is running on load, and not being re-run upon creating the element.
using the following jQuery works correctly!
$.getScript("http://platform.twitter.com/widgets.js");
It's worth noting that as of recently you can use the following twitter widget function:
twttr.widgets.load();
Assuming you've loaded the widgets.js file:
<script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
This will dynamically re-create the tweet button for you.
I've now managed to solve the problem. The problem i'd imagine is that the twitter script is running on load, and not being re-run upon creating the element.
using the following jQuery works correctly!
$.getScript("http://platform.twitter.com/widgets.js");
You're just using the wrong code. To specify the URL, you use url, not data-url. This works:
var twitter = document.createElement('a');
twitter.setAttribute('href', 'http://twitter.com/share');
twitter.setAttribute('class', 'twitter-share-button twitter-tweet');
twitter.setAttribute('url','http://mindcloud.co.uk/idea/?idea=' + this.id);
twitter.setAttribute('data-count', 'horizontal');
twitter.setAttribute('data-via', 'jtbrowncouk');
twitter.style.top = '20px';
twitter.style.left = '300px';
twitter.innerHTML = "Tweet";
For more details, check out Twitter's documentation at https://dev.twitter.com/docs/tweet-button#properties

Categories