Then dhtmlxLayout cell is collapsed, how can I make the header text as center align and how to make the entire tab cell as clickable when it is in collapsed state?
I have the next code:
dhxLayout = new dhtmlXLayoutObject(document.body, "3U");
dhxLayout.cells('a').setText('<div id="a">Text to Center</div>');
dhxLayout.cells('b').setText('<div id="b">Text to Center</div>');
dhxLayout.attachEvent("onDblClick", function (itemId){
//how can I do it here?
}
You can try the next approach:
var h, panName;
function doOnLoad() {
dhxLayout = new dhtmlXLayoutObject(document.body, "3U");
//put cell text in a div
dhxLayout.cells('a').setText('<div id="a">Text to Center</div>');
dhxLayout.cells('b').setText('<div id="b">Text to Center</div>');
//use double click to collapse/expand cell
dhxLayout.attachEvent("onDblClick", function (itemId){
if (dhxLayout.cells(itemId).isCollapsed() == false){
dhxLayout.cells(itemId).collapse();
}
else dhxLayout.cells(itemId).expand();
});
//center the label
dhxLayout.attachEvent("onCollapse", function(name){
panName = name;
recount(panName)
});
dhxLayout.attachEvent("onPanelResizeFinish", function(){
recount(panName)
});
dhxLayout.attachEvent("onResizeFinish", function(){
recount(panName)
});
}
function recount(panName){
h = dhxLayout.cells("a").getHeight();
document.getElementById(panName).style.width = (h-20)+"px";
document.getElementById(panName).style.textAlign = 'center';
}
Related
Seems like a simple task but I have been unsuccessful so far using Slickgrid to get the row number of the highlighted row in a grid when I press a key, specifically the Enter key. I need no data, just the row number so I can use it to reference an array element.
I have managed to do this with the mouse using the onDblClick event handler but not with the simple onKeyDown handler.
Here is the function I use to fill the grid with data which I call when specifically needed:
var grid;
function ttesting(){
var data=[];
load_text_resource(descsource);
grid = new Slick.Grid("#myGrid", data, columns, options);
grid.invalidate();
//load data from multidimensional array:
for (var i = 0; i < maxdesc-2; ++i) {
data[i] = {
aName: descarray[i][2] + " " + descarray[i][3] + descarray[i][4] + descarray[i][5] + descarray[i][6],
aTitle: descarray[i][8],
aDesc:descarray[i][9]
};
}
grid.setOptions(options);
// the following mouse handler works:
grid.onDblClick.subscribe(function(event) {
var cell = grid.getCellFromEvent(event),
row = cell.row;
alert(descarray[row][10]);
});
//This keyDown handler does not work:
grid.onKeyDown.subscribe(function(event) {
var cell = grid.getCellFromEvent(event),
row = cell.row;
if (event.keyCode == 13) {
alert(descarray[row][10]);
}
}
grid.setSelectionModel(new Slick.RowSelectionModel());
grid.render();
}
All I need to know is the row number of the highlighted row when I press the Enter key. I have also tried using instead in the above with no success:
if (event.keyCode == 13) {
selectRow = grid.getSelectedRows();
alert(selectRow);
}
Suggestions welcome.
The traditional way to do this is to create a custom formatter for the ID column, and embed the value (ie. the row id) into the button or link displayed. For example, here's an edit link that I use to open an external page:
function EditLinkFormatter(rowIndex, cell, value, columnDef, grid, dataProvider) {
if (value == null || value === "" || !columnDef.hyperlink) { return "-"; }
if (typeof value == 'string') { value = urlEncode(value); }
return 'edit';
}
This uses value, which is the value of the ID column for the row, but rowIndex is what you are after. It's there in the formatter parameters too.
Found the solution. I needed to include the args variable in the event function:
grid.onKeyDown.subscribe(function(event,args) {
if (event.keyCode == 13) {
var cell = args.cell,
row = args.row;
alert(descarray[row][10]);
}
});
I am using the formatter:"link" url callback to generate a hyperlink for a certain column in my Tabulator table
tabulatorTable.addColumn({
title: "Value",
field: "JSONDoc.Path.To.Property",
formatter: "link",
formatterParams: {
url: getHyperLink,
target: "_blank"
}
});
Then in my callback function:
function getHyperLink(cellComp) {
var cellData = cellComp.getData();
var propValFromJSONSource = cellData.SomeProperty;
if( propValFromJSONSource != 0) {
return "http://hostname/report/showLog.php?prop=" + propValFromJSONSource;
}
else {
// If here, I can't generate a valid link, so I want to not have a hyperlink and just show the data
return ???;
}
}
Is there anything that I can do in the else statement to return from the formatter to instruct Tabulator to not create a hyperlink?
I've tried:
return ""; // This makes the hyperlink go to "<currentURL>"
return null; // This generates a relative hyperlink to "<currentURL>/null"
return undefined; // This generates a relative hyperlink to "<currentURL>/undefined"
I suspect I might not be able to use the link formatter and will need to switch to a custom formatter callback that returns "
I also have the problem of not being able to left-click on the hyperlink (even though it appears correctly down in the status bar); I can only center click or right-click and choose "Open in new tab". I'm not sure if this a bug within Tabulator, or Chrome not understanding it for some reason, but that shall be another SO question...
For now, I'm recommending the use of a custom formatter:
tabulatorTable.addColumn({
title: "Value",
field: "JSONDoc.Path.To.Property",
formatter: getHyperLink,
});
Then have the callback return the html code for a hyperlink or just text:
function getHyperLink(cellComp, formatterParams, onRendered) {
var cellData = cellComp.getData();
var cellValue = cellComp.getValue();
var propValFromJSONSource = cellData.SomeProperty;
if( propValFromJSONSource != 0) {
var hrefString = "http://hostname/report/showLog.php?prop=" + propValFromJSONSource;
return "<a href='" + hrefString + "' target='_blank'>" + cellValue + "</a>";
}
else {
return cellValue;
}
}
I want to remove elements based on ID with double click
Tried this but it is not working:
paper.on('cell:pointerdblclick', function (cellView,cell)
{
selectedId = cellView.model.id;
selected = cellView.model;
$.each(cellsAdded, function(index, value)
{
if(selectedId !== cellsAdded[index])
{
selected.remove();
}
});
});
These are the cells in the graph:
var cellsAdded = graph.addCells([sidebar, rect, circle1, circle2, circle3, rectGroup0, diamond]);
All of the above cells have ids and I dont want to remove them, I only want to remove other elements which are not part of the above
I'm trying to get a table in Titanium where each row has a static text and a textField where I can input something.
So I go and create a row where it's left part is the static text and the right part it's my input text field.
Just a small problem, I can't hide the keyboard by clicking outside of it.
If it was a normal textField outside a table I would just use the blur method, but in this case I can't get that to work.
This is my code so far:
Any idea on how this works and if the solution is valid for both iOS and Android?
var winAddObjectView = Titanium.UI.currentWindow;
var tableAddObjectData = [
{title:'name', hintText:'item name (optional)'},
{title:'track no.', hintText:'object tracking code'}
];
var tableAddObjectRowData = [];
for (var i = 0; i < tableAddObjectData.length; i++) {
var title = Ti.UI.createLabel({
text:tableAddObjectData[i].title,
textAlign:"right",
left:"20",
height:'auto',
width:'68',
color:'#526691',
font:{fontSize:12, fontWeight:'bold'},
});
var textField = Ti.UI.createTextField({
hintText:tableAddObjectData[i].hintText,
textAlign:"left",
left:"96",
height:'auto',
width:'184',
color:'#4C4C4C',
font:{fontSize:12, fontWeight:'bold'},
});
winAddObjectView.addEventListener("click", function(e){
textField.blur();
});
var row = Ti.UI.createTableViewRow({
height:"45",
});
row.add(title);
row.add(textField);
tableAddObjectRowData.push(row);
}
var tableAddObjectView = Ti.UI.createTableView({
headerTitle:'Enter Tracking Information',
style:Titanium.UI.iPhone.TableViewStyle.GROUPED,
backgroundColor:'transparent',
data:tableAddObjectRowData,
});
winAddObjectView.add(tableAddObjectView)
I have made a few changes in your code. Please try this
var tableAddObjectRowData = [];
var textFields = []; //Created an array of textFields
for (var i = 0; i < tableAddObjectData.length; i++) {
var title = Ti.UI.createLabel({
text:tableAddObjectData[i].title,
textAlign:"right",
left:"20",
height:'auto',
width:'68',
color:'#526691',
font:{fontSize:12, fontWeight:'bold'},
});
textFields[i] = Ti.UI.createTextField({ //Creating the textField
hintText:tableAddObjectData[i].hintText,
textAlign:"left",
left:"96",
height:'auto',
width:'184',
color:'#4C4C4C',
font:{fontSize:12, fontWeight:'bold'},
});
var row = Ti.UI.createTableViewRow({
height:"45",
});
row.add(title);
row.add(textFields[i]);
tableAddObjectRowData.push(row);
}
var tableAddObjectView = Ti.UI.createTableView({
headerTitle:'Enter Tracking Information',
style:Titanium.UI.iPhone.TableViewStyle.GROUPED,
backgroundColor:'transparent',
data:tableAddObjectRowData,
height : (tableAddObjectRowData.length * 45) + 60 //Added the height property for the tableView
});
winAddObjectView.addEventListener("click", hideSoftKeyboard); //added event listener to the window, moved this to out of the loop
function hideSoftKeyboard(){ //Added function to hide the keyboard
for(var i=0; i<textFields.length; i++){
textFields[i].blur(); //Hiding each keyboards
}
}
winAddObjectView.add(tableAddObjectView);
Explanation
winAddObjectView.addEventListener("click", function(e){
textField.blur();
});
The above code segment in your program didn't worked because the click event for the window was not firing due to the height of tableView, the window was hidden and your clicks were firing on the tableView. You can see the difference if you set the backgroundColor property for your tableView. So I adjusted the height of the tableView and hence the click fired in the window and the keyboard has gone.
Creation of textField array : You can do the same without creating the textField array and inside the for loop you can create the textField as var textField = Ti.UI.createTextField();. But if you do so, you cannot hide keayboard all the times, since event will be fired for the last textField only. Hence I created the textField array
For Android you can also use Ti.UI.android.hideSoftKeybaord() method. For that just change the hideSoftkeyboard() method in our code as follows
function hideSoftKeyboard(){ //Added function to hide the keyboard
if(Ti.Platform.osname === 'android'){
Ti.UI.Android.hideSoftKeyboard();
} else {
for(var i=0; i<textFields.length; i++){
textFields[i].blur(); //Hiding each keayboards
}
}
}
Using sharepoint build in lookup column and it set to required field. SharePoint automatically selects the first item in the dropdown box (kinda misleading for the end users).
Is there a way to display blank or Null for the first row of this drop down box?
(I am open to any solution. I prefer javascript type solution)
For Choice fields, the default value is configured in the column settings. If the "Default value" input box is populated, delete the value in order to use no default value.
Edit
For Lookup fields, the field seems to change dramatically if it is required. Fields that are NOT required have a "(None)" value by default. However, toggling the field to required will remove the "(None)" value and the first value is selected automatically.
One thing I found, is that if you use JavaScript to add the null value to the dropdown and then try to press OK you get an error page: "An unexpected error has occurred." As a workaround, I wrote some more code to do a quick validation that the field has a value before the form is submitted. If the field has no value, then it will prompt the user and cancel the submit. (Note: this code is only attached to the OK buttons so you may get errors while editing EditForm.aspx.. just choose a value for your lookup field and you'll be able to edit like normal)
Anyways, onto the code... I think the only line you'll need to change is var fieldTitle = 'Large Lookup Field'; to update it to the name of your field.
<script type="text/javascript">
function GetDropdownByTitle(title) {
var dropdowns = document.getElementsByTagName('select');
for (var i = 0; i < dropdowns.length; i++) {
if (dropdowns[i].title === title) {
return dropdowns[i];
}
}
return null;
}
function GetOKButtons() {
var inputs = document.getElementsByTagName('input');
var len = inputs.length;
var okButtons = [];
for (var i = 0; i < len; i++) {
if (inputs[i].type && inputs[i].type.toLowerCase() === 'button' &&
inputs[i].id && inputs[i].id.indexOf('diidIOSaveItem') >= 0) {
okButtons.push(inputs[i]);
}
}
return okButtons;
}
function AddValueToDropdown(oDropdown, text, value, optionnumber){
var options = oDropdown.options;
var option = document.createElement('OPTION');
option.appendChild(document.createTextNode(text));
option.setAttribute('value',value);
if (typeof(optionnumber) == 'number' && options[optionnumber]) {
oDropdown.insertBefore(option,options[optionnumber]);
}
else {
oDropdown.appendChild(option);
}
oDropdown.options.selectedIndex = 0;
}
function WrapClickEvent(element, newFunction) {
var clickFunc = element.onclick;
element.onclick = function(event){
if (newFunction()) {
clickFunc();
}
};
}
function MyCustomExecuteFunction() {
// find the dropdown
var fieldTitle = 'Large Lookup Field';
var dropdown = GetDropdownByTitle(fieldTitle);
if (null === dropdown) {
alert('Unable to get dropdown');
return;
}
AddValueToDropdown(dropdown, '', '', 0);
// add a custom validate function to the page
var funcValidate = function() {
if (0 === dropdown.selectedIndex) {
alert("Please choose a value for " + fieldTitle + ".");
// require a selection other than the first item (our blank value)
return false;
}
return true;
};
var okButtons = GetOKButtons();
for (var b = 0; b < okButtons.length; b++) {
WrapClickEvent(okButtons[b], funcValidate);
}
}
_spBodyOnLoadFunctionNames.push("MyCustomExecuteFunction");
</script>
In response Kit Menke, I've made a few changes to the code so it will persist previous value of the dropdown. I have added the following lines of code to AddValueToDropdown()....
function AddValueToDropdown(oDropdown, text, value, optionnumber){
var selectedIndex
if (oDropdown.options.selectedIndex)
selectedIndex = oDropdown.options.selectedIndex;
else
selectedIndex = -1;
// original code goes here
// changed last line of code (added "selectedIndex+1")
oDropdown.options.selectedIndex = selectedIndex+1;
}
To improve on top of Aaronster's answer: AddValueToDropdown can be done that way:
var injectedBlankValue = false;
function AddValueToDropdown(oDropdown, text, value, optionnumber) {
for (i = 0; i < oDropdown.options.length; i++) {
option = oDropdown.options[i];
if(option.getAttribute('selected')) // If one is already explicitely selected: we skip the whole process
return;
}
var options = oDropdown.options;
var option = document.createElement('OPTION');
option.appendChild(document.createTextNode(text));
option.setAttribute('value', value);
if (typeof (optionnumber) == 'number' && options[optionnumber]) {
oDropdown.insertBefore(option, options[optionnumber]);
}
else {
oDropdown.appendChild(option);
}
// changed last line of code (added 'selectedIndex+1')
oDropdown.options.selectedIndex = 0;
injectedBlankValue = true;
}
This is needed for document libraries where "add" and "set properties" are two distinct pages.
And funcValidate starts with:
var funcValidate = function () {
if (!injectedBlankValue)
return true;
All these changes is to make the whole thing work with document libraries.