How do you open a kendo drop down popup on page load? - kendo-dropdown

I have several uses for kendo drop-downs in my application (DDL, ComboBox, etc.).
I want them to open up on page load, but Kendo's documentation doesn't indicate that is possible.
I am using the MVC server variables.
This is my view coding:
<script id="itemTemplate" type="text/x-kendo-template">
# var index=FullName.indexOf(" *****");
if (index > 0)
{
#
<span style="font-weight:bold;">
#: FullName.substring(0, index)#
</span>
#
} else {
#
<span style="font-weight:normal;">
#: FullName#
</span>
#
}
#
</script>
<table class="form-horizontal table-condensed" style="width:100%;">
<tr style="height:400px;">
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">Available Members</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("AvailableWGMembers")
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.AvailableWGMembers)
.AutoBind(true)
.Placeholder("Click here to select one or more members to add, ...")
.AutoClose(false)
.HtmlAttributes(new { style = "width:100%;", #class = "Roles" })
.Events(events => { events.Change("doRoles");})
.Value(new int[0])
.Height(650)
)
</td>
<td style="width:20%;text-align:center;vertical-align:top;">
<input id="btnAdd" type="submit" value="Select" class="btn btn-default" disabled="disabled" />
</td>
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">#Model.WGTitle</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("ExistingWGMembers")
.AutoBind(false)
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.ExistingWGMembers)
.Placeholder("Click here to select one or more members to remove, ...")
.AutoClose(true)
.HtmlAttributes(new { style = "width:100%;", #class = "UnusedRoles" })
.Events(events => { events.Change("doRoles"); })
.Value(new int[0])
.Height(650)
)
</td>
</tr>
</table>
I want the lists to both be open when the page loads, and I want to be able to use unobstrusive jQuery or javascript to control it if I have to.
Does anyone have any suggestions?

It took a little digging, but I finally figured out the answer. It was actually pretty simple.
The following should be added to the unobstrusive javascript code file:
function openPopup(e)
{
if (e.sender.list[0].childNodes['1'].childNodes['0'].childElementCount > 0) {
e.sender.popup.open();
}
}
You add the following code to your event listing:
.Events(events => { ...; events.DataBound("openPopup"); })
This can be done with any of the lists that have popups like Kendo DropDownList or ComboBox or MultiSelect.
I would check for the list length to make sure the list has members so you don't get an ugly empty list shown, but otherwise the result is actually pretty simple.

This answer is dependent upon the code example at: http://demos.telerik.com/aspnet-mvc/window/index
I took that example from the Index.cshtml version of their example and simply replaced the Content value of the # with your table template from the original question:
#(Html.Kendo().Window()
.Name("window")
.Title("Your modal popup with dropdown menus")
.Content(#<text>
<table class="form-horizontal table-condensed" style="width:100%;">
<tr style="height:400px;">
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">Available Members</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("AvailableWGMembers")
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.AvailableWGMembers)
.AutoBind(true)
.Placeholder("Click here to select one or more members to add, ...")
.AutoClose(false)
.HtmlAttributes(new { style = "width:100%;", #class = "Roles" })
.Events(events => { events.Change("doRoles");})
.Value(new int[0])
.Height(650)
)
</td>
<td style="width:20%;text-align:center;vertical-align:top;">
<input id="btnAdd" type="submit" value="Select" class="btn btn-default" disabled="disabled" />
</td>
<td style="width:40%;vertical-align:top;">
<h4 style="width:100%;text-align:center;">#Model.WGTitle</h4>
<h4 style="width:100%;text-align:center;font-size:smaller;">Current Cancer Center Members are highlighted in Bold.</h4>
#(Html.Kendo()
.MultiSelect()
.Name("ExistingWGMembers")
.AutoBind(false)
.DataTextField("FullName")
.DataValueField("id")
.ItemTemplateId("itemTemplate")
.TagTemplateId("itemTemplate")
.BindTo((System.Collections.IEnumerable)ViewBag.ExistingWGMembers)
.Placeholder("Click here to select one or more members to remove, ...")
.AutoClose(true)
.HtmlAttributes(new { style = "width:100%;", #class = "UnusedRoles" })
.Events(events => { events.Change("doRoles"); })
.Value(new int[0])
.Height(650)
)
</td>
</tr>
</table>
</text>)
.Draggable()
.Resizable()
.Width(600)
.Actions(actions => actions.Pin().Minimize().Maximize().Close())
.Events(ev => ev.Close("onClose"))
)
I hope this helps!

Related

View is posting a empty object on submit when expecting the modified object

I have a View that lets users edit data that is fetched from a database and converted into a DataTable (for simplicity since the data can get really complicated and deep).
The issue is that when I POST the data back to the responsible Controller the controller receives the DataTable object but it's empty, e.g. the changes made by a user never get back to the Controller and cannot be saved to Database.
I am at most intermediate at web programming so I appreciate straight answers or direct pointers.
View:
#model System.Data.DataTable
#{
ViewData["Title"] = "Edit";
Layout = "~/Views/Shared/_LayoutAdminlte.cshtml";
}
#using (Html.BeginForm("EditSave", "Recipe", FormMethod.Post, new { #id = "Properties-Form" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<h2>#Html.DisplayFor(m => Model.TableName)</h2>
</div>
<div class="box box-primary">
<table id="Properties" class="table table-condensed">
<thead>
<tr>
#foreach (System.Data.DataColumn col in Model.Columns)
{
<th>
#Html.DisplayFor(m => col.Caption)
</th>
}
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.Rows)
{
<tr>
#foreach (var cell in row.ItemArray)
{
<td>
#if (row.ItemArray.ToList().IndexOf(cell) == 0)
{
#cell.ToString()
}
else
{
<input asp-for="#cell" />
}
</td>
}
</tr>
}
</tbody>
</table>
</div>
<div class="box-footer">
<!-- id="Save" -->
<input class="btn btn-primary pull-right" type="submit" value="Spara" id="Save" />
<i class="fa fa-show"></i> Visa
<i class="fa fa-show"></i> Avbryt
</div>
</div>
}
#section Scripts{
#await Html.PartialAsync("_ValidationScriptsPartial")
}
Controller:
[HttpPost]
public ActionResult EditSave(DataTable model)
{
Debugger.Break();
return View("Edit", model);
}
This <input asp-for="#cell" /> is your problem.
If you run your program and use the developer tools to inspect the html generated for the input fields, you will notice the generated html attributes.
the particular one that you should pay attention to is the name attribute.
The way model binding works in .net core when you send data to the controller.
public IActionResult DoSomething(Model model) { ... }
you would have match the name attribute to the property of the object. Example:
<input name="model.Level" value="8999" />
so then you would get var level = model.Level and level will be 8999.
So you have to take care when you use the asp-for it's not doing as much heavy lifting as you think. Always check the html generated.
PS
Don't use DataTables, other developers will throw rocks at you. Don't be lazy map to an actual object or use an ORM, programs quickly become unmaintainable if you use them to dynamically store data.

