Show iframes in angular-xeditable editables - javascript

I'm using angular-xeditable, here is my editable element:
<div class="like-pre" editable-textarea="question.answer" e-rows="10" e-cols="40" onbeforesave="validateFaq($data, 'answer')" ng-bind-html="question.answer"></div>
In controller, I use $sce.trustAsHtml to make question.answer appear as regular HTML instead of raw text. HTML can contain iframe (for youtube videos) or img elements. It works.
Problem is that after I change anything in question.answer through the editable element, IFRAME elements disappears complately. IMG elements still appears correctly after edition.
Anyone have idea whats wrong ?

Found solution. Problem was that xeditable only updates model data. After model is updated, it update editable div element through angulars bindings. Iframe was not shown, because new model content was not signed as trusted.
I had tried pass question.answer variable through $sce.trustAsHtml in onaftersave, but it didnt do anything. Thats because trustAsHtml didnt changed anything, I suppose it just marked it as trusted (dont know how it works internally).
Solution was adding empty space like this:
$sce.trustAsHtml(newQuestion.answer + ' ');
So angular finds that model has been changed and reloads editabel div with new - trusted as html - content.

Related

Insert schema data inside html tag with javascript

I am wondering if there is a way to insert text, schema data in particular, into a html div tag using javascript. I know there are methods for modifying existing values inside a tag such as class, href, title, but can't seem to find a way to add something new.
Basically I have <div id="main"> and I want to modify it to be <div id="main" itemtype="http://schema.org/SomeCategory" itemscope> and to be able to remove it later.
The context for such a need is using fetch / js to replace parts of webpages rather than reloading the entire page. The product pages use the schema notation, whereas general info pages do not, though all templates use the "main" div.
Unbeknownst to me, the innerHTML function attached to the body tag allows me to change actual div tags using replace. So it is simple:
input ='<div id="main">';
output='<div id="main" itemtype="http://schema.org/SomeCategory" itemscope>';
document.body.innerHTML = document.body.innerHTML.replace(input,output);

JavaScript DIV Editing Destroys Functionality of Other Elements

