Parameter int in MVC - asp.net-mvc

How can I assignment parameter int in Razor view in MVC. Here is my code:
<div class="pagesize">
#{
Html.Repeat(new[] { 5, 10, 15 }, ps =>
{
if (ps == Model.Search.PageSize)
{
#<span>#(ps)</span>; <-- Here I don't know how to assignment or call expression "ps"
}
else
{
##(ps);
}
}, () => { | });
<p>Items per page.</p>
}
So what code should do ... First the purpose of this line of code is to set how many row in my table I shoudl display. In this case: 5, 10 or 15 rows.
The line of code: ##(ps); shoud return number that user chose. e.g. if user click on 10; in this line #(ps) is 10; second line in else sets rest numbers to ; so if user clicked on 10, #(ps) in this second line is: first is 5, then 15; 10 skips because it is clicked already.
Thanks for help.

<div class="pagesize">
#{
Html.Repeat(new[] { 5, 10, 15 }, ps =>
{
if (ps == Model.Search.PageSize)
{
ps = 50; <-- Here I don't know how to assignment or call expression "ps"
var i = ps + 2;
var s = ps.ToString();
}
else
{
##(ps);
}
}, () => { | });
<p>Items per page.</p>
}

Related

AddEventListener only works with the last picture

I have one problem. addEventListener only works with the last element of the loop. I know what is the problem, but I can't figure it out. I get the JSON object from another function with the information. Later on the left side there should be clickable pictures. After clicking it I should get the same picture on the right side showed. Still it works only with the last one.
function myFunction(obj) {
var listItems = document.getElementsByClassName("newimg");
for (var i = 0; i < obj.length; i++) {
(function (i) {
document.getElementById("imgSmall").innerHTML += `<br></br><img id="${i}" class="newimg" src=${obj[i].download_url} >`;
let p = obj[i];
listItems[i].addEventListener('click', function() { makeithappen(p);},true);
}(i));
//obj[i].width,obj[i].height,obj[i].author,obj[i].download_url>
}
}
function makeithappen(k) {
document.getElementById("imgLarge").innerHTML = `<br class="text"> AUTHOR: ${k.author}, WIDTH: ${k.width}, HEIGHT: ${k.height}</br><img class="img2" src=${k.download_url} >`;
}
For quick fix.
Replace in your code
listItems[i].addEventListener('click', function() { makeithappen(p);},true);
with
listItems[i].onload = function() {
listItems[i].addEventListener('click', function () { makeithappen(p); }, true);
}
So when you got your listItems you weren't finished with the creation of more images. So new image means new list.
for (let i = 0; i < obj.length; i++) {
document.getElementById("imgSmall").innerHTML += `<br></br><img id="${i}" class="newimg" src=${obj[i].download_url}>`;
const listItems = document.getElementsByClassName("newimg");
listItems[i].addEventListener('click', function () { makeithappen(p); }, true);
}
function makeithappen(k) {
document.getElementById("imgLarge").innerHTML = `<br class="text"> AUTHOR: ${k.author}, WIDTH: ${k.width}, HEIGHT: ${k.height}</br><img class="img2" src=${k.download_url} >`;
}
Pleas do refactor <br></br> into something with css, margin or padding or whatever. This will then allow you to create the images with let div = document.createElement('img') and bind the event listener directly div.addEventlistener(...)

Seach when input is not empty and with delay for typing complete

