React JS Radio input state - forms

What is the correct way to manage the state of radio and checkboxes using React?
In some instances a form would be rendered partially completed so some radio and checkboxes would be pre selected on first load.
I have the following code snippet and i cannot get it to work as expected.
var formData = {
"id": 13951,
"webform_id": 1070,
"page": 0,
"type": "radios",
"name": "What industry are you in?",
"tooltip": "",
"weight": 0,
"is_required": 1,
"default_value": "",
"validation": "",
"allow_other_option": 0,
"other_option_text": "",
"mapped_question_id": "a295189e-d8b4-11e6-b2c5-022a69d30eef",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"option_conditional_from": null,
"default_value_querystring_key": "",
"deleted_at": null,
"is_auto_save": 0,
"is_component_number_hidden": 0,
"is_component_inline": 0,
"enable_confirm_validation": 0,
"confirm_validation_text": null,
"additional_options": "",
"url_mapping": "",
"webformcomponentoptions": [
{
"id": 13888,
"webform_component_id": 13951,
"key": "Hospitality",
"value": "Hospitality",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13889,
"webform_component_id": 13951,
"key": "Retail",
"value": "Retail",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13890,
"webform_component_id": 13951,
"key": "Other",
"value": "Other",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
}
]
}
class WebformApp extends React.Component {
render() {
return (
<form>
<label>{this.props.webform.name}</label>
<div className="group-wrapper">
<Radio radio={this.props.webform.webformcomponentoptions} />
</div>
</form>
)
}
}
class Radio extends React.Component {
render() {
var options = [];
this.props.radio.forEach(function(radio, i) {
options.push(<Option option={radio} key={radio.id} index={i} />);
})
return (
<div>{options}</div>
)
}
}
class Option extends React.Component {
constructor(props) {
super(props);
this.handleOptionChange = this.handleOptionChange.bind(this);
this.state = {selectedIndex: null};
}
handleOptionChange(e) {
this.setState({selectedIndex: this.props.index}, function() {
});
}
render() {
const selectedIndex = this.state.selectedIndex;
return (
<div>
<input type="radio"
value={this.props.option.value}
name={this.props.option.webform_component_id}
id={this.props.option.id}
checked={selectedIndex === this.props.index}
onChange={this.handleOptionChange} />
<label htmlFor={this.props.option.id}>{this.props.option.key}</label>
</div>
)
}
}
ReactDOM.render(
<WebformApp webform={formData} />,
document.getElementById('app')
);
https://codepen.io/jabreezy/pen/KWOyMb

The most important thing would be to have the Radio component handle the state, and keeping track of the selected option.
In addition, I would simplify by using map instead of forEach, and foregoing the Option component for a class method returning an <input type='radio'>. For simplicity's sake, using the option value for keeping track of the selected state instead of the index, and mimicking React's select component allowing a default value prop instead of setting each option's selected prop (which you don't seem to be using).
Finally, for order's sake, renaming the Radio:s radio prop to the (IMO) more correct options. Ergo (caveat, I haven't tested this):
class WebformApp extends React.Component {
render() {
return (
<form>
<label>{this.props.webform.name}</label>
<div className="group-wrapper">
<Radio options={this.props.webform.webformcomponentoptions} value={this.props.webform.value} />
</div>
</form>
)
}
}
class Radio extends React.Component {
constructor (props) {
super(props)
this.handleOptionChange = this.handleOptionChange.bind(this)
this.state = {value: this.props.value}
}
render() {
return this.props.options.map(this.getOption)
}
handleOptionChange (e) {
this.setState({value: e.target.value})
}
getOption (option) {
return (
<div>
<input type='radio'
value={option.value}
name={option.webform_component_id}
id={option.id}
key={option.id}
checked={this.state.value === option.value}
onChange={this.handleOptionChange} />
<label htmlFor={option.id}>{option.key}</label>
</div>
)
}
}
ReactDOM.render(
<WebformApp webform={formData} />,
document.getElementById('app')
);

