I am trying to change the row of a table to #0093ff; if the Holidays.HolidayDate is the next upcoming holiday.
NEW CODE:
<table ng-if="model.Holidays" class="table">
<tr>
<th>Holiday</th>
<th>Date</th>
<th>Branch</th>
<th>Hours</th>
</tr>
<tr ng-repeat="Holidays in model.Holidays" ng-style="isUpcomingHoliday(Holidays.HolidayDate) ? 'color:#0093ff' : '' ">
<td>{{Holidays.HolidayName}}</td>
<td>{{Holidays.HolidayDate | fulldaydate}}</td>
<td>{{Holidays.Branch ? Holidays.Branch : 'All'}}</td>
<td>{{Holidays.Hours ? Holidays.Hours : 'Closed'}}</td>
</tr>
</table>
JS
.filter('isUpcomingHoliday', ['$filter',
function ($filter) {
return function (input) {
const sortedHolidays = this.model.Holidays.sort((a, b) => {
return moment(b.date).isAfter(moment(a.date))
});
const upcomingHoliday = sortedHolidays[0];
return moment(holidayDate).isSame(upcomingHoliday);
};
}])
You can achieve it by sorting holidays and compare with the first element. I think it can look like this:
isUpcomingHoliday(holidayDate) {
const sortedHolidays = this.model.Holidays.sort((a, b) => {
return new Date(b.HolidayDate) - new Date(a.HolidayDate)
};
return holidayDate.getTime() === sortedHolidays[0].getTime();
}
<section class="module module-divider-bottom" data-app="global">
<div class="container" ng-controller="ContactController">
<div class="container">
<table ng-if="model.Holidays" class="table">
<tr>
<th>Holiday</th>
<th>Date</th>
<th>Branch</th>
<th>Hours</th>
</tr>
<tr ng-repeat="Holidays in model.Holidays" ng-style="isUpcomingHoliday(Holidays.HolidayDate) ? 'background-color:#0093ff' : '' ">
<td>{{Holidays.HolidayName}}</td>
<td>{{Holidays.HolidayDate | fulldaydate}}</td>
<td>{{Holidays.Branch ? Holidays.Branch : 'All'}}</td>
<td>{{Holidays.Hours ? Holidays.Hours : 'Closed'}}</td>
</tr>
</table>
</div>
</div>
</section>
It could be better and more readable with moment.js:
isUpcomingHoliday(holidayDate) {
const sortedHolidays = this.model.Holidays.sort((a, b) => {
return moment(b.date).isAfter(moment(a.date))
};
const upcomingHoliday = sortedHolidays[0];
return moment(holidayDate).isSame(upcomingHoliday);
}
Something like this should do the trick. I didn't know if you already had an api that tells you the next holiday, If you are using moment to check if the date is the same (or if you already have something to compare dates).
I chose the class vs ngStyle because you might want to style other things related to that holiday. Hope that helps.
isNextHoliday (holidayDate): boolean {
// return some function that compares the two dates
}
.some-color {
background: red;
}
<section class="module module-divider-bottom" data-app="global">
<div class="container" ng-controller="ContactController">
<div class="container">
<table ng-if="model.Holidays" class="table">
<tr>
<th>Holiday</th>
<th>Date</th>
<th>Branch</th>
<th>Hours</th>
</tr>
<tr ng-repeat="Holidays in model.Holidays">
<td>{{Holidays.HolidayName}}</td>
<td [class.some-color]="isNextHoliday(Holidays.HolidayDate)">{{Holidays.HolidayDate | fulldaydate}}</td>
<td>{{Holidays.Branch ? Holidays.Branch : 'All'}}</td>
<td>{{Holidays.Hours ? Holidays.Hours : 'Closed'}}</td>
</tr>
</table>
</div>
</div>
</section>
Related
I am creating an editable JQuery data-table from the model list . I want to edit some of the column [Rate, Qty, IsBranded, Description] of each record listed in a table. My code is given below.
ProductModel
Id int
Name string
Rate decimal
Qty int
Price decimal
Description string
Html and Javascript
<script type="text/javascript">
$("document").ready(function () {
$('#tbllist').DataTable();
});
</script>
#model List<Product>
<table id="tbllist" class="cell-border" style="width:100%">
<thead class="thead-light">
<tr>
<td>Name</td>
<td>Rate</td>
<td>Qty</td>
<td>total</td>
<td>IsBranded</td>
<td>Description</td>
</tr>
</thead>
<tbody>
#if (Model != null)
{
for (var i = 0; i < Model.Count; i++)
{
<tr>
<td>#Model[i].Name</td>
<td>#Model[i].Rate</td>
<td>#Model[i].Qty</td>
<td>#Model[i].total</td>
<td><input type="checkbox" #(Model[i].IsBranded ? "checked" : "") /></td>
<td>#Model[i].Description</td>
</tr>
}
}
</tbody>
</table>
I want to make edit Rate,Qty, Description, IsBranded column. It would be very appreciated , if someone can help me with appropriate code to make .
With Thanks
Alan
I made an example based on #StéphaneLaurent comment, hope it can work for you.
Copy the dataTables.cellEdit.js to your project, you can place it under wwwroot/js
Reference it in your page
<script src="~/js/dataTables.cellEdit.js"></script>
Then follow the tutorial.
#model List<ProductModel>
<table id="tbllist" class="cell-border" style="width:100%">
<thead class="thead-light">
<tr>
<td>Name</td>
<td>Rate</td>
<td>Qty</td>
<td>Total</td>
<td>IsBranded</td>
<td>Description</td>
</tr>
</thead>
<tbody>
#if (Model != null)
{
for (var i = 0; i < Model.Count; i++)
{
<tr>
<td>#Model[i].Name</td>
<td>#Model[i].Rate</td>
<td>#Model[i].Qty</td>
<td>#Model[i].Total</td>
<td><input type="checkbox" #(Model[i].IsBranded ? "checked" : "") /></td>
<td>#Model[i].Description</td>
</tr>
}
}
</tbody>
</table>
#section scripts{
<script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
<script src="~/js/dataTables.cellEdit.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css" />
<script type="text/javascript">
var table = $('#tbllist').DataTable();
function myCallbackFunction(updatedCell, updatedRow, oldValue) {
console.log("The new value for the cell is: " + updatedCell.data());
console.log("The values for each cell in that row are: " + updatedRow.data());
}
table.MakeCellsEditable({
"onUpdate": myCallbackFunction
});
</script>
}
Result:
I want to display the database values depending on the particular ID. I pass that id in the URL, and it redirects to another page with ID. In that page I have to display that particular user's records.
Here is the controller function:
public function consultants()
{
return view('Hr/view-request-candidates', [
'consultant' => HrRequestConsultant::all(),
]);
}
Route:
Route::get(
'/view-request-candidates/{hr_request_id}',
'Hr\HrDashboardController#consultants'
);
URL:
CANDIDATES
View:
<div class="col-md-12">
<table class="table table-striped">
<tbody>
<tr>
<th>Hr Request ID</th>
<th>Consultant ID</th>
<th>No Of Candidates</th>
<th>Actions</th>
</tr>
#foreach($consultant as $row)
<tr>
<td>{{$row->hr_request_id}}</td>
<td>{{$row->consultant_id}}</td>
<td>{{30}}</td>
<td>
<a href="/view-hr-candidates" class="btn btn-primary">View</button>
</td>
</tr>
#endforeach
How can I do this?
Routes::
Route::get('home','HrDashboardController#home');
Route::get('view-hr-candidates/{hr_request_id}','HrDashboardController#consultants');
Controller::
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\HrRequestConsultant;
use DB;
class HrDashboardController extends Controller
{
public function home(){
$home = HrRequestConsultant::select('id','hr_request_id','consultant_id')->get();
return view('home')->with('home', $home);
//Its View: home.blade.php file
}
public function consultants($id){
$result = HrRequestConsultant::select('id','hr_request_id','consultant_id')->where('hr_request_id',$id)->first();
return $returnview = view('Hr.view-request-candidates')->with('result', $result);
// Its view-request-candidates.blade.php file InSide the Hr Dir.
}
}
home.blade.php::
<body>
<div class="flex-center position-ref full-height">
<div class="content">
<div class="title m-b-md"> View Details </div>
<div class="col-md-12">
<table border="1" style='color: black'>
<tr>
<th>Hr Request ID</th>
<th>Consultant ID</th>
<th>No Of Candidates</th>
<th>Actions</th>
</tr>
#foreach ($home as $data){
<tr>
<td> {{ $data['hr_request_id'] }} </td>
<td> {{ $data['consultant_id'] }} </td>
<td> 30 </td>
<td> View </td>
</tr>
#endforeach
</table>
</div>
</div>
</div>
</body>
view-request-candidates.blade.php
<h1> Hello .. This Is Request Id: {{ $result['hr_request_id'] }} </h1>
<br>
<h1> Hello .. This Is Consultant Id: {{ $result['consultant_id'] }} </h1>
To get the single record use the find method instead of all:
public function consultants($id)
{
return view('Hr/view-request-candidates', [
'consultant' => HrRequestConsultant::find($id),
]);
}
It is best practice to name the route and use name wherever you need that route. So change the route like this :
Route::get(
'/view-request-candidates/{hr_request_id}',
'Hr\HrDashboardController#consultants')->name('view.consultant');
Remove the foreach loop from your view and change the route to named route:
<div class="col-md-12">
<table class="table table-striped">
<tbody>
<tr>
<th>Hr Request ID</th>
<th>Consultant ID</th>
<th>No Of Candidates</th>
<th>Actions</th>
</tr>
<tr>
<td>{{$consultant->hr_request_id}}</td>
<td>{{$consultant->consultant_id}}</td>
<td>{{30}}</td>
<td>
<a href="{{ route('view.consultant', ['hr_request_id' => $consultant->hr_request_id]) }}" class="btn btn-primary">View</button>
</td>
</tr>
I am using knockout binding to bind some data into html tables. My knockout view Model had multiple products and each product will have multiple chars. I want to display the products in one table and when i select the link "show chars" it should display the corresponding chars in below table.
This is my View Model
var ProductViewModel = function(items) {
this.items = ko.observableArray(items);
this.itemToAdd = ko.observable("");
this.addItem = function() {
if (this.itemToAdd() != "") {
this.items.push(this.itemToAdd());
this.itemToAdd("");
}
}.bind(this);
};
And this is my html tables
<div id="productTable">
<table class="ui-responsive table">
<thead>
<tr>
<th >Product Name</th>
<th >Description</th>
<th >Parent?</th>
</tr>
</thead>
<tbody id="pBody" data-bind="foreach: items">
<tr class="success" >
<td><span data-bind="text: name"></span>
</td>
<td><span data-bind="text: desc"></span>
</td>
<td>show chars</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="productChars">
<div id="productCharTable">
<table class="ui-responsive table">
<thead>
<tr>
<th >Char Name</th>
<th >Description</th>
<th >Length</th>
<th >Type</th>
</tr>
</thead>
<tbody id="pBody" data-bind="foreach: $data['chars']">
<tr class="success">
<td><span data-bind="text: name"></span>
</td>
<td>asdf asdfasdf</td>
<td>10</td>
<td>String</td>
</tr>
</tbody>
</table>
</div>
I am able to bind the products into first table. But for characteristics i am not sure how to achieve the same.
Could someone please help me in figuring out how to achieve the same.
Here is the jsfiddle
https://jsfiddle.net/sirisha_k/0Ln7h2bo/7/
As #supercool pointed out you can use "data-bind='with selectedItem'" to populate the second table with chars data. For that you need to add one more item into your model called selectedItem and every time you select or add a row, you point the selectedItem to that elementdata. And use "data-bind='with selecteItem'" for second table.
var ProductViewModel = function(items) {
this.items = ko.observableArray(items);
this.selectedItem = ko.observableArray();
this.itemToAdd = ko.observable("");
this.addItem = function() {
if (this.itemToAdd() != "") {
this.items.push(this.itemToAdd());
this.itemToAdd("");
}
}.bind(this);
};
and on row select call some function selectedItem($data) where $data refers to the current item.
then set that data to selectedItem in model.
function selectedItem(prod){
ProductViewModel.selectedItem(prod);
}
I'm trying to hide some rows from a table when a button is clicked. I want to hide just the rows where the number of exams is equals to zero.
HTML code:
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-class="{'showNot' : item.examsNum === 0}" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
AngularJS:
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.hide = function () {
angular.element('.showNot').css("display", "none");
};
}]);
Here is the jsfiddle: link
I'm pretty new to AngularJS, and I can't see what I'm doing wrong.
Thanks!
Try using a show/hide flag, and use it in ng-show along with the zero check:
Here's a fiddle.
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-hide="(item.examsNum == 0) && hideZero" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
and
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.hide = function () {
$scope.hideZero = !$scope.hideZero;
};
}]);
You can give an id to your table <table id="table"> then change your selector to
var elem = document.querySelector('#table');
angular.element(elem.querySelector('.showNot')).css('display', 'none')
We cant use class selectors easily in jQlite - Limited to lookups by tag name but this should work your you
JSFiddle Link
you need to use the ng-show or ng-hide directive insted of display none
html
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide()"> HIDE ROWS</button>
<br/>
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-show="Display" ng-repeat="item in data.records">
<td>{{item.name}}</td>
<td>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
script
var myApp = angular.module('myApp', []);
myApp.controller('myController', ['$scope', function ($scope) {
$scope.data = {
records: [{
name: 'Mel',
examsNum: 2
}, {
name: 'Sarah',
examsNum: 2
}, {
name: 'Jane',
examsNum: 0
}]
};
$scope.Display = true;
$scope.hide = function () {
$scope.Display = !$scope.Display ;
};
}]);
Perhaps using a filter is more correct.
https://docs.angularjs.org/api/ng/service/$filter
Filters may be used to hide items in a list based on some criteria - which sounds like what you are doing
Okay. So you got something wrong over here. the 'item' is only available inside the scope of ng-repeat. You cannot access it at the same level as ng-repeat.
Here is a working version of your code. And please use ng-hide/ng-show for such things. Its more efficient.
<div ng-app="myApp">
<div ng-controller="myController">
<button ng-click="hide();"> HIDE ROWS</button>
<br />
<table>
<thead>
<tr>
<th>Name</th>
<th>Exams</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in data.records">
<td ng-hide='item.examsNum === 0'>{{item.name}}</td>
<td ng-hide='item.examsNum === 0'>{{item.examsNum}}</td>
</tr>
</tbody>
</table>
</div>
</div>
I've got a site build with RazorViewEngine where using "_ViewStart.cshtml" to set the layout to "Shared/_Layout.cshtml". Then, I've the following module:
public class LogModule : NancyModule
{
public LogModule()
{
Get["/log"] = _ =>
{
var list = GetLog().ToPagedList(1, 5);
return View["Index", list];
};
Get["/log/{page:int}"] = _ =>
{
int pageNumber = _.page ?? 1;
var list = GetLog().ToPagedList(pageNumber, 5);
return View["_List", list];
};
}
}
And the following views:
Index.cshtml
#using Nancy.ViewEngines.Razor
#using PagedList
#inherits NancyRazorViewBase<IPagedList<LogModel>>
<h1>View Log</h1>
<div id='container'>
#Html.Partial("_List", Model)
</div>
_List.cshtml
#using Nancy.ViewEngines.Razor
#using PagedList
#inherits NancyRazorViewBase<IPagedList<LogModel>>
<table class="table table-hover table-condensed">
<thead>
<tr>
<th>Date</th>
<th>Message</th>
</tr>
</thead>
<tbody>
#foreach (var log in Model)
{
<tr class="#log.Class">
<td>#log.Date</td>
<td>#log.Message</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td colspan="2">
<div class="pagination" data-current="#Model.PageNumber" data-count="#Model.PageCount">
<ul class="list-unstyled list-inline">
<li>|<</li>
<li><</li>
<li class="active"><span>#Model.PageNumber / #Model.PageCount</span></li>
<li>></li>
<li>>|</li>
</ul>
</div>
</td>
</tr>
</tfoot>
</table>
And finally, some javascript code to manage ajax requests to the '/log/{page:int}" action and replace the 'container' div with the result. Sadly, this result contains a full page, including _Layout.cshtml and breaking all the page.
In MVC this is solved using return PartialView(viewName, Model) but I couldn't find something similar in NancyFx. Is there something I'm missing?
Turned out that the solution is quite simple. Just create an 'empty' layout file with this single line:
#RenderBody()
And then use it in your partial view:
#{ Layout = "Shared/_EmptyLayout"; }