vue.js does not correctly rerender compared to the vue instance object

I have a small issue with my vue template. The code is the following :
<template>
<div class="panel panel-default"
v-bind:id="'panel_'+noeud.id">
<div class="panel-heading">{{noeud.name}}</div>
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>Noeud</th>
<th>Poid</th>
</tr>
</thead>
<tbody>
<tr
v-for="noeud_poids in weightSorted"
v-if="noeud_poids.macro_zonning_noeud_id_2 != noeud.id"
is="macrozonningproximitenoeudpoids"
:noeud_poids="noeud_poids"
:noeud="noeud"
:noeuds="noeuds"
:delete_callback="delete_final"
:change_callback="update_line">
</tr>
<tr>
<td>
<select v-model="new_noeud">
<option value=""></option>
<option v-for="one_noeud in noeuds "
v-bind:value="one_noeud.id">{{one_noeud.name}}</option>
</select>
</td>
<td>
<input type="text" v-model="new_weight">
</td>
<td>
<input type="button" class="btn btn-primary" #click="addNoeudProximite" value="Ajouter"/>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<script>
export default {
props: ['pnoeud', 'pnoeuds'],
data: function(){
return {
points: 0,
points_restants: 100,
new_weight:0,
new_noeud:0,
noeud:this.pnoeud,
noeuds:this.pnoeuds,
weightSorted:this.pnoeud.weightSorted
}
},
mounted() {
},
methods:{
delete_final(macro_zonning_noeud_id_2){
axios.delete("/macrozonning/proximite/",{
params:{
macro_zonning_noeud_id_2:macro_zonning_noeud_id_2,
macro_zonning_noeud_id_1:this.noeud.id
}
}).then((res) => {
Vue.delete(this.weightSorted, String(macro_zonning_noeud_id_2));
})
},
update_line(nb_points){
this.points_restants = this.points_restants - nb_points;
this.points = this.points + nb_points;
},
addNoeudProximite(){
axios.put('/macrozonning/proximite/', {
'macro_zonning_noeud_id_1': this.noeud.id,
'macro_zonning_noeud_id_2': this.new_noeud,
'weight': this.new_weight
}).then((res) => {
Vue.set(this.weightSorted, String(this.new_noeud), res.data);
});
}
}
}
</script>
When the function delete_final is executed on the last item of my list, the view is correctly rerendered as the last item of my list is removed. But when I try to remove the first item of my list then the view rerenders but the the last item has been removed. When I check the Vue object in devtools, it does not reflect the new view, but it reflects the action taken (my first item has been removed).
If you have any idea where this problem comes from it would be awesome.
Thanks a lot community
Use a key attribute on the element you are rendering with v-for so that vue can exactly identify VNodes when diffing the new list of nodes against the old list. See key attribute
<tr> v-for="noeud_poids in weightSorted" :key="noeud_poids.id" </tr>

