Deform 2.0: Adding HTML5 placeholder - pyramid

I am trying to add HTML5 placeholder attribute to Deform 2.0 TextInputWidget. However I am not sure if this should be supported or how this should be supported as documentation is not very clear about this - there seems to be some mask_placeholder feature which doesn't be what I want.
How to add HTML5 placeholder to Deform text input (2.0+)?

EDIT: As of Deform 2.0.7, HTML5 attributes are supported.
https://docs.pylonsproject.org/projects/deform/en/latest/changes.html
Ok - the trick is to have a custom template - Deform templates did not yet have support for placeholder:
<!--! This adds placeholder attribute support for TextInput.
-->
<span tal:define="name name|field.name;
css_class css_class|field.widget.css_class;
oid oid|field.oid;
mask mask|field.widget.mask;
mask_placeholder mask_placeholder|field.widget.mask_placeholder;
style style|field.widget.style;
placeholder field.widget.placeholder|nothing;
type field.widget.type|'text';
"
tal:omit-tag="">
<input type="${type}" name="${name}" value="${cstruct}"
tal:attributes="class string: form-control ${css_class};
style style;
placeholder placeholder;"
id="${oid}"/>
<script tal:condition="mask" type="text/javascript">
deform.addCallback(
'${oid}',
function (oid) {
$("#" + oid).mask("${mask}",
{placeholder:"${mask_placeholder}"});
});
</script>
</span>
And then you can define your widget as:
class InviteFriends(CSRFSchema):
email = c.SchemaNode(
c.String(),
missing=None,
validator=c.Email(),
widget=w.TextInputWidget(template="textinput_placeholder", type="email", placeholder="Friend's email"),
)
phone_number = c.SchemaNode(
c.String(),
missing=None,
validator=c.Length(min=7),
widget=w.TextInputWidget(template="textinput_placeholder", type="tel", placeholder="Friend's phone number"),
)

Related

If element hasClass, add another class to its title value

I'm using slick carousel, and once a div is active I want to open the corresponding description.
Problem I'm having is with this code:
if ($('div').hasClass('active')) {
var title = $(this).attr('title');
$('ul li').removeClass('open');
$(title).addClass('open');
}
What I'm trying to achieve:
Once a div gets class 'active', I want to take its title value, and use it as a id link to list element I want to display(add class to).
Here is a FIDDLE.
Use event handling, not class monitoring.
The slick carousel API has events for this, I believe you want to use the afterChange event to act on the active element after it has been made visible.
Check out the docs and examples, especially the section titled "Events" on Slick page: http://kenwheeler.github.io/slick/
And I think you don't want to use title attribute for this because that is for tooltips. I recommend data-* attributes instead. And element IDs should generally start with a letter and not a number (was required in HTML4 and makes life easier when mapping IDs to JavaScript variables; though if you are using HTML5 I think this requirement is no longer in effect).
HTML
<div id="carousel">
<div data-content-id="content1">
Selector 1 </div>
<div data-content-id="content2">
Selector 2 </div>
<div data-content-id="content3">
Selector 3 </div>
</div>
<ul class="content">
<li id="content1">Content 1</li>
<li id="content2">Content 2</li>
<li id="content3">Content 3</li>
</ul>
JavaScript
$('#carousel').on('afterChange', function(event, slick, currentSlide) {
// get the associated content id
var contentId = $(slick.$slides.get(currentSlide)).data("content-id");
if(contentId && contentId.length)
{
var $content = $("#" + contentId);
$(".content>li").removeClass("open"); // hide other content
$content.addClass("open"); // show target content, or whatever...
}
});
I have found a solution:
$('.slider').on('afterChange', function(event, slick, currentSlide, nextSlide){
var contentId= $(slick.$slides.get(currentSlide)).data('content');
if(contentId)
{
$(".content li").removeClass('open');
$('#' + contentId).addClass('open');
}
});
Working fiddle

reactjs unrecognized tag attributes

