CKEDITOR On element append - javascript

I can't seem to find an event in the documentation that will trigger when a specific element has been inserted into the HTML of a textarea.
For example if the user makes text bold, I would like to trigger an event when the 'b' tag is added into the HTML; as well as any other tag.

You can use change event and check if b is present in input:
var editor = CKEDITOR.inline(element, {
resize_enabled: false,
skin: 'rich-text,' + RX_RICH_TEXT.ckeditor.skinPath,
on: {
change: function () {
var dom = this.getData();
if (dom.includes('<b>')) {
// your logic
}
},

Related

Jquery Select Dynamically added element

Several similar question exist, but after fighting with this for a day or so I feel the need to ask because the vast majority of the answers refer to adding event handlers to elements.
I am not interested in adding an event handler to the elements in question, rather I am interested in adding additional dynamic content to dynamically generated content.
The app works thusly:
load a modal form dynamically upon the click of a static element (working properly)
function loadModal(target,modalId) {
console.log("==================> loadModal() Entry");
$.ajax({
type: "GET",
url: 'http://localhost/retrieve-modal/'+modalId,
success : function (text) {
$("#"+modalId)[0].innerHTML = text;
modalSaveIntercept($("#"+modalId)[0])
},
failure : function (e) {
console.log("something is wrong");
}
})
}
Then I have a save interceptor that overrides the default save behavior of my form here this is also working properly, (I suspect because I am loading this event handler at the time of loading the modal)
function modalSaveIntercept(eventTarget) {
if(eventTarget.hasChildNodes()) {
eventTarget.childNodes.forEach(function(e) {
if(e.tagName == "FORM") {
console.log("found the form: " + e.id + " applying save override listener");
$("#"+e.id).submit(function(event){
event.preventDefault();
submitForm(e);
});
modalSaveIntercept(e)
}
});
}
}
the above attaches a listener to the form loaded into my modal and rather than firing the default behavior of a Save button click, it fires my submitForm() function which is here:
function submitForm(form) {
let payload = constructPayloadFromFormData(form);
validate(payload).then(function(v) {
console.log("response Data:");
for(let p in v) {
if(v.hasOwnProperty(p)) {
constructInvalidFeedbackForProperty(p,v[p])
}
}
});
}
this function constructs a payload from the form data (working fine) then executes another ajax call inside of validate() - I wait for the return call from ajax and then iterate through an array of validation data to confirm the form's validity. However, here is where the problem is:
function constructInvalidFeedbackForProperty(prop,e) {
let el = $("#" + "ic-role-" + prop);
console.log(el);
el.append("<div class=\"invalid-feedback\">problem</div>");
}
the problem is the append - I cannot seem to fire that method. I can select the element as the console.log(el) writes to the log the correctly identified element in my dom.
What am I doing wrong?
I have created a contrived jsfiddle for a sample of the problem. I actually believe it may be that an input field is not something you can append to... perhaps? https://jsfiddle.net/jtango/xpvt214o/987051/
Okay, I messed around with your fiddle a bit. If you inspect the input element that is created you can see that your append does work. It's just not displaying. If you are trying to edit what is in the input box then you must use val()
Here is a copy of your fiddle that will display inside the input:
$("#top").on("click", function(){
$("#form").append("<label>some label: </label><input type=\"text\" id=\"myinput\">");
});
$("#btm").on("click",function(){
$("#myinput").val("<div>I will not appear</div>");
});
As your shared https://jsfiddle.net/jtango/xpvt214o/987051/ It will not appear, this is wrong way to append any HTML element inside "input box" or any of form elements. it should allow to set only new attribute or value.
check screenshot: https://i.stack.imgur.com/4FBgn.png
So verify your below code if it's similar then it will not work:
let el = $("#" + "ic-role-" + prop);
console.log(el);
el.append("<div class=\"invalid-feedback\">problem</div>");

How to focus cursor on a stripe input element

I am trying to add in a credit card form with Stripe Elements (https://stripe.com/docs/stripe-js/reference#other-methods).
Normally I would focus on an element by doing:
$('input[type="tel"]').focus()
However, this doesn't work with the Stripe credit card input. However, the following does work:
$('input[type="tel"]').value='asdf'
So it is grabbing the correct item. How would I focus the cursor on the input item? It seems like it may be inside an iframe, even though I can write a value to it in jquery/javascript.
The element needs to be fully initialized before you can call focus(). Ensure the element is ready with a simple event handler:
element.on('ready', () => {
element.focus()
})
You should use the focus() method on the element that you created and not the div itself.
For example you can have a button that gives focus to the CVC element (assuming split fields) by doing
document.getElementById('give-focus').addEventListener('click', function () {
cardCvcElement.focus();
});
You can see this in action here: https://jsfiddle.net/4c72oyap/
let elements = stripe.elements();
let cardCvcElement = elements.create("cardCvc");
cardCvcElement.mount("#card-cvc-element");
let cvc = document.querySelector("#card-cvc-element");
cardCvcElement.addEventListener("blur", () => {
cvc.style.removeProperty("border");
});
cardCvcElement.addEventListener("focus", () => {
cvc.style.setProperty("border-color","red");
}
});
You can trigger the focus method after your element created when it's ready
Example:
var cardElement = elements.create('cardNumber', { showIcon: true, style: style, classes: elementClasses });
cardElement.mount('#card-element');
cardElement.on('ready', (e) => cardElement.focus());
If you are using Stripe-react-js SDK, here is how to focus:
<CardElement
options={CARD_ELEMENT_OPTIONS}
onReady={(e) => e.focus()}
/>
Link to official docs https://stripe.com/docs/stripe-js/react#element-components

Find and replace text without destroying click events

A client has asked for all of the trademark symbols (™ and ®) on their website to be styled in a specific way; given the quantity in which they appear—everywhere from titles to body text and navigation—we've decided to do this with JavaScript.
What we want to do is find every instance of ™ and ® in the page text (but not inside element attributes) and wrap them in <sup> tags so we can style them in CSS.
This is the code we currently have:
Trademark = {
init: function () {
$('body').contents().each(function () {
var element = $(this);
if (element.html()) {
element.html(element.html().replace(/(?![^<]+>)™/gi, '<sup class="trademark">™</sup>'));
element.html(element.html().replace(/(?![^<]+>)®/gi, '<sup class="trademark">®</sup>'));
}
});
}
}
$(function () {
Trademark.init();
})
It works well, but we're now suffering the problem that JavaScript click events aren't being registered on elements that have had their contents replaced—I'm assuming because they're being removed from the DOM when they're being manipulated.
Is there a modification to this (to the JS or regex) that will stop this from happening? Thanks!
Filter for textNodes only and replace the innerHTML of the parentNode, that way the elements themselves are never replaced and the event handlers should stay intact.
Trademark = {
init: function () {
$('*').contents().each(function() {
if (this.nodeType == 3 && this.nodeValue) {
if ( this.nodeValue.indexOf('™') != -1 || this.nodeValue.indexOf('®') != -1 ) {
this.parentNode.innerHTML = this.parentNode.innerHTML.replace(/(?![^<]+>)(™|®)/gi, '<sup class="trademark">$1</sup>');
}
}
});
}
}
FIDDLE

edit page with ckeditor

I am building a feature similar to the page customization feature of pagemodo.com. The user has to click on a label(div) in a HTML page and a CKEDITOR will load in a separate div with the label text.
Now, the ckeditor is loading with the label text but the "KeyUp" event of CKEDITOR is not firing. Only if the "KeyUp" event fires, I would be able to call another function "readAsTyped" to change the text in the label simultaneously.
You can see the working copy here http://graffiti-media.co/testing/rashmi/custom/
$(document).ready(function() {
$('.editable').click(function(){
$(this).children().each(function(index, domEle) {
createEditor($(domEle).text(), domEle);
});
});
});
var editor, html = '';
function createEditor(text1, domEle)
{
// Create a new editor inside the <div id="editor">, setting its value to html
var config = {};
ckeditor_instance = CKEDITOR.appendTo( 'editor', config, text1 );
var abc=ckeditor_instance.name;
ckeditor_instance.on('instanceCreated', function(e) {
e.editor.on('contentDom', function() {
e.editor.document.on('keyup', function(event) {
// keyup event in ckeditor
readAsTyped($('#cke_editor2'),$(domEle));
//on focus
}
);
});
});
}
function readAsTyped(obj, label) {
var typedVal = obj.val();
// set the value of characters into the label
$(label).html(typedVal);
}
Any help would be greatly appreciated.
Do you mean something like this?
http://alfonsoml.blogspot.com.es/2012/05/recipe-live-preview-of-ckeditor.html

Is there an easier way to reference the source element for an event?

I'm new to the whole JavaScript and jQuery coding but I'm currently doing this is my HTML:
<a id="tog_table0"
href="javascript:toggle_table('#tog_table0', '#hideable_table0');">show</a>
And then I have some slightly ponderous code to tweak the element:
function toggle_table(button_id, table_id) {
// Find the elements we need
var table = $(table_id);
var button = $(button_id);
// Toggle the table
table.slideToggle("slow", function () {
if ($(this).is(":hidden"))
{
button.text("show");
} else {
button.text("hide");
}
});
}
I'm mainly wondering if there is a neater way to reference the source element rather than having to pass two IDs down to my function?
Use 'this' inside the event. Typically in jQuery this refers to the element that invoked the handler.
Also try and avoid inline script event handlers in tags. it is better to hook those events up in document ready.
NB The code below assumes the element invoking the handler (the link) is inside the table so it can traverse to it using closest. This may not be the case and you may need to use one of the other traversing options depending on your markup.
$(function(){
$('#tog_table0').click( toggle_table )
});
function toggle_table() {
//this refers to the element clicked
var $el = $(this);
// get the table - assuming the element is inside the table
var $table = $el.closest('table');
// Toggle the table
$table.slideToggle("slow", function () {
$el.is(":hidden") ? $el.text("show") : $el.text("hide");
}
}
You can do this:
show
and change your javascript to this:
$('a.tableHider').click(function() {
var table = $(this.name); // this refers to the link which was clicked
var button = $(this);
table.slideToggle("slow", function() {
if ($(this).is(':hidden')) { // this refers to the element being animated
button.html('show');
}
else {
button.html('hide');
}
});
return false;
});
edit: changed script to use the name attribute and added a return false to the click handler.
I'm sure this doesn't answer your question, but there's a nifty plugin for expanding table rows, might be useful to check it out:
http://www.jankoatwarpspeed.com/post/2009/07/20/Expand-table-rows-with-jQuery-jExpand-plugin.aspx

Categories

Resources