I am working on a shopping project. Currently I have a map of Shoppingcart which contains shoppingcart and quantity. I have to iterate the OrderlineDtolist
and add them to the ShoppingcartMap. I have tried and achieved it but I am not sure this as the best. If there are any other ways out please let me know.
Below is a snippet of my code. Please let me know if there is any better way around.
orderLineDTOList.stream().forEach((orderLineDTO) -> {
if (orderLineDTO != null && orderLineDTO.getTempQuantity() != null && orderLineDTO.getTempQuantity() > 0) {
if (shoppingCartItemMap.containsKey(orderLineDTO.getProduct().getProductCode())) {
shoppingCartItem = shoppingCartItemMap.get(orderLineDTO.getProduct().getProductCode());
shoppingCartItem.setQuantity(orderLineDTO.getTempQuantity());
} else {
shoppingCartItem = new ShoppingCartItem(orderLineDTO.getProduct(), orderLineDTO.getTempQuantity());
}
getSession().getShoppingCartItemMap().put(orderLineDTO.getProduct().getProductCode(), shoppingCartItem);
}
});
Java-8 does not provide any new specific construct which would replace if statements. However here you may utilize new methods like Stream.filter and Map.computeIfAbsent to increase the readability:
orderLineDTOList.stream()
.filter(orderLineDTO -> orderLineDTO != null &&
orderLineDTO.getTempQuantity() != null && orderLineDTO.getTempQuantity() > 0)
.forEach((orderLineDTO) ->
shoppingCartItemMap.computeIfAbsent(orderLineDTO.getProduct().getProductCode(),
code -> new ShoppingCartItem(orderLineDTO.getProduct(), 0)
).setQuantity(orderLineDTO.getTempQuantity()));
I assume that getSession().getShoppingCartItemMap() is the same as shoppingCartItemMap.
Related
I have "Optimize Code" in the properties of my C# project turned OFF. This project contains various if statements like...
if (this.Count == 1) {
if (object != null) {
// do something
}
}
Whenever I build this project, the compiled code instead looks like...
bool flag1 = this.Count == 1;
if (flag1) {
bool flag2 = object != null;
if (flag2) {
// do something
}
}
(This happens no matter what the original if condition is, what context the if statement is used in, etc.)
Could I turn this off if I wanted to, and if so, how?
Why does this happen? Is this actually an optimization so important that it bypasses the "Optimize Code" option?
I have a parent table with rows.
When they select a row, an AJAX call fires that returns the child details.
I have multiple text boxes showing child properties
<div class="row">
#Html.CheckBoxFor(m => m.Child.Property)
#Html.LabelFor(m => m.Child.Property)
</div>
but I can't see how to update the text boxes with the child I get back in AJAX results.
The best I've been able to do is manually updating each field from the 'complete' method. But I've got about 30 more fields to add and it feels like the wrong approach.
How do I bind the edit boxes to the returned model without using partials and without refreshing the entire page?
I added Child as a property in the #model, and the TextFor appears to bind properly. But of course
#Model.Child = child
does not. So they never show any data.
This question was based on a misunderstanding on my part. At first I deleted the question when I realized my mistake. I'm reinstating it because I think it is an easy mistake for a noobie to fall into and once you do, the answer is hard to sort out.
The problem is that #model no longer exists once the page is rendered. There is no data binding going on behind the scenes as I thought there was.
Your options are
populating the elements manually. (this will need editing to fit your particular elements)
function DisplayMergeSection(data) {
for (var key of Object.keys(data)) {
DisplayElement(data, key, "#Clients_");
}
}
function DisplayElement(data, key, prefix) {
return;
var val = data[key];
var valString = data[key + "String"];
var element = $(prefix + key)[0];
if (element && element.type === 'text') {
if ((val || '').toString().indexOf("Date(") > -1) {
var dtStart = new Date(parseInt(val.substr(6)));
element.value = moment(dtStart).format('MM/DD/YYYY');
} else {
element.value = val;
}
} else if (element && element.type === 'checkbox') {
element.checked = val;
} else if (element && element.type === 'select-one') {
element.value = valString;
} else if (element && element.nodeName === 'DIV') {
if ((val || '').toString().indexOf("Date(") > -1) {
var dtStart = new Date(parseInt(val.substr(6)));
element.innerText = moment(dtStart).format('MM/DD/YYYY');
} else {
element.innerText = val;
}
}
}
create a bunch of observables with knockout and then set up data binding. This is a lot cleaner.
https://knockoutjs.com/documentation/json-data.html
set up a mapping with the knockout plugin.
https://knockoutjs.com/documentation/plugins-mapping.html
I am familiar with the Google Apps script DataValidation object. To get and set validation criteria. But how to tell programatically if a cell value is actually valid. So I can see the little red validation fail message in the spreadsheet but can the fact the cell is currently failing validation be picked up thru code?
I have tried to see if there is a cell property that tells you this but there is not. Also I looked for some sort of DataValidation "validate" method - i.e. test a value against validation rules, but nothing there either
Any ideas? Is this possible??
Specific answer to your question, there is no method within Google Apps Script that will return the validity of a Range such as .isValid(). As you state, you could reverse engineer a programatic one using Range.getDataValidations() and then parsing the results of that in order to validate again the values of a Range.getValues() call.
It's a good suggestion. I've added a feature request to the issue tracker -> Add a Star to vote it up.
I've created a workaround for this issue that works in a very ugly -technically said- and slightly undetermined way.
About the workaround:
It works based on the experience that the web browser implementation of catch() function allows to access thrown errors from the Google's JS code parts.
In case an invalid input into a cell is rejected by a validation rule then the system will display an error message that is catchable by the user written GAS. In order to make it work first the reject value has to be set on the specified cell then its vale has to be re-entered (modified) then -right after this- calling the getDataValidation() built in function allows the user to catch the necessary error.
Only single cells can be tested with this method as setCellValues() ignores any data validation restriction (as of today).
Disadvantages:
The validity won't be necessarily re-checked for this function:
it calls a cell validation function right after the value is inserted into the cell.
Therefore the result of this function might be faulty.
The code messes up the history as cells will be changed - in case they are
valid.
I've tested it successfully on both Firefox and Chromium.
function getCellValidity(cell) {
var origValidRule = cell.getDataValidation();
if (origValidRule == null || ! (cell.getNumRows() == cell.getNumColumns() == 1)) {
return null;
}
var cell_value = cell.getValue();
if (cell_value === '') return true; // empty cell is always valid
var is_valid = true;
var cell_formula = cell.getFormula();
// Storing and checking if cell validation is set to allow invalid input with a warning or reject it
var reject_invalid = ! origValidRule.getAllowInvalid();
// If invalid value is allowed (just warning), then changing validation to reject it
// IMPORTANT: this will not throw an error!
if (! reject_invalid) {
var rejectValidRule = origValidRule.copy().setAllowInvalid(false).build();
cell.setDataValidation(rejectValidRule);
}
// Re-entering value or formula into the cell itself
var cell_formula = cell.getFormula();
if (cell_formula !== '') {
cell.setFormula(cell_formula);
} else {
cell.setValue(cell_value);
}
try {
var tempValidRule = cell.getDataValidation();
} catch(e) {
// Exception: The data that you entered in cell XY violates the data validation rules set on this cell.
// where XY is the A1 style address of the cell
is_valid = false;
}
// Restoring original rule
if (rejectValidRule != null) {
cell.setDataValidation(origValidRule.copy().setAllowInvalid(true).build());
}
return is_valid;
}
I still recommend starring the above Google bug report opened by Jonathon.
I'm using this solution. Simple to learn and fast to use! You may need to adapt this code for your needs. Hope you enjoy
function test_corr(link,name) {
var ss = SpreadsheetApp.openByUrl(link).getSheetByName(name);
var values = ss.getRange(2,3,200,1).getValues();
var types = ss.getRange(2,3,200,1).getDataValidations()
var ans
for (var i = 0; i < types.length; i++) {
if (types[i][0] != null){
var type = types[i][0].getCriteriaType()
var dval_values = types[i][0].getCriteriaValues()
ans = false
if (type == "VALUE_IN_LIST") {
for (var j = 0; j < dval_values[0].length; j++) {
if (dval_values[0][j] == values[i][0]) { ans = true }
}
} else if (type == "NUMBER_BETWEEN") {
if (values[i][0] >= dval_values[0] && values[i][0] <= dval_values[1]) { ans = true }
} else if (type == "CHECKBOX") {
if (values[i][0] == "Да" || values[i][0] == "Нет") { ans = true }
}
if (!ans) { return false }
}
}
return true;
}
I cannot get the logic for this down correctly. I am using a wizard with separate views in the controller (no javascript). Based on a selection in Step 2 of the wizard I want to either skip Step 7 or show Step 7. The wizard uses next/back buttons to control where to go.
I was able to "show" Step 7 if the user selected "A" (for example), but when I created the logic to skip Step 7 if either "B" or "C" were selected I either get a "redirect loop / too many redirects error" on Chrome (I cleared out the cookies to no avail) or the "Next" button on the prior step won't work (it just shows the same view).
Step 2 in and of itself is unimportant in terms of the controller, it contains a drop down list with the 3 choices, and based on that choice this is the controller code I have (I leave out serializing the myViewModel code in the Controller, which is decorated with [Serializable]):
// STEP 6:
// Based on selection in Step 2, show or don't show Step 7
public ActionResult Step6(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("Step5");
else if ((nextButton != null) &&
ModelState.IsValid &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.A))
return RedirectToAction("Step7");
else if ((nextButton != null) &&
ModelState.IsValid &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.B) ||
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.C))
return RedirectToAction("Step8");
else
return View("Step6", myViewModel);
}
// STEP 7:
// Only shown if Choice in MyDropDown is "A",
// otherwise if "B" or "C" skipped
public ActionResult Step7(string backButton, string nextButton)
{
if (backButton != null)
return RedirectToAction("Step6");
else if ((nextButton != null) &&
ModelState.IsValid)
return RedirectToAction("Step8");
else
return View("Step7", myViewModel);
}
// STEP 8:
// Arrive here either from Step 6
// (if "B" or "C" chosen),
// or from Step 7 (if "A" chosen)
public ActionResult Step8(string backButton, string nextButton)
{
if ((backButton != null) &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.A))
return RedirectToAction("Step7");
else if ((backButton != null) &&
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.B) ||
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.C))
return RedirectToAction("Step6");
else if ((nextButton != null) &&
ModelState.IsValid)
return RedirectToAction("Step9");
else
return View("Step8", myViewModel);
}
I know I am just getting the logic down wrong. Any help is much appreciated.
The above code (without the logic I am asking about) works perfectly, as does the code I use to display the DropDown.
Ugh, I should have encapsulated the || logic in its own () to read thusly:
else if ((backButton != null) &&
//Extra opening parenthesis-->
((myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.B) ||
(myVieModel.MyModel.MyDropDown ==
MyNamespace.Models.MyModel.MyEnum.C))) //<--extra closing parenthesis
return RedirectToAction("Step6");
I'm looking for a simple way to loop through all buttons onscreen for a given tag. Eg "foo". I'm using WP7, using C#. I'm very new to the platform so go easy on me :P
Googling this sort of thing isn't really working out for me either - I think I have my terminology wrong, so any tips on that too would be appreciated.
You should probably loop through all the controls on your page, check whether each one is a button, and if so check its Tag property.
Something like this...
foreach (UIElement ctrl in ContentPanel.Children)
{
if (ctrl.GetType() == typeof(Button))
{
Button potentialButton = ((Button)ctrl);
if (potentialButton.Tag = Tag)
return (Button)ctrl;
}
}
Bear in mind, though, that if you have nested controls on the page, you will need to think about recursing into any item with children to make sure you catch all the controls.
First, create a method to enumerate recursively the controls in your page:
public static IEnumerable<FrameworkElement> FindVisualChildren(FrameworkElement control)
{
if (control == null)
{
yield break;
}
for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(control); i++)
{
var child = System.Windows.Media.VisualTreeHelper.GetChild(control, i) as FrameworkElement;
if (child != null)
{
yield return child;
foreach (var grandChild in FindVisualChildren(child))
{
yield return grandChild;
}
}
}
}
Then call it and keep only the controls you want:
var buttons = FindVisualChildren(this.ContentPanel)
.OfType<Button>()
.Where(b => b.Tag is string && (string)b.Tag == "foo");
(where ContentPanel is the root element of your page)