TLDR:
Is there a way to force-append an attribute to a react tag?
.
The full story:
I'm using reactjs and i've run into a problem with SVG and foreignObjects.
I wanted to center text in an SVG image so i figured the easiest approach would be to use a div in a foreign object.
It works fine on chrome, but in firefox the text isn't displayed.
On closer inspection, it appears that my
requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"
requiredExtensions="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/2000/svg"
Isn't coming through to the browser.
I've read the reactjs docs which suggested putting the prefix
data-
in, but the prefix stays in the browser.
I also tried to set the required features using the style={...}, but then this was inside the style string and not inserted as a tag attribute.
React Code:
import React, {Component,PropTypes} from 'react';
export default class myComponent extends Component {
render() {
return (<svg width = {this.props.width}
height = {this.props.height}>
<foreignObject x = {0} y = {0}
width = {this.props.width}>
<div> <p> {this.props.title} </p> </div > </foreignObject>
</svg>)
}
PARTIAL ANSWER:
I haven't been able to get text in a foreignObject to work with react in firefox, but i did work out how to set 'arbitary' tag attributes.
For each of the react components i assigned refs, i.e.:
<div style={divStyle} ref="d2">
<p style={{wordWrap: 'normal', textAlign: 'left', margin: 'auto', position: 'relative'}} key="p2">
{Math.round(this.props.kW)} W
</p>
</div>
Then in componentdidmount:
componentDidMount() {
this.refs.svg1.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
this.refs.svg1.setAttribute('version', '1.2');
this.refs.fo1.setAttribute('requiredExtensions', 'http://example.com/SVGExtensions/EmbeddedXHTML');
this.refs.d1.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
this.refs.fo2.setAttribute('requiredExtensions', 'http://example.com/SVGExtensions/EmbeddedXHTML');
this.refs.d2.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
this.refs.fo3.setAttribute('requiredExtensions', 'http://example.com/SVGExtensions/EmbeddedXHTML');
this.refs.d3.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
this.refs.fo4.setAttribute('requiredExtensions', 'http://example.com/SVGExtensions/EmbeddedXHTML');
this.refs.d4.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
this.refs.fo5.setAttribute('requiredExtensions', 'http://example.com/SVGExtensions/EmbeddedXHTML');
this.refs.d5.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
this.refs.fo6.setAttribute('requiredExtensions', 'http://example.com/SVGExtensions/EmbeddedXHTML');
this.refs.d6.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml');
}
This actually broke the foreign object in BOTH chrome and firefox!!
I think the issue is that i'm going by
https://www.w3.org/TR/SVG/extend.html
and they have:
<body xmlns="http://www.w3.org/1999/xhtml">
<p>Here is a paragraph that requires word wrap</p>
</body>
But since you can't use the <body> tag inside a react component, this doesn't get rendered.
I will manually edit the code in firefox and see if the inclusion of <body> in the foreign object fixes this issue.
I think the only option I have is to layer a second SVG component over the top of the first then use setInnerHTMLDangerously to write all of the foreign objects inside. Such a filthy hack!!

Orchard Alternate Shape Template Not Displaying Values

I'm new to Orchard and have watched both the Pluralsight "Orchard Fundamentals" and "Advanced Orchard" tutorials. Its a great platform, but I'm having a hard time wrapping my head around a couple of things.
I'd like to create a blog showcase banner on the home page only that rotates blog posts on the site. I have the HTML sliced up and functioning on an HTML template. The banner looks like this:
http://arerra.com/news-slideshow.jpg
So far I have done the following:
I've created a Blog called "Articles" and have placed a single post in there for testing.
Added a Layer called "ArticleList" where I have placed a Widget for "Recent Blog Posts"
I've created a custom layout for the home page called "Layout-Url-HomePage.cshtml" in my theme.
In my Theme "Views" folder, I have created a file called "Widget.Wrapper.cshtml" with only #Display(Model.Child) in it to remove the <article><header/><footer /><article> tags globally from the widgets.
Added a file in "Views > Parts > Blogs.RecentBlogPosts.cshtml" to control the layout of my shape. The code is the following:
#using Orchard.ContentManagement;
#{
IEnumerable<object> blogPosts = Model.ContentItems.ContentItems;
}
#if (blogPosts != null) {
<div class="container news-slider">
<ul class="slide-images">
#foreach (dynamic post in blogPosts) {
string title = post.Title;
ContentItem item = post.ContentItem;
<img src="/Themes/MountainWestHoops/Content/img/placeholder-700x380.jpg" alt="#title" class="active" />
}
</ul>
#foreach (dynamic post in blogPosts) {
string title = post.Title;
string body = post.Body;
ContentItem item = post.ContentItem;
<div class="featured-story threeD active">
<h1>#title</h1>
<p>#body #Html.ItemDisplayLink("READ MORE", item)</p>
</div>
}
<aside>
<ul class="tabs">
#foreach (dynamic post in blogPosts) {
string title = post.Title;
string url = post.Url;
ContentItem item = post.ContentItem;
<li><h3>#title</h3></li>
}
</ul>
<div class="ad-three-day-trial">
<img src="/Themes/Content/img/placeholder-260x190.gif" />
</div>
</aside>
</div>
}
My HTML is rendering properly, but none of the values that I have specified are showing up.
I am using the "Shape Tracer" module to see what template is being used. What is funny, is that the #Html.ItemDisplayLink("READ MORE", item) is rendering the article's URL, and if I replace the "READ MORE" with the string title, the title renders properly.
What am I doing wrong here that is causing strings to not display? Am I missing a larger point and misunderstanding the fundamentals? The tutorials seems to say that you can simply move around parts, but in this case, I need to have very specific markup for this slider to work.
Seems like your source was http://weblogs.asp.net/bleroy/archive/2011/03/27/taking-over-list-rendering-in-orchard.aspx
That is a rather old post, and the way the title is handled has changed since then.
The DisplayLink works because the only correct property here is post.ContentItem, which is what that API takes. post.Title and post.Body on the other hand are very likely null, which is why you see nothing. To access the title, you can use post.ContentItem.TitlePart.Title and to get the body, post.ContentItem.BodyPart.Text.