Thank you so much for your input Linus. You set me along the correct path and i've solved my problem the following way:
var formData = {
"id": 13951,
"webform_id": 1070,
"page": 0,
"type": "radios",
"name": "What industry are you in?",
"tooltip": "",
"weight": 0,
"is_required": 1,
"default_value": "",
"validation": "",
"allow_other_option": 0,
"other_option_text": "",
"mapped_question_id": "a295189e-d8b4-11e6-b2c5-022a69d30eef",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"option_conditional_from": null,
"default_value_querystring_key": "",
"deleted_at": null,
"is_auto_save": 0,
"is_component_number_hidden": 0,
"is_component_inline": 0,
"enable_confirm_validation": 0,
"confirm_validation_text": null,
"additional_options": "",
"url_mapping": "",
"webformcomponentoptions": [
{
"id": 13888,
"webform_component_id": 13951,
"key": "Hospitality",
"value": "Hospitality",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13889,
"webform_component_id": 13951,
"key": "Retail",
"value": "Retail",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
},
{
"id": 13890,
"webform_component_id": 13951,
"key": "Other",
"value": "Other",
"created_at": "2017-04-07 18:40:39",
"updated_at": "2017-04-07 18:40:39",
"group": "",
"selected" : false
}
]
}
class WebformApp extends React.Component {
render() {
return (
<form>
<label>{this.props.webform.name}</label>
<div className="group-wrapper">
<Radio radio={this.props.webform.webformcomponentoptions} />
</div>
</form>
)
}
};
class Radio extends React.Component {
constructor(props) {
super(props);
this.state = {selectedOption: 'Other'};
}
handleOptionChange(changeEvent) {
this.setState({
selectedOption: changeEvent.target.value
})
};
renderOption(props) {
return (
<div>
<h3>{props.index}</h3>
<input type="radio"
value={props.option.value}
name={props.option.webform_component_id}
id={props.option.id}
checked={props.status}
onChange={props.clickeme} />
<label htmlFor={props.option.id}>{props.option.key}</label>
</div>
)
};
render() {
return (
<div>
{this.props.radio.map(function(radio) {
var selected = this.state.selectedOption === radio.value;
return <this.renderOption option={radio} key={radio.value} status={selected} clickeme={(e)=> this.handleOptionChange(e)} />;
}, this)}
</div>
)
};
};
ReactDOM.render(
<WebformApp webform={formData} />,
document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Related

Show Facebook events with angular

I want to display events on my website.
I take events from facebook with this :
infos.service.ts :
getEvents(link: string): Observable<any>{
let id = link.split('facebook.com/')[1].split('?')[0];
console.log("id ------> ",id);
return this.http.get(`https://graph.facebook.com/${id}?fields=events{name}&access_token=`)
.map(events => events.json());
}
After in home.component.ts :
onChange(e: Event) {
let value = e.target['value'];
this.service.getEvents(value).subscribe(event => {
console.log('events: ', event);
})
this.service.getEvents(value).subscribe((data) => this.events=data);
}
}
And I use this in order to display :
<ul>
<li> {{ events | json}}</li>
</ul>
But it shows me that and I can't use *ngFor :
"events": { "data": [ { "name": "Qui veut partir à Ibiza avec la team Coke TV cet été ?", "id": "1039032149505674" }, { "name": "MoveMyCity #MoveLyon", "id": "891490744279264" }, { "name": "MoveMyCity #MoveToulouse", "id": "816021265181647" }, { "name": "MoveMyCity #MoveMontpellier", "id": "801781889934749" }, { "name": "MoveMyCity #MoveMarseille", "id": "1610198129252793" }, { "name": "MoveMyCity #MoveNantes", "id": "936652956376199" }, { "name": "MoveMyCity #MoveParis", "id": "1609074386008334" } ], "paging": { "cursors": { "before": "QVFIUmdUc21tQW80b0tzLVgtc3VtUHI5OFNxdlZAMaVUwZAW02R1JvbGs4ZAUVwTUpmbUNiSVJ5eTBHVXMwSkw4RkFQQWNzZA3o1eTgzN2hxUFVINnlzd1ZA1eE93", "after": "QVFIUjgtRUUwR29ud25QdlE2YmVhQ3BfZAXdsd1R2SDlqeWlaeEk5empwVlBWQ1VkOXFtUkF2VUVPQlhvMWlLaHdNZA2VXczBuQkpyc0o1V2dNQUdZAYjllVE1B" } } }, "id": "998589190158511" }
Thanks for ur help.
I would step into the JSON and extract the array:
return this.http.get('the url')
.map(events => events.json().events.data);
}
The component code would stay the same, then you can very well iterate your data:
<div *ngFor="let event of events">
{{event.name}}
</div>
If you do not want to extract only the array, but keep your code like it is, then you need to iterate like so:
<div *ngFor="let event of events.events.data">
{{event.name}}
</div>