How to edit particular row in a table by popping a form modal in vuejs?

I am using a modal form to add new details to the row of a table. After adding details, I’m just adding edit and delete buttons at the end of it. Now here delete button is working fine. How to edit a row of a table by popping replicate of form modal by clicking “edit” button in a row.
Here’s my code:
<div class="layout-padding">
<div
class="item item-link"
v-for="modal in types"
#click="$refs[modal.ref].open()"
>
<i class="item-primary">add</i>
<div class="item-content has-secondary">
<div>{{modal.label}}</div>
</div>
</div>
</div>
<q-modal ref="maximizedModal" class="minimized" :content-css="{padding: '50px'}">
<div class="main">
<label>Enter Your Name:</label>
<input id="name" name="name" type="text" placeholder="Enter your Name" v-model="YourName">
<br>
<label>I am:</label>
<input type="radio" id="Male" value="male" v-model="picked">
Male
<input type="radio" id="Female" value="female" v-model="picked">
Female
<br>
<div class="button">
<button class="red" #click="$refs.maximizedModal.close()">Close</button>
<button class="blue" v-on:click="sub" #click="$refs.maximizedModal.close()">Submit</button>
</div>
</div>
</q-modal>
<table>
<thead>
<th>Name</th>
<th>Gender</th> </thead>
<tbody class="result">
<tr v-for="(h, index) in final">
<td v-for="(value, key, index) in h">
{{ value }}
</td>
<td><button id="edit" class="green edit" v-for="modal in types"
#click="ed(h, index);$refs[modal.ref].open()" type="submit">EDIT</button></td>
<td><button id="delete" class="red delete" v-on:click="del(index)" type="submit">Delete</button></td>
</tr>
</tbody>
</table>
And my script is:
export default {
data () {
return {YourName: '',
details: [],
final: [],
types: [
{
label: 'Add Details',
ref: 'maximizedModal'
}
],
position: 'bottom'
}
},
methods: {
sub: function () {
this.details = {
'name': this.YourName,
'gender': this.picked,
}
this.ed()
if (index === '[object MouseEvent]') {
this.final.push(this.details)
}
if (index > -1) {
this.final.splice(index, 1, this.details)
}
else {
alert('else')
alert(JSON.stringify(this.details))
this.final.push(this.details)
}
},
del: function (index) {
this.$delete(this.final, index)
},
ed: function (details, index) {
return index
}
}
}
If edit button is clicked, the same row should be edited. I don’t know how to proceed further. Please, guide me.
Using the 'splice' can able to modify the given array of object.
Can simply include this inside an 'if' loop:
this.final.splice(this.indi, 1, this.details)

How do I include html in C# block and C# in html block in the following View?

