Sitecore Viewrendering with dynamic datasource - sitecore

Hi I have simple view rendering (e.g. with title and body).
While it works perfectly fine when i give a datasource to my rendering control in presentation layout - I am wondering if I can do it by code - i.e. define the data datasource by code.
Currently I have something like this that works just fine:
#inherits Glass.Mapper.Sc.Web.Mvc.GlassView<sample.Web.Models.sampleclass>
#if (Model != null)
{
<div>
#Model.Title
</div>
}
Looking for something like below where i can define my datasource or the item
#inherits Glass.Mapper.Sc.Web.Mvc.GlassView<sample.Web.Models.sampleclass>
#datasource = Sitecore.context.database.getitem("some different path or id");
#if (Model != null)
{
<div>
#Model.Title
</div>
}

You can use something like this:
#{
var dynamicDatasource = new SitecoreContext().GetItem<sampleclass>(other_item_id)
}
#if (dynamicDatasource != null)
{
<div>
#Html.Glass().Editable(dynamicDatasource, d => d.Title)
</div>
}

Related

In ember, how to change values of checkboxes based on another

I have four checkbox and I want to check automatically checkbox with id = 2 if checkbox with id = 4 is checked.
I did the following but did not get the output. Could someone help me with this.
{#each category in checkboxList}}
{{input id = category.CHECKBOX_ID type="checkbox" checked=category.IS_CHECKED}}
{{#if category.CHECKBOX_ID == 4 && category.IS_CHECKED == true}}
{{action 'CheckSize'}}
{{/if}}
The checkboxList is
[
{"IS_CHECKED":false,"CHECKBOX_ID":1},
{"IS_CHECKED":false,"CHECKBOX_ID":2},
{"IS_CHECKED":true,"CHECKBOX_ID":3},
{"IS_CHECKED":false,"CHECKBOX_ID":4}
]
You'll want to manage the state of the checkboxes separately.
Here is an example I did for another SO question that had a similar problem to solve:
https://ember-twiddle.com/468a737efbbf447966dd83ac734f62ad
The gist of it is
we use a single action in response to a click of any checkbox:
#action
toggleChecked(id) {
const newTree = check(this.options, id);
this.set('options', newTree);
}
In this example (taken from the ember-twiddle), all of the logic is extracted to a pure-function named check.
Check itself is pretty involved, but because the application logic is different between that example and the problem you've run in to, I'll just show the entry point function:
export function check(tree, id, transform = toggle) {
if (tree === undefined) return undefined;
if (Array.isArray(tree)) {
return tree.map(t => check(t, id, transform));
}
if (tree.id === id || id === 'all') {
return checkNode(tree, id, transform);
}
if (tree.children) {
return checkChildren(tree, id, transform);
}
return tree;
}
This is just an example of how you can immutably modify the representation of all checkboxes by using a pure function. Your logic may vary.
Hope this helps :)

Inline Template Editor for jsRender or other template engine

I need a component that would;
Work within a web page to allow a nontechnical user to create and edit templates for customized reports.
Allow the user to easily place a set of pre-defined template data tokens in the report that conforms to the templating engine syntax without the user needing to know how to write the syntax themselves.
Support the ability to change and update data items that can be used in the report without extensive rewriting of the code or creating a new plugin.
The goal is for end users to create their own personalized templates for a specific set of JSON data. The ability to create templates would be available on a web page and the templates would be stored for later use. Storing and using the templates is not a problem, but an easy to use editor for the templates is.
I have been using jsRender for a templating engine and like it but I am open to other engines if what I need is easier to support.
My goal is to have an online editor, similar to MCE or CKEditor, that would have the ability to place a preset list of data tokens into a custom template the user creates. These templates would be used for auto-generated content based on the data supplied to the template engine.
The solution needs to be fairly simple on the user side. The user skills could range from "Not Ignorant" up to "Almost Programmer". I would like to avoid anything that involves the user actually having to learn to hand write HTML, understand jsRender or other template library syntax. A drop down list of insertable data would be ideal.
I don't see much need for any complex logic syntax. My need is basic data token replacement, not any complex logic.
You can use jsviews + inner jsrender.
Create custom tag:
$.views.tags({
render : {
isUpdate : false,
init : function (tagCtx, linkCtx) {
var tag = this;
tag._template = tagCtx.args[0];
tag._data = tagCtx.args[1];
tag.template = "<div class='content'></div>";
},
_render : function () {
var tag = this;
var template = $.templates(tag._template.text);
tag.linkedElem.html(template.render(tag._data));
},
onUpdateTemplate : function () {
this._render();
},
onUpdateData : function () {
this._render();
},
onAfterLink : function (tagCtx, linkCtx) {
var tag = this;
tag._template = tagCtx.args[0];
tag._data = tagCtx.args[1];
if (tag._.unlinked) {
if (!tag.linkedElem) {
tag.linkedElem = tag._.inline ? tag.contents("*").first() : $(linkCtx.elem);
}
$.observable(tag._template).observeAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).observeAll($.proxy(tag.onUpdateData, tag));
} else {
$.observable(tag._template).unobserveAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).unobserveAll($.proxy(tag.onUpdateData, tag));
$.observable(tag._template).observeAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).observeAll($.proxy(tag.onUpdateData, tag));
}
tag._render();
},
onDispose : function () {
debugger;
var tag = this;
$.observable(tag._template).unobserveAll($.proxy(tag.onUpdateTemplate, tag));
$.observable(tag._data).unobserveAll($.proxy(tag.onUpdateData, tag));
},
onUpdate : function () {
return false;
},
dataBoundOnly : true
}
});
Create html:
<div id="page"></div>
<script id="templateEditor" type="text/x-jsrender">
<select data-link="selectedTemplate">
<option value="-">Please select</option>
{^{for templates}}
<option data-link="value{:#index} {:name} selected{:#index == ~root.selectedTemplate}"></option>
{{/for}}
</select>
<button data-link="{on addNew}">Add</button>
<br/>
<br/>
{^{if selectedTemplate!=="-"}}
template Name:<input data-link="templates[selectedTemplate].name" />
<br/>
<br/>
<textarea name="template" cols="40" rows="5" data-link="templates[selectedTemplate].text trigger=true"></textarea>
{{/if}}
<br/>
<br/>
{^{if selectedTemplate!=="-"}}
{^{render templates[selectedTemplate] data/}}
{{/if}}
</script>
And add app code:
var app = {
data : {
value : "test"
},
templates : [{
name : "Main",
text : "<span>{{:value}}</span>"
}
],
selectedTemplate : 0,
addNew : function () {
$.observable(this.templates).insert({
name : "new",
text : ""
});
}
};
$([app.templates]).on("arrayChange", function (o, e) {
if (e.change === "insert") {
$.observable(app).setProperty("selectedTemplate", e.index);
}
});
var templateEditor = $.templates("#templateEditor");
templateEditor.link("#page", app);
see live example on jsfiddle
Update 1:
I don't see much need for any complex logic syntax. My need is basic data token replacement, not any complex logic.
If you do not want to use jsRender use this code:
function template(str, data) {
return str.replace(/%(\w*)%/g, function (m, key) {
return data.hasOwnProperty(key) ? data[key] : "";
});
}
example on jsfiddle

