I have created code to count data collection by using group aggregate but now I have problem where the process count group cannot give the correct result. I don't know where the problem is.
The result from this code is like this Result. There is my code:
//js
Template.laporankategori.helpers({
profilcount: function() {
var subs = {};
Profil.find().forEach(function(e) {
if (subs[e.kategori] == null)
subs[e.kategori] = 0;
subs[e.kategori] += e.amount;
});
var result = [];
_.each(subs, function(value, key) {
result.push({kategori: key, amount: value});
});
return result;
}
});
//publish
Meteor.publish("profilcount",function(args) {
var sub = this;
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
var pipeline = [
{ "$group": {
"_id": "$kategori",
count:{$sum:amount}
}}
];
db.collection("profil").aggregate(
pipeline,
Meteor.bindEnvironment(
function(err, result) {
_.each(result, function(e) {
sub.added("profil", Random.id(), {
kategori: kategori._id,
amount: kategori.count
});
});
sub.ready();
},
function(error) {
Meteor._debug( "Error doing aggregation: " + error);
}
)
);
});
//html
{{#each profilcount}}
<tr>
<td>{{kategori}}</td>
<td>{{ amount}}</td>
</tr>
{{/each}}
I want the result like this. Result
I have other solution for this, without using aggregate. Just in case if it helps you.
//js
Template.laporankategori.helpers({
profilcount () {
var result = [];
var categs = [];
profil.find().forEach(function(profil) {
if(categs.indexOf(profil.kategori) > -1) {
for (var i = 0; i < result.length; i++) {
var res = result[i];
var count = res.count + 1;
var amount = res.amount + profil.amount;
result[i].count = count;
result[i].amount = amount;
break;
}
} else {
result.push({
name: profil.kategori,
amount : profil.amount,
count : 1
});
categs.push(profil.kategori);
}
});
return result;
}
});
Meteor.publish("profil",function(args) {
return profil.find({},{fields: {amount: 1, kategori:1}});
});
//HTML
<table>
<thead>
<tr>
<td> Kategori </td>
<td> Total Amount</td>
<td> Count </td>
</tr>
</thead>
<tbody>
{{#each profilcount}}
<tr>
<td>{{ name }}</td>
<td>{{ amount }}</td>
<td>{{ count }}</td>
</tr>
{{/each}}
</tbody>
</table>
Related
'how display data in table by search only .net core razor , i have this data view on table i want appear row when searching only`
<tbody id="tblBody" >
#{
foreach (var item in Model.Patients)
{
<tr id="row_#item.Id">
<td id="patientName_#item.Id" class="table-cell-arabic">#item.PatientName</td>
<td id="phone_#item.Id">#item.Phone</td>
<td id="Diseases_#item.Id">#item.Diseases</td>
<td>
<button class="btn btn-danger btn-xs sm-btn-table" type="button" onclick="OnDelete(#item.Id)">Delete</button>
<button class="btn btn-success btn-xs sm-btn-table" type="button" onclick="OnEdit(#item.Id)">Edit</button>
<button class="btn btn-success btn-xs sm-btn-table" type="button" onclick="OnDetails(#item.Id)">Details</button>
</td>
</tr>
}
}
</tbody>
Do you want to load data via search button like this (take Id for example):
Index.cshtml.cs:
public void OnGet()
{
}
public JsonResult OnGetTest(int Id)
{
if (Id == 0)
{
var patient = (from m in _context.Patient select m).ToList();
return new JsonResult(patient);
}
else
{
var patient = (from m in _context.Patient select m).Where(c => c.Id == Id).ToList();
return new JsonResult(patient);
}
}
Index.cshtml:
<div>
<input id="Search" />
<button class="btn-primary" onclick="Test()">Search</button>
</div>
<div>
<table class="table">
<thread>
<tr>
<td>PatientName</td>
<td>Phone</td>
<td>Diseases</td>
</tr>
</thread>
<tbody id="tbody">
</tbody>
</table>
</div>
<script>
function Test() {
$.ajax({
url: '?handler=Test&id=' + $("#Search").val(),
success: function (result) {
var html = "";
for (var i = 0; i < result.length; i++) {
html += "<tr><td id='patientName_'" + result[i].id + ">" + result[i].patientName + "</td>"
+ "<td id='phone_'" + result[i].id + ">" + result[i].phone + "</td>"
+ "<td id='Diseases_'" + result[i].id + ">" + result[i].diseases + "</td></tr>"
}
$("#tbody").html(html);
},
error: function (error) {
console.log(error);
}
});
}
</script>
Result:
Before searching:
After searching:
If you use MVC:
Controller:
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult Index(int Id)
{
if (Id == 0)
{
var patient = (from m in _context.Patient select m).ToList();
return Json(patient);
}
else
{
var patient = (from m in _context.Patient select m).Where(c => c.Id == Id).ToList();
return Json(patient);
}
}
View:
<div>
<input id="Search"/>
<button class="btn-primary" onclick="Test()">Search</button>
</div>
<div>
<table class="table">
<thread>
<tr>
<td>PatientName</td>
<td>Phone</td>
<td>Diseases</td>
</tr>
</thread>
<tbody id="tbody">
</tbody>
</table>
</div>
<script>
function Test()
{
$.ajax({
type: 'POST',
url: "/Home/Index",
data: { id: $("#Search").val()},
success: function (response) {
var html = "";
for(var i=0;i<response.length;i++)
{
html += "<tr><td id='patientName_'" + response[i].id + ">" + response[i].patientName + "</td>"
+ "<td id='phone_'" + response[i].id + ">" + response[i].phone + "</td>"
+ "<td id='Diseases_'" + response[i].id + ">" + response[i].diseases + "</td></tr>"
}
$("#tbody").html(html);
},
error: function(error){
console.log(error);
}
});
}
</script>
Is this what you want?
I've had problems with this for a while. After I attempt to login with wrong password, it doesn't keep me on that login modal. It opens the index page and I have to press button "login" from navbar to open the modal. Then it does give me the error message "Failed login.". But I don't want to double click everything. I need it to stay in the login modal after failed login and show the error message.
Here is my code:
Controller:
[HttpPost]
public ActionResult Authorize(Logins LoginModel)
{
var LoggedUser = db.Logins.SingleOrDefault(x => x.Username == LoginModel.Username && x.Password == LoginModel.Password);
if (LoggedUser != null)
{
//ViewBag.LoginMessage = "Login was a success!";
ViewBag.LoggedStatus = "In";
ViewBag.LoginError = 0; //no errors
Session["Username"] = LoggedUser.Username;
return RedirectToAction("Index", "Home");
}
else
{
LoginModel.ErrorMessage = "Login failed.";
ViewBag.LoggedStatus = "Out";
ViewBag.LoginError = 1;
return View("Index", LoginModel);
}
}
_LoginModal.csthml :
<div class="modal-header">
<h1>Login</h1>
</div>
<div class="modal-body">
#using (Html.BeginForm("Authorize", "Home", FormMethod.Post, new { id = "loginForm" }))
{
<table>
<tr>
<td></td>
</tr>
<tr>
<td>Username</td>
<td> #Html.EditorFor(model => model.Username)</td>
</tr>
<tr>
<td></td>
<td>#Html.ValidationMessageFor(model => model.Username)</td>
</tr>
<tr>
<td>Salasana</td>
<td> #Html.EditorFor(model => model.Password)</td>
</tr>
<tr>
<td></td>
<td>#Html.ValidationMessageFor(model => model.Password)</td>
</tr>
<tr>
<td colspan="2">
<label class="field-validation-error">#Html.DisplayFor(model => model.ErrorMessage)</label>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" name="name" class="btn btn-success" value="Login" />
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
</td>
</tr>
</table>
}
<div class="modal-footer" style="margin-top:10px">
</div>
</div>
And on the index page I have this added so it opens the login modal:
#{
Html.RenderPartial("_LoginModal");
}
So I tried to do it like this and added it to the _LoginModal.csthml, but it didn't work:
#section scripts {
<script type="text/javascript">
function login() {
#if(ViewBag.ErrorMessage == "Wrong username/password")
{
WriteLiteral("$('#LoginModal').modal('show');");
};
</script>
}
I really need the help!
This is because you send the entire form to be posted back to the server. That is why entire page gets refresh.
Try Ajax.BeginForm() to post only form not the entire page
Create Ajax form (replace #html.beginform with this code)
#using (#Ajax.BeginForm("Authorize", "Your_Controller_Name", new AjaxOptions
{
HttpMethod = "Post",
OnSuccess = "OnSuccess(data)",
UpdateTargetId = "modalbody"
}, new { id = "loginForm" }))
{
<table>...</table>
}
Add OnSuccess(data) function at the bottom of the view
function OnSuccess(data) {
if (data.IsSuccess == false) {
/*Login unsuccessful*/
$(".field-validation-error").html(data.message);
}
else {
/*Login successful*/
$('#LoginModal').modal('hide');
window.location.replace("/Home/Index");
}
}
And last change Authorize action method
public JsonResult Authorize(Logins LoginModel)
{
var LoggedUser = db.Logins.SingleOrDefault(x => x.Username == LoginModel.Username && x.Password == LoginModel.Password);
if (LoggedUser != null)
{
//ViewBag.LoginMessage = "Login was a success!";
ViewBag.LoggedStatus = "In";
ViewBag.LoginError = 0; //no errors
Session["Username"] = LoggedUser.Username;
return Json(new { IsSuccess = true, message = "Login successfully!" }, JsonRequestBehavior.AllowGet);
}
else
{
LoginModel.ErrorMessage = "Login failed.";
ViewBag.LoggedStatus = "Out";
ViewBag.LoginError = 1;
return Json(new { IsSuccess = false, message = LoginModel.ErrorMessage }, JsonRequestBehavior.AllowGet);
}
}
I am trying to bind a table using a foreach binding of Knockout. However, my observable properties are reflecting changes, but the data is not able to bind with the table. Below is the code:
HTML
<div class="container-fluid ">
<table class="table table-Alternate table-condensed header" id="appTable">
<thead>
<tr>
<th></th>
<th style="font-weight: bold;">Market </th>
<th style="font-weight: bold;">Product Name</th>
<th style="font-weight: bold;">Company Name</th>
<th style="font-weight: bold;">Product Id</th>
<th style="font-weight: bold;">Publisher Name </th>
<%--<th><span style="font-weight: bold;" id="Span1">Action</span></th>--%>
</tr>
</thead>
<tbody id="appAnnieData" data-bind="foreach: CompanyInfo">
<%-- <tr>
<td><span data-bind="text:Market"></span></td>
<td><span data-bind="text: Product_Name"></span></td>
<td><span data-bind="text: Company_Name"></span></td>
<td><span data-bind="text: Product_id"></span></td>
<td><span data-bind="text: Unified_Product_Name"></span></td>
</tr>--%>
</tbody>
</table>
</div>
script
$(document).on('click', '#appAnnieSearch', function() {
mainModel = $(this);
var id = $(this).parents().find("#txtCompanyId").val();
if (id == "") {
toastr.info('Please enter Company ID');
return false;
}
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "../../Services/AService.asmx/GetCompanyInformation",
data: {
id: JSON.stringify(id)
},
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function(res) {
if (res.d != null && res.d != undefined && res.d != "NotFound") {
var options = JSON.parse(res.d);
FillDetailsForCompany(options.app_list);
} else {
toastr.options.timeOut = 7000;
toastr.options.closeButton = true;
toastr.info('No information found for the selected Company Id. Please try another one.');
}
document.getElementById("loader_search").style.display = "none";
},
error: function(errormsg) {
$(".dropdown_SubDomainLoading").hide();
toastr.options.timeOut = 7000;
toastr.options.closeButton = true;
toastr.error('Something Went Wrong');
}
});
});
function FillForCompany(appanydata) {
var dataArray = [];
for (var i = 0; i < appanydata.length; i++) {
dataArray.push(new AppViewModel(appanydata[i].market, appanydata[i].product_name, appanydata[i].company_name, appanydata[i].product_id, appanydata[i].unified_product_name,
appanydata[i].product_franchise_id, appanydata[i].product_category, appanydata[i].unpublished, appanydata[i].company_id, appanydata[i].unified_product_id, appanydata[i].product_franchise_name, appanydata[i].publisher_id,
appanydata[i].publisher_name, appanydata[i].product_code));
}
DomainModule.dataContext.CompanyInfo(dataArray);
}
function AppViewModel(market, product_name, company_name, product_id, unified_product_name, product_franchise_id, product_category, unpublished, company_id,
unified_product_id, product_franchise_name, publisher_id, publisher_name, product_code) {
self = this;
self.Market = ko.observable(market);
self.Product_Name = ko.observable(product_name);
self.Company_Name = ko.observable(company_name);
self.Product_Id = ko.observable(product_id);
self.Unified_Product_Name = ko.observable(unified_product_name);
self.Product_Franchise_Id = ko.observable(product_franchise_id);
self.Product_Category = ko.observable(product_category);
self.Unpublished = ko.observable(unpublished);
self.Company_Id = ko.observable(company_id);
self.Unified_Product_Id = ko.observable(unified_product_id);
self.Product_Franchise_Name = ko.observable(product_franchise_name);
self.Publisher_Id = ko.observable(publisher_id);
self.Publisher_Name = ko.observable(publisher_name);
self.Product_Code = ko.observable(product_code);
}
The observable property is getting populated and when I inspect the object value DomainModule.dataContext.CompanyInfo has the respective data. However, I do not get the table populated.
I am trying to fetch the data on the click event of a button. Is there something I am missing?
I am creating a modal to manage the permissions of a user. But when the modal is loaded. The console returns true from the server, if a users has the role. While {{#if hasRole}} is still showing the wrong label.
editUserPermissionsModal.html
<tbody>
{{#each roles}}
<tr>
<td>{{this.name}}</td>
<td>
{{#if hasRole}}
<span class="label label-success">Toegang</span>
{{else}}
<span class="label label-danger">Geweigerd</span>
{{/if}}
</td>
<td>
<select class="roleSelect">
{{#if hasRole}}
<option value="allow">Toestaan</option>
<option value="deny">Weigeren</option>
{{else}}
<option value="deny">Weigeren</option>
<option value="allow">Toestaan</option>
{{/if}}
</select>
</td>
</tr>
{{/each}}
</tbody>
editUserPermissionsModal.js
Template.editUserPermissionsModal.helpers({
roles: function() {
return Roles.getAllRoles();
},
hasRole: function(){
var userId = Session.get("editing_user");
var role = this.name;
Meteor.call("checkRole", userId, role, function(error, result){
if(error){
console.log("error", error);
}
if(result){
console.log(result);
return result;
}
});
}
});
Template.editUserPermissionsModal.events({
"change .roleSelect": function(event, template){
var addRole = event.target.value;
if(addRole == 'allow') {
var user = Session.get("editing_user");
var role = this.name;
Meteor.call('addRoleToUser', user, role)
}
}
});
server.js
checkRole:function(userId, role) {
return Roles.userIsInRole(userId, role);
}
This is a typical "method call within a helper" issue. You can read about it here.
Given that you need variable arguments to your method, the easiest solution in your case would probably be using David Weldon's answer and install Sashko's meteor-reactive-method package:
$ meteor add simple:reactive-method
And then:
Template.editUserPermissionsModal.helpers({
roles: function() {
return Roles.getAllRoles();
},
hasRole: function(){
var userId = Session.get("editing_user");
var role = this.name;
var result = ReactiveMethod.call("checkRole", userId, role);
console.log(result);
return result;
}
});
I'm discovering the awesome KnockoutJS library and I'm stuck on a feature I would like to implement:
Explanation
I have an array containing n lines of a type of object:
Html:
<tbody data-bind="foreach: indexItems">
<tr data-bind="click: $parent.UpdateInterfaceItems, css: { 'active-row' : $root.selecteditem() === $data }">
<td data-bind="text: param1"></td>
<td data-bind="text: param2"></td>
<td data-bind="text: param3"></td>
</tr>
</tbody>
Javascript:
function ViewModel() {
var self = this;
//Public Properties
self.selecteditem = ko.observable();
self.indexMats = ko.observableArray();
....
hub.client.receivedNewValue= function (param1Value, param2Value, param3Value)
{
var match = ko.utils.arrayFirst(vm.indexItems(), function (item) {
return item.param1() == param1Value;
});
if (match)
{
match.param1(param1Value);
match.param2(param2Value);
match.param3(param3Value);
}
}
}
Feature
Sometimes I want to update one row (on some values only) and I would like to highlight the modified cell with a color which would fade away. Is there any way to do that?
I've found out a quite similar question but it doesn't match my need (Knockout JS Update Color)
Thanks a lot
I have written a binding name highlight long time ago. Think that is smilar to what you need.
ko.bindingHandlers.highlight = {
update: function(element, valueAccessor) {
ko.toJS(valueAccessor());
var old = parseInt($(element).html(),10);
var current = parseInt(valueAccessor()(),10);
if ($(element).data("ko_init")) {
if(current < old) {
$(element).effect('highlight', {
color: '#AA0000'
}, 1000);
} else if (current>old ) {
$(element).effect('highlight', {
color: '#00AA00'
}, 1000);
}
}
else {
$(element).data("ko_init", true);
}
}};
function Table(rowCount, columnCount, headItems, initiliaze) {
var self = this;
var Cell = function(data, css, animate) {
var cellInstance = this;
this.data = ko.observable(data);
this.css = ko.observable(css);
this.animate = ko.observable(animate);
}
this.rowCount = ko.observable(rowCount);
this.columnCount = ko.observable(columnCount);
this.headItems = ko.observableArray(headItems);
this.rowsData = ko.observableArray();
if (initiliaze) {
for (var i = 0; i < rowCount; i++) {
var tmpArray = new Array();
for (var j = 0; j < columnCount; j++)
tmpArray.push(new Cell("0", "", ""));
self.rowsData.push(ko.observableArray(tmpArray));
}
}}
function ViewModel() {
var self = this;
this.table = new Table(5, 4, ["Name", "DT", "BID", "ASK"], true);
};
$(function() {
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
function changeData(x, y, data) {
viewModel.table.rowsData()[x]()[y].data(data);
}
setInterval(function() {
changeData(parseInt(Math.random(1000) * 5, 10), parseInt(Math.random(1000) * 4, 10), parseInt(Math.random(1000) * 10000, 10));
}, 1000);
})
Check out jsfiddle demo