Binding a DropDownList in Kendo Scheduler Custom Template (ASP.NET MVC Wrapper version) - kendo-asp.net-mvc

I'm using the ASP.NET MVC wrapper for Kendo UI and I'm trying to bind several dropdownlists within a custom template (x-kendo-template). I can't figure out how to do this using the ASP.NET MVC Wrapper (this is similar to this question: How do I bind a DropDownList to a DataSource within an editor template using the scheduler?).
There are some examples on using the Kendo Web version, but no complete examples out there that show using a custom pop-up editor with the scheduler that contains a dropdownlist pulling data from a URL (json data).
Is there an end-to-end example? I can load the scheduler with data. The issue is with the custom template and dropdownlist binding.
EDIT:
After searching extensively, I stumbled upon a "getting started" page from Telerik on using the Kendo UI Scheduler in ASP.NET MVC. They (Telerik) really need to do a better job cross-linking between Demos to Documentation to APIs and Examples (Here is the example)
I've also created a blog post that wraps everything for a Scheduler (from the database table to the Views), you can see that here.Kendo UI Scheduler with ASP.NET MVC and Peta Poco
The example shed some light which the demo and documentation do not do, like for instance, the ViewModel they use in their example online:
C# ViewModel
public class Projection : ISchedulerEvent
{
public string Title { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string Recurrence { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
// Custom Field
public int EventId { get; set; }
public int CustomerId { get; set; }
}
Your ViewModel that you use for the Scheduler must inherit from the ISchedulerEvent class or it will not work correctly.
Razor View
The Razor View is pretty straight-forward, although most of the demos you run across will show data getting passed via the server-side (from the controller). Here, I'm doing this via Ajax methods (Create, Read, Update, Destroy).
#(Html.Kendo().Scheduler<KendoUISchedulerDemo.Models.Projection>()
.Name("scheduler")
.Date(DateTime.Today)
.Height(600)
.DataSource(d => d
.Model(m =>
{
m.Id(f => f.EventId);
m.Field(f => f.Title);
m.Field(f => f.CustomerId);
m.Field(f => f.Description);
m.RecurrenceId(f => f.Recurrence);
})
.Read("Read", "Shared", new { Area = "Events" })
.Create("Create", "Shared", new { Area = "Events" })
.Destroy("Destroy", "Shared", new { Area = "Events" })
.Update("Update", "Shared", new { Area = "Events" })
)
.Events( events =>
{
events.Add("ABC.events.SchedulerAdd");
})
.Editable(edit =>
{
edit.TemplateId("schedulerTemplate");
})
)
The main point with using the datasource with ajax calls like above is that it allows us to put the methods in a separate controller so that we can keep the controller that is displaying the view clean.
Razor View - Kendo Template (for the pop-up editor of events)
This is the script block for the x-kendo-template that overwrites the default pop-up window when creating and editing events in the Kendo Scheduler. This script is pretty much the wild west and you can do whatever you want in it, and it is bound by default with the Kendo MVVM model. Take that with a grain of salt though because there is not a documented way to "extend" that ViewModel to properly put your datasources from custom drop down lists in the ASP.NET MVC wrapper (version) of the Scheduler. (This uses Twitter Bootstrap as well)
<script type="text/x-kendo-template" id="schedulerTemplate">
<div class="form-group">
<div class="col-md-5">
#Html.Label("title", "Title", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<input class="k-textbox" data-bind="value: title" />
</div>
</div>
</div>
<div class="form-group mTop10">
#Html.Label("CustomerId", "Customer", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<input id="CustomerId" class="w450" />
</div>
</div>
<div class="form-group mTop10">
<div class="left col-md-5">
#Html.Label("start", "Start", new { #class = "col-md-2 control-label left" })
<div class="col-md-10">
<input name="start" type="text" required data-type="date" data-role="datetimepicker" data-bind="value: start,invisible: isAllDay" />
<input name="start" type="text" required data-type="date" data-role="datepicker" data-bind="value: start,visible: isAllDay" />
</div>
</div>
<div class="left col-md-5">
#Html.Label("end", "End", new { #class = "col-md-2 control-label left" })
<div class="col-md-10">
<input name="end" type="text" required data-type="date" data-role="datetimepicker" data-bind="value: end ,invisible:isAllDay" />
<input name="end" type="text" required data-type="date" data-role="datepicker" data-bind="value: end ,visible:isAllDay" />
</div>
</div>
</div>
<div class="clear"></div>
<div class="form-group mTop10">
#Html.Label("isAllDay", "All Day", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
<input type="checkbox" name="isAllDay" data-type="boolean" data-bind="checked:isAllDay">
</div>
</div>
</script>
JsonResults (in Controller)
Here are the CRUD Json Results. The Create, Update and Destroy JsonResults have been trimmed for the example.
public virtual JsonResult Read([DataSourceRequest] DataSourceRequest request)
{
var data = new List<Projection>();
data.Add(new Projection()
{
EventId = 1,
Start = DateTime.Now.AddDays(-2),
End = DateTime.Now.AddDays(-2).AddHours(2),
IsAllDay = false,
CustomerId = 1,
Description = "Booked for plumbing",
Title = "Manchester Residence"
});
return Json(data.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
public virtual JsonResult Create([DataSourceRequest] DataSourceRequest request, Projection evt)
{
if (ModelState.IsValid)
{
// Other code here
}
return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
}
public virtual JsonResult Update([DataSourceRequest] DataSourceRequest request, Projection evt)
{
if (ModelState.IsValid)
{
// Other code here
}
return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
}
public virtual JsonResult Destroy([DataSourceRequest] DataSourceRequest request, Projection evt)
{
if (ModelState.IsValid)
{
// Other code here
}
return Json(new[] { evt }.ToDataSourceResult(request, ModelState));
}
JavaScript
Here is the JavaScript contained within a stand alone JS file that corresponds to my "Add" event for the Scheduler. I didn't show the "Edit" event as it is pretty much the same idea and you should be able to figure it out.
ABC.Events.SchedulerAdd = function (e) {
function GetCustomers(value) {
var url = "/Events/Shared/GetCustomers"
var success = function (result) {
if (result != null) {
$("#CustomerId").kendoDropDownList({
dataTextField: "FullName",
dataValueField: "CustomerId",
dataSource: new kendo.data.DataSource({ data: result })
});
}
};
$.ajax({ url: url, success: success });
}
GetCustomers();
};
One of the keys in this JavaScript function is that we are turning our field into a Kendo DropDownList and wiring our datasource up at the same time that we are receiving as a JsonResult (not shown, but it's a simple Json object). Another key is how we wire up the datasource as we are creating a new kendo.data.DataSource. If you try to simply wire up the JsonResult, it won't work.
Conclusion
This is a work around to fill dropdownlists in a Scheduler Template (pop-up) when using the ASP.NET MVC Wrapper version of the Kendo UI. I am open for a better way, in which I imagine it will be adding the Json list data to the Internal MVVM that the Kendo Scheduler uses, but without the documentation for ASP.NET MVC or examples of how to pull it off, this is a way it can work.
EDIT #2 - Telerik ASP.NET MVC Example
I finally heard back from Telerik Support on this issue and was directed to this link: http://www.telerik.com/support/code-library/custom-editor-9fd60fca3c02 There is a sample MVC project there that shows how to use a Custom Editor, Drop Down Lists with datasources, all within ASP.NET MVC. Why on Earth there is no link from the documentation to such projects that can obviously help is a mystery to me.

Did you manage to figure this out? I'm working on something similar and have managed to get some of this to work and I have a demo that might help. Mine is not 100% right now but I am getting there. I have a custom template linked to a resource. My issue is sometimes the model doesn't validate so I don't get a post back to the Jason method in the controller. Have you seen this example?

Related

Binding ember model in dynamically generated form

I am learning ember js from last couple of weeks, and building an application to learn it. I am in a situation where I have to build a dynamic form which will be bind to ember model. (the simplest example for this problem could be nested form, where we can click on add more link/button to add form on the fly, and add values to them).
But for me, I am building survey like site, where we can have lots of option to select and user can select one of the option from available one:
what I have done so far?
readAnswer: Ember.computed(function() {
return this.get('store').query('answer', { filter:
{
question_id: this.get('question.id'),
submission_id: this.get('submission.id')
}
})
}),
buildAnswer: Ember.computed(function() {
this.get('store').createRecord('answer', {
question: this.get('question'),
submission: this.get('submission')
})
}),
answer: Ember.computed(function() {
const ans = this.get('readAnswer');
console.log(`question_id: ${this.get('question.id')}, submission_id: ${this.get('submission.id')}`);
if(Ember.isEmpty(ans)) {
return this.get('buildAnswer');
} else {
return ans;
}
})
answer.hbs
<div class="row col-sm-12">
<div class="form-group">
<label>{{model.title}}</label>
<p>
{{input type="text" value=answer.field01 class="form-control" placeholder="width"}}
</p>
<p>
{{input type="text" value=answer.field02 class="form-control" placeholder="depth"}}
</p>
</div>
</div>
NOTE here answer.hbs is a component, and these are call recursively (in loop) from parent route. So for 2 questions, we can have 4 textboxes, 2 text box for each question, first textbox for answer.field01 and second textbox for answer.field02
Let's say I have 2 questions, till now, I can see 2 answers build in the ember store if they don't already exists in database and then, I can see 4 textboxes generated in view. But they are not binding. Meaning, if I can value of the textbox, nothing happens in the ember store.
Expected Result
When I input answer in the textbox, it should bind with answer.fieldxx properly.
I extracted those codes from computed property to init() function and everything works now:
answer: null,
init() {
this._super(...arguments);
// build without computed property
this.get('store').query('answer', { filter:
{
question_id : this.get('question.id'),
submission_id : this.get('submission.id')
}
}).then((answers) => {
if(Ember.isEmpty(answers)) {
let a = this.get('store').createRecord('answer', {
question : this.get('question'),
submission : this.get('submission')
})
this.set('answer', a); // build new object and set answer
} else {
this.set('answer', answers.get('firstObject')); // get first answer and build it (because it is always 1 record)
}
}, (reason) => {
console.log(reason);
});
},

Unable to locate button to simulate click - Unit Testing React w/ Mocha, Chai, Enzyme

I'm attempting to simulate a button click with Enzyme. I've been able to write simple tests if an element renders, however the fun tests such as button clicks etc. are falling short.
In this example the error in terminal is:
1) Front End #Profile Component clicks a button :
Error: This method is only meant to be run on single node. 0 found instead.
at ShallowWrapper.single (node_modules/enzyme/build/ShallowWrapper.js:1093:17)
at ShallowWrapper.props (node_modules/enzyme/build/ShallowWrapper.js:532:21)
at ShallowWrapper.prop (node_modules/enzyme/build/ShallowWrapper.js:732:21)
at ShallowWrapper.simulate (node_modules/enzyme/build/ShallowWrapper.js:505:28)
at Context.<anonymous> (cmpnt-profile.spec.js:36:32)
the unit test is:
describe('Front End #Profile Component', () => {
const wrapper = shallow(<Profile/>);
...(other tests here)...
it('clicks a button ', () => {
wrapper.find('button').simulate('click');
expect(onButtonClick.calledOnce).to.equal(true);
})
});
the component is:
import _ from 'lodash';
import React, { Component, PropTypes } from 'react';
import { reduxForm } from 'redux-form';
import ExpireAlert from '../components/alert';
import SocialAccount from '../components/socialAccounts'
const FIELDS = {
name : {
type : 'input',
label : 'name'
},
username : {
type : 'input',
label: 'username'
},
email : {
type : 'input',
label: 'email'
}
};
let alert = false;
export default class Profile extends Component {
componentWillReceiveProps(nextProps){
if(nextProps.userIsUpdated){
alert = !alert
}
}
handleSubmit(userData) { // update profile
userData.id = this.props.userInfo.id
this.props.updateUserInfo(userData)
}
renderField(fieldConfig, field) { // one helper per ea field declared
const fieldHelper = this.props.fields[field];
return (
<label>{fieldConfig.label}
<fieldConfig.type type="text" placeholder={fieldConfig.label} {...fieldHelper}/>
{fieldHelper.touched && fieldHelper.error && <div>{fieldHelper.error}</div>}
</label>
);
}
render() {
const {resetForm, handleSubmit, submitting, initialValues} = this.props;
return (
<div className="login">
<div className="row">
<div className="small-12 large-7 large-centered columns">
<div className="component-wrapper">
<ExpireAlert
set={this.props.userIsUpdated}
reset={this.props.resetAlert}
status="success"
delay={3000}>
<strong> That was a splendid update! </strong>
</ExpireAlert>
<h3>Your Profile</h3>
<SocialAccount
userInfo={this.props.userInfo}
unlinkSocialAcc={this.props.unlinkSocialAcc}
/>
<form className="profile-form" onSubmit={this.props.handleSubmit(this.handleSubmit.bind(this))}>
<div className="row">
<div className="small-12 large-4 columns">
<img className="image" src={this.props.userInfo.img_url}/>
</div>
<div className="small-12 large-8 columns">
{_.map(FIELDS, this.renderField.bind(this))}
</div>
<div className="small-12 columns">
<button type="submit" className="primary button expanded" disabled={submitting}>
{submitting ? <i/> : <i/>} Update
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
);
}
}
const validate = values => {
const errors = {}
if (!values.name) {
errors.name = 'Name is Required'
}
if (!values.username) {
errors.username = 'Username is Required'
} else if (values.username.length > 30) {
errors.username = 'Must be 30 characters or less'
}
if (!values.email) {
errors.email = 'Email is Required'
} else if (!/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address'
}
return errors;
}
Profile.propTypes = {
fields: PropTypes.object.isRequired,
handleSubmit: PropTypes.func.isRequired,
resetForm: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired
}
export default reduxForm({
form: 'Profile',
fields: _.keys(FIELDS),
validate
})(Profile)
Any suggestions appreciated. I would love to make some amazing unit tests!
ZekeDroid is correct. Another way to handle the situation though would be to use mount, which is Enzyme's way to deep render components, meaning the entire tree of components are rendered. This would be considered an integration test, instead of a unit test. ZekeDroid mentions "This assumes your component can handle not receiving whatever reduxForm supplies it with, which is good practice anyhow as you will find it easier to test.", and I believe he's referencing unit testing. Ideally, your tests should include both unit tests and integration tests. I created a simple project to show how to do both unit and integration tests with redux-form. See this repo.
You have two export defaults on your file. This will naturally mean that the second one is overriding the first. If you really want to be able to export the reduxForm version and the component itself, as you should for testing, then remove the word default from the component.
On your test, you shallow render, meaning no children are rendered. Since you import the reduxForm, nothing much will get rendered, definitely not your Profile. Therefore, if you removed the default keyword like I mentioned, your test will start working when you import it using a named import:
import { Profile } from 'path/to/component';
*This assumes your component can handle not receiving whatever reduxForm supplies it with, which is good practice anyhow as you will find it easier to test.

Sitecore MVC Sitecore.Mvc.Presentation.RenderingModel

I am pretty new at sitecore and i faced a problem when rendering controller.
As you can see from below picture i created a "Mainlayout" and putted the placeholders.
<div id="page-wrapper">
<div class="container-fluid">
<div class="row">
#Html.Sitecore().Placeholder("content")
#Html.Sitecore().Placeholder("content1")
</div>
<!-- /.row -->
</div>
<!-- /.container-fluid -->
</div>
After that i created a class Driver which contains Name and Text properties
public class Driver
{
public HtmlString Name { get; set; }
public HtmlString Text { get; set; }
}
The third picture has a method for getting the driver.
public class DriverRepository
{
public Driver GetDriver()
{
var driver = new Driver();
var rendering = RenderingContext.Current.Rendering;
var datasource = rendering.Item;
driver.Name = new HtmlString(FieldRenderer.Render(datasource, "Name"));
driver.Text = new HtmlString(FieldRenderer.Render(datasource, "Text"));
return driver;
}
}
After that i created a controller Driver with actionresult Featured
public class DriverController : Controller {
// GET: Driver public ActionResult Featured() {
var repository = new DriverRepository();
var driver = repository.GetDriver();
return View(driver);
}
}
And generated the view for the controller
using Sitecore.Mvc
model TestMvcTaulantTutorial.Models.Driver
Name : Model.Name <br />
Text : Model.Text
After that in sitecore I created a controller rendering for the Driver controller
I specified to home page this rendering to be read to content1
But when I deploy it returns me this error
The model item passed into the dictionary is of type
'TestMvcTaulantTutorial.Models.Driver', but this dictionary requires a
model item of type 'Sitecore.Mvc.Presentation.RenderingModel'.
1. My first assumption, as far as I understood from your description, seems that your rendering is not re-deployed and you are having a previous version of the same rendering at your deployment target, because dictionary requires a model item of type 'Sitecore.Mvc.Presentation.RenderingModel' while you have clearly specified correct model at the top:
model TestMvcTaulantTutorial.Models.Driver
... so that's probably another rendering being taken.
2. Another assumption, could you please replace that:
return View(driver);
.. with thу code below, explicitly specifying your view path, just to understand wether that is a root of a problem:
return View("your_correct_view_path", driver);
3. Also, what I've noticed, on a view you should have:
Name : #Model.Name <br/>
Text : #Model.Text
instead of:
Name : Model.Name <br/>
Text : Model.Text
The Driver class should inherit from RenderingModel class.
public class Driver: Sitecore.Mvc.Presentation.RenderingModel { .. }
I think Rvan is right. That error caused you to create the view rendering and not the controller rendering. Remember in the naming convention you don't need the controller keyword after the controller's name.

Is duplicating state of props the only way to go in React.js?

Take a look at the source code given below. It models a form that is composed out of two WHOIS components and a radio button group. The radio button determines the WHOIS component that is selected. Once the selected WHOIS component is valid the form should be submittable and emit the data of the selected WHOIS.
/** #jsx React.DOM */
var Publish = React.createClass({
getInitialState: function() {
return {
type: 'intern',
intern: {
domain: '',
valid: false
},
extern: {
domain: '',
valid: false
}
};
},
updateWhois: function(type, domain, state) {
var newState = {};
newState[type] = {
domain: domain,
valid: state === 'free'
};
this.setState(newState);
},
switchTo: function(type) {
this.setState({
type: type
});
},
isValid: function() {
var type = this.state.type;
var typeState = this.state[type];
return typeState.valid;
},
render: function() {
return (
<form className="publish">
<div>
<input name="publish-type" type="radio" checked={this.state.type === 'intern'} onChange={this.switchTo.bind(this, 'intern')} />
<Whois onFocus={this.switchTo.bind(this, 'intern')} onChange={this.updateWhois.bind(this, 'intern')} />
</div>
<div>
<input name="publish-type" type="radio" checked={this.state.type === 'extern'} onChange={this.switchTo.bind(this, 'extern')} />
<Whois onFocus={this.switchTo.bind(this, 'extern')} onChange={this.updateWhois.bind(this, 'extern')} />
</div>
<input type="submit" disabled={!this.isValid()} />
</form>
);
}
});
This code works perfectly. However I feel I am duplicating the state of the child components. How could I improve this example? Upon submit I would rather query the Whois component directly (for example an .getDomain method), but I have not clue if and how I should do so in ReactJs.
I feel as though there's nothing directly wrong with your example here, as there are different paradigms you can use when writing ReactJS components. If you do want to read from a rendered component, look at the methods in more about refs. Adding a ref property to your whois like so:
<Whois onFocus={this.switchTo.bind(this, 'intern')} onChange={this.updateWhois.bind(this, 'intern')} ref="whoIs1" />
this.refs.whoIs1.getDOMNode();
would make it possible to look at the component after it has been rendered into the DOM. Using the event argument inside a handler for your onChange method would also be a good option, as you can query the component's state out of the properties on event.

How to make react.js play nice together with zurb reveal modal form

I am trying to integrate zurb reveal with form into react component. So far next code properly displays modal form:
ModalForm = React.createClass({
handleSubmit: function(attrs) {
this.props.onSubmit(attrs);
return false;
},
render: function(){
return(
<div>
Add new
<div id="formModal" className="reveal-modal" data-reveal>
<h4>Add something new</h4>
<Form onSubmit={this.handleSubmit} />
<a className="close-reveal-modal">×</a>
</div>
</div>
);
}
});
The Form component is pretty standard:
Form = React.createClass({
handleSubmit: function() {
var body = this.refs.body.getDOMNode().value.trim();
if (!body) {
return false;
}
this.props.onSubmit({body: body});
this.refs.body.getDOMNode().value = '';
return false;
},
render: function(){
return(
<form onSubmit={this.handleSubmit}>
<textarea name="body" placeholder="Say something..." ref="body" />
<input type="submit" value="Send" className="button" />
</form>
);
}
});
Problem: When I render form component within modal form component and enter something into form input then I see in console exception Uncaught object. This is a stack:
Uncaught object
invariant
ReactMount.findComponentRoot
ReactMount.findReactNodeByID
getNode
...
If I just render form component directly in the parent component then everything works. Could anybody help please?
In short, you're doing this wrong and this is not a bug in react.
If you use any kind of plugin that modifies the react component's dom nodes then it's going to break things in one way or another.
What you should be doing instead is using react itself, and complementary css, to position the component in the way you'd like for your modal dialog.
I would suggest creating a component that uses react's statics component property to define a couple of functions wrapping renderComponent to give you a nice clean function call to show or hide a react dialog. Here's a cut down example of something I've used in the past. NB: It does use jQuery but you could replace the jQ with standard js api calls to things like elementById and etc if you don't want the jQuery code.
window.MyDialog = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
content: React.PropTypes.string.isRequired
},
statics: {
// open a dialog with props object as props
open: function(props) {
var $anchor = $('#dialog-anchor');
if (!$anchor.length) {
$anchor = $('<div></div>')
.prop('id', 'dialog-anchor');
.appendTo('body');
}
return React.renderComponent(
MyDialog(props),
$anchor.get(0)
);
},
// close a dialog
close: function() {
React.unmountComponentAtNode($('#dialog-anchor').get(0));
}
},
// when dialog opens, add a keyup event handler to body
componentDidMount: function() {
$('body').on('keyup.myDialog', this.globalKeyupHandler);
},
// when dialog closes, clean up the bound keyup event handler on body
componentWillUnmount: function() {
$('body').off('keyup.myDialog');
},
// handles keyup events on body
globalKeyupHandler: function(e) {
if (e.keyCode == 27) { // ESC key
// close the dialog
this.statics.close();
}
},
// Extremely basic dialog dom layout - use your own
render: function() {
<div className="dialog">
<div className="title-bar">
<div className="title">{this.props.title}</div>
<a href="#" className="close" onClick={this.closeHandler}>
</div>
</div>
<div className="content">
{this.props.content}
</div>
</div>
}
});
You then open a dialog by calling:
MyDialog.open({title: 'Dialog Title', content: 'My dialog content'});
And close it with
MyDialog.close()
The dialog always attaches to a new dom node directly under body with id 'dialog-anchor'. If you open a dialog when one is already open, it will simply update the dom based on new props (or not if they're the same).
Of course passing the content of the dialog as a props argument isn't particularly useful. I usually extend below to either parse markdown -> html for the content or get some html via an ajax request inside the component when supplying a url as a prop instead.
I know the above code isn't exactly what you were looking for but I don't think there's a good way to make a dom-modifying plugin work with react. You can never assume that the dom representation of the react component is static and therefore it can't be manipulated by a 3rd party plugin successfully. I honestly think if you want to use react in this way you should re-evaluate why you're using the framework.
That said, I think the code above is a great starting point for a dialog in which all manipulation occurs inside the component, which afterall is what reactjs is all about!
NB: code was written very quickly from memory and not actually tested in it's current form so sorry if there are some minor syntax errors or something.
Here is how to do what Mike did, but using a zf reveal modal:
var Dialog = React.createClass({
statics: {
open: function(){
this.$dialog = $('#my-dialog');
if (!this.$dialog.length) {
this.$dialog = $('<div id="my-dialog" class="reveal-modal" data-reveal role="dialog"></div>')
.appendTo('body');
}
this.$dialog.foundation('reveal', 'open');
return React.render(
<Dialog close={this.close.bind(this)}/>,
this.$dialog[0]
);
},
close: function(){
if(!this.$dialog || !this.$dialog.length) {
return;
}
React.unmountComponentAtNode(this.$dialog[0]);
this.$dialog.foundation('reveal', 'close');
},
},
render : function() {
return (
<div>
<h1>This gets rendered into the modal</h1>
<a href="#" className="button" onClick={this.props.close}>Close</a>
</div>
);
}
});