React/Jasmine/Karma/Phantom Unit Test: findDOMNode and renderIntoDocument not working as expected

I'm trying to write a simple unit test and can't seem to figure it out. I want to test a bootstrap modal to ensure it displays the correct contents when I pass certain object properties to it. Here's what my modal code looks like:
import React, { Component, PropTypes } from 'react';
import { Button, Modal } from 'react-bootstrap';
class ModalBox extends Component {
render() {
const { modalBox } = this.props;
let content;
if (modalBox.contentBody) {
content = modalBox.contentBody;
} else {
content = (
<span>
<Modal.Header closeButton onHide={this.close.bind(this)}>
<Modal.Title>{modalBox.title}</Modal.Title>
</Modal.Header>
<Modal.Body>
{modalBox.message}
</Modal.Body>
{modalBox.isConfirm &&
<Modal.Footer>
<Button onClick={modalBox.onCancel} className="modal-button cancel">{modalBox.cancelText || 'Cancel'}</Button>
<Button onClick={modalBox.onConfirm} className="modal-button confirm">{modalBox.confirmText || 'Confirm'}</Button>
</Modal.Footer>
}
</span>
);
}
return (
<Modal show={typeof modalBox != 'undefined'} onHide={this.close.bind(this)} dialogClassName={modalBox.dialogClassName || ''} backdrop={modalBox.backdrop || true}>
{content}
</Modal>
);
}
}
So for a test, I want to make sure that if I pass the prop modalBox containing the contentBody field that it just returns the contentBody for the modal body. Here's an example of what I'm trying to test:
it("renders only contentBody when provided", () => {
let modalBoxObj = {
contentBody: <div className="test-content-body">This is a test.</div>
};
let element = React.createElement(ModalBox, {modalBox: modalBoxObj});
let component = TestUtils.renderIntoDocument(element);
let modalWrapper = TestUtils.scryRenderedDOMComponentsWithClass(component, 'modal');
// modalWrapper returns an empty array, so this returns "Expected 0 to be 1"
expect(modalWrapper.length).toBe(1);
let testBody = TestUtils.scryRenderedDOMComponentsWithClass(component, 'test-content-body');
// testBody returns an empty array, so this returns "Expected 0 to be 1"
expect(testBody.length).toBe(1);
// this returns "TypeError: 'undefined' is not an object (evaluating 'testBody[0].innerHTML')"
expect(testBody[0].innerHTML).toEqual("This is a test.");
}
I've also tried doing shallow rendering with TestUtils.createRenderer and trying that approach, but had no luck with it. Based on the examples I've seen online and previous testing experience with react <0.14, I feel this test should work. I just don't know what I'm missing or misunderstanding. In the past, I did something like below and just looked at the componentNode object to find elements and such, but componentNode is returning null.
let component = TestUtils.renderIntoDocument(element);
let componentNode = findDOMNode(component);
Thanks for your help!
The solution ended up being to add a ref to the ModalBox component. Once added, we were able to target the node like this:
let component = TestUtils.renderIntoDocument(<ModalBox modalBox={modalBoxObj} />);
let componentNode = findDOMNode(component.refs.modalBox._modal);

Rails or Ember object model breaking browser's pushState functionality?

** I'm using Ember.Object instead of Ember Data, to pull data from an api and I believe that might be causing the issue.**
I have my resources nested as so:
Mdm.Router.map ->
#resource "groups", ->
#resource "group", path: ':group_id'
'/groups/ loads a list of all groups on the left side of the browser. Each group is linking to its specific group_id. When clicked, the 'group' template renders on the right side of the screen, showing details of one group while the list remains to the left.
However, when you click the back button, or manually enter the group_id into the url the individual groups dont render. The url will update in the browser window, but the content wont change to match it.
I have the singular 'group' template rendering inside of the 'groups' template with the {{outlet}}.
My groups_route.js.coffee looks like this:
Mdm.GroupsRoute = Ember.Route.extend(model: ->
Mdm.Group.all()
)
application.hbs:
<div class="container">
<div class="nav-bar">
<img src="assets/logo_loginbox.png" class="logo">
<ul class="nav-menu">
<li>GROUPS</li>
<li>USERS</li>
</ul>
</div><!-- nav-bar -->
<hr>
{{outlet}}
</div><!-- container -->
groups.hbs:
<h1>Groups</h1>
{{ partial groupsList }}
<div class="group">
{{outlet}}
</div><!-- group -->
group.hbs:
<h1>{{name}}</h1>
I'm getting the following error in the console when I use the back button or try to load the page with the group_id present:
Uncaught TypeError: Object function () {
if (!wasApplied) {
Class.proto(); // prepare prototype...
}
o_defineProperty(this, GUID_KEY, undefinedDescriptor);
o_defineProperty(this, '_super', undefinedDescriptor);
var m = meta(this);
m.proto = this;
if (initMixins) {
// capture locally so we can clear the closed over variable
var mixins = initMixins;
initMixins = null;
this.reopen.apply(this, mixins);
}
if (initProperties) {
// capture locally so we can clear the closed over variable
var props = initProperties;
initProperties = null;
var concatenatedProperties = this.concatenatedProperties;
for (var i = 0, l = props.length; i < l; i++) {
var properties = props[i];
Ember.assert("Ember.Object.create no longer supports mixing in other definitions, use createWithMixins instead.", !(properties instanceof Ember.Mixin));
for (var keyName in properties) {
if (!properties.hasOwnProperty(keyName)) { continue; }
var value = properties[keyName],
IS_BINDING = Ember.IS_BINDING;
if (IS_BINDING.test(keyName)) {
var bindings = m.bindings;
if (!bindings) {
bindings = m.bindings = {};
} else if (!m.hasOwnProperty('bindings')) {
bindings = m.bindings = o_create(m.bindings);
}
bindings[keyName] = value;
}
var desc = m.descs[keyName];
Ember.assert("Ember.Object.create no longer supports defining computed properties.", !(value instanceof Ember.ComputedProperty));
Ember.assert("Ember.Object.create no longer supports defining methods that call _super.", !(typeof value === 'function' && value.toString().indexOf('._super') !== -1));
if (concatenatedProperties && indexOf(concatenatedProperties, keyName) >= 0) {
var baseValue = this[keyName];
if (baseValue) {
if ('function' === typeof baseValue.concat) {
value = baseValue.concat(value);
} else {
value = Ember.makeArray(baseValue).concat(value);
}
} else {
value = Ember.makeArray(value);
}
}
if (desc) {
desc.set(this, keyName, value);
} else {
if (typeof this.setUnknownProperty === 'function' && !(keyName in this)) {
this.setUnknownProperty(keyName, value);
} else if (MANDATORY_SETTER) {
Ember.defineProperty(this, keyName, null, value); // setup mandatory setter
} else {
this[keyName] = value;
}
}
}
}
}
finishPartial(this, m);
delete m.proto;
finishChains(this);
this.init.apply(this, arguments);
} has no method 'find' application.js:51233
Mdm.GroupRoute.Ember.Route.extend.model application.js:51233
superWrapper application.js:12849
Ember.Route.Ember.Object.extend.deserialize application.js:36503
collectObjects application.js:35614
proceed application.js:35638
(anonymous function) application.js:1193
fire application.js:1038
self.fireWith application.js:1149
(anonymous function) application.js:1200
fire application.js:1038
self.fireWith application.js:1149
done application.js:8075
script.onload.script.onreadystatechange

SWFobject embedded swf, ExternalInterface.Call returns null

im working on a flash game with django backend using swfobject to embed the swf into the view,
however when i do externalinterface.call() from flash in InternetExplorer(Chrome and Firefox are fine), it returns null
the flash game itself works perfectly
Django view and embed code:
<div id="game_container">
<div id='flashContent'></div>
</div>
<script type="text/javascript" src="swfobject.js"></script>
<script type='text/javascript'>
var flashvars={{flashvars|safe}};
var params={wmode:"opaque", allowscriptaccess:"always" };
var attributes={id:"flashContent", name:"flashContent"};
swfobject.embedSWF("{{SWF_URL}}", "flashContent", "{{ appsettings.SWF_WIDTH }}", "{{ appsettings.SWF_HEIGHT }}", "10.0.0", false, flashvars, params, attributes);
</script>
function fqlearn_isEventInteresting(data) {
ln_log(['isEventInteresting',data]);
if (!BASE_URL) BASE_URL = data.baseURL;
ln_log(['got lesson?',fqlearn_findLearningModule(data) != null]);
return fqlearn_findLearningModule(data) != null;
//shuld return either true or false.
}
Flash AS3 code:
var isInteresting:Object = false;
try {
isInteresting = ExternalInterface.call('fqlearn_isEventInteresting', data);
} catch (e:Error) {
trace("error calling external interface");
// Container does not support outgoing calls :/
rpc.forceLogUncaughtError("ExternalInterface.call problem",
e.name, e.toString(), e.getStackTrace());
rest.apply(restThis);
return;
} catch (e:SecurityError) {
// Security sandbox nonsense :/
throw e;
}
if (isInteresting == null) {
// Something went wrong :/
rpc.forceLogUncaughtError("ExternalInterface.call problem", "JS_returned_null_error");
}
if (isInteresting) {
trace("showing learning blackout")
dispatch(CoordinationEvent.newLEARNING_ABOUT_TO_SHOW());
learningPendingData = {
rest: rest,
restThis: restThis
};
ExternalInterface.call() from Flash in InternetExplorer(Chrome and Firefox are fine), it returns null . how do i fix this?
Fixed it: console.debug was choking up Internet Explorer. I removed those and it worked.