Adding two numbers in lightswitch 2013 - visual-studio-2013

I used this code for adding two numbers
//contentItem.dataBind("screen.Table1Item.Value1", function (newValue) {
// contentItem.screen.Property1 =(contentItem.screen.Table1Item.Value1);
//});
//contentItem.dataBind("screen.Table1Item.Value2", function (newValue) {
// contentItem.screen.Property1 = (contentItem.screen.Table1Item.Value2);
//});
//contentItem.dataBind("screen.Table1Item.Property1", function (newValue) {
// contentItem.screen.Property1 = (contentItem.screen.Table1Item.Value1) + (contentItem.screen.Table1Item.Value2);
//});
Instead of adding the numbers it is appending.Is there anyone who can help me to figure out this issue?

this works:
myapp.ViewTable1Item.Property1_postRender = function (element, contentItem) {
function updateTotalAmount() {
element.innerText =
contentItem.screen.Table1Item.value1 +
contentItem.screen.Table1Item.value2;
}
contentItem.dataBind("screen.Table1Item.value1", updateTotalAmount);
contentItem.dataBind("screen.Table1Item.value2", updateTotalAmount);
};
both value1 and value2 are set as integers in the table.
Property1 is a data item set as an integer

Related

dc.js filtering on multi-criteria dimension

I can't figure out how to get the following filter on column A working, in case multiple columns are used for a dimension in dc.js:
var Dimension = dim.dimension(function(d) {
return [d.columnA, d.columnB, d.columnC];
});
var Measure = Dimension.group().reduceSum(function(d) {
return d.columnD;
});
Dimension.filter("Value_in_columnA");
In case only a single column is used in the dimension, a filter works fine as follows:
var Dimension = dim.dimension(function(d) {
return d.columnA;
});
var Measure = Dimension.group().reduceSum(function(d) {
return d.columnB;
});
Dimension.filter("Value_in_columnA");
Does anyone have an idea how to get it working?
Fixed, solution is as follows:
var Dimension = dim.dimension(function(d) {
return [d.columnA, d.columnB, d.columnC];
});
var Measure = Dimension.group().reduceSum(function(d) {
if (d.columnA === 'Value_in_columnA') {
return d.columnD;
} else {
return 0;
}
});

Kendo Grid always focus on first cell of Top Row