So my website is built using a company's software called Inksoft which leaves me very little to work in the way of customization. So I have to do many workarounds.
Here is my site's homepage.
The header on top of the page only has two links right now. "Products" and "Design Studio". My goal is to add an "About Us" link and "Buyers Guide" to the header as well.
I cannot add new content to the header using Inksoft's backend. So I coded a workaround to replace the content of existing DIV's within the header to say and link to where I want them to go.
The only issue is, the responsive mobile-nav loses functionality when this is implemented. As seen here on this test page.
The test page has the About Us in the top header, added by the use of this code:
<script>
$("#header-nav-designs").html('<document.write="<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
So, the simplified question is: how do I implement this code without losing the responsive functionality of the nav bar?
The jQuery .html function will replace the HTML inside the target element. If you want to just append the one value, you likely want to .append to the element.
In addition, you aren't setting the HTML to a valid html string. You probably just want to get rid of the <document.write=" at the beginning of the string. The rest of it looks fine with just a cursory glance.
So:
<script>
$("#header-nav-designs").append('<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
Edit:
After looking at it a little more, it appears as though the $('#header-nav-designs') that you are selecting is already an <li> which means you need to either select the parent <ul> list or you can use the jquery .after function instead.
<script>
$("#header-nav-designs").after('<li id="header-nav-studio"><font color="#000000">About Us</font></li>');
</script>
And as someone else commented above, you are getting an error on the page. It appears as though you are trying to get an element with the id divID and the appending some html to it, but there is no element with the id divID and so you are getting an error saying that you can't read the property innerHTML of null as the call to document.getElementById is returning null (element not found).
Element id header-nav-designs witch your code is referring have CSS style on line 170:
#header-nav-designs {display:none;}
The element will be hidden, and the page will be displayed as if the element is not there. With display:none;
If I understand you correctly your code selector points to wrong element id. It should point $(".header-nav > ul"). Document.write is not needed inside jQuery you need to give only an valid html string as argument.
jQuery html function erase html that is all ready inside element and replace it with html string given as argument. You have to use append if you want to add more html but not remove what is allready in element.
$(".header-nav > ul").append('<li><font color="#000000">About Us</font></li>');
$(".header-nav > ul").append('<li><font color="#000000">Buyers Guide</font></li>');

Attributes in html tags and angular is not working

I´m creating application for students where the user is gonna be able to select text and highlight the text, now what i´m doing is get the selected text saved on the server to have persistent marker, in the document each paragraph is a block and each block has a id, in that way i can know where was the selection made, when i get the marker back from the server i get a list of marker per document, i use the start and end of the selection to know where i need to place the marker in the text, when i place the marker a use i create a string like this:
const markerText = `<mark class="${marker.color}"
data-marker-id="${marker.id}">${textSelected}</mark>`;
and i replaced for the one on the original text, but for some reason when replace the text only the class attribute of the mark tag appear in the html, for some reason the data-marker-id it doesn´t.
i event try to use [attr.data-marker.id]="${marker.id}"
because the paragraph(blocks of text) are coming from the server with html markup i getting the content of the block with html tags as string so i´m using
<p [innerHTML]="block.text"></p>
any idea why....?
I think angular teams dropped the $compile functionnality in Angular (2+). It is still possible to load remote html strings and put them in [innerHTML] but that is all. There is no native nor simple way to interpolate data from remote HTML.
See this post :
https://medium.com/lacolaco-blog/forget-compile-in-angular-2-a2893d8291b1

Looking for custom script (capturing inner HTML using jQuery) in Adobe DTM data element?

I am trying to capture HTML text value using jQuery in custom script of DTM data element.
See the scenario:
Below is the snippet of code on the page:
<div class="site-categories">
<ul>
<li class="mobile-tablets main">
Mobiles & Tablets
Computers
Electronics
and so on.
So basically the ask is to capture the inner HTML text of anchor tag i.e. 'Mobiles & Tablets' or 'Computers' or 'Electronics', depending upon on what link, user clicks.
To achieve this, in the event based rule section, I have set Condition as the tag to fire when class (under div tag) equals 'site-categories' and enabled bubbling on child elements (so as to cover everything under this to fire omniture tag). And then assigning the value of data element in any evar variable.
In the data element section, after selecting the custom script option, I am writing this code:
var value = $('this').html();
return value;
or
var value = jQuery('this').html();
return value;
But this is not working. I even tried using this:
var value;
_satellite.setVar('value', jQuery('this').html());
return value;
But this also didn't worked. Can I have a solution for this ? I want this to be dynamic as in, depending upon which section user is clicking on the page, the data element should capture the inner HTML text of that particular anchor tag.
Not sure where I am going wrong.
If there is any other solution that exist for this, please let me know. That would be a great help.
Thanks in advance,
Adi
Couple of notes:
Firstly on a sidenote, in your jQuery code, this should not be wrapped in quotes. You should be passing an object reference to the jQuery wrapper. Wrapping it in quotes makes it look for an html element called "this" (e.g. <this>foobar</this>) which is not right.
As to your issue.. not sure how you have setup your rule but basically what you want to do is grab the value and put it into a data element, and then reference the data element when you set the Adobe Analytics variable. So it looks like you were on the right track, and BrettAHale's answer is on the right track too, but to put it all together:
In your rule, add a condition with criteria Data > Custom. Then click "add criteria" and in the codebox, enter in:
_satellite.setVar('linkText', jQuery(this).text());
return true;
This will set a data element named "linkText", and you return true to make sure the condition is always true. You can use "value" as the name but you should use something more descriptive so you can more easily remember it's purpose later (I used "linkText").
Then, in your Adobe Analytics section of the rule, go to the eVars section and select the eVar you want to set. Then for the "set as" value, enter in %linkText%. This is a reference to the data element you just set in the rule. Don't worry if DTM shows a tooltip saying not found or w/e; it only shows/searches for known data elements you set in the interface, not on-the-fly in rules. Click the "save evar" button and you should see e.g. eVar3="%linkText%" listed (but for whatever eVar you chose).
Save and then test/publish the rule.
In the analytics tool section or your rule, set the eVar using the following, not a data element.
%this.text%
Your evar box will show something like this. eVarX="%this.text%"

How to use ng-bind-html with two-way databinding?

I'm currently working on a simple editor built with angular. The main textbox is just a div with the contenteditable set to true and the ng-bind-html attribute, like this:
<div contenteditable="true" ng-bind-html="field.content">HTML content here</div>
The value is set and rendered properly with the right tags and look at page load. But since it's only bound one way I my data or model isn't updated upon edit.
I've tried some contenteditable directivs but most of them requires ng-model, but if I add that my html tags are not rendered and converted into symbols.
How would I go about updating my data after the div's content have been changed and also keep the HTML tags and so on formatted correctly?
EDIT: Just using this temporary "fix" for the time being, but I would like something more robust.
<div contenteditable="true" ng-bind-html="field.content"
ng-blur="saveHTML($event)"></div>
$scope.saveHTML = function(event) {
this.field.content = event.target.innerHTML;
}

Categories