I am creating a custom module in Orchard CMS 1.7.1
So far all is going well (ish)
One of my properties is a string (called InfoBubbleHtml).
I would like to utilise the rich text edit for this input on my modules create/edit form.
Is there a helper already in place that would render my property as a rich text area rather than just a textarea or input field?
If not, what would i need to do to be able to have this property render the rich text editor?
Thanks in advance.
Update
As an update/addition to this question... Any HTML that I enter into my current text area is being ignored; guessing to do with request validation. how is this disabled for my controller so i can allow html in the admin?
Update 2
Ok, so i have figured out how to add this to my view by using:
#Display.Body_Editor(Text:Model.InfoBubbleHtml,EditorFlavor:"html")
Any idea how to set the ID of the editor?
#Display.Body_Editor(Text:Model.InfoBubbleHtml,EditorFlavor:"html") is rendering a shape named Body.Editor.cshtml.
This file lives in : Orchard.Web\Core\Common\Views\Body.Editor.cshtml
And it's content is
#using Orchard.Utility.Extensions;
#{
string editorFlavor = Model.EditorFlavor;
}
#Html.TextArea("Text", (string)Model.Text, 25, 80, new { #class = editorFlavor.HtmlClassify() })
So using this Shape you cannot set Id, Model is the anon that you send on the Display (Text and EditorFlavor).
Shapes.cs on Orchard.Core/Common is hooking an alternate using the EditoFlavor string.
public void Discover(ShapeTableBuilder builder) {
builder.Describe("Body_Editor")
.OnDisplaying(displaying => {
string flavor = displaying.Shape.EditorFlavor;
displaying.ShapeMetadata.Alternates.Add("Body_Editor__" + flavor);
});
}
So the final file that is rendered : TinyMVC\Views\Body-Html.Editor.cshtml
using Orchard.Environment.Descriptor.Models
#{
var shellDescriptor = WorkContext.Resolve<ShellDescriptor>();
}
<script type="text/javascript">
var mediaPickerEnabled = #(shellDescriptor.Features.Any(x => x.Name == "Orchard.MediaPicker") ? "true" : "false");
var mediaLibraryEnabled = #(shellDescriptor.Features.Any(x => x.Name == "Orchard.MediaLibrary") ? "true" : "false");
</script>
#{
Script.Require("OrchardTinyMce");
Script.Require("jQueryColorBox");
Style.Require("jQueryColorBox");
}
#Html.TextArea("Text", (string)Model.Text, 25, 80,
new Dictionary<string,object> {
{"class", "html tinymce"},
{"data-mediapicker-uploadpath",Model.AddMediaPath},
{"data-mediapicker-title",T("Insert/Update Media")},
{"style", "width:100%"}
})
You need to add this to the template and include another parameter in the TextArea Dictionary parameter named : {"id", "THE ID YOU LIKE"}.
Take a look at the docs about Shapes if you want to learn more Docs
You can patch the TinyMVC\Views\Body-Html.Editor.cshtml file to enable it to use custom Name/ID for the text area. The modification is quite simple - replace
#Html.TextArea("Text", (string)Model.Text, 25, 80,
with
#Html.TextArea((string)Model.PropertyName ?? "Text", (string)Model.Text, 25, 80,
Now you can use additional parameter PropertyName in your call:
#Display.Body_Editor(PropertyName:"InfoBubbleHtml", Text:Model.InfoBubbleHtml, EditorFlavor:"html")
The downside is that you are patching a foreign code and have to reapply this patch every time this file in TinyMVC module is updated.
Related
I am binding a model to view.
public class Validation
{
[Display("Please enter in <h5>day(s)</h5>")]
public string Message { get; set; }
}
Here Message property will be set as Please enter in <h5>day(s)</h5>.
In view am binding model property to LabelFor.
#Html.LabelFor(m => m.Message)
Expecting output as
Please enter in day(s)
But actual output is
Please enter in <h5>day(s)</h5>
I want part of the string to vary in size and cosmetics, so applying CSS to the entire label is not what I'm looking for.
Your display string "<h5>some text</h5>" will be rendered as text, not HTML. MVC will encode the < > characters to < >, causing them to be displayed as-is.
You shouldn't want to do this like this anyway.
The proper way would be to apply the display string to contain the text you want:
[Display("some text")]
Then create a CSS class:
label.fancyLabel {
/* your style here that makes a label look like a h5 */
}
Then apply that class to the label (from .NET MVC - How to assign a class to Html.LabelFor?):
#Html.LabelFor(m => m.Message, new { #class= "fancyLabel" })
As for your edit, if you want to just render the Display attribute's text as literal HTML, you'll have to:
Introduce your own HTML helper.
In there, write a label (and make sure to set the for= attribute).
Read the DisplayAttribute's value.
#Html.Raw() that value as the label text.
Use #Html.YourLabelHelper(m => m.Message) to render it.
But using HTML on your models like that isn't really advisable. Views and templates should decide how to render a model, not the other way around.
Odoo v8 uses Qweb and we need to print the terms and conditions of sale on the last page of the invoice.
As I understand we need to test that it is the last page of the report and print some static HTML on this page.
Does anyone know how to test the last page and remove the header and footer from it to achieve what I am trying.
Or even another way of doing it.
In last version of odoo, version 8 (or saas-6), to enable special class names to do special things (as for instance a 'last-page' class name to trigger visibility), you should only modify report module, in static/src/js/subst.js, and add this code to the subst function:
var operations = {
'last-page': function (elt) { elt.style.visibility = (vars.page === vars.topage) ? "visible" : "hidden"; },
};
for (var klass in operations) {
var y = document.getElementsByClassName(klass);
for (var j=0; j<y.length; ++j) operations[klass](y[j]);
}
In the QWEB ir.ui.views used by your report, you can then add anywhere (header, body, footer), code with:
<div class="last-page">
My content only displayed if on last page.
<div>
EDIT: An OpenERP/Odoo addon to add this magic class last-page easily was implemented as an example: https://github.com/0k/report_extended
I am trying to create a custom link from sitecore into my view
#Html.Sitecore().Field("CTA display", Model.Item, new { text = "<span>" + + "</span>"})
I am not 100% sure what the correct way to do this is, but I want to wrap the text from the link into a for styling. I've tried to put the Model.Rendering.Item.Fields["CTA display"] into there with .Text and it doesn't work.
Any help would be appreciated.
First, I'd start by creating a SitecoreHelper extension method that allows you to modify the inner html of the element you're rendering:
public static HtmlString Field(this SitecoreHelper helper, string fieldName, Item item, object parameters, string innerHtml)
{
if (helper == null)
{
throw new ArgumentNullException("helper");
}
if (innerHtml.IsNullOrEmpty())
{
return helper.Field(fieldName, item, parameters);
}
return new HtmlString(helper.BeginField(fieldName, item, parameters).ToString() + innerHtml + helper.EndField().ToString());
}
This will allow you to pass an optional innerHtml string that will be inserted between opening and closing tags of your element (in this case, an <a> tag).
From here, pass your html string containing your CTA label to the above method, or modify the method to output the field's Text value wrapped in a <span>.
I used the solution posted above by computerjules which worked a treat. You can then called the extended method like follows
#Html.Sitecore().Field("Link", Html.Sitecore().CurrentItem, new {Class = "some-class"}, "<span class='some-other-class'></span>")
and the span is rendered within the anchor tabs
I'm using asp.net MVC 4. NOTE I'm using arrays for this. I know about list use em all of the time but this should be arrays.
QUESTION
Now It's a really long list and lots of checkboxes. In order to package this into a more userfriendly UI, I would like a dropbox with all certificates. And a button that says "add mandatory certificate" aswell as a button that says "add desirable certificate".
My solution(feel free to criticize)
Create part
Add two string properties to the viewmodel alternatively / or two arrays
Create a dropdownlist.
Create two buttons (one for mandatory, second for desirable)
Create two a hidden fields
Logical part
On button click add/append the value of the certificate in the dropdown list to either the
hidden field for "mandatory" or "desirable".
In controller split the strings on ",", and build arrays of choosen "mandatory" / "desirable" certficates.
Is that particulary ugly or how should I do it?
I have a the following view
#using (Html.BeginForm())
{
for (int i = 0; i <= Model.Certificates.Count - 1; i++)
{
#Html.HiddenFor(x => x.Certificates[i].Value)
#Html.HiddenFor(x => x.Certificates[i].Name)
#Html.CheckBoxFor(x => x.Certificates[i].Checked)
#Html.LabelFor(x => x.Certificates[i].Checked, Model.Certificates[i].Name)
#Html.DropDownListFor(m => m.Certificates[i].SearchIncluded,
new SelectList(new []
{ new { Selected = true, Text = "Not included", Value = "Not included"},
new { Selected = false, Text = "Mandatory", Value = "Mandatory"},
new { Selected = false, Text = "Desirable", Value = "Desirable"},
}, "Value","Text","Selected"));
<br />
}
<Input type = "submit" Name = "SearchButton" value = "Search" />
}
I guess I have a few critiques
create a partial view for the add a certificate form.
potenially create a partial view for the Certificate display within the loop, so the loop would look like
#Html.Parital("CertificatePartial", x.Certificates[i])
if your forms are identical for the "Mandatory" or "Desirable" certificate, have a single "Save" button at the bottom of the Add A Certificate form. If the forms are identical, then the mandatory or desirable condition should be a property of the certificate. It can be included using a radio button on the form so the user can choose between "Mandatory" or "Desirable".
and I have another possibliiliy regaruding the way it works, but is speculation based on some things I don't really know about the intent or layout of your page
you could always use an ajax form post to save the new certificatation data, and then use javascript result to append it to your certification list, ie
public ActionResult AddCertificate (AddCertificateViewModel model){
...save to database
return Partial("CertificateParital", CertificateModel);
}
you would do this by using an Ajax Form
#using(Ajax.BeginForm("action","controller",new AjaxOptions{InsertionMode = InsertionMode.InsertAfter, UpdateTargetId = "CertificationsListContainer"}))
I'm kind of assuming this works the same way as a blog post and comments.
I am trying to create a simple safari extension. My current version of Safari is 5.1.7 running in Snow Leopard.
I have 2 documents :
global.html
<!DOCTYPE HTML>
<script>
safari.application.addEventListener("command", performCommand, false);
function performCommand(event) {
if (event.command === "traducir") {
var query = event.userInfo;
alert(query);
query = query.replace(/\s+/g,"+");
var newTab = safari.application.activeBrowserWindow.openTab();
newTab.url = "http://translate.google.es/#en/es/" + query ;
}
}
</script>
and the injected script : injected.js
document.addEventListener("contextmenu", handleMessage, false);
function handleMessage(msgEvent) {
var sel = '';
sel = window.parent.getSelection()+'';
sel = sel.replace(/^\s+|\s+$/g,"");
safari.self.tab.setContextMenuEventUserInfo(msgEvent, sel);
}
The extension is very simple :
1- When the user selects one text or word, click right-button and select the item of the contextual menu that raise the function.
2- The injected file gets the value of the selected text and it shared with the global.html through the userInfo.
3- The global.html script open a new tab with the url of google translate.
The problem is that event.userInfo is always NULL. I was searching in Google and all the examples are like this and I donĀ“t know where the problem is and why it returns always NULL.
This could possibly be due to a too strict setting for "Access Level" in the Extension Builder. Try setting the dropdown menu to "All", and tick the "Include Secure Pages" checkbox.