I need to add some custom attributes into my compiled Foundation for Emails code:
<div class="row" customAttribute="value" customAttributeName="value" customAttributeId="value">
When I use Inky, I can write code like this:
<row class="xyz" customAttribute="value">
But it is stripped out of the final compilation. Is there a hint I can add to the code so that it is added back into the dist code?
In the latest release of Foundation for Email (2.2) this should be possible.
HTML attributes can now be passed to rows and columns thanks to Brandon Barringer - commit
Referenced from here: http://zurb.com/article/1439/foundation-for-emails-2-2-what-a-ruby-gem
The background to the pull request is explained by Brandon in this discussion with a good example for adding bgcolor attribute.
in node_modules/inky/lib/componentFactory.js, towards the bottom you'll see this:
// <wrapper>
case this.components.wrapper:
var classes = ['wrapper'];
if (element.attr('class')) {
classes = classes.concat(element.attr('class').split(' '));
}
return format('<table class="%s" align="center" ><tr><td class="wrapper-inner">%s</td></tr></table>', classes.join(' '), inner);
That builds the tables structure when it sees
Adding in some code to also look for the attribute bgcolor="#XXXXXX". If it finds it, it adds the value into the HTML that it outputs. If it does not find a value, it reverts to the default value from the var, which is bgcolor="". You could also put a value in there if you have a default color.
// <wrapper>
case this.components.wrapper:
var classes = ['wrapper'];
var bgcolor = ""; // corey add this line
if (element.attr('class')) {
classes = classes.concat(element.attr('class').split(' '));
}
// corey added the following statement
if (element.attr('bgcolor')) {
bgcolor = (element.attr('bgcolor'));
} // stop new statement
return format('<table class="%s" align="center" bgcolor="'+bgcolor+'"><tr><td class="wrapper-inner">%s</td></tr></table>', classes.join(' '), inner);
The inky markdown can then be written like so:
<wrapper bgcolor="#b9cd98">
Related
I'm building a simple code editor to help children learn HTML. One feature I'm trying to add is that when users mouseover their rendered code (in an iframe), the corresponding HTML code in the editor is highlighted. So, for example, if a user mouses-over an image of kittens, the actual code, , would be highlighted in the editor.
Mousing-over the iframe to get the html source for that element is the easy part, which I've done (using document.elementFromPoint(e.clientX, e.clientY in the iframe itself, and posting that up to the parent) - so that's not the part I need help with. The part I can't figure out is how to search for and highlight that string of selected code in the code editor.
I'm using Codemirror 6 for this project, as it seems as it will give me the most flexibility to create such a feature. However, as a Codemirror 6 novice, I'm struggling with the documentation to find out where I should start. It seems like the steps I need to complete to accomplish this are:
Search for a range in the editor's text that matches a string (ie.'<img src="kittens.gif"').
Highlight that range in the editor.
Can anyone out there give me some advice as to where in the Codemirror 6 API I should look to start implementing this? It seems like it should be easy, but my unfamiliarity with the Codemirror API and the terse documentation is making this difficult.
1. Search for a range in the editor's text that matches a string (ie.'<img src="kittens.gif"').
You can use SearchCursor class (iterator) to get the character's range where is located the DOM element in your editor.
// the import for SearchCursor class
import {SearchCursor} from "#codemirror/search"
// your editor's view
let main_view = new EditorView({ /* your code */ });
// will create a cursor based on the doc content and the DOM element as a string (outerHTML)
let cursor = new SearchCursor(main_view.state.doc, element.outerHTML);
// will search the first match of the string element.outerHTML in the editor view main_view.state.doc
cursor.next()
// display the range where is located your DOM element in your editor
console.log(cursor.value);
2. Highlight that range in the editor.
As described in the migration documentation here, marked text is replace by decoration. To highlight a range in the editor with codemirror 6, you need to create one decoration and apply it in a dispatch on your view. This decoration need to be provide by an extension that you add in the extensions of your editor view.
// the import for the 3 new classes
import {StateEffect, StateField} from "#codemirror/state"
import {Decoration} from "#codemirror/view"
// code mirror effect that you will use to define the effect you want (the decoration)
const highlight_effect = StateEffect.define();
// define a new field that will be attached to your view state as an extension, update will be called at each editor's change
const highlight_extension = StateField.define({
create() { return Decoration.none },
update(value, transaction) {
value = value.map(transaction.changes)
for (let effect of transaction.effects) {
if (effect.is(highlight_effect)) value = value.update({add: effect.value, sort: true})
}
return value
},
provide: f => EditorView.decorations.from(f)
});
// this is your decoration where you can define the change you want : a css class or directly css attributes
const highlight_decoration = Decoration.mark({
// attributes: {style: "background-color: red"}
class: 'red_back'
});
// your editor's view
let main_view = new EditorView({
extensions: [highlight_extension]
});
// this is where the change takes effect by the dispatch. The of method instanciate the effect. You need to put this code where you want the change to take place
main_view.dispatch({
effects: highlight_effect.of([highlight_decoration.range(cursor.value.from, cursor.value.to)])
});
Hope it will help you to implement what you want ;)
Have a look at #codemirror/search.
Specifically, the source code implementation of Selection Matching may be of use for you to adapt.
It uses Decoration.mark over a range of text.
You can use SearchCursor to iterate over ranges that match your pattern (or RegExpCursor)
Use getSearchCursor, something like this:
var cursor = cmEditor.getSearchCursor(keyword , CodeMirror.Pos(cmEditor.firstLine(), 0), {caseFold: true, multiline: true});
if(cursor.find(false)){ //move to that position.
cmEditor.setSelection(cursor.from(), cursor.to());
cmEditor.scrollIntoView({from: cursor.from(), to: cursor.to()}, 20);
}
Programmatically search and select a keyword
Take a look at getSearchCursor source code it it give some glow about how it works and its usage.
So use getSearchCursor for finding text and optionally use markText for highlighting text because you can mark text with setSelection method of editor.
Selection Marking Demo
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
styleSelectedText: true
});
editor.markText({line: 6, ch: 26}, {line: 6, ch: 42}, {className: "styled-background"});
And it seem this is what you are looking for:
codemirror: search and highlight multipule words without dialog
RegExpCursor is another option that you can use:
new RegExpCursor(
text: Text,
query: string,
options?: {ignoreCase?: boolean},
from?: number = 0,
to?: number = text.length
)
Sample usage at:
Replacing text between dollar signs for Mathml expression.
Hi I just created the ionic accordion dropdowns by following a tutorial blog link which used widgets for creating an accordion dropdowns, Below is the link of that blog.
http://masteringionic.com/blog/2019-01-27-creating-a-simple-accordion-widget-in-ionic-4/
updated: here is the my project demo link https://stackblitz.com/github/dSaif/search-accordion
Everything is working perfect, but i want to add Ion-searchbar at the top of the accordions sothat the dropdowns gets filter by inputing text.
please assist me how can i do that. Thank you.
You are going to have to create a variable in your homepage to store your filtered results. Then you need to have a filter function that will take the input from the search bar and filter your master list. Keep in mind you should not set the new variable to the master list, this could cause issues due to object referencing.
So you should have something like
in your html
<ion-searchbar placeholder="Search a name." [(ngModel)]="searchValue" (ionChange)="filterList()"></ion-searchbar>
In your ts file
searchValue: string = '';
filteredList: Array<{ name: string, description: string, image: string }> = this.technologies;
// function called in the html whenever you change the ion searchbar value
private filterList(){
//Make a variable so as to avoid any flashing on the screen if you set it to an empty array
const localFilteredList = []
this.technologies.forEach(currentItem => {
//here goes your search criteria, in the if statement
if(currentItem.name && currentItem.name.toLowerCase().includes(this.searchValue.toLowerCase())) {
localFilteredList.push(currentItem);
}
});
//finally set the global filter list to your newly filtered list
this.filteredList = localFilteredList;
}
You also need to make sure to reference the filterList variable instead of the current one you are referencing.
We're aware of that amazing trick which allows users to highlight a link. But, you must repeat it for each link. for example: a href="https://www.yahoo.com" Onclick="window.open(this.href); return false" onmouseout="this.style.color = '#0000ff';" onmouseover="this.style.color = '#e3FF85';" align="justify">Yahoo. But, I would like this code to apply to every link on the page. I've explored 2 possible methods. One is to use STYLE TYPE and CLASS= methods. Another possibility is using STYLE H1 /H1 (similar to W3 schools). But, I haven't even come close to getting a universal application.
1. You can try this:
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; ++i)
{
links[i].onmouseenter = function() {links[i].style.color = '#e3FF85';};
links[i].onmouseout= function() {links[i]..style.color = '#0000ff';};
}
You get the list of all links using getElementsByTagName('a') ('a' is tag name for links), and you can do anything you want with them.
2. You can also try it with jquery:
var allLinks = $('a');
allLinks.mouseenter(function() { $(this).css('color', '#e3FF85'); });
allLinks.mouseout(function() { $(this).css('color', '#0000ff'); })
3. If you just care about changing style (like color or background) when mouse is over your link, you can do it from CSS:
a:hover
{
color: #123456;
}
I'm trying to add a CSS property dynamically to a control.
I have a group of RadioButton. On selection of any one of the buttons, I want to make one layout visible.
Below are some of the snippets I tried, none of them seem to work!
Snippet-1
showhide: function(){
var fcid = sap.ui.getCore().byId("FC7");
fcid.visibility = "hidden";
}
Snippet-2
showhide: function(){
var fcid = sap.ui.getCore().byId("FC7");
jquery('#fcid').css("visibility","hidden");
}`
Snippet-3
showhide: function(){
var fcid = sap.ui.getCore().byId("FC7");
jquery('#fcid').hide();
}
You cannot use fcid.visibility = "hidden"; and expect it to behave like a DOM object; it's not, it's a Javascript class with getters, setters, events, aggregations, etc.
Therefore, you should use the control's properties instead: fcid.setVisible(true);
See the API docs for the correct signature of the control/layout properties
You can:
var fcid = ...byId("FC7");
fcid.setVisible(false);
Or
fcid.$().hide(); // or every other jquery method
Or
fcid.addStyleClass("hiddenObject");
Last one with Css-Class:
.hiddenObject { display:none; }
It seems that when using Knockout's text binding, multiple spaces become collapsed into one. For example:
<textarea data-bind="value: Notes"></textarea>
<p data-bind="text: Notes"></p>
function VM() {
this.Notes = ko.observable();
}
var vm = new VM();
ko.applyBindings(vm);
Here is a fiddle to demonstrate this: http://jsfiddle.net/9rtL5/
I am finding that in jsfiddle, the spaces are compacted in Firefox, Chrome and IE9. Strangely though within my app IE9 does not compact them, but the others do.
My understanding is that Knockout uses an HTML text node to render the value. I found this related question on preserving spaces when creating a text node:
http://www.webdeveloper.com/forum/showthread.php?193107-RESOLVED-Insert-amp-nbsp-when-using-createTextNode%28%29
Should Knockout handle transforming spaces appropriately? I don't really want to use a custom binding handler for this.
I actually came across this in the context of the display text within a select, and only discovered that it also relates to a simple text binding while debugging that issue. I presume the select issue is the same.
What you are observing is normal behavior. When rendered in certain elements, the whitespace is trimmed. Knockout shouldn't be doing any automatic replacements, if I wanted to send a string to a server with leading/trailing spaces using knockout, it better make it there with those spaces.
You should create a binding handler to replace the spaces with no-breaking spaces so it can be rendered that way.
ko.bindingHandlers.spacedtext = {
replaceSpace: function (str) {
return new Array(str.length + 1).join('\xA0');
},
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var spacedValue = ko.computed(function () {
var value = ko.utils.unwrapObservable(valueAccessor()),
text = value && value.toString();
return text && text.replace(/^\s+|\s+$/gm, ko.bindingHandlers.spacedtext.replaceSpace);
});
ko.applyBindingsToNode(element, { text: spacedValue });
}
};
Demo