return PartialView[viewname, model] equivalent? - razor

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"; }

Related

How to redirect to url external example www.google.com

I'm studing Asp.Net core web applications.
I successfully created a CRUD website.
In the site I want to create a link to an external URL, e.g., to www.google.com
Here, the link is created this way.
https://localhost:44311/pVagaDivulgar/details/www.google.com
expected: www.google.com
Curso
Go
I dont know if I have to set some properties to make it work.
#model SiteJob1.ViewModel.pVagaDivulgar.IndexViewModel
#{
ViewData["Title"] = "details";
}
<h1>Jobdetails</h1>
#foreach (var item in Model.VMvagasdivulgar)
{
<h4>#item.VagadivulgarVaga.VagaTitulo</h4>
}
<table class="table">
<thead>
<tr>
<th>ID</th><th>Course</th><th>Link</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.VMvagasdivulgar)
{
<tr>
<td>
#item.VagadivulgarId
</td>
<td>
#item.VagadivulgarCurso1Navigation.CursoNome
</td>
<td>
Curso
Go
</td>
</tr>
}
</tbody>
</table>
<div>
#Html.ActionLink("Edit", "Edit", new { /* id = Model.PrimaryKey */ }) |
<a asp-action="Index">Back to List</a>
</div>
ok, i understand your problem if you need to open Url then write full url like https://toastguyz.com
public ActionResult Index()
{
ViewBag.Title = "Home Page";
ViewBag.link = "https://www.toastguyz.com";
return View();
}

Remove products from the database with vue.js

How can I remove products from the MySql database when I click on a button in the Vue.js table?
I just wrote it so that it only deletes in View. Database is associated with Laravel.
<div class="container" id="main">
<h1>#{{title}}</h1>
<h3>Products (#{{products.length}})</h3>
<table class="table table-striped">
<thead>
<tr style="font-size: 14px;">
<th>Name</th>
<th>Price</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="(item,index) in products" class="prodimg">
<td><h5>#{{item.name}}</h5></td>
<td><h5>#{{item.price}}</h5></td>
<td><button v-on:click.prevent="deleteProduct(index)">Delete
Product</button></td>
</tr>
</tbody>
</table>
<script type="text/javascript">
new Vue({
el:"#main",
data:{
products:[],
title: "Products panel"
},
methods:{
deleteProduct:function(r){
this.$delete(this.products,r);
}
},
created:function(){
axios.get("/products/all").then(r=>{
this.products = r.data;
})
}
})
</script>
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\UserModel;
use App\ProductModel;
class Admin extends Controller
{
function productsPanel(){
return view('/adminproducts');
}
function products(){
return ProductModel::all();
}
}
What function should be written for this in Laravel and Vue.js?
You need an DELETE api which is callable like this.
axios.delete(`/product/${product_id}`).then(r=>{
// do something
})

Angular determine style based off conditional

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>

Razor - two forms within one html table

Is it possible to combine these two html tables into one table instead?
I can't seems to do it no matter how, it either tell me no start tag or no close tag for the table.
Goals:
1) One <table> with two <tr> and each <tr> has two <td>.
2) Top download button (from top form) in top <tr>.
3) Bottom download button (from bottom form) in bottom <tr>.
<table>
<tr>
<td></td>
<td>
#using (Html.BeginForm("GenerateExcelReport", "Pages", FormMethod.Post, new { name = "formExcel", id = "formExcel" }))
{
#Html.DevExpress().Button(button =>
{
button.ClientSideEvents.Click = "OnClick";
button.Name = "buttonExcel";
button.Text = Resources.Global.buttonExportExcelExtra;
button.UseSubmitBehavior = true;
}).GetHtml()
}
</td>
</tr>
</table>
#using (Html.BeginForm("DownloadMainReport", "Pages", FormMethod.Post))
{
<table>
<tr>
<td style="padding:2px;">
#Html.DevExpress().ComboBox(settings =>
{
settings.Name = "ExportMode";
settings.Properties.Caption = Resources.Global.labelExportMode;// "Details Export Mode ";
settings.Properties.ValueType = typeof(GridViewDetailExportMode);
settings.SelectedIndex = 0;
}).BindList(Enum.GetValues(typeof(GridViewDetailExportMode))).Bind(GridViewDetailExportMode.None).GetHtml()
</td>
<td style="padding:2px;">
#Html.DevExpress().Button(settings =>
{
settings.Name = "buttonExportExcel";
settings.Text = Resources.Global.buttonExportExcel;
settings.UseSubmitBehavior = true;
}).GetHtml()
</td>
</tr>
</table>
#Html.Partial("HomeReportPartial", Model)
}
Even if I use div, it will tell me it cannot find matching tag.
<div class="container-fluid">
<div class="row">
<div class="col-md-1">1</div>
<div class="col-md-1">
#using (Html.BeginForm("test0", "test0", FormMethod.Post))
{ }
</div>
<div class="col-md-10">3</div>
</div>
#using (Html.BeginForm("test1", "test1", FormMethod.Post))
{
<div class="row">
<div class="col-md-1">1</div>
<div class="col-md-1">2</div>
<div class="col-md-10">3</div>
</div>
</div>
}
Parser Error Message: Encountered end tag "div" with no matching start tag. Are your start/end tags properly balanced?

Iterating in JSON using knockout.js

I'm using Knockout.js to realize my web app.
I get data from a database and i use Json to pass data to html page that is rendered through data-bind.
I would like to set the more dynamic possible my app so i would like to iterate through json keys without "hardcoding" the field name
I have the following json: {"id_user":"63","email":"mail#email.it","flag":"1"}
and iterate using:
<table data-bind="foreach:page().users">
<tr>
<td data-bind="text:$data.email"></td>
<td data-bind="text:$data.flag"></td>
</tr>
</table>
but i would like to avoid the .email and .flag and using [0] or [1] to reuse this structure for all the models. How can i do it?
You could do this with a custom binding:
<table data-bind="foreach:page().users">
<tr data-bind="createHeaderRow: $data">
</tr>
<tr data-bind="createTableRow: $data">
</tr>
</table>
Then create these methods:
ko.bindingHandlers.createHeaderRow = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
for (var property in valueAccessor()) {
$(element).append('<td>' + property + '</td>');
}
}
};
ko.bindingHandlers.createTableRow = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
for (var property in valueAccessor()) {
$(element).append('<td data-bind="text: ' + property + '"></td>');
}
}
};
I've created a jsFiddle to demonstrate it too.
Here is some updated html to get a header and the rows with thead and tbody
<table class="table" >
<thead data-bind="with: page().users()[0]">
<tr data-bind="createHeaderRow: $data">
</tr>
</thead>
<tbody data-bind="foreach: page().users()">
<tr data-bind="createTableRow: $data">
</tr>
</tbody>
</table>