I want to call service only when user input is not empty and ith some delay so user finish the typing.
Below is the code. Please help.
Component.ts
searchByName(event) {
this.facilityService.searchFacilityName(event.target.value).subscribe(facilities => this.facilities = facilities);
}
Service.ts
searchFacilityName(name) {
return this.http.get('http://localhost:8000/searchFacilityByName/' + name)
.map((response:Response) => response.json())
.catch(
(error: Response) => {
return Observable.throw('Something went wrong. Please try again.')
}
);
}
This will be helpful,
this.testForm.controls.searchText.valueChanges.subscribe(x=>{
if(this.testForm.controls.searchText.dirty && this.testForm.controls.searchText.valid) {
setTimeout(function(){
this.searchFacilityName(this.testForm.controls.searchText.value)
},3000);
} });
You need to specify a time limit first i.e. amount of time you want to wait after the last keyup event to make sure that the user has stopped typing.
After that you can try this
<input type='text' [ngModel]='userInput' (keyup)='checkTimeLimit()' (keydown)='typeCheck = typeCheck + 1'>
In your component:
typeCheck = 0;
userInput;
timeLimit = 5000; // It is the time limit after which you consider that user has stopped typing (5s)
checkTimeLimit() {
const temp = this.typeCheck;
setTimeout(() => {
if (temp === this.typeCheck) { // It checks whether the user has pressed another key before the specified time limit
this.typeCheck = 0;
this.searchFacilityName(userInput);
}
}, this.timeLimit);
}

Angular UI-grid not sorting by date

I am using UI-grid, and I have a bunch of JS date objects like so:
"dob": new Date('1942-11-19')
I want to be able to filter the column by date when you click the "sort ascending/descending" buttons. As such, I have set the colDef up like so:
{
field: 'dob'
, displayName: 'D.O.B.'
, width: '130'
, editableCellTemplate: '<div><form name="inputForm"><input type="INPUT_TYPE" ng-class="\'colt\' + col.uid" ui-grid-editor ng-model="MODEL_COL_FIELD" style="border-bottom-color: #74B3CE; border-bottom-width: 2px;"></form></div>'
, headerCellClass: $scope.highlightFilteredHeader
, cellTemplate: '<div class="ui-grid-cell-contents" >{{grid.getCellValue(row, col)| date:\'MM-dd-yyyy\'}}</div>'
, cellFilter: 'date'
, type: 'date'
},
however, the column simply does not sort correctly. I even tried to set up a function to sort it from an external button like so:
function mostRecent(){
console.log('clicked mostRecent');
$scope.gridApi.grid.sortColumn(
$scope.gridApi.grid.getColumn('dob'), uiGridConstants.DESC
);
$scope.gridApi.grid.notifyDataChange(uiGridConstants.dataChange.ALL); //this line updates the rest of the columns accordingly
};
But it also causes a mish-mush sort that is not correct. Does anyone know what the issue is? I thought it might have to do with my cellTemplate, but after removing the template, there wasn't a difference...
Yes you are right, ui-grid doesn't support sorting of Date type columns.
However you can define a sortingAlgorithm in the columnDef.
Here is how your column definition should look like:
...
columnDefinition.sortingAlgorithm = function (firstDateString, secondDateString) {
var dateFormat = 'YYYY-MM-DD';
return function (firstDateString, secondDateString, dateFormat) {
if (!firstDateString && !secondDateString) {
return 0;
}
if (!firstDateString) {
return 1;
}
if (!secondDateString) {
return -1;
}
var firstDate = $window.moment(firstDateString, dateFormat);
if (!firstDate.isValid()) {
throw new Error('Invalid date: ', firstDateString);
}
var secondDate = $window.moment(secondDateString, dateFormat);
if (!firstDate.isValid()) {
throw new Error('Invalid date: ', secondDateString);
}
if (firstDate.isSame(secondDate)) {
return 0;
} else {
return firstDate.isBefore(secondDate) ? -1 : 1;
}
};
};
...
Please note that in this example Moment.js is used. It is a very useful library so you might probably find also another place in your project where to use it.
$scope.gridOptions = {
data: 'gridData',
columnDefs: [
{field: 'name', displayName: 'Name'},
{field:'age',
displayName:'Birth Date',
sortFn: function (aDate, bDate) {
var a=new Date(aDate);
var b=new Date(bDate);
if (a < b) {
return -1;
}
else if (a > b) {
return 1;
}
else {
return 0;
}
}
}]
};
Try this
http://plnkr.co/edit/0VD3X5YvuNSWAZlig95X?p=info
reference :
https://github.com/angular-ui/ui-grid/issues/222
You can define the Sorting Algorithm for the date fields in UI Grid like below
columnDefs: [
{
field: 'DateFrom', displayName: 'From',
sortingAlgorithm: function (aDate, bDate, rowA, rowB, direction) {
var a = new Date(moment(aDate, "DD-MM-YYYY").format("YYYY-MM-DD"));
//here DD-MM-YYYY is the current format in which the dates are returned
var b = new Date(moment(bDate, "DD-MM-YYYY").format("YYYY-MM-DD"));
if (a < b) {
return -1;
}
else if (a > b) {
return 1;
}
else {
return 0;
}
}
}
]
We can sort the ui-grid column containing date field in a simplest way.
Make use of cellTemplate in this way:
{
name: "Date",
field: 'date',
cellTemplate:'<div>{{row.entity.date | date:"dd/MM/yyyy"}}</div>'
},
So, you can choose any format for date, for eg. date:"dd-MM" etc.