I have my view here and it throws errors, either there is missing {} block or an "eternal components throws and exception" when I remove those if/else block along with #: the code works just like before so how do I include html code in a C# block and C# code in html block in the following view:
#model IEnumerable<ecomm2.Models.HomeSearchResultsViewModel>
#{
if (Model.Count < 1)
{
#:<p style="color:red">Item not found</p>
}
else
{
#:<table style="background-color:#f7f7f7;width:100%; border:0px solid black;">
foreach (var item in Model) {
#:<tr style="border:1px solid #bbb9b9;">
#: <td style="width:177px;">
#: <img src="~/Content/images/meter.jpeg" alt="Alternate Text" style="height:177px;width:177px;padding:10px;"/>
#:</td>
#:<td style="width:100%;padding-left:2px;float:left;padding-top:20px;border:0px solid black;font-size:medium">
<span>
#Html.ActionLink(item.ProductLineName, "GetProductDetails", "Product", new { id = item.Id }, new { }) <br />
#: </span>
#:<span style="font-size:small">By #Html.ActionLink(item.BrandName, "GetProductByBrandName", new { id=item.BrandName})</span><br />
#:<span style="font-size:x-small">
#Html.ActionLink(item.CategoryName, "GetProductsByCategoryName", new { id=item.CategoryName}) | Stock Count: #Html.DisplayFor(modelItem => item.StockCount)
</span><br />
#using(Html.BeginForm("AddToCart", "Cart", new { id=item.Id}))
{
<fieldset>
<input type="submit" name="name" value="Add to Cart" class="btn btn-default"/>
</fieldset>
}
</td>
<td style="width:20%;color:#00b02f;font-weight:bold;padding-top:20px;float:none;padding-left:20px;">
LKR: #Html.DisplayFor(modelItem => item.ListPrice)
</td>
</tr>
}
#:</table>
}
}
Here is the original code that threw the error
External component has thrown an exception.
Here is the original code
#model IEnumerable<ecomm2.Models.HomeSearchResultsViewModel>
#if (Model.Count < 1)
{
<p style="color:red">Item not found</p>
}
else
{
<table style="background-color:#f7f7f7;width:100%; border:0px solid black;">
#foreach (var item in Model) {
<tr style="border:1px solid #bbb9b9;">
<td style="width:177px;">
<img src="~/Content/images/meter.jpeg" alt="Alternate Text" style="height:177px;width:177px;padding:10px;"/>
</td>
<td style="width:100%;padding-left:2px;float:left;padding-top:20px;border:0px solid black;font-size:medium">
<span>
#Html.ActionLink(item.ProductLineName, "GetProductDetails", "Product", new { id = item.Id }, new { }) <br />
</span>
<span style="font-size:small">By #Html.ActionLink(item.BrandName, "GetProductByBrandName", new { id=item.BrandName})</span><br />
<span style="font-size:x-small">
#Html.ActionLink(item.CategoryName, "GetProductsByCategoryName", new { id=item.CategoryName}) | Stock Count: #Html.DisplayFor(modelItem => item.StockCount)
</span><br />
#using(Html.BeginForm("AddToCart", "Cart", new { id=item.Id}))
{
<fieldset>
<input type="submit" name="name" value="Add to Cart" class="btn btn-default"/>
</fieldset>
}
</td>
<td style="width:20%;color:#00b02f;font-weight:bold;padding-top:20px;float:none;padding-left:20px;">
LKR: #Html.DisplayFor(modelItem => item.ListPrice)
</td>
</tr>
}
</table>
}
In the Index view it calls the partial page "_SearchResultList" here is the video that shows all
None of your #: code is necessary. The reason you get the exception is that IEnumerable<T> does not have a property Count so your if block throws an exception. Change you code to
if (Model.Count() < 1)
of better, use
if (Model.Any())
and swap the code in the if and else blocks

Cannot pass SelectedValue and Text to Controller for a KendoUIDropDownListFor widget

This works fine if I don't use any KendoUI functionality and am able to pass it easily using a regular Html.DropDownListfor helper (seen as comments in the code). The Description and the StatusID both do not come through.
How can I pass these values to the controller after selecting them in the dropdown list and then clicking enter with the KendoUI extension?
If I uncomment the Value and Text properties, I get "Object not set to an instance of an Object".
#using (Html.BeginForm("AddSingleStatus", "Status", new AjaxOptions { HttpMethod = "POST", }))
{
#Html.ValidationSummary(true)
<table>
<tr>
<td>
<div class="display-label">
#Html.LabelFor(model => Model.Description);
</div>
<div class="display-label" style="display: none;">
#Html.HiddenFor(model => Model.Description)
</div>
<div class="editor-field">
#(Html.Kendo().DropDownListFor(model => Model.StatusID)
.Name("statusDropDownList")
.DataTextField("Description")
.DataValueField("StatusID")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("ReadDDL", "Status");
})
.ServerFiltering(false);
})
.OptionLabel("Select a status")
.SelectedIndex(0)
.Events(e => e
.Change("dropdownlist_change")
)
)
#* #Html.DropDownListFor(model => Model.StatusID, new SelectList((YeagerTechModel.Status[])ViewData["statuses"], "StatusID", "Description"));*#
#*#Html.ValidationMessageFor(model => Model.StatusID)*#
</div>
</td>
</tr>
<tr>
<td>
<input type="submit" id="ddlSubmit" value='#Resources.Add' />
</td>
</tr>
</table>
}
<script type="text/javascript">
function dropdownlist_change()
{
var dropdownlist = $("#statusDropDownList").data("kendoDropDownList");
dropdownlist.bind("change", function (e)
{
var value = dropdownlist.value();
});
}
</script>