I am trying to properly place my returned results into labeled sections - example of what i mean.
Controller:
public IEnumerable<Users> GetUserList(int? id, int? pageNumber)
{
if (!id.HasValue)
throw new HttpResponseException(HttpStatusCode.NotFound);
int _pageNum = pageNumber.HasValue ? pageNumber.Value : 1;
return new UserService().GetUsers(id.Value, pageNumber: _pageNum);
}
View:
<div id="listView" data-bind="template: { name: 'list', foreach: Users }">
<section id="Images">
<section id="users"></section>
</section>
</div>
knockout.js/jquery: UPDATED
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// The ViewModel for the page
var viewModel = {
Users: ko.observableArray([]),
users: ko.observableArray([]),
groups: ko.computed({
read: function(){
var groups = [];
var groupLetter;
for(var i = 0; i <letters.length; i++){
viewModel.Users.groups[letters[i]].users([]);
}
ko.utils.arrayForEach(viewModel.users(), function (user) {
groupLetter = user.name()[0].toUpperCase();
if (groups.indexOf(groupLetter) < 0) {
groups.push(groupLetter);
}
groups[groupLetter].users.push(user);
});
return groups.sort();
},
deferEvaluation: true
}),
};
for (var i = 0; i < letters.length; i++) {
viewModel.users.groups[letters[i]] = { users: ko.observableArray([]) };
}
// The ViewModel for the page
var viewModel = {
Users: ko.observableArray([]), //already a sorted list of users
TotalRoster: null,
CurrentPage: ko.observable(1),
DataIsLoading: ko.observable(false),
};
So this returns in the view:
Amanda
Bob
Frank
Kate
Tim
I would like to have this displayed in the view:
A (Header)
Amanda
B (Header)
Bob
F (Header)
Frank
K (Header)
Kate
T (Header)
Tim
Mainly for a visual reference for viewers to see - it will show letter headers for the users that exist so if there are no users with a name that starts with S then there won't be a S header. Any help as to where i could look into or what this could be called i could read about that would be great.
You can group the users by their name on client side as follow :
// assuming the array is sorted
var users = ['Amanda', 'Anna', 'Bob', 'Frank', 'Francois', 'Sam'];
var lastGroup = null;
var vm = {
groups: []
};
ko.utils.arrayForEach(users, function (user) {
// known group
if (lastGroup && lastGroup.name == user[0]) {
lastGroup.users.push(user);
} else {
// unknown group
lastGroup = {
name :user[0], users : [user]
};
vm.groups.push(lastGroup);
}
});
<div data-bind="foreach:groups">
<span data-bind="text:name" style="font-weight: bold"></span>
<br/>
<div data-bind="foreach:users">
<span data-bind="text:$data"></span>
<br/>
</div>
</div>
See fiddle
I can tell you that you're not going to be able to do this by just looping through the Users array in the binding. Each iteration through will generate that templated html code provided for each of the User objects.
One approach I would consider is creating a dynamic array of groups that are based on the first letter of the User's name and attach these to the root observableArray object.
function ViewModel() {
var self = this;
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
self.users = ko.observableArray([]);
self.users.groups = ko.computed({
read: function(){
var groups = [];
var groupLetter;
for (var i = 0; i < letters.length; i++) {
self.users.groups[letters[i]].users([]);
}
ko.utils.arrayForEach(self.users(), function (user) {
groupLetter = user.name()[0].toUpperCase();
if (groups.indexOf(groupLetter) < 0) {
groups.push(groupLetter);// not listed? Add it
}
self.users.groups[groupLetter].users.push(user);// Add to the grouped users array
});
return groups.sort();
},
deferEvaluation: true
});
for (var i = 0; i < letters.length; i++) {
self.users.groups[letters[i]] = { users: ko.observableArray([]) };
}
}
Now in your View:
<div data-bind="foreach: { data: $root.users.groups, as: '$group' }">
<h3 data-bind="text: $group"></h3>
<ul data-bind="foreach: { data: $root.users.groups[$group].users, as: '$user' }">
<li data-bind="text: $user.name"></li>
</ul>
</div>
jsFiddle
*Note: You'd only want to go this route if you had a need to update these names dynamically on the client side. If this list were to remain static, it'd probably be best to go with Damien's answer.
Related
I have display for my data like
#Html.DisplayFor(m=> m.UserName)
Result
John
I want to show only one character and hide the rest for user name data.
Result that is required
J######
Is there a quick way to display something like this, or will I have to write my own backend logic?
You can try to put #Html.DisplayFor(m=> m.UserName) into div;
and change the content of div with $(function(){}):
<div id="UserName">#Html.DisplayFor(m => m.UserName)</div>
<script>
$(function () {
var userName = document.getElementById('UserName').innerHTML;
var characters = userName.split('');
var newUserName = "";
if (characters.length > 0) {
newUserName = characters[0];
for (var i = 1; i < characters.length; i++) {
newUserName += '#';
}
}
document.getElementById('UserName').innerHTML = newUserName;
})
</script>
I have a list in Razor Page which i want to use in java script.I'm using viewdata to send data to view VIewbag is working for some reason in razor page.
I'm using .net core 2.2
Things i already tried.
View
Things i already tried:
var a=#Model.listname
var stringArray = #Html.Raw (Json.Serialize(ViewData["Quest"]));` viewdata[Quest] contains list
string jsonn = JsonConvert.SerializeObject(quelist);`
and then send jsoon to view.
using custom class object and create create json object using Newtonsoft.Json and send to view
If you proposing ajex solution explain it a little as i dont know much about it or share a link for explanation
Razor page .cs file Commented the things that didn't
public async Task OnGetAsync()
{
ViewData["opt1"] = o1list;
ViewData["quest"] = quelist;
// string jsonn = JsonConvert.SerializeObject(quelist);
// ViewData["Jon"] = jsonn;
QuestionBank = await _context.QuestionBank
.Include(q => q.QuestionLevel)
.Include(q => q.QuestionStyle)
.Include(q => q.Teacher)
.Include(q => q.Topic).ToListAsync();
Answer = await _context.Answer.ToListAsync();
QSID = await _context.QSID.ToListAsync();
View
#{var name = (List<String>)ViewData["Quest"]; }
<script>
/*function test() {
var array = #Html.Raw(Json.Serialize(ViewData["Jon"]));
for(var i = 0; i < array.length; i++) {
alert(array[i]);
console.log(array[i]);
}
}
test();
*/</script>
</head>
<body>
#{
Model.run();
var name = (List<String>)ViewData["Quest"];
var nam = (List<String>)ViewData["opt1"];
int j = 0;
for (int i = 0; i <= 4; i++)
{
var a = name[i];
<p > #a </p>
<form action="">
<input type="radio" name="s" value="">#nam[j]<br>
#{j = j + 1; }
<input type="radio" name="s" value="">#nam[j]<br>
#{j = j + 1; }
<input type="radio" name="s" value="">#nam[j]<br>
#{j = j + 1; }
<input type="radio" name="s" value="">#nam[j]
#{j = j + 1; }
</form>
}
}
I expect to get a array containing my list or in json format
This is how I do it in a project I created:
<script>
var saleTypesById = #Html.Raw(JsonConvert.SerializeObject(Model.TypesById));
</script>
Where Model.TypesById is a Dictionary<long,SaleType>.
To use from javascript I call:
var selectedSaleType = saleTypesById[selectedId];
Then I can just call properties on it like selectedSaleType.Comission
This code requires #using Newtonsoft.Json; directive and a reference to the corresponding nugget package.
I follow the above example but with an extra step:
<script type="text/javascript">
window.onload = function () {
try {
var movsArray = '#Html.Raw(JsonConvert.SerializeObject(Model))';
var opt = JSON.parse(movsArray);//Extra step
if (opt.length > 0) {
//You can use opt as array of objects
}
} catch (Error) {
console.log("Error");
}
};
</script>
or maybe you can use a loop instead of if
<script type="text/javascript">
window.onload = function () {
try {
var movsArray = '#Html.Raw(JsonConvert.SerializeObject(Model))';
var opt = JSON.parse(movsArray); //Extra step
for(var i = 0;i<opt.length;i++){
//you can use opt[i] as object, example opt[i].id
}
} catch (Error) {
console.log("Error");
}
};
</script>
Where Model is List<Mov_Tipo>
I have a Generic List and I'm passing it as ViewData from my Controller to my .aspx View.
I need to get and iterate it with a Jquery Script.
How could I make this script works?
Regards
success: function (result) {
var myArray = new Array();
var myArray = '<%: ViewData["List"] %>';
for (var i = 0; i < myArray.length; i++) {
alert(i);
}
You can do something like this..
<script type="text/javascript">
#{ List<string> ss = (List<string>)ViewData["List"];}
var myArray = [
#for (int i = 0; i < ss.Count; i++)
{
#: #(ss[i]),
}
]
</script>
my syntax for razor view(you can do it for classic)
Try like this , push items of list view to the array of javascript, wrap below code in script tag
--script tag--
var jList = new Array();
#foreach (var item in ViewData["List"] as List<String>)
{
#:jList.push('#item'); // That will work if its a one letter string but It doesnt know that its a string untill you use ''
}
--script tag--
Ok if you are using just a list of strings then
this will do
$(document).ready(function () {
#{List<string> listFromController = (List<string>)ViewData["List"];}
var myArray = [
#for (int i = 0; i < listFromController.Count; i++)
{
#: '#(listFromController[i])',
}
]
});
But if you are passing list of another type rather than string like an student Employee or a user you will need the following
Please use the appropriate class that you have passed and the
properties suppose "UserName" could be "FirstName" "EmpId" or what ever
$(document).ready(function () {
#{ var listFromController = (List<KnockoutJSWebApi.Models.LoginViewModel>)ViewData["list"];}
var totalArray = [];
#for (int i = 0; i < listFromController.Count; i++)
{
<text>
var thisArray= {
'username': '#(listFromController[i].UserName)',
'password': '#(listFromController[i].Password)'
};
totalArray.push(thisArray);
</text>
}
});
Aspx View Engine syntax:
<script>
$(document).ready(function () {
<% List<string> listFromController = (List<string>)ViewData["List"]; %>
var myArray = [
<% for (int i = 0; i < listFromController.Count; i++){ %>
'<%: listFromController[i] %>',
<% } %>
]
debugger;
});
</script>
Problem solved.
I used a JsonResult method in my Controller and returned the needed values as:
Json(List, JsonRequestBehavior.AllowGet);
With that, I don't need to iterate the values because I assign them as datasource to my DropDownList control.
$("#Generic_FK").data("DropDownList").dataSource.data(result);
Hope to help other people with the same issue!
Server Side
public class users
{
public string name{ get; set; }
}
// in your controller code
ViewData["list"] = new List<users>(new users[] { new users()
{ name="prasad"}, new users() {name="raja"}});
Client Side
<script type="text/javascript">
$(function(){
var myitems=JSON.parse('#Html.Raw(Json.Encode(this.ViewData["list"]))');
$.each(myitems, function(index, item) {
var name = item.name;
});
});
</script>
i hope this may help you
Hello i want to use counter which takes value from js file, but i want to change it.
Here is js code;
function countUp(count)
{
var div_by = 100,
speed = Math.round(count / div_by),
$display = $('.count'),
run_count = 1,
int_speed = 24;
var int = setInterval(function() {
if(run_count < div_by){
$display.text(speed * run_count);
run_count++;
} else if(parseInt($display.text()) < count) {
var curr_count = parseInt($display.text()) + 1;
$display.text(curr_count);
} else {
clearInterval(int);
}
}, int_speed);
}
countUp(600);
It counts to 600 but i want assign variable to this from database probly with codebehind.
Here is html code ;
<div class="col-lg-3 col-sm-6">
<section class="panel">
<div class="symbol red">
<i class=" fa fa-times text-muted"></i>
</div>
<div class="value">
<h1 class="count">123123123</h1>
<p>Position Canceled</p>
</div>
</section>
</div>
How can i change countUp value in js. Please help me.
Thank You
function countUp(count)
{
var div_by = 100,
speed = Math.round(count / div_by),
$display = $('.count'),
run_count = 1,
int_speed = 24;
var int = setInterval(function() {
if(run_count < div_by){
$display.text(speed * run_count);
run_count++;
} else if(parseInt($display.text()) < count) {
var curr_count = parseInt($display.text()) + 1;
$display.text(curr_count);
} else {
clearInterval(int);
}
}, int_speed);
}
var _count=0;
//If you are retreiving count from database, you can perform ajax call
var request = $.ajax({
url: url,
type: "GET",
dataType: json
});
request.done(function(msg) {
_count=msg.data;
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
//if you are assinging count value from html tags
eg: assign value into hidden field, then
<input type="hidden" id="count" value="600"/>
_count=$('#count).val();
countUp(600);
You can use following syntax:
countUp('<%= CountValueFromDB %>');
Where CountValueFromDB is variable you can declare in your code-behind for particular page and populate it from database or any other source in your Page_Load method or another method called during page life cycle.
Alternatively you can call RegisterStartupScript in your code behind passing "countUp(" + CountValueFromDB + ");" for 'script' parameter.
I have a html document but it's size is about 5MB.
Here is my code "../Product/index?page=1" it generates 5MB html :
Plugin url : http://andersonferminiano.com/jqueryscrollpagination/
<script type="text/javascript">
$(function () {
$('#content').scrollPagination({
'contentPage': '../Product/index?page=1',
'contentData': {},
'scrollTarget': $(window),
'heightOffset': 10,
'beforeLoad': function () {
$('#loading').fadeIn();
},
'afterLoad': function (elementsLoaded) {
$('#loading').fadeOut();
var i = 0;
$(elementsLoaded).fadeInWithDelay();
if ($('#content').children().size() > 100) {
$('#nomoreresults').fadeIn();
$('#content').stopScrollPagination();
}
}
});
$.fn.fadeInWithDelay = function () {
var delay = 0;
return this.each(function () {
$(this).delay(delay).animate({ opacity: 1 }, 200);
delay += 100;
});
};
});
</script>
<!--_____________________________________________________________________-->
#{
// here is "Product/index" Code
if (Request.QueryString.HasKeys())
{
int iPage = Request.QueryString["page"].AsInt();
using (var db = new PNUBOOKIR.Models.KowsarSiteEntities())
{
var queries = from n in db.vwGood
select n;
long counter = 0;
for (int i = 1; i <= iPage; i++)
{
foreach (var q in queries)
{
counter++;
<li style="opacity: 0; -moz-opacity: 0; filter: alpha(opacity=0);">
<p>
#counter
</p>
</li>
}
}
}
}
}
I don't want to load it complete when the scroll goes down it should load 10 other "li" element
I do not simulate so heavy page, but I have an other way to load page. Maybe, it can be a reference for you.
Separate each page request at action side, and return for only one page content.
Collect "style" content to css class, to reduce page content.
Improve performance of LINQ with PLINQ.
I notice the code output every page content.
var queries = from n in db.vwGood select n;
long counter = 0;
for (int i = 1; i <= iPage; i++)
{
foreach (var q in queries)
{
counter++;
}
}
I suggest you can
modify LINQ with Paging function.
Update LINQ as PLINQ to improve performance. I add AsParallel() after db.vwGood, I am not sure what db.vwGood instance and wish this modify can be good.
Not return HTML content in Razor View, but in Action.
Pseudo code of Action is as below,
// iAmount is record amount in each page.
int iAmount = 50;
// queries is only the iPage content
// but not all of content from page one to page iPage.
var queries = (from n in db.vwGood.AsParallel() select n)
.Skip(iPage - 1).Take(iAmount);
long counter = 0;
string strContent = string.Empty;
foreach (var q in queries)
{
counter++;
// Generate Cotnent here.
strContent += #"<li class='YourClassName'><p>#counter</p></li>"
}
return Content(strContent)
When ShowMore button is clicked, ShowMore_OnClick() is performanced.
<input type="button" style="width: 100%" id="BtnShowMore" value="MORE"
onclick="return ShowMore_OnClick();" />
This is JavaScript for Loading function.
I notice you do not use button to control content display, but scrollPagination. You can modify the JavaScript to suit with scrollPagination plugin. The thinking of code structure is same.
var PageNO = 1;
function ShowMore_OnClick() {
var BtnShowMore = document.getElementById("BtnShowMore");
BtnShowMore.value = "Loading...";
jQuery.post(
"/Home/GetHomeEventAjax/",
{ "PageNO": PageNO + 1 },
function (data, states) {
if (states == "success") {
var EventListArea = document.getElementById("EventListArea");
var newCommentItem = document.createElement("DIV");
newCommentItem.setAttribute("ID", "EventItem");
newCommentItem.innerHTML = data;
EventListArea.appendChild(newCommentItem);
PageNO = PageNO + 1;
BtnShowMore.value = "More";
}
}
);
}