i have a question regarding the dojotoolkit.
I have a DataGrid and want to get a value inside of it. The tricky part is, that the value is a
TextBox.
My structure for the DataGrid looks like this:
grid = new dojox.grid.DataGrid({
store: store,
structure: [
{
name: "Quantity", field: "Quantity", width: "30px",
formatter: function(item)
{
var tb = new dijit.form.TextBox(
{
name: "quantity",
value: "1",
placeHolder: "quantity",
});
return tb;
}
},
{ name: "Value", field: "Value", width: "auto"}
]
}, "bGrid");
I have furthermore a button which can be clicked.
If the button was clicked, this function is executed:
myClass.prototype.Test = function Test(tItem)
{
var item = tItem;
var val = grid.getItem(item.value); //Value in this case is an integer refering to the position of my item in the grid
var quantity;
var name;
if(val!==null){
var store = grid.store;
quantity = store.getValue(val, 'Quantity');
name = store.getValue(val, 'Value');
}
console.log("Quantity "+quantity+ " Name: "+name);
}
the name variable is set correctly but i don't get anything from quantity.
I would guess that i would get the TextBox but i receive nothing.
Does anybody know how to access the field of the store ?
I think because the Textbox is a widget you can get access to its value by setting an id for it and get the element by
dijit.byId("YourTB").get('value');
Regards, Miriam
Related
document_table_Settings : function ()
{
return{
rowsPerPage: 5,
showNavigation: 'auto',
showColumnToggles: false,
fields: [
{key: 'para',label: 'Para',sortable: false},
{key: 'desc', label: 'Description',sortable: false},
{
key: 'rowId', label: 'Delete',sortable: false, fn: function (rowId, object) {
var html = "<button name='Del' id=" + rowId + " class='btn btn-danger'>Delete</button>"
return new Spacebars.SafeString(html);
}
},
{
key: 'rowId', label: 'Edit',sortable: false, fn: function (rowId, object) {
var html = "<button name='edit' id=" + rowId + " class='btn btn-warning'>Edit</button>"
return new Spacebars.SafeString(html);
}
}
]
};
}
I want to show description entries having show more and show less feature .As the description is long enough. so after 100 character it shows button to toggle.
If I understand you correctly, you are trying to only show the first 100 characters of the 'Description' column in the Reactive Table and then add some mechanism so that the user can click or rollover to see the entire 'Description' text.
There are a few ways to achieve this and I have provided two options below (in order of simplicity).
For a low tech rollover option, truncate the text to only show the first 100 characters, add an ellipsis (...) to the end of your text, then use the title property in a span element to show the full text on rollover.
First you will need to define a 'truncate' Template helper (I would make this a global helper so that you can use anywhere in your app).
Template.registerHelper('truncate', function(strValue, length) {
var len = DEFAULT_TRUNCATE_LENGTH;
var truncatedString = strValue;
if (length && length instanceof Number) {
len = length;
}
if (strValue.length > len) {
truncatedString = strValue.substr(1, len) + "...";
}
return truncatedString;
});
Then create a new Template for the column.
<template name="field_description">
<span title="{{data.description}}">{{truncate data.description}}</span>
</template>
And finally, change your Reactive Table configuration to use a Template.
fields: [
...,
{ key: 'desc', label: 'Description', tmpl: Template.field_description }
...,
];
For a slightly more complicated option, you can take a similar approach but add a clickable link that would show more or less detail. To get it to work you have to define a few Reactive Vars, define an event handler, and change your 'Description' Template accordingly. Here is a rough solution that should work.
Change your template like so.
<template name="field_description">
<span>{{truncatedDescription}}
{{#if showLink}}
{{linkState}}
{{/if}}
</span>
</template>
Then add the necessary logic to your field_description template (including an event handler).
import { Template } from 'meteor/templating';
import './field-description.html';
Template.field_descirption.onCreated(function() {
const MAX_LENGTH = 100;
this.description = new ReactiveVar(Template.currentData().description);
this.showMore = new ReactiveVar(true);
if (this.description.get().length > MAX_LENGTH) {
this.description.set(Template.currentData().description.substr(1, MAX_LENGTH));
}
this.showLink = () => {
return Template.currentData().description.length > MAX_LENGTH;
};
this.toggleTruncate = () => {
if (this.showMore.get()) {
this.description.set(Template.currentData().description);
this.showMore.set(false);
} else {
this.description.set(Template.currentData().description.substr(1, MAX_LENGTH));
this.showMore.set(true);
}
};
});
Template.field_descirption.helpers({
truncatedDescription: function() {
return Template.instance().description.get();
},
showLink: function() {
return Template.instance().showLink();
},
linkState: function() {
if (Template.instance().showMore.get()) {
return 'show more';
} else {
return 'show less';
}
};
});
Template.field_descirption.events({
'click .js-more-less'(event, instance) {
instance.toggleTruncate();
},
});
Lastly, make sure your Reactive Table config is still setup to use a Template for the field.
fields: [
...,
{ key: 'desc', label: 'Description', tmpl: Template.field_description }
...,
];
Note that the second option makes use of Meteor's Reactivity to solve the problem. Let me know if you need additional explanation on how the 2nd solution works.
That should do it!
I have the following Webix combo:
{
view: "combo",
label: 'Select the name',
labelWidth:130,
options: {
data:[
{ itemId:"120", itemName:"Name 1"},
{ itemId:"121", itemName:"Name 2"}
],
body: { template: '#itemName#' }
},
on:{
onChange:function(id){ alert(id) }
}
}
It looks just as needed, but how can I get itemId after selecting new item? I can only get the auto-generated ID
The same code in a snippet:
http://webix.com/snippet/3a431f1c
Thanks in advance!
You have to get the object of the combobox and then you can get data of the selected item with the help of its getItem() method as:
var obj = this.getPopup().getBody().getItem(newValue); //the object
var id = obj.itemId; //the desired id which is itemId in your code
Please check the snippet here.
So I have a Select that has its options from a computed. I want to select a default every time the selects options change.
I have tried several different ways of doing it:
subscribe to list - is called before list has returned so changes the value of the observable alright but it dosnt render right because the list changes AFTER.
afterRender - Does not work with this type of binding.
OptionsafterRender - works, as in the fiddle below, HOWEVER its called for every individual item rather then just once on the whole render so strikes me as the Wrong Way to do this.
var rawData = [{
Type: "1",
Color: "Blue",
Name: "Blue Car"
}, {
Type: "2",
Color: "Blue",
Name: "Blue House"
}, {
Type: "1",
Color: "Red",
Name: "Red Car"
}, {
Type: "2",
Color: "Red",
Name: "Red House"
}];
var viewModel = {
FirstSelectedOption: ko.observable(),
SecondSelectOptions: null,
SecondSelectedOption: ko.observable(),
Load: function() {
var self = viewModel;
self.SecondSelectOptions = ko.computed(function() {
var selected = self.FirstSelectedOption();
var returnValue = new Array({
Type: "*",
Color: "All",
Name: "All"
});
var filteredlist = ko.utils.arrayFilter(rawData, function(item) {
return item.Type == selected;
});
returnValue = returnValue.concat(filteredlist);
return returnValue;
}, self);
self.SecondSelectedOption.SetDefault = function() {
// we want the default to always be blue instead 'all', blue might not be the last option
var self = viewModel;
var defaultoption = ko.utils.arrayFirst(self.SecondSelectOptions(), function(item) {
return item.Color == "Blue";
});
self.SecondSelectedOption(defaultoption);
};
}
};
viewModel.Load();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="value: FirstSelectedOption">
<option value="1">Car</option>
<option value="2">House</option>
</select>
<br/>
<select data-bind="options: SecondSelectOptions,
optionsText: 'Name',
value: SecondSelectedOption,
optionsAfterRender: SecondSelectedOption.SetDefault"></select>
http://jsfiddle.net/dt627rkp/
The only way I can think off off the top of my head is a custom binding...and im not even sure that would really be possible without reimplemnting the entire options binding.
I can't be the first one to want this, is there a best practice/way that I'm missing?
The optionsAfterRender callback passes 2 parameters: option (element), and item (data bound to the option). The callback already loops over the options, so no need to reiterate:
self.SecondSelectedOption.SetDefault = function (option, item) {
var self = viewModel;
if (item.Color === 'Blue')
self.SecondSelectedOption(item);
};
Updated fiddle
Ref: from the docs
EDIT: That being said, if you don't want the options to re-evaluate every time,
you could also simply bind the change event with the setDefault method on the first <select>. If I were faced with this code 'issue', I would probably preprocess the data into separate arrays, like in this fiddle
Currently i am using the Dojo dgrid with select box,textbox and two checkboxes but i am not able to disable the whole row selection and also when i click the second checkbox the dgrid select and deselect not working and its reflecting the first checkbox.
1.How to disable the whole row selection in dojo Dgrid?
2.How to get the values of Dgrid selectbox and Dgrid textbox when i click on save?
3.If i use selectors(Checkbox) i am not able to render the label for that column?
var columns = {
person :{
sortable: false,
renderCell: lang.hitch(this, function(object,value,node) {
if(value == true){
myTextBox = new dijit.form.TextBox({
name: "Amount",
value: "" ,
placeHolder: "Enter Amount"
}).placeAt(node);
}
})
},
description:{
label:"description",
field:"description",
sortable: false,
renderCell : lang.hitch(this, function(object,
value, node, options) {
new Select({
name : "select",
options : [ {
label : "Daily",
value : "daily"
}, {
label : "Weekly",
value : "weekly",
}]
}).placeAt(node);
}),
},
email : selector({
sortable:false,
field:"email"
})
/*i tried this instead of using selectors inserting a checkbox so that i can remove complete row selection but not working*/
email: {
sortable:false,
field:"email",
renderHeaderCell : function(node) {
var cellDiv = domConstruct.create("label", {
innerHTML : "Email"
}, node);
var checkBox = new CheckBox({
name: "checkBox",
id:"emailAddress",
checked: false,
}, cellDiv);
},
renderCell:createMessageLabel
}
};
function createMessageLabel(object,value, node,options){
console.log("node option",node);
var checkbox = new CheckBox({
name: "checkBox",
id:"emailAddress",
checked: false,
}).placeAt(node);
};
var grid = new GridView().show(gridData, columns, "",
"dgridAutoHeight", true);
function addSelection(self, event) {
console.log("Row selected: ", event.rows[0].data);
}
function removeSelection(self, event) {
console.log("Row deselected: ", event.rows[0].data);
}
grid.startup();
grid.on("dgrid-select", lang.hitch(grid, addSelection, this), true);
grid.on("dgrid-deselect", lang.hitch(grid, removeSelection, this), true);
Hope i can get some valuable answers....
To disable direct selection, set selectionMode: "none" in the properties passed to the constructor. This does not affect selection via a selector column.
You should still be able to set the label in the header cell of a selector column by setting the label property in the object passed to the selector column plugin.
If you want to use Dijit form widgets for the purpose of changing values of fields in items, you should probably not be defining renderCell functions yourself, but instead use the editor column plugin, which does the work of maintaining the state of data and putting it back in the store when you call save.
Thank you so much Ken for your valuable answer and as you said editor suits perfect for the above situation....but i have an another doubt like can't we user editor inside a renderCell like below as i needed the value of textbox on datachange so i thought of using editor inside rendercell....below code is working fine but the TextBox is not getting placed inside a particular node(Textbox view is not getting rendered) whereever the value is "True"....
dollarThresholdAvailable :{
field: "dollarThresholdAvailable",
label : "Threshold Limit",
sortable: false,
"class":"dollarThresholdAvailableValue",
renderCell: lang.hitch(this, function(object,value,node) {
if(value === true){
editor({
field: "dollarThresholdAvailable",
sortable: false
},TextBox).placeAt(node);
}
}),
}
I have a dojox.grid.DataGrid. In this a set of values are being displayed along with last 2 columns being filled up with buttons which are created dynamically according to data being retrieved from database using formatter property in gridStruture. Now i am getting the my grid fine. Buttons are also coming up fine. What i need to do now is when i click on a particular button on that button click event i redirect it to a new URL with a particular value(A) being passes as a query string parameter in that URL. And i don't want my page to be refreshed. Its like when a button is clicked it performs action on some other JSP page and displays message alert("Action is being performed").
My java script code where i have coded for my data grid ::
<script type="text/javascript">
function getInfoFromServer(){
$.get("http://localhost:8080/2_8_2012/jsp/GetJson.jsp?random=" + new Date().getTime(), function (result) {
success:postToPage(result),
alert('Load was performed.');
},"json");
}
function postToPage(data){
alert(data);
var storedata = {
identifier:"ActID",
items: data
};
alert(storedata);
var store1 = new dojo.data.ItemFileWriteStore({data: storedata}) ;
var gridStructure =[[
{ field: "ActID",
name: "Activity ID",
classes:"firstName"
},
{
field: "Assigned To",
name: "Assigned To",
classes: "firstName"
},
{ field: "Activity Type",
name: "Activity Type",
classes:"firstName"
},
{
field: "Status",
name: "Status",
classes: "firstName"
},
{
field: "Assigned Date",
name: "Assigned Date",
classes: "firstName"
},
{
field: "Assigned Time",
name: "Assigned Time",
classes: "firstName"
},
{
field: "Email",
name: "Send Mail",
formatter: sendmail,
classes: "firstName"
},
{
field: "ActID",
name: "Delete",
formatter: deleteact,
classes: "firstName"
}
]
];
//var grid = dijit.byId("gridDiv");
//grid.setStore(store1);
var grid = new dojox.grid.DataGrid({
store: store1,
structure: gridStructure,
rowSelector: '30px',
selectionMode: "single",
autoHeight:true,
columnReordering:true
},'gridDiv');
grid.startup();
dojo.connect(grid, "onRowClick", grid, function(){
var items = grid.selection.getSelected();
dojo.forEach(items, function(item){
var v = grid.store.getValue(item, "ActID");
getdetailsfordialog(v);
function showDialog() {
dojo.require('dijit.Tooltip');
dijit.byId("terms").show();
}
showDialog();
}, grid);
});
}
function sendmail(item) {
alert(item);
return "<button onclick=http://localhost:8080/2_8_2012/jsp/SendMailReminder.jsp?Send Mail="+item+"'\">Send Mail</button>";
}
function deleteact(item) {
alert(item);
return "<button onclick=http://localhost:8080/2_8_2012/jsp/DeleteActivity.jsp?Activity ID="+item+"'\">Delete</button>";
}
</script>
I am getting grid data using $.get call. In the above code field Email and ActID are actually buttons being created when each time function sendmail and deleteact are being called up in formatter. Grid is displayed. Also the value of alert(item) in both functions are coming up right that is there respective values. Like for alert(item) in Delete i am getting ActID and alert(item) in sendmail getting "shan#gmail.com" Now i want that on a particular button click(button in Sendmail column) my page
http://localhost:8080/2_8_2012/jsp/SendMailReminder.jsp?Send Mail="+item+"'
and button click in Delete column this page
http://localhost:8080/2_8_2012/jsp/DeleteActivity.jsp?Activity ID="+item+"'\"
opens up with value of items being retrieved from database. I have applied a rowClick event also which is also causing problem as when i click u button my Rowclick event fires instead of button click event. How to do this. I thought of applying click event to each button on grid. But there ID i don't know. Please help me on this one. Thanks..
I think, what you need is adjusting your server-side code to handle ajax post requests for sending mail and use dojo.xhrPost method when user clicks button. Your JS code may look like this:
function sendMailHandler(evt, item) {
dojo.xhrPost({
url: "/2_8_2012/jsp/SendMailReminder.jsp",
content: {
'SendMail': item
},
error: function() {
alert("Sent failure");
},
load: function(result) {
alert("Email sent with result: " + result);
}
});
dojo.stopEvent(evt);
}
function sendmail(item) {
return "<button onclick='sendMailHandler(arguments[0], \"" + item + "\")'>Send Mail</button>";
}
Note that dojo.stopEvent(evt); in sendMailHandler is used to stop event bubbling and prevents RowClick raising.
There is also dojo.xhrGet with similar syntax to perform ajax GET requests, which you can use instead of jQuery's $.get. You can also use dojo.xhrGet instead of dojo.xhrPost in my example, because there is chance that it will work with your back-end without tweaking, but POST (or ajax form submission) would be more semantically correct.
And about "Tried to register an id="something", you should adjust your code to avoid IDs duplication. Or show your code causing errors.