Custom design using webgrid - webgrid

I need to show records some thing like thing. Please check the Image give below. I need to show the records in webgrid.
#{
MalayaleeTech.Models.NewLIst newsL = new MalayaleeTech.Models.NewLIst();
}
#{
var grid = new WebGrid(Model.News, canPage: true, rowsPerPage: 10, selectionFieldName: "selectedRow", ajaxUpdateContainerId: "gridContent");
grid.Pager(WebGridPagerModes.NextPrevious);
}
#grid.GetHtml(tableStyle: "webGrid",
headerStyle: "header",
mode: WebGridPagerModes.All,
numericLinksCount: 10,
firstText: "<<",
previousText: "<",
nextText: ">",
lastText: ">>",
displayHeader:false,
footerStyle: "webgrid-footer",
columns: grid.Columns(
grid.Column("NewsID", "News ID", style: "gridrow"),
grid.Column("NewsHeader", "News Header", style: "gridrow")
))

My initial response is that actually, you DON'T want to use a WebGrid for the scenario outlined in your image. The WebGrid renders an HTML table which is designed for the display of tabular data - columns and rows (which is why the WebGrid includes column sorting features).
However, you can pass any HTML template to the format parameter of the WebGrid column. So this could provide a starting point for you:
var grid = new WebGrid(Model.News)
#grid.GetHtml(
columns: grid.Columns(
grid.Column("", "SPORTS", format: #<div>
<h1>#item.Headline</h1>
<div class="block">
<img src="#item.Image" />
</div>
<div class="block">#item.Text</div>
</div>)))
You will need to change the property names to match those of your model and you will also need to apply some CSS to style this correctly - I recommend using display:inline-block for the block CSS class.
If you decide not to use the Webgrid for this but still want to be able to use paging, I have written an article about how to do that. It's for Web Pages, but it still uses the Razor syntax: http://www.mikesdotnetting.com/Article/150/Web-Pages-Efficient-Paging-Without-The-WebGrid

Related

Can I pass metadata through Vue Formulate's schema API without affecting input attributes?

