I'm trying to perform a simple search and I cant find out what I have missed here
This is my ( I think very simple code)
public ActionResult WeeklyVorts(string sortOrder, string searchString, int page = 1 )
{
ViewData["corentSort"] = sortOrder;
ViewData["productSortParm"] = string.IsNullOrEmpty(sortOrder) ? "Product desc" : "";
var weeklyS = from c in _repository.List().OrderBy(x=>x.UParasha) select c;
if(!string.IsNullOrEmpty(searchString))
{
weeklyS = weeklyS.Where(v => v.UHeadLine.ToUpper().Contains(searchString.ToUpper())
|| v.UParasha.ToUpper().Contains(searchString.ToUpper())
|| v.Uvort.ToUpper().Contains(searchString.ToUpper())
);
}
switch (sortOrder)
{
case "Product desc":
weeklyS = weeklyS.OrderByDescending(s => s.UHeadLine);
break;
default:
weeklyS = weeklyS.OrderBy(d => d.UParasha);
break;
}
ViewData["weeklyS"] = _repository.List().ToList();
int hlist = (_repository.List().Count());
ViewData["TotalPages"] = (int)Math.Ceiling((double)hlist / PageSize);
ViewData["CurrentPage"] = page;
return View(_repository.List().Skip((page - 1) * PageSize).Take(PageSize));
}
My View
<div class="search">
<% using (Html.BeginForm())
{ %>
<p>
Find: <%=Html.TextBox("SearchString", ViewData["currentFilter"] as string) %>
<input type="submit" value="Search" />
</p>
<%} %>
</div>
//in a brackpoint I can c that the typed parameter is pass to
// if(!string.IsNullOrEmpty(searchString))
I know I have missed same thing in my view I just cand find out what
Thanks
It doesn't look like you are assigning the weeklyS variable into your ViewData["weeklyS"]
try this
ViewData["weeklyS"] = weeklyS;
instead of this
ViewData["weeklyS"] = _repository.List().ToList();
your code have some lines that I can not understand
why do you use _repository after searching should you use weeklyS variable?
try this
ViewData["weeklyS"] = weeklyS.ToList();
int hlist = weeklyS.Count();
ViewData["TotalPages"] = (int)Math.Ceiling((double)hlist / PageSize);
ViewData["CurrentPage"] = page;
return View(weeklyS.Skip((page - 1) * PageSize).Take(PageSize));
Related
I am using Blazor.
I am trying to get a specific result from dbset.
I have two conditions, salary is 620 and deduction is for p2.
The difficult thing is range, btw 600~700 for salary. Then how I move to specific column to get the result for p2.
var result = await _db.TaxTable.......blah...blah...
In this case, I have to find the result 70
I have tried some code..but I failed everytime.
Could you share the exact knowledge?
Thank you in adv.
You have to locate the row. Then use a switch statement to get the appropriate value.
double GetDeduction(double salary, string discount)
{
var row = someData.SingleOrDefault(a => salary >= a.start && salary < a.end);
if(row == null) throw new SomeRowNotFoundException();
return discount switch
{
"p1" => row.p1,
"p2" => row.p2,
"p3" => row.p3,
_ => throw new SomeDiscountNotValidException();
}
}
You have to include one of the boundaries and exclude the other to avoid overlap. I arbitrarily chose to include start the alternative would be
someData.SingleOrDefault(a => salary > a.start && salary <= a.end)
Your query into your DbSet should look something like this to get the specific value:
using var dbContext = _factory.CreateDbContext();
dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var value = await dbContext.Set<TRecord>()
.SingleOrDefault(item => item.start <= this.salary && item.end >= this.salary)?.p2 ?? 0;
Here's a demo page.
#page "/"
<PageTitle>Index</PageTitle>
<input class="form-control" #bind-value=this.salary />
<div class="text-end m-2">
<button class="btn btn-primary" #onclick=Calc>Calculate</button>
<button class="btn btn-secondary" #onclick=Calc2>Calculate 2</button>
</div>
<div class="bg-dark text-white m-2 p-2">
P2 = #P2
</div>
#code {
private int salary;
private int P2;
private void Calc()
{
var record = deductions.SingleOrDefault(item => item.start <= this.salary && item.end >= this.salary);
P2 = record?.p2 ?? 0;
}
private void Calc2()
{
P2 = deductions.SingleOrDefault(item => item.start <= this.salary && item.end >= this.salary)?.p2 ?? 0;
}
private List<Deduction> deductions = new List<Deduction>
{
new Deduction(1,0,199,10,20,30),
new Deduction(2,200,299,20,30,40),
new Deduction(3,300,399,30,40,50),
new Deduction(4,400,499,40,50,60),
};
public record Deduction(int Id, int start, int end, int p1, int p2, int p3 );
}
Note: there's a problem in your dataset your ranges overlap!
I am building a Framework7 MVC app and found myself in a dead end alley. I have a form which I need to evaluate. This form contains selects. I am using localStorage to store the form values and everything works OK in that sense, I mean everything is stored correctly. ¿What is the issue? When I fill the form I answer some questions on textareas inputs, select inputs and inputs. everything goes fine until I try to reedit the form, then everything is display correctly on the form, including the score i got from my previous answers, but, the selects appears as if I have never touch them. Their previously selected value is stored but not display on the form. I have found that the issue is caused by the fact that I have set numerical values to the options values but what the form show is "yes" or "no". If I change the option values to "yes" or "no" then the form displays correctly but I need to set "5" or "0" because I need to evaluate the user's answers.
This is my code
The form
<li style="margin-top:-10px;">
<input style="visibility:hidden;height:1px;" value="0" name="choice" onchange="checkTotal()"/>
<input style="visibility:hidden;height:1px;" value="1" type="checkbox" name="choice" onchange="checkTotal()" checked="on">
</li>
<li><div class="item-content">1. ¿Sueles quejarte de sentirte mal?</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<select name="pr1" id="pr1" onchange="checkTotal()">
<option class="item-inner" value="5">No</option>
<option class="item-inner" value="0">Si</option>
</select>
</div>
</div>
</div>
<div class="item-content">En tal caso,</div>
<div class="item-content">
<div class="item-inner">
<div class="item-input">
<textarea class="resizable" id="pr1notes" placeholder="¿cuál es la causa?">{{model.pr1notes}}</textarea>
</div>
</div>
</div>
</li>
The functions on the editController
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
and the model
Protection.prototype.setValues = function(inputValues, extras) {
for (var i = 0, len = inputValues.length; i < len; i++) {
var item = inputValues[i];
if (item.type === 'checkbox') {
this[item.id] = item.checked;
}
else {
this[item.id] = item.value;
}
}
for (var i = 0, len = extras[0].length; i < len; i++) {
var item = extras[0][i];
if((item.id).localeCompare("pr1notes")==0) {this[item.id] = item.value;}
}
console.log('starting loop for extras 3...');
for (var i = 0, len = extras[2].length; i < len; i++) {
var item = extras[2][i];
this[item.name] = item.value;
}
};
Protection.prototype.validate = function() {
var result = true;
if (_.isEmpty(this.prdate)
) {result = false;}
return result;
};
Protection.prototype.getSelectFields = function() {
return ['pr1'];
}
What should I change in order to keep my "5" or "0" values on the select options while the form options still show "yes" or "no" to the user just like this: <select name="pr1" id="pr1" onchange="checkTotal()"><option class="item-inner" value="5">No</option><option class="item-inner" value="0">Si</option></select>?
need anything else to help you understand the issue?
The simplest solution
function init(query){
var protections = JSON.parse(localStorage.getItem("f7Protections"));
if (query && query.id) {
protection = new Protection(_.find(protections, { id: query.id }));
state.isNew = false;
}
else {
protection = new Protection({ isFavorite: query.isFavorite });
state.isNew = true;
}
View.render({ model: protection, bindings: bindings, state: state, doneCallback: saveProtection });
showSelectedValues();
}
function showSelectedValues(){
var fieldNames = protection.getSelectFields();
for (var i = 0, len = fieldNames.length; i < len; i++) {
var itemname = fieldNames[i];
var selectObj = document.getElementById(itemname);
if (selectObj!=null) {
var objOptions = selectObj.options;
var selIndex=0;
for (var j = 0, len2 = objOptions.length; j < len2; j++) {
if ((objOptions[j].value).localeCompare(protection[itemname])==0){
selIndex=j;
}
}
selectObj.options[selIndex].setAttribute("selected","selected");
}else{
}
}
}
Just changed this line
if ((objOptions[j].label).localeCompare(protection[itemname])==0){
selIndex=j;
and changed .label for .value.
I'm using angular 2 reactive forms and made a validator for a date of birth field. The validator is working, but it turns out the date of birth field is split into three new field: year, month, day. They all have their own validators. My question is, how can I change my code so my original date of birth validator works on three fields.
my original validator that checks one field.
input(2000/12/12) is valid
export function dobValidator(control) {
const val = control.value;
const dobPattern = /^\d{4}\/\d{2}\/\d{2}$/ ;
const comp = val.split('/');
const y = parseInt(comp[0], 10);
const m = parseInt(comp[1], 10);
const d = parseInt(comp[2], 10);
const jsMonth = m - 1;
const date = new Date(y, jsMonth, d);
const isStringValid = dobPattern.test(control.value);
const isDateValid = (date.getFullYear() === y && date.getMonth() === jsMonth && date.getDate() === d);
return (isStringValid && isDateValid) ? null : { invalidDob: ('Date of birth not valid') };
};
new html with 3 fields
year has a validator that checks the year
day has a validator that checks if the input is between 1 and 31
month has a validator that checks if the input is between 1 and 12.
I want to combine the above input of the three field into a new string and use my original date of birth validator.
<label>Date of birth :</label>
<div>
<div class="col-xs-1">
<input required type="text" formControlName="day" class="form-control" placeholder="dd" id="day"/>
<p *ngIf="form.controls.day.dirty && form.controls.day.errors">{{ form.controls.day.errors.invalidDay }}</p>
</div>
<div class="col-xs-1">
<input required type="text" formControlName="month" class="form-control" placeholder="mm" id="month"/>
<p *ngIf="form.controls.month.dirty && form.controls.month.errors">{{ form.controls.month.errors.invalidMonth }}</p>
</div>
<div class="col-xs-2">
<input required type="text" formControlName="year" class="form-control" placeholder="yyyy" id="year"/>
<p *ngIf="form.controls.year.dirty && form.controls.year.errors">{{ form.controls.year.errors.invalidYear }}</p>
</div>
</div>
<div>
<button type="submit" [disabled]="form.invalid">Submit</button>
</di>
I have created a validator for comparing two dates (their format is NgbDateStruct - as used in ng-bootstrap package's datepickers)
import { Directive, forwardRef, Attribute } from '#angular/core';
import { Validator, AbstractControl, NG_VALIDATORS, ValidatorFn } from '#angular/forms';
import { NgbDateStruct } from "#ng-bootstrap/ng-bootstrap";
import { toDate } from "../helpers/toDate";
export function dateCompareValidator(compareToControl: string, compareToValue: NgbDateStruct, compareType: string, reverse: boolean, errorName: string = 'dateCompare'): ValidatorFn {
return (c: AbstractControl): { [key: string]: any } => {
let compare = function (self: Date, compareTo: Date): any {
console.log('comparing ', compareType.toLowerCase());
console.log(self);
console.log(compareTo);
if (compareType.toLowerCase() === 'ge') {
if (self >= compareTo) {
return true;
} else {
return false;
}
} else if (compareType.toLowerCase() === 'le') {
if (self <= compareTo) {
return true;
} else {
return false;
}
}
return false;
};
// self value
let v = c.value;
// compare vlaue
let compareValue: Date;
let e;
if (compareToValue) {
compareValue = toDate(compareToValue);
} else {
e = c.root.get(compareToControl);
if (e) {
compareValue = toDate(e.value);
}
else {
// OTHER CONTROL NOT FOUND YET
return null;
}
}
let controlToValidate: AbstractControl = reverse ? e : c;
// validate and set result
let error = null;
let result = compare(toDate(c.value), compareValue);
if (result === true) {
console.log('clearing errors', compareToControl);
if (controlToValidate.errors) {
delete controlToValidate.errors[errorName];
if (!Object.keys(controlToValidate.errors).length) {
controlToValidate.setErrors(null);
}
}
else {
console.log('errors property not found in control', controlToValidate);
}
} else {
error = {};
error[errorName] = false;
controlToValidate.setErrors(error);
console.log(controlToValidate.errors);
console.log(controlToValidate.value);
console.log('Error Control', controlToValidate);
console.log('returning errors');
}
return reverse ? null : error;
}
}
Couldn't manage to modify much lot to best describe here as an answer but I believe you would get your query answered in this validator function code.
Note:
Function toDate() used in the code is a small function I created to convert NgbDateStruct into a javascript date object so that comparing dates can get easier. Here goes its implementation:
import { NgbDateStruct } from "#ng-bootstrap/ng-bootstrap"
export function toDate(ngbDate: NgbDateStruct): Date {
return ngbDate != null ? new Date(Date.UTC(ngbDate.year, ngbDate.month, ngbDate.day)) : null;
}
I have tried to extend the Dynamic-Forms app from angular 2 cookbook so I can have an array of multiple fields. I have been able to show the fields, but when I'm filling the form, I'm getting just the last element of the array filled.
Hier is my plunker with that state of the app:
//question-array.ts
import { QuestionBase } from './question-base';
export class ArrayQuestion extends QuestionBase<string> {
controlType = 'array';
options:{childe:FormElement<string>}[] = [];
constructor(options:{} = {}){
super(options);
this.options = options['options'] || [];
}
}
//question-control.service.ts
...
toFormGroup(formelements: QuestionBase<any>[] ) {
let group:any = {};
formelements.forEach(element => {
console.log("+element",element);
if(element.controlType === "array"){
let arr:any[] = [];
let locobj = {};
element["options"].forEach((option:any) => {
option["element"].forEach((e:any) =>{
locobj[e.key] = new FormControl(e.value || '');
});
arr.push(new FormGroup(locobj))
});
group[element.key] = new FormArray(arr);
}else{
group[element.key] = element.required ? new FormControl(element.value || '', Validators.required)
: new FormControl(element.value || '');
}
});
return new FormGroup(group);
}
//dynamic-form-question.component.html
...
<div *ngSwitchCase="'array'" [formArrayName]="question.key">
<div *ngFor="let item of question.options; let i=index" [formGroupName]="i" >
<div *ngFor="let element of item.element">
<div *ngIf="element.controlType === 'textbox'" >
<label>{{element.label}}</label>
<input [formControlName]="element.key" [id]="element.key" [type]="element.type" />
</div>
<div *ngIf="element.controlType === 'dropdown'" >
<label>{{item.label}}</label>
<select [id]="element.key" [formControlName]="element.key">
<option *ngFor="let opt of element.options" [value]="opt.key">{{opt.value}}</option>
</select>
</div>
</div>
</div>
</div>
...
http://plnkr.co/edit/DZ05fO
Best regard,
Shefki
I found the bug, the problem was that I was passing the same reference in the form group her is what i changed:
//question-control.service.ts
toFormGroup(formelements: QuestionBase[] ) {
let group:any = {};
formelements.forEach(element => {
if(element.controlType === "array"){
let arr:any[] = [];
let locobj = {};
element["options"].forEach((option:any) => {
option["element"].forEach((e:any) =>{
locobj[e.key] = e.value || '';
});
arr.push(new FormGroup(this.getFormControlObject(locobj)));
});
group[element.key] = new FormArray(arr);
}else{
group[element.key] = element.required ? new FormControl(element.value || '', Validators.required)
: new FormControl(element.value || '');
}
});
return new FormGroup(group);
}
private getFormControlObject(keys){
let retobj = {};
Object.keys(keys).forEach(function(key) {
retobj[key] = new FormControl(keys[key]);
});
return retobj;
}
Hier is a working plunker
http://plnkr.co/edit/4IMKdLKE51n41jzYY8sU
i done with sorting on single column header of liferay searchcontainer in liferay 6.0.6.
now i want to apply sorting on multiple fields i.e FirstName,LastName,Date either in asc or desc order.
can anybody help me out..
Thanks in advance....
view.jsp
<%
PortalPreferences portalPrefs = PortletPreferencesFactoryUtil.getPortalPreferences(request);
String orderByCol = ParamUtil.getString(request, "orderByCol");
String orderByType = ParamUtil.getString(request, "orderByType");
System.out.println("Col "+ orderByCol);
if (Validator.isNotNull(orderByCol) && Validator.isNotNull(orderByType)) {
portalPrefs.setValue("NAME_SPACE", "order-by-col", orderByCol);
portalPrefs.setValue("NAME_SPACE", "order-by-type", orderByType);
} else {
orderByCol = portalPrefs.getValue("NAME_SPACE", "order-by-col", "Date");
orderByType = portalPrefs.getValue("NAME_SPACE", "order-by-type", "asc");
}
%>
<liferay-ui:search-container delta='20' emptyResultsMessage="No Form Submitted" orderByCol="<%= orderByCol %>" orderByType="<%= orderByType %>">
<liferay-ui:search-container-results>
<%
List<User> userList = UserLocalServiceUtil.getUsers(-1,-1);
OrderByComparator orderByComparator =
CustomComparatorUtil.getUserOrderByComparator(orderByCol, orderByType);
Collections.sort(userList,orderByComparator);
results = ListUtil.subList(userList, searchContainer.getStart(),
searchContainer.getEnd());
if (userList.size()< total)
{total = userList.size();
}
pageContext.setAttribute("results", results);
pageContext.setAttribute("total", total);
%>
</liferay-ui:search-container-results>
<liferay-ui:search-container-row
className="com.liferay.portal.model.User"
modelVar="user">
<liferay-ui:search-container-column-text
name="Screen Name"
property="screenName"
orderable="<%= true %>"
orderableProperty="screenName"
/>
<liferay-ui:search-container-column-text
name="Email"
property="emailAddress"
orderable="<%= true %>"
orderableProperty="emailAddress"
/>
<liferay-ui:search-container-column-text
name="Date"
property="createDate"
orderable="<%= true %>"
/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
CustomComparatorUtil
public static OrderByComparator getUserOrderByComparator(
String orderByCol, String orderByType) {
boolean orderByAsc = false;
if (orderByType.equals("asc")) {
orderByAsc = true;
}
OrderByComparator orderByComparator = null;
System.out.println("Custom "+ orderByCol);
if (orderByCol.equalsIgnoreCase("screenName")) {
System.out.println("1");
orderByComparator = new FirstNameComparator(orderByAsc);
}
else if (orderByCol.equalsIgnoreCase("emailAddress")) {
System.out.println("2");
orderByComparator = new EmailComparator(orderByAsc);
}
else if (orderByCol.equalsIgnoreCase("Date")) {
System.out.println("3");
orderByComparator = new DateComparator(orderByAsc);
}/*
else if (orderByCol.equalsIgnoreCase("Job Title")) {
orderByComparator = new JobTitleComparator(orderByAsc);
}*/
return orderByComparator;
}
FirstNameComparator
public static String ORDER_BY_ASC = "status ASC";
public static String ORDER_BY_DESC = "status DESC";
public FirstNameComparator()
{
this(false);
}
public FirstNameComparator(boolean asc) {
_asc = asc;
}
public int compare(Object obj1, Object obj2) {
User instance1 = (User) obj1;
User instance2 = (User) obj2;
int value = instance1.getFirstName().toLowerCase().compareTo(instance2.getFirstName().toLowerCase());
if(_asc)
{
return value;
} else
{
return -value;
}
}
public String getOrderBy() {
if (_asc) {
return ORDER_BY_ASC;
}
else {
return ORDER_BY_DESC;
}
}
private boolean _asc;
}
similarly u can make class for emailaddress and date..