Switch case is not working in Reactjs

I have a json and I'm trying to display a form using the json data. I tried to display the indexes using the Switch case, so based on the html control type the index will be displayed. Below is my code
var React = require('react');
var ReactDOM = require('react-dom');
var DATA = {
"indexList": [{
"Label": "Name",
"Type": "text",
"Regex": "",
"Default_Val": "",
"Values": {
"Key": "",
"Value": ""
},
"Validtion Msg": "",
"Script": "",
"Mandatory": "required",
"maxLength":"16",
"minLength":"7",
"format":"Alphanumeric",
"cssClassName": "form-control",
"Placeholder": ""
},
{
"Label": "Select Language",
"Type": "dropdown",
"Regex": "",
"Default_Val": "English",
"Values": [{
"Key": "option1",
"Value": "English"
},{
"Key": "option2",
"Value": "Spanish"
}],
"Validtion Msg": "",
"Script": "",
"Mandatory": "Y",
"maxLength":"",
"minLength":"",
"format":"",
"cssClassName": "form-control",
"Placeholder": ""
},
{
"Label": "Type",
"Field_Type": "radio",
"Regex": "",
"Default_Val": "",
"Values": [{
"Key": "option1",
"Value": "Form1"
}, {
"Key": "option2",
"Value": "Form2"
}, {
"Key": "option3",
"Value": "Form3"
},{
"Key": "option4",
"Value": "Form4"
},{
"Key": "option5",
"Value": "Form5"
}],
"Validtion Msg": "",
"Script": "",
"Mandatory": "Y",
"maxLength":"",
"minLength":"",
"format":"",
"cssClassName": "form-control",
"Placeholder": ""
}
]
};
var Menu = React.createClass({
renderForm: function () {
var data = DATA.indexList;
console.log(data);
return data.map(group =>{
return <div>
<label for={group.Label}>{group.Label}</label>
<div>
switch(group.Type) {
case 'text':
return <input className={group.cssClassName}
id={group.Label}
placeholder={group.Placeholder}
{group.Mandatory}/>
case 'dropdown':
return <select className={group.cssClassName}>
<option value="">{group.Placeholder}</option>
<option for="let values of group.Values.value">{values}</option>
</select>
case 'radio':
return <div className={group.Type}>
<div for="let value of group.Values">
<label><input
name="radios"/>{value}</label>
</div>
</div>
case 'chekbox'
return <div className={group.Type}>
<div for="let value of group.Values">
<label><input name="checkbox"/>{value}</label>
</div>
</div>
}
</div>
</div>
});
},
render: function() {
return (
<div className="container">
<br/>
<div className="panel panel-primary">
<div className="panel-heading">Form</div>
<div className="panel-body">
<form>
<div className="form-group">
<div className="col-xs-5">
{this.renderForm()}
<button type="button" className="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
)}
});
module.exports = Menu
With the above code Im getting an error "Unexpexcted token" and the error is pointing towards the "case". Can anyone help to resolve the issue, Im new to react and Im not able to resolve this issue. Any syntax error in the code?
Because you forgot to put {}, use this:
<div>
{
}
To use any javascript code inside HTML element we need to use {}.
Note: We can't directly use if-else/switch statement inside JSX, use either ternary operator or call a function from JSX and use if-else/switch inside that.
Reference: http://reactjs.cn/react/tips/if-else-in-JSX.html
Check the working example:
var DATA = {
"indexList": [{
"Label": "Name",
"Type": "text",
"Regex": "",
"Default_Val": "",
"Values": {
"Key": "",
"Value": ""
},
"Validtion Msg": "",
"Script": "",
"Mandatory": "Y",
"maxLength":"16",
"minLength":"7",
"format":"Alphanumeric",
"cssClassName": "form-control",
"Placeholder": ""
},
{
"Label": "Select Language",
"Type": "dropdown",
"Regex": "",
"Default_Val": "English",
"Values": [{
"Key": "option1",
"Value": "English"
},{
"Key": "option2",
"Value": "Spanish"
}],
"Validtion Msg": "",
"Script": "",
"Mandatory": "Y",
"maxLength":"",
"minLength":"",
"format":"",
"cssClassName": "form-control",
"Placeholder": ""
},
{
"Label": "Type",
"Type": "radio",
"Regex": "",
"Default_Val": "",
"Values": [{
"Key": "option1",
"Value": "Form1"
}, {
"Key": "option2",
"Value": "Form2"
}, {
"Key": "option3",
"Value": "Form3"
},{
"Key": "option4",
"Value": "Form4"
},{
"Key": "option5",
"Value": "Form5"
}],
"Validtion Msg": "",
"Script": "",
"Mandatory": "Y",
"maxLength":"",
"minLength":"",
"format":"",
"cssClassName": "form-control",
"Placeholder": ""
}
]
};
var Menu = React.createClass({
_renderElement: function(group){
switch(group.Type){
case 'text':
return <input className={group.cssClassName}
id={group.Label}
placeholder={group.Placeholder}
required={group.Mandatory == 'Y'? true: false}/>
case 'dropdown':
return <select className={group.cssClassName}>
<option value="">{group.Placeholder}</option>
{group.Values.map(el => <option key={el.Key} for="let values of group.Values.value">{el.Value}</option>)}
</select>
case 'radio':
return <div className={group.Type}>
<div for="let value of group.Values">
{group.Values.map(el=> <label key={el.Value}><input
name="radios"/>{el.Value}</label>)}
</div>
</div>
case 'checkbox':
return <div className={group.Type}>
<div for="let value of group.Values">
<label><input name="checkbox"/>{value}</label>
</div>
</div>
}
},
renderForm: function () {
var data = DATA.indexList;
return data.map(group =>{
return <div>
<label for={group.Label}>{group.Label}</label>
<div>
{
this._renderElement(group)
}
</div>
</div>
});
},
render: function() {
return (
<div className="container">
<br/>
<div className="panel panel-primary">
<div className="panel-heading">Form</div>
<div className="panel-body">
<form>
<div className="form-group">
<div className="col-xs-5">
{this.renderForm()}
<button type="button" className="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
)}
});
ReactDOM.render(<Menu/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
swithc-case should be within braces
renderForm: function() {
var data = DATA.indexList;
console.log(data);
return data.map(group => {
return <div >
< label
for = {
group.Label
} > {
group.Label
} < /label> < div >{
switch (group.Type) {
case 'text':
return <input className = {
group.cssClassName
}
id = {
group.Label
}
placeholder = {
group.Placeholder
}
/>
case 'dropdown':
return;
}} < /div> < /div>
});
},

Limit the number of rows of autocomplete result , and match strings with starting letters only

I'm using jquery autocomplete in my project,
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
Json file
[
{ "value": "Saree",
"url": "/collection/saree" },
{ "value": "Lehangas",
"url": "/collection/lehangas" },
{ "value": "Dresses",
"url": "/collection/dresses" },
{ "value": "Tunics",
"url": "/collection/tunics" },
{ "value": "Kurtis",
"url": "/collection/kurtis" },
{ "value": "Blouses",
"url": "/collection/blouses" },
{ "value": "Duppattas",
"url": "/collection/duppattas" },
{ "value": "Shawls",
"url": "/collection/shawls" },
{ "value": "Plazos",
"url": "/collection/plazos" },
{ "value": "Skirts",
"url": "/collection/skirts" },
{ "value": "Patiala",
"url": "/collection/patiala" }
]
my js file:
$( function (){
$( "#tags" ).autocomplete({
source: "/static/admin/json/search.json",
select: function (event, ui) {
window.location = ui.item.url;
}
});
});
It displays all the results no matter which character i enter. I want the string to be matched according to its first letter and the following letters. And also, i want to limit the number of rows displayed to 10.
So , please some one help me with this.
Thanks in advance.
HTML
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
Here I have no idea whether you are getting json data in your js file or not , So In my case json data is available in js file and I am accessing json data in my own way I hope you can manage those things.
JS File
var data = [
{ "value": "Saree",
"url": "/collection/saree" },
{ "value": "Lehangas",
"url": "/collection/lehangas" },
{ "value": "Dresses",
"url": "/collection/dresses" },
{ "value": "Tunics",
"url": "/collection/tunics" },
{ "value": "Kurtis",
"url": "/collection/kurtis" },
{ "value": "Blouses",
"url": "/collection/blouses" },
{ "value": "Duppattas",
"url": "/collection/duppattas" },
{ "value": "Shawls",
"url": "/collection/shawls" },
{ "value": "Plazos",
"url": "/collection/plazos" },
{ "value": "Skirts",
"url": "/collection/skirts" },
{ "value": "Patiala",
"url": "/collection/patiala" }
]
$( function (){
$( "#tags" ).autocomplete({
source: function(request, response){
var lengthOfSearch= request.term.length;
var arr = jQuery.map(data, function( element, index ) {
if(element.value.substr(0,lengthOfSearch).toLowerCase() === request.term.toLowerCase()){
return element;
}
});
response(arr.slice(0,10));
},
select: function (event, ui) {
window.location = ui.item.url;
}
});
});
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>

how to code sap.m.sample.ListGrouping by using js view in openui5

hi i need List grouping control by using js view.but openui5 provides code by using xml view.
https://openui5.hana.ondemand.com/explored.html#/sample/sap.m.sample.ListGrouping/preview
how to convert this code into js view and how to make ListGrouping able to selection for both element level and group level and change this as dropdown box
List.view.xml
<mvc:View
controllerName="sap.m.sample.ListGrouping.List"
xmlns:l="sap.ui.layout"
xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m">
<List
items="{
path: '/ProductCollection',
sorter: {
path: 'SupplierName',
descending: false,
group: true
},
groupHeaderFactory: '.getGroupHeader'
}"
headerText="Products" >
<StandardListItem
title="{Name}"
description="{ProductId}"
icon="{ProductPicUrl}"
iconDensityAware="false"
iconInset="false" />
</List>
</mvc:View>
List.controller.js
sap.ui.define([
'jquery.sap.global',
'sap/m/GroupHeaderListItem',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, GroupHeaderListItem, Controller, JSONModel) {
"use strict";
var ListController = Controller.extend("sap.m.sample.ListGrouping.List", {
onInit : function (evt) {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
getGroupHeader: function (oGroup){
return new GroupHeaderListItem( {
title: oGroup.key,
upperCase: false
} );
}
});
return ListController;
});
how to write the same code by using js view
I have tried like as follows, but i am getting Error: Missing template or factory function for aggregation items of Element sap.m.List#__list0 !
List.view.js
sap.ui.jsview("oui5mvc.List", {
getControllerName : function() {
return "oui5mvc.List";
},
createContent : function(oController) {
odbbshiftGlobalId = this.getId();
var oMyFlexbox = new sap.m.FlexBox({
items: [
oList = new sap.m.List({
width: '500px',
group: true,
groupHeaderFactory: '.getGroupHeader',
items: [
]
}),
]
});
oMyFlexbox.placeAt(this.getId()).addStyleClass("tes");
}
});
List.controller.js
sap.ui.controller("oui5mvc.List", {
onInit: function() {
var data = {
"ProductCollection": [
{
"ProductId": "1239102",
"Name": "Power Projector 4713",
"Category": "Projector",
"SupplierName": "Titanium",
"Description": "A very powerful projector with special features for Internet usability, USB",
"WeightMeasure": 1467,
"WeightUnit": "g",
"Price": 856.49,
"CurrencyCode": "EUR",
"Status": "Available",
"Quantity": 3,
"UoM": "PC",
"Width": 51,
"Depth": 42,
"Height": 18,
"DimUnit": "cm",
"ProductPicUrl": "https://openui5.hana.ondemand.com/test-resources/sap/ui/demokit/explored/img/HT-6100.jpg"
},
{
"ProductId": "2212-121-828",
"Name": "Gladiator MX",
"Category": "Graphics Card",
"SupplierName": "Technocom",
"Description": "Gladiator MX: DDR2 RoHS 128MB Supporting 512MB Clock rate: 350 MHz Memory Clock: 533 MHz, Bus Type: PCI-Express, Memory Type: DDR2 Memory Bus: 32-bit Highlighted Features: DVI Out, TV Out , HDTV",
"WeightMeasure": 321,
"WeightUnit": "g",
"Price": 81.7,
"CurrencyCode": "EUR",
"Status": "Discontinued",
"Quantity": 10,
"UoM": "PC",
"Width": 34,
"Depth": 14,
"Height": 2,
"DimUnit": "cm",
"ProductPicUrl": "https://openui5.hana.ondemand.com/test-resources/sap/ui/demokit/explored/img/HT-1071.jpg"
},
{
"ProductId": "K47322.1",
"Name": "Hurricane GX",
"Category": "Graphics Card",
"SupplierName": "Red Point Stores",
"Description": "Hurricane GX: DDR2 RoHS 512MB Supporting 1024MB Clock rate: 550 MHz Memory Clock: 933 MHz, Bus Type: PCI-Express, Memory Type: DDR2 Memory Bus: 64-bit Highlighted Features: DVI Out, TV-In, TV-Out, HDTV",
"WeightMeasure": 588,
"WeightUnit": "g",
"Price": 219,
"CurrencyCode": "EUR",
"Status": "Out of Stock",
"Quantity": 25,
"UoM": "PC",
"Width": 34,
"Depth": 14,
"Height": 2,
"DimUnit": "cm",
"ProductPicUrl": "https://openui5.hana.ondemand.com/test-resources/sap/ui/demokit/explored/img/HT-1072.jpg"
},
],
"ProductCollectionStats": {
"Counts": {
"Total": 14,
"Weight": {
"Ok": 7,
"Heavy": 5,
"Overweight": 2
}
},
"Groups": {
"Category": {
"Projector": 1,
"Graphics Card": 2,
"Accessory": 4,
"Printer": 2,
"Monitor": 3,
"Laptop": 1,
"Keyboard": 1
},
"SupplierName": {
"Titanium": 3,
"Technocom": 3,
"Red Point Stores": 5,
"Very Best Screens": 3
}
},
"Filters": [
{
"type": "Category",
"values": [
{
"text": "Projector",
"data": 1
},
{
"text": "Graphics Card",
"data": 2
},
{
"text": "Accessory",
"data": 4
},
{
"text": "Printer",
"data": 2
},
{
"text": "Monitor",
"data": 3
},
{
"text": "Laptop",
"data": 1
},
{
"text": "Keyboard",
"data": 1
}
]
},
{
"type": "SupplierName",
"values": [
{
"text": "Titanium",
"data": 3
},
{
"text": "Technocom",
"data": 3
},
{
"text": "Red Point Stores",
"data": 5
},
{
"text": "Very Best Screens",
"data": 3
}
]
}
]
}
};
var oTemplate11 = new sap.m.StandardListItem({title : "{Name}"});
oList.setModel(new sap.ui.model.json.JSONModel(data));
oList.bindItems("/ProductCollection");
oList.placeAt('content');
},
getGroupHeader: function (oGroup){
return new sap.m.GroupHeaderListItem( {
title: oGroup.key,
upperCase: false
});
},
});
Your call to bind items to the list is not entirely correct.
The method takes an object with binding information as parameter instead of just the path to the model property. See the documentation for bindItems and bindAggregation in general.
In your case it should look like
oList.bindItems({
path: "/ProductCollection",
template: new sap.m.StandardListItem({
title: "{Name}",
description: "{ProductId}",
icon: "{ProductPicUrl}"
})
});

Kendo grid with declarative editor template

Hopefully someone can help me with this - I've been staring at this for 8 hours and can't seem to find a solution. I'm trying to implement a pretty simple Kendo UI MVVM grid. The grid just has a list of roles with an attached category. When you click edit, the grid should allow an inline edit and the category column should turn into a drop down - which is a template that is also bound to a field in the view model.
Here's my jsfiddle: http://jsfiddle.net/Icestorm0141/AT4XT/3/
The markup:
<script type="text/x-kendo-template" id="someTemplate">
<select class="form-control categories" data-auto-bind="false" data-value-field="CategoryId" data-text-field="Description" data-bind="source: categories"></select>
</script>
<div class="manage-roles">
<div data-role="grid"
data-scrollable="true"
data-editable="inline"
data-columns='[
{ "field" : "JobTitle", "width": 120, "title" : "Job Title Code" },
{ "field" : "Description" },
{ "field" : "Category", "template": "${Category}","editor" :kendo.template($("#someTemplate").html()) },
{"command": "edit"}]'
data-bind="source: roles"
style="height: 500px">
</div>
</div>
And the javascript:
var roleViewModel = kendo.observable({
categories: new kendo.data.DataSource({
data: [
{ "CategoryId": 1, "Description": "IT" },
{ "CategoryId": 2, "Description": "Billing" },
{ "CategoryId": 3, "Description": "HR" },
{ "CategoryId": 4, "Description": "Sales" },
{ "CategoryId": 5, "Description": "Field" },
{ "CategoryId": 10, "Description": "Stuff" },
{ "CategoryId": 11, "Description": "Unassigned" }
]
}),
roles: new kendo.data.DataSource({
data: [
{ "RoleId": 1, "JobTitle": "AADM1", "Description": "Administrative Assistant I", "Category": "Stuff", "CategoryId": 10 },
{ "RoleId": 2, "JobTitle": "AADM2", "Description": "Administrative Assistant II", "Category": null, "CategoryId": 0 },
{ "RoleId": 3, "JobTitle": "ACCIN", "Description": "Accounting Intern", "Category": null, "CategoryId": 0 },
{ "RoleId": 4, "JobTitle": "ACCSU", "Description": "Accounting Supervisor", "Category": null, "CategoryId": 0 }, { "RoleId": 5, "JobTitle": "ACCTC", "Description": "Accountant", "Category": null, "CategoryId": 0 }
]
})
});
kendo.bind($(".manage-roles"), roleViewModel);
I havent been able to figure out why the editor template is not binding the drop down. When I use the same markup for template rather than binding to the category name with ${Category}, it works for the template property. (For some reason this doesnt work in fiddle. But the exact same code works locally).
At this point I'll take any suggestions/approaches anything. I really wanted to use MVVM and not the .kendoGrid() syntax but I'll get over myself if it cannot be done. Anyone got any insight into whats going on with the editor template?
You can still build your grid using MVVM, but I think you have to make custom editors with a function call.
So instead of "editor" :kendo.template($("#someTemplate").html()), you just call a function.
edit: rolesViewModel.categoryEditor
See http://demos.kendoui.com/web/grid/editing-custom.html
See sample http://jsbin.com/UQaZaXO/1/edit