The goal:
generate form fields from JSON/CMS
have a param in the JSON that allows two fields to sit next to each other on a single line
The solution so far:
I’m using Vue Formulate's schema API to generate fields. In Vue Formulate's options, I can conditionally add a class to the outer container based on a parameter in the context.
classes: {
outer(context, classes) {
if (context.attrs.colspan === 1) {
return classes.concat('col-span-1')
}
return classes.concat('col-span-2')
},
I’m using Tailwind, which requires no classname concatenation and actually want the default to be col-span-2, so if you’re inclined to copy this, your logic may vary.
With a few classes applied to the FormulateForm, this works really well. No additional wrapper rows required thanks to CSS grid:
<FormulateForm
v-model="values"
class="sm:grid sm:grid-cols-2 sm:gap-2"
:schema="schema"
/>
The schema now looks something like this:
[
{
type: 'text',
name: 'first_name',
label: 'First name',
validation: 'required',
required: true,
colspan: 1,
},
The problem/question
Vue Formulate’s schema API passes all attributes defined (other than some reserved names) down to the input element. In my case, that results in:
<div
data-classification="text"
data-type="text"
class="formulate-input col-span-1"
data-has-errors="true"
>
<div class="formulate-input-wrapper">
<label
for="formulate-global-1"
class="formulate-input-label formulate-input-label--before"
>
First name
</label>
<div
data-type="text"
class="formulate-input-element formulate-input-element--text"
>
<input
type="text"
required="required"
colspan="1" <--------------- hmm…
id="formulate-global-1"
name="first_name"
>
</div>
</div>
</div>
I recognize that I can name my attribute data-colspan so that I’m not placing a td attribute on an input, but I think of colspan as metadata that I don’t want applied to the template. Is there a way to prevent this from being applied to the input—perhaps a reserved word in the schema API that allows an object of metadata to be accessed via context without getting applied to v-bind="$attrs"?
The vue-formulate team helped me out on this one. Very grateful. Much love.
There is a way to prevent it from landing on the input, and that's to use the reserved outer-class property in the schema:
[
{
type: 'text',
name: 'first_name',
label: 'First name',
validation: 'required',
required: true,
'outer-class': ['col-span-1'],
},
This means that I don't need to do this at all:
classes: {
outer(context, classes) {
if (context.attrs.colspan === 1) {
return classes.concat('col-span-1')
}
return classes.concat('col-span-2')
},
vue-formulate supports replacing or concatenating classes via props. I managed to overlook it because I didn't recognize that everything you pass into the schema API is ultimately the same as applying a prop of that name.
Classes can be applied to several other parts of the component as well—not just the outer/container. More information here:
https://vueformulate.com/guide/theming/customizing-classes/#changing-classes-with-props

Vue.js: binding select boxes, but don't want to ajax all the options

Good day. I'm using Vue.js to render an arbitrary number of select elements from the data in a component.
Here's sample JSON data that indicates there are two select elements, each with one or more options.
{
"dropdowns":[
{
"cd":"UG9ydGZvbGlv",
"formname":"sp_filter_UG9ydGZvbGlv",
"nm":"Portfolio",
"selected":"1a",
"options":[
{
"cd":"1a",
"val":"Option 1A"
}
]
},
{
"cd":"UHJvZHVjdCBOYW1l",
"formname":"sp_filter_UHJvZHVjdCBOYW1l",
"nm":"Product Name",
"selected":"2b",
"options":[
{
"cd":"2a",
"val":"Option 2A"
},
{
"cd":"2b",
"val":"Option 2B"
}
]
}
]
}
Here's the template HTML:
<form>
<div v-for="dropdown in dropdowns">
<div v-if="dropdown.availableToView">
<h4>{{dropdown.nm}}</h4>
<select v-model="dropdown.selected" v-on:change="triggerUpdate">
<option value="">(Make a selection)</option>
<option v-for="option in dropdown.options" :value="option.cd">{{option.val}}</option>
</select>
</div>
</div>
</form>
So far so good.
I've got the data loading and Vue is building the dropdowns.
When the user changes any select box (remember there can be an arbitrary number of them), the trigger action needs to submit ALL of the elements in the form via ajax. It sounds like the most correct option is to bind the form fields to the underlying component data, as I've done.
My triggerUpdate looks like this:
methods: {
triggerUpdate: function() {
axios({
method: "post",
url: actionURL,
data: this.dropdowns
})
.then(response => (this.data = response));
}
}
...but this submits the entire dropdowns data element, including all of the options in each select box. It's unnecessary to send all of the options in. I just want to send each field name along with its selected option (i.e. the "value").
I know i could serialize the whole form and make that my ajax payload. But that seems to be making an "end run" around Vue.js. Everyone talks about having your form fields bound to the Vue model...is it then correct to basically ignore the model when making an ajax request whose purpose is to then update the model?
I'm relatively new to Vue.js so I'd appreciate help with what I'm overlooking here. How should I go about sending in the data from the form (a) while using proper Vue.js binding and (b) without sending extraneous data?
Thanks for your time.
If you need to post only the selected values, and you store those in each dropdown's selected property, the sensible approach seems to be just mapping it to a simple array of name/value objects.
Try this (it assumes the name of each field is the formname property, if it isn't you can just replace it):
var submitData = this.dropdowns.map((dropdown) => {
return { name: dropdown.formname, value: dropdown.selected };
});
Then you send submitData in your ajax request.

Asp.net MVC4 partial view loading inside popup

I am having an issue with a MVC4 app I have a view that has two partial view on it.
My main view is opening inside the popup. My screen open successfully with 2 partial view on a popup window.
Upper part of my view contains data entry/edit( partial view) and bottom part is display ( partial view).
Display part partial view contains web grid and eac a hyperlink ( edit and delete ) . when user click on edit , application should load the entry/edit view inside the same page.
My application should load entry/edit partial view on the same window .
Please suggest how to achieve this.
see the below code i am using on display view.
---------------------------------------------------------- First Partial view---
#model IEnumerable<Peabody.LMS.WebApp.ViewModels.AUTenement.TenementTypeLookupViewModel>
<div id="gridContent">
#{
var grid = new WebGrid(Model, defaultSort: "TypeCode", rowsPerPage: 10, ajaxUpdateContainerId: "gridContent");
}
#grid.GetHtml(tableStyle: "table",mode: WebGridPagerModes.All,
firstText: "<< First",
    previousText: "< Previous",
nextText: "Next >",
    lastText: "Last >>",
footerStyle: "foot-grid",
columns:
grid.Columns(
grid.Column("TypeCode",header:"TenementType Code"),
grid.Column("TypeDescription", header: "Tenement Description"),
grid.Column("Country", header: "Country"),
grid.Column("State", header: "State"),
grid.Column("LastModifiedBy", header: "Last Modified By"),
grid.Column("LastModifiedOn", header: "Modified On"),
grid.Column("Actions", "",#<a href='/TenementTypeLookup/LoadHeaderEdit/#item.TypeCode' ><img src="~/Images/edit-icon.png" alt='Edit' /></a>, style: "width:auto"),
grid.Column("", "",#<a href='/TenementTypeLookup/Delete/#item.TypeCode' ><img src="~/Images/Delete-icon.png" alt='Edit' /></a>, style: "width:auto")
))
</div>
------------------------------
the best way I have found is to load the partial with an ajax call.
$(document).on('click', '.btnDisplay', function(){
$.ajax({
type: "POST",
url: '#Url.Action("Action", "Controller")',
data: {
Field1: 'field1',
Field2: 'field2'
}
success: function (result) {
$('.targetDiv').html(result);
}
});
then on your controller
[HttpPost]
public PartialViewResult Action(string Field1, string Field2){
var model = //populate model from database
return PartialView("_PartialName", model);
}
so the ajax call will call the controller and pass whatever parameters you want. Then you can build the model and return the partial view. In the success of the ajax call it will take the returned partial view and put them into the whatever your target it (a div with class .targetDiv in this case)

Dojo declarative vs. programmatic creation of Select elements with stores

I'm trying to hook up a Select element with a Dojo store. The Select element is declared in HTML and I'm trying to give it a store in some JavaScript code.
It seems the Dojo documentation recommends against this and is in favor of programatically creating the Select element when using a store. However this is a yellow flag to me because I like to keep creation of HTML elements separate from their behavior. In this case, it would be ideal if I could keep the Select element in HTML and hook up the store in JavaScript.
Is the statement in the Dojo docs really the 'best practice' for this? I'm looking for opinions from experienced Dojo developers as I'm still getting my feet wet with Dojo.
Intuitively one would use select.set("store", store) to assign/change store to a dijit as all widgets are dojo/Stateful, but surprisingly it does not work.
Anyway there is a method select.setStore(store, selectedValue, fetchArgs) which (also surprisingly) is not deprecated and works.
Define dijit/form/Select without a store:
<select id="select1" data-dojo-type="dijit/form/Select"></select>​
Assign a store to it:
require([
"dojo/ready",
"dijit/registry",
"dojo/store/Memory",
], function(
ready, registry, Memory
) {
ready(function() {
var store1 = new Memory({
idProperty: "value",
data: [
{ value: "AL", label: "Alabama" },
{ value: "AK", label: "Alaska" },
{ value: "AZ", label: "Arizona" }
]
});
var select1 = registry.byId("select1");
select1.set("labelAttr", "label");
select1.setStore(store1, "AZ");
});
});
See it in action at jsFiddle: http://jsfiddle.net/phusick/ZmsYV/
Adding some UX sugar to the aforementioned I would create dijit/form/Select disabled with single option e.g. Loading... and its final desired width:
<select
id="select1"
data-dojo-type="dijit/form/Select"
data-dojo-props="disabled:true"
style="width:150px;"
>
<option>Loading...</option>
</select>​
Then I would enable it after calling setStore():
var select1 = registry.byId("select1");
select1.set("labelAttr", "label");
select1.setStore(store1);
select1.set("disabled", false);
See this enhanced version at work: http://jsfiddle.net/phusick/xdDEm/
Debugging bad store data/definitions can get pretty nasty when doing so declaratively. Additionally, you may run into strange annoyance when trying to create multiple of the same widget following a declaratively built select/store combination. For example (pseudocode):
<div dojotype="dojox.data.QueryReadStore" url="someurl/blah.do" jsId="mystore"/>
<select dojotype="dijit.form.FilteringSelect" store="mystore">
</select>
The would in theory do what you want by binding mystore to the select, however if you were to create multiple of this widget, you'd have an id conflict with "mystore." As a workaround you'd have to do something like jsId="${id}_mystore" for both the jsId and the store's id.
One option if you would like to keep a declarative behavior is to have attachpoints for both your store and your select, then you can simply call selectwidget.set("store",mystore) after initialization.

How to show a checkbox in a dojo datagrid?

How to show a checkbox in a dojo datagrid?
I would suggest setting cellType to dojox.grid.cells.Bool, instead of the formatter.The formatter gives you much freedom, but also the responsibility of gathering the data from all the checkboxes (for all the rows) afterwards. Something like this as a structure-entry should do the trick:
{
name: "is awesome?",
width: "auto",
styles: "text-align: center",
type: dojox.grid.cells.Bool, editable: true
}
Please make sure to use a write-store (like ItemFileWriteStore) and not just a read-store, otherwise you will be disabled to actually check the checkbox :)
Use formatter function as described in Widgets Inside dojo.DataGrid
You can return new dijit.form.Checkbox from formatter function in dojo 1.4
You need the IndirectSelection plugin for the EnhancedGrid, here's a fiddle: http://jsfiddle.net/raybr/w3XpA/5/
You can use something like this, with Json
HTML
<table id="myGrid" dojoType="dojox.grid.DataGrid"
clientSort="true" autoHeight="true" autoWidth="true">
<script type="dojo/method">
showFields();
</script>
</table>
DOJO
showFields:function () {
dojo.xhrPost({
url:"/getFields.do",
timeout:2000,
handleAs:"json",
load:dojo.hitch(this, "displayInGrid")
});
},
displayInGrid:function (jsonResult) {
var dataStore = new dojo.data.ItemFileReadStore(
{ data:jsonResult }
);
var checkboxLayout = [
[
{name:'ID', field:"id" },
{name:'Value', field:"id", formatter:this.addCheckBox}
]
];
var grid = dijit.byId("myGrid");
grid.setStructure(checkboxLayout);
grid.setStore(dataStore);
},
addCheckBox:function (val) {
var checkbox = "<input type='checkbox' name='myfields' value='" + val + "/>";
return checkbox;
},
If you are trying to show a checkbox selector on each row of the grid you can follow this tutorial
http://dojotoolkit.org/documentation/tutorials/1.8/working_grid/demo/selector.php
If the type of the cell is a boolean, then its value is displayed as either the string true or false. If a check box is desired, setting the cellType to be dojox.grid.cells.Bool and marking it as editable will make a checkbox appear.
http://dojotoolkit.org/reference-guide/1.9/dojox/grid/DataGrid.html#editing-cells
From markup, do like this for the desired result:
<th field="booleanField" cellType="dojox.grid.cells.Bool" editable="true">Checkbox field</th>