I have checkbox in Kendo grid. Once i click on Checkbox it always focus the top cell in Kendo Grid. Below is code for Kendo grid that I am binding to checkbox value on checkbox click event in Kendo Grid
$("#contactgrid").on('click', '.chkbx', function () {
var checked = $(this).is(':checked');
var grid = $('#contactgrid').data().kendoGrid;
var rowIdx = $("tr", grid.tbody).index(row);
var colIdx = $("td", row).index(this);
// grid.tbody.find("tr").eq(rowIndex).foucs(); This doesn't work
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set('IsSelected', checked);
});
I can get the row index and cell Index in click event but I was not able to figure out to focus the specific cell.
Thanks!
When you want to edit Grid with checkbox then I would suggest you to use the approach from this code library. No matter it uses the MVC extensions open Views/Home/Index.cshtml and see how the template is defined and the javascript used after initializing the Grid.
Here it is
Column template:
columns.Template(#<text></text>).ClientTemplate("<input type='checkbox' #= IsAdmin ? checked='checked':'' # class='chkbx' />")
.HeaderTemplate("<input type='checkbox' id='masterCheckBox' onclick='checkAll(this)'/>").Width(200);
<script type="text/javascript">
$(function () {
$('#persons').on('click', '.chkbx', function () {
var checked = $(this).is(':checked');
var grid = $('#persons').data().kendoGrid;
var dataItem = grid.dataItem($(this).closest('tr'));
dataItem.set('IsAdmin', checked);
})
})
function checkAll(ele) {
var state = $(ele).is(':checked');
var grid = $('#persons').data().kendoGrid;
$.each(grid.dataSource.view(), function () {
if (this['IsAdmin'] != state)
this.dirty=true;
this['IsAdmin'] = state;
});
grid.refresh();
}
</script>
I struggled with this. I essential refocused the cell as shown below. There's plenty of room for improvement in the Kendo grid client-side API. Hopefully my helper methods below will help people out.
var $row = getRowForDataItem(this);
var $current = getCurrentCell($row);
var currentCellIndex = $row.find(">td").index($current);
this.set('PriceFromDateTime', resultFromDate);
$row = getRowForDataItem(this);
var grid = getContainingGrid($row);
//select the previously selected cell by it's index(offset) within the td tags
if (currentCellIndex >= 0) {
grid.current($row.find(">td").eq(currentCellIndex));
}
//Kendo grid helpers
function getColumn(grid, columnName) {
return $.grep(grid.columns, function (item) {
return item.field === columnName;
})[0];
}
function getRowForDataItem(dataItem) {
return $("tr[data-uid='" + dataItem.uid + "']");
}
function getCurrentCell($elem) {
return getContainingGrid($elem).current();
}
function getContainingDataItem($elem) {
return getDataItemForRow(getContainingRow($elem));
}
function getContainingCell($elem) {
return $elem.closest("td[role='gridcell']");
}
function getContainingRow($elem) {
return $elem.closest("tr[role='row']");
}
function getContainingGrid($elem) {
return $elem.closest("div[data-role='grid']").data("kendoGrid");
}
function getGridForDataItem(dataItem) {
return getContainingGrid(getRowForDataItem(dataItem));
}
function getDataItemForRow($row, $grid) {
if (!$grid) $grid = getContainingGrid($row);
return $grid.dataItem($row);
}
function getMasterRow($element) {
return $element.closest("tr.k-detail-row").prev();
}
function getChildGridForDataItem(dataItem) {
return getRowForDataItem(dataItem).next().find("div.k-grid").data("kendoGrid");
}
function getMasterRowDataItem($element) {
var $row = getMasterRow($element);
return getDataItemForRow($row);
}

Update knockout viewmodel when uploading documents via ajax

I'm trying to use knockout for a view where I'm uploading documents and showing a list. For this I'm using jquery.form.js in order to upload them using ajax. I've changed that to use knockout and my viewmodel looks like this
var ViewModel = function (groups) {
var self = this;
self.groups = ko.observableArray(ko.utils.arrayMap(groups, function (group) {
return {
planName: ko.observable(group.Key),
documentList: ko.observableArray(ko.utils.arrayMap(group.Values, function (value) {
return {
document: ko.observable(new Document(value))
};
}))
};
}));
var options = {
dataType: 'json',
success: submissionSuccess
};
self.add = function () {
$('#addForm').ajaxSubmit(options);
return false;
};
function submissionSuccess(result) {
alert('success');
}
};
Having one Document function for doing the mapping. I'm stuck when receiving the Json data from the controller. The result is correct, a list of objects in the same format I'm receiving on first load but I don't know how to "refresh" the viewmodel to use this new list.
Don't know if using the ko mapping plugin would make it easier as I have never used it and don't even know if it's applicable for this.
The controller method, in case is relevant, is this (if something else neede let me know althoug won't have access to the code in the next hours)
[HttpPost]
public ActionResult AddDocument(AddDocumentViewModel viewModel)
{
var partyId = Utils.GetSessionPartyId();
if (viewModel.File.ContentLength > Utils.GetKBMaxFileSize * 1024)
ModelState.AddModelError("File", String.Format("The file exceeds the limit of {0} KB", Utils.GetKBMaxFileSize));
if (ModelState.IsValid)
{
_documentsManager.AddDocument(viewModel, partyId);
if (Request.IsAjaxRequest())
{
var vm = _displayBuilder.Build(partyId);
return Json(vm.Documents);
}
return RedirectToAction("Index");
}
var newViewModel = _createBuilder.Rebuild(viewModel, partyId);
return PartialView("_AddDocument", newViewModel);
}
Thanks
EDIT: I came up with this code which seems to work (this function is inside the ViewModel one
function submissionSuccess(result) {
self.groups(ko.utils.arrayMap(result, function (group) {
return {
planName: ko.observable(group.Key),
documentList: ko.utils.arrayMap(group.Values, function (value) {
return {
document: new Document(value)
};
})
};
}));
};
Are you sure the documentList and document need to be observables themselves ?
To update the list you can push to it as you'd do on a regular array.
You could try something like this:
function submissionSuccess(result) {
self.groups.removeAll();
$.each(result, function(index, value) {
var documentList = [];
$.each(value.Values, function(index, value) {
documentList.push(new Document(value));
});
var group = {
planName:value.Key,
documentList: documentList
};
self.groups.push(group);
});
};

multiple knockout validators on an observablearray

I tried to define multiple custom validation rules under a observable array, I was referring to https://github.com/ericmbarnard/Knockout-Validation/wiki/Custom-Validation-Rules.
Following is my observablearray with the validation calls:
this.WeeklyData = ko.observableArray([]).extend({
validation: [
{
validator : fminIncrements,
message: 'use 15 min increments'
},
{
validator: ValidateMinMax,
message: "Invalid min/max value"
}
]
});
var ValidateMinMax = function (valueArray) {
var check = true;
ko.utils.arrayFirst(valueArray, function (value) {
if (parseInt(value.Val(), 10) < 0 || parseInt(value.Val(), 10) > 168) {
check = false;
return true;
}
});
return check;
};
var fminIncrements = function (valueArray) {
var check = true;
ko.utils.arrayFirst(valueArray, function (value) {
if (parseInt(value.Val(), 10) % 15 !== 0) {
check = false;
return true;
}
});
return check;
};
when I do this only the first rule fires. I debugged, and it doesn't even hit the second one. Any idea?
Thanks in advance for any help.
I believe its because you are using the ko.utils.arrayFirst(). If you use the ko.utils.arrayForEach() instead to check for every case then it shouldn't return at the first occurrence.

MVVM binding to a Kendo Grid is VERY slow?

I am trying to bind a ViewModel to a Kendo DataSource which in turn is given to a Kendo Grid. Nothing too fancy at this point.
It sort of works but is VERY slow! I have an alert informing me that I have received my json data (700 rows) within 2 seconds but it then takes around 15 seconds to update the viewmodel.
What am I doing wrong?
Thanks
$(document).ready(function () {
// create the viewmodel we use as the source for the list
var viewModel = kendo.observable({
items: [],
total: function () {
return this.get("items").length;
}
});
var dataSource2 = new kendo.data.DataSource({
data: viewModel,
pageSize: 50
});
// create the grid
$("#grid").kendoGrid({
dataSource: dataSource2,
height: 500,
scrollable: {
virtual: true
},
columns: [
{ field: "ID_ORDER", title: "ID", width: 80 },
{ field: "CREATION_DATE", title: "Creation Date" },
{ field: "STATUS", title: "STATUS", width: 80 },
** more columns (around 10) **
]
});
// pass this on to initialise
APPS.View.Orders.Initialise(viewModel);
});
Then in my typescript I am handling the Initialise call where the viewModel is passed in:
module APP.View.Orders {
export var _Scope: string = "Orders";
var _viewModelOrders: any;
export var Initialise = function (viewModelOrders: any) {
_viewModelOrders = viewModelOrders;
var orderdetails = {
userid: APP.Core.userID,
context: "DEAL"
};
// retrieve all orders
$.getJSON("/api/omsapi/GetOrders", orderdetails, function (mydata) {
try {
alert("item count (1): " + mydata.length);
jQuery.each(mydata, function () {
var newItem = this;
_viewModelOrders.items.push(newItem);
});
alert("item count (2): " + _viewModelOrders.items.length);
}
catch (e) {
alert(e.message);
}
});
}
}
Try building the item array and then assign it into the model.
Something like:
// retrieve all orders
$.getJSON("/api/omsapi/GetOrders", orderdetails, function (mydata) {
try {
alert("item count (1): " + mydata.length);
var items = [];
jQuery.each(mydata, function () {
items.push(this);
});
_viewModelOrders.items = items;
alert("item count (2): " + _viewModelOrders.items.length);
}
catch (e) {
alert(e.message);
}
});
You can suspend the observable temporarily by doing the following:
$.getJSON("/api/omsapi/GetOrders", orderdetails, function (mydata) {
try {
var simpleArray = viewModel.items(); // get a reference to the underlying array instance of the observable
jQuery.each(mydata, function () {
items.push(this);
});
viewModel.items.valueHasMutated(); // let the observable know it's underlying data has been updated
}
catch (e) {
alert(e.message);
}
}
Doing the above technique dramatically improves loading times. I have testing this loading a few thousand rows in a reasonable time.
To explain further, this is due to the line:
_viewModelOrders.items.push(newItem);
Each time you push an item into the array, it triggers a change event, which the Grid sees and updates itself. So if you push 700 items in, you are really causing the grid to update the DOM 700 times.
It would be much better to aggregate all the items into an array, then assign the array to the DataSource, with something like:
$.getJSON("/api/omsapi/GetOrders", orderdetails, function (mydata) {
datasource2.data(mydata);

Resources