Orchard CMS work with MediaPickerField defined in Migrations.cs

MediaPickerFields still elude me.
I've defined a new Part in Migrations.cs and added a Boolean column and a MediaPickerField to the part as follows:
SchemaBuilder.CreateTable("ImageContentPartRecord", table =>
table.ContentPartRecord()
.Column("DisplayImage", DbType.Boolean));
ContentDefinitionManager.AlterPartDefinition("ImageContentPart", builder =>
builder
.Attachable()
.WithField("ImageField", fld =>
fld.OfType("MediaPickerField")
.WithDisplayName("Image")));
Assuming I have ImageContentPart and ImageContentPartRecord classes, how can I retrieve the data from my MediaPickerField (url, dimensions, alt text, class, etc) in my Driver and in my Part Templates (Edit / Display)?
i.e. - Parts.ImageContent.cshtml (I want to accomplish something like this):
<div>
<img src="#Model.ImageField.Url" alt="#Model.ImageField.Alt" />
</div>
Any ideas?
Here is the solution:
In my Display Driver method, I make sure to pass my ImageContentPart(part) when building the ContentShape:
return ContentShape("Parts_ImageContent", () =>
shapeHelper.Parts_ImageContent(
Content: part));
Then in my Template View, I leverage the dynamic nature of Orchard's architecture to consume my MediaPickerField. To do this, you access the .ContentItem property on your part, then leaning on dynamics, chain the part name (.ImageContentPart) and then the field name (.ImageContent) to access the field.
#{
// Attempting to access MediaPickerField named 'ImageContent'
var image = Model.Content.ContentItem.ImageContentPart.ImageContent;
// Leaning on Orchard dynamics to access properties of the field
var url = image.Url;
}
<img src="#url" alt="#T(image.AlternateText)" />
Here is an exhaustive list of MediaPickerField properties from \\Orchard.Fields\Views\Fields\MediaPicker.cshtml:
#*
Alternate Text: #Model.ContentField.AlternateText
Class: #Model.ContentField.Class
Style: #Model.ContentField.Style
Alignment: #Model.ContentField.Alignment
Width: #Model.ContentField.Width
Height: #Model.ContentField.Height
Url: #Model.ContentField.Url
You can also display an image using this example, and add the attributes you need:
<img src="#Href(Model.ContentField.Url)" />
*#
Hopefully, if you stumble upon a similar problem, this will help out!

Getting the co-ordinates of a component

How to get the co-ordinates of a JSF component after onclick event ? I need to place an overlay just below an icon that was clicked.
Is there any such in-built facility provided by JSF rather than manually writing a javascript function for that ?
No, there isn't. The position is browser (client) dependent. In the client side there is also totally no means of JSF, it's all just plain HTML/CSS/JS. The location can only be extracted from the HTML DOM element. You'd have to pass it from JS to JSF or do the business job fully in JS instead of JSF.
As PrimeFaces ships with jQuery, your best way to retrieve the element position relative to the document is using jQuery.offset().
var $element = jQuery('#someid');
var offset = $element.offset();
var x = offset.left;
var y = offset.top;
// ...
In addition to BalusC's answer, here is an example, where a click on a component with id=placeholder (maybe a link or button) will open another component (id=menu) directly below the triggering component. If the mouse is moved away from the triggering component, the menu will disappear:
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("#placeholder").click(function(event) {
//get the position of the placeholder element
var pos = jQuery(this).offset();
var height = jQuery(this).height();
//show the menu directly below the placeholder
jQuery("#menu").css( { "left": pos.left + "px", "top": (pos.top + height) + "px" } );
jQuery("#menu").show();
});
// hide the menu on mouseout
jQuery("#placeholder").mouseout(function(event) {
jQuery("#menu").hide();
});
});
</script>
The component with id=menu can be a div or a jsf h:panelGroup or any other component. The style attribute with display: none will initially hide the component:
<h:panelGroup style="position: absolute; display: none;" id="menu">
<!-- content here -->
</h:panelGroup>
Make sure that the jQuery id selector gets the correct id of the component. E.g. if your elements are inside a form with id=form1, the jQuery call has to look something like this:
jQuery("#form1\\:placeholder").click(function(event)
Notice the double backslash.
I'd recommend using a JSF component library like RichFaces or IceFaces. Many of them have AJAX capabilities and JavaScript library integration, and therefore have components for doing that kind of thing.

Resources