Blackberry 10 Cascades - search-ahead drop-down + tag field

My question is related to Filipe Figueiredo's query (see: Blackberry 10 Cascades - Images inside Text Area)
My Cascades BB10 App requires a search-ahead drop-down with the ability to have multiple items selected and displayed as Tag Fields. Look & feel and behavior same as BB10 email composer's "To" address field - but with different data (e.g. country names).
Questions:
Is there a way to do this using Cascades components / controls?
(FlowListLayout does not meet exact requirements)
Can we achieve this using QML + javascript?
Or is there a way using C++ and QML for achieving this?
Is there a Component market Place for procuring custom controls for Cascades?
My development is stalled. Please help.
It should be possible. This is a prototype. It doesn't work well, but it's an idea. This is how it looks:
Code (yeah, it's bad. but it should work out of the box):
import bb.cascades 1.2
Page {
Container {
ListView {
id: tagList
dataModel: tagModel
layout: FlowListLayout {
headerMode: ListHeaderMode.None
}
preferredHeight: 200
function itemType(data, indexPath) {
return (data.add == 1 ? 'add' : '');
}
function mload(text) {
myList.load(text);
}
function showDropDown() {
myList.visible = true;
}
listItemComponents: [
ListItemComponent {
type: "add"
Container {
id: myAdd
TextField {
id: searchBox
preferredWidth: 300
onTextChanging: {
myAdd.ListItem.view.mload(searchBox.text);
}
onFocusedChanged: {
if (focused)
myAdd.ListItem.view.showDropDown();
}
}
}
},
ListItemComponent {
Container {
background: Color.create("#660000FF")
leftPadding: 10
rightPadding: 10
topPadding: 10
bottomPadding: 10
leftMargin: 10
bottomMargin: 10
Label {
id: country
textStyle.fontSize: FontSize.Medium
text: ListItemData.country
}
}
}
]
onTriggered: {
//todo: make it possible to remove a tag
console.log("item touched.. yay!")
}
attachedObjects: [
ArrayDataModel {
id: tagModel
}
]
}
ListView {
id: myList
visible: false
dataModel: mdataModel
preferredHeight: 400
attachedObjects: [
ArrayDataModel {
id: mdataModel
}
]
onTriggered: {
var selected = dataModel.data(indexPath);
var tmp = new Object();
tmp.country = selected;
tagModel.insert(tagModel.size() - 1, tmp);
console.log("removing: " + (tagModel.size() - 1 ) + " at size " + tagModel.size())
visible = false;
}
function load(text) {
var cities = [ "Slovenia", "Italy", "Slovakia", "Croatia", "Sweden", "Norway", "Poland", "Finland", "Spain",
"Indonesia", "Ireland" ]
var tmp = [];
for (var i = 0; i < cities.length; i ++)
if (cities[i].toLowerCase().indexOf(text.toLowerCase()) >= 0)
tmp.push(cities[i]);
mdataModel.clear();
mdataModel.insert(0, tmp);
}
function insertEdit() {
var edit = new Object();
edit["add"] = "1";
tagModel.insert(tagModel.size(), edit);
}
}
}
onCreationCompleted: {
myList.load("");
myList.insertEdit(); // insert item with TextField
}
}

Override Minimum length string of Select2

Select2 Jquery Plugin
I was having hard time how to override the default message for minimum length input in jquery Select2.
by default the plugin gives the following message.
Default Text
Please enter 1 more characters
My requirement was to show, the following text
Required Text
Enter 1 Character
please share the solution.
Thanks.
The accepted answer does not work for Select2 v4. Expanding on the comment by #IsaacKleinman, the way to override the default messages for an individual Select2 instance is through the language property:
var opts = {
language: {
inputTooShort: function(args) {
// args.minimum is the minimum required length
// args.input is the user-typed text
return "Type more stuff";
},
inputTooLong: function(args) {
// args.maximum is the maximum allowed length
// args.input is the user-typed text
return "You typed too much";
},
errorLoading: function() {
return "Error loading results";
},
loadingMore: function() {
return "Loading more results";
},
noResults: function() {
return "No results found";
},
searching: function() {
return "Searching...";
},
maximumSelected: function(args) {
// args.maximum is the maximum number of items the user may select
return "Error loading results";
}
}
};
$('#mySelect').select2(opts);
To override the functions globally, call the set function on the defaults (according to the docs):
$.fn.select2.defaults.set("key", "value")
However, in our code we do it like this:
$.fn.select2.defaults.defaults['language'].searching = function(){
return 'Custom searching message'
};
I don't know why we don't follow the docs, but it works.
Solution
Here is the solution that i have found out.
Prior to v4
Initialize
$("input[name='cont_responsible'],input[name='corr_responsible'],input[name='prev_responsible'],input[name='pfmea_responsible']").select2({
minimumInputLength: 1,
formatInputTooShort: function () {
return "Enter 1 Character";
},
});
Note
Do not forget to add this code in your document. ready function.
$(document).ready(function () {
});
I shared my solution, any better solutions are welcome.
Thanks.
Using v4 and onwards
The following worked for V4. #Isaac Kleinman
language: { inputTooShort: function () { return ''; } },
You can try this on version 4.0 or higher
you can see reference for answer frome this link :
issues reference
$("#select2").select2({
minimumInputLength: 1,
language: {
inputTooShort: function() {
return 'Please Add More Text';
}
}
});
If you are using django-select2, just add attributes to your form in forms.py:
widget=BookSelect2Widget(
attrs={'data-minimum-input-length': 1}
)
Override the function behaviour like below
$.fn.select2.defaults = $.extend($.fn.select2.defaults, {
formatMatches: function(matches) {
return matches + $filter('translate')('label.matches.found');
},
formatNoMatches: function() {
return $filter('translate')('noMatches.found');
},
formatInputTooShort: function(input, min) {
var n = min - input.length;
return $filter('translate')('label.please.enter ') + n + $filter('translate')(' more.characters') + (n == 1 ? "" : "s");
},
formatInputTooLong: function(input, max) {
var n = input.length - max;
return $filter('translate')('please.delete ') + n + $filter('translate')('')('delete.characters') + (n == 1 ? "" : "s");
},
formatSelectionTooBig: function(limit) {
return $filter('translate')('select.only') + limit + $filter('translate')('select.item ') + (limit == 1 ? "" : "s");
},
formatLoadMore: function(pageNumber) {
return $filter('translate')('load.results');
},
formatSearching: function() {
return $filter('translate')('label.search');
}
});
}

Resources