I want to implement the ability to dynamically add comboboxes and I have to use Telerik ComboBox for that. I put this logic into button click.
$('#add-presenter').click(function (e) {
e.preventDefault();
var combobox = '#(Html.Telerik().ComboBox()
.Name("Presenters[" + (Model.Count) + "]")
.BindTo(new SelectList(LeaderList, "ID", "Value"))
.ClientEvents(ev => ev.OnChange("onSelect"))
.DataBinding(bnd => bnd.Ajax().Select("_LoadJournalist", "MonitoringFRadio"))
.Filterable(filter => filter.FilterMode(AutoCompleteFilterMode.StartsWith))
.HtmlAttributes(new { style = "width:320px;vertical-align:middle;" }))';
combobox = combobox.split('Presenters[' + index + ']').join('Presenters[' + (index + 1) + ']');
index++;
$('#presenters-block').append(combobox);
}
This code renders in browser as this:
$('#add-presenter').click(function (e) {
e.preventDefault();
var combobox = '<div class="t-widget t-combobox t-header" style="width:320px;vertical-align:middle;"><div class="t-dropdown-wrap t-state-default"><input class="t-input" id="Presenters[0]-input" name="Presenters[0]-input" type="text" /><span class="t-select t-header"><span class="t-icon t-arrow-down">select</span></span></div><input id="Presenters[0]" name="Presenters[0]" style="display:none" type="text" /></div>';
combobox = combobox.split('Presenters[' + index + ']').join('Presenters[' + (index + 1) + ']');
index++;
$('#presenters-block').append(combobox);
combobox = $('#Presenters\\['+index+'\\]').data('tComboBox');
});
The problem is in data-binding. This code generates proper HTML, but newly added list doesn't "drop"
When I do combobox = $('#Presenters\\['+index+'\\]').data('tComboBox'); for newly added item I get undefined (it exists, but data isn't set), so combobox.dataBind(dataSource) approach doesn't work.
Ok, I tried, but failed to do this without postback. Here's rough solution to the problem: do ajax request and replace content with partial view:
The Partial view:
#model List<int>
#{
var LeaderList = ViewData["LeaderList"] as List<ListItem>;
}
<div id="presenters-ajax-wrapper">
<div id="presenters-block">
#(Html.Telerik().ComboBox()
.Name("Presenters[0]")
.BindTo(new SelectList(LeaderList, "ID", "Value"))
.ClientEvents(ev => ev.OnChange("onSelect"))
.DataBinding(bnd => bnd.Ajax().Select("_LoadJournalist", "MonitoringFRadio"))
.Filterable(filter => filter.FilterMode(AutoCompleteFilterMode.StartsWith))
.HtmlAttributes(new { style = "width:320px;vertical-align:middle;" }))
#for(int i=1; i<Model.Count; i++)
{
var item = LeaderList.FirstOrDefault(l => l.ID == Model[i]);
var value = item != null ? item.Value : "";
#(Html.Telerik().ComboBox()
.Name("Presenters[" + i + "]")
.Value(value)
.BindTo(new SelectList(LeaderList, "ID", "Value"))
.ClientEvents(ev => ev.OnChange("onSelect"))
.DataBinding(bnd => bnd.Ajax().Select("_LoadJournalist", "MonitoringFRadio"))
.Filterable(filter => filter.FilterMode(AutoCompleteFilterMode.StartsWith))
.HtmlAttributes(new { style = "width:320px;vertical-align:middle;" }))
}
</div>
<button id="add-presenter" class="t-button">+</button>
<script type="text/javascript">
var index = #(Model.Count == 0 ? 0 : Model.Count-1);
$('#add-presenter').click(function (e) {
e.preventDefault();
index++;
var msg = $('#monitForm').serialize();
$.ajax({
url: '#Url.Action("_GetPresenters","MonitoringFRadio")'+'?count='+(index+1),
data: msg,
type: 'POST',
success: function(data) {
$('#presenters-ajax-wrapper').html(data);
}
});
});
</script>
</div>
Action:
[HttpPost]
public virtual ActionResult _GetPresenters(EditableMonitoring model, int count)
{
//some logic here...
return PartialView("EditorTemplates/Presenters", model.Presenters);
}
Well, probably it would be better to create another partial view which would render a single combobox, instead of redrawing all of them...
Related
I'm having a foreach that it gives me a list of values that when click it call a controller:
#foreach (var item in Model)
{
<div>#Html.ActionLink(item.Text, "UpdateController",
new { subSectionID = item.Value, subsectionName = item.Text })</div>
}
I would like to do this but now using a dropdown list where clicking on the value redirects me to the controller.
If someone knows how to do it or do it in some other way, maybe using Select in html, it would help me, thanks!
Try the following:
<script type="text/javascript">
$('#subsec').change(function () {
var url = $(this).val();
if (url != null && url != '') {
window.location.href = url;
}
});
</script>
#Html.DropDownListFor(m => Model.GetEnumerator().Current,
Model.Select(d =>
{
return new SelectListItem() {
Text = d.Text,
Value = Url.Action("Your_Action_Name", "Your_Controller_Name", new { subSectionID = d.Value, subsectionName = d.Text })
};
}),
"-Select a value-",
new { id = "subsec" })
A similar solution you can find here: https://stackoverflow.com/a/6088047/6630084
I am using Asp.MVC 5 for an application and I want to generate many checkboxes with different angularjs models, and I thought the best option is by using array model in angularjs. I tried the code below inside a foreach:
#{
int i = 0;
foreach (var selectedVesselViewModel in Model.SelectedVesselViewModels)
{
using (Html.BeginForm("SelectNotificaiton", "Admin", new { area = "DashBoard" }, FormMethod.Post, new { id = "filterVesselsForm_" + i}))
{
#Html.HiddenFor(item => selectedVesselViewModel.VesselId, new {ng_model= "SelectedVessels[" + i + "].VesselId" })
<li class="row">
<div class="col-md-10">
<a href="#" class="text-admin-area">
#selectedVesselViewModel.VesselName
</a>
</div>
<div class="col-md-2">
<div class="pull-right">
<div class="checkbox checkbox-inline">
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng_model = "SelectedVessels[" + i + "].Selected"
})
<label for="SelectedVesselViewModels_#(i++)__Selected"></label>
</div>
</div>
</div>
</li>
}
}
}
i variable is an incrementing variable:
in the angularjs controller I have something like this:
(function (app) {
"use strict";
app.controller("DashboardCtrl", ['$scope',
function ($scope) {
function init() {
// $scope.SelectedVessels = [];
}
$scope.SelectedVessels = [];
init();
$scope.RefreshSideBarVessels = function() {
angular.forEach($scope.SelectedVessels, function (value, key) {
alert($scope.SelectedVessels[key].VesselId);
});
}
}]);
})(adminModule);
When I use angularjs foreach loop the $scope.SelectedVessels seems to be empty but I dont know why!
angular.forEach($scope.SelectedVessels, function (value, key) {
alert($scope.SelectedVessels[key].Selected);
});
Does anybody know where is the problem, why I cant access the inner properties of the $scope.SelectedVessels array and why it is empty ?
How you are adding values to your array ie. $scope.SelectedVessels is important
Please have a look at below example.
var values = {name: 'Raja', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key) {
this.push(key + ': ' + value);
}, log);
expect(log).toEqual(['name: Raja', 'gender: male']);
Here is the solution to this problem:
I had to use ng-init to each checkbox to instantiate the ng-model.
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng_model = "SelectedVessels[" + i + "].Selected",
ng_init = "SelectedVessels[" + i + "].Selected="+ selectedVesselViewModel.Selected.ToString().ToLower()
})
First off , its ng-model not ng_model (- vs _) but that could be typo.
Second, try this code
$scope.onChange = function (index, value) {
$scope.SelectedVessels[index] = value;
}
#Html.CheckBoxFor(item => selectedVesselViewModel.Selected,
SelectedVessels[i] = selectedVesselViewModel.Selected
new {id = "SelectedVesselViewModels_"+i+"__Selected",
onchange ="document.getElementById('filterVesselsForm_"+i+"').submit()",
ng-model = "SelectedVessels[" + i + "].Selected",
on-change="onChange(i,selectedVesselViewModel.Selected)
})
I'm trying to sort a list of divs with the properties shown by particular attributes (gender, level, name etc) using the following script:
html:
<div id="sortThis" class="col-xs-12 alert-container">
<div id="1" class="container-element sortable box box-blue" data-gender="1" data-level="4" data-name="AAA"> <h3>AAA</h3><div class="panel-body">AAA is resp</div>
</div>
<div id="2" class="container-element sortable box box-pink" data-gender="2" data-level="3" data-name="DDD"><h3>DDD</h3><div class="panel-body">DDD is a s</div>
</div>
<div id="3" class="container-element sortable box box-blue" data-gender="1" data-level="2" data-name="FFF"><h3>FFF</h3><div class="panel-body">FFF has mad</div>
</div>
<div id="4" class="container-element sortable box box-pink" data-gender="2" data-level="4" data-name="CCC"><h3>CCC</h3><div class="panel-body">CCC has ma</div>
</div>
<div id="5" class="container-element sortable box box-pink" data-gender="2" data-level="2" data-name=EEE><h3>EEE</h3><div class="panel-body">EEE is a f</div>
</div>
<div id="6" class="container-element sortable box box-blue" data-gender="1" data-level="3" data-name="BBB"><h3>BBB</h3><div class="panel-body">BBB is an ou</div>
</div>
</div>
<button id="sLevel" class="LbtnSort">Sort by Level</button><br/>
<button id="sGender" class="GbtnSort">Sort by Gender</button><br/>
js:
var LdivList = $(".box");
LdivList.sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
var GdivList = $(".box");
GdivList.sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
/* sort on button click */
$("button.LbtnSort").click(function() {
$("#sortThis").html(LdivList);
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GdivList);
});
when the .sortable divs are static, the sort works fine, as this jfiddle shows, however if the contents of the #sortable div (i.e. .sortable divs) are dynamically generated (in this case as the result of a form submit), when the sort button is pressed, the entire contents of the #sortable div disappears, and I can't seem to get it to work.
Any help or suggestions would be appreciated.
edit: The code for dynamic generation of the list is as follows - effectively it's an AXAX form submit that pulls data from a sorted list of items and outputs them.
$('#formStep2').submit(function(event) {
// get the form data
var studentArray = [];
$(".listbox li").each(function() {
studentArray.push({
'name': ($(this).text()),
'gender': ($(this).closest('ol').attr('id')).substr(0, 1),
'level': ($(this).closest('ol').attr('id')).substr(2, 3),
'topic': ($('input[name=topic]').val())
})
});
var studentString = JSON.stringify(studentArray);
console.log(studentString);
var formData = {
'students': studentString,
};
// process the form
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: 'process_step2.php', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true
})
// using the done promise callback
.done(function(data) {
if (!data.success) {
// error handling to go here.....
} else {
$('.alert-container').empty();
var obj = JSON.parse(data.message);
//sort the array alphabetically by name (default status)
var test = obj.sort(function(a,b){
var lccomp = a.name.toLowerCase().localeCompare(b.name.toLowerCase());
return lccomp ? lccomp : a.name > b.name ? 1 : a.name < b.name ? -1 : 0;
});
console.log(test);
var i=0;
test.forEach(function(st) {
console.log(st['name']);
var gen = (st['gender'] == 1) ? "blue" : (st['gender'] == 2) ? "pink" : NULL;
$('.alert-container').append('<div id="' + (i+1) + '" class="container-element sortable box box-' + gen + '" data-gender="' + st['gender'] + '" data-level="' + st['level'] + '" data-name="' + st['name'] + '"><h3>' + st['name'] + '</h3><div class="panel-body"><div class="col-xs-9"><i class="fa fa-quote-left fa-3x fa-pull-left fa-' + gen + '" aria-hidden=:true"></i>' + st['comment'] + '</div></div></div>');
i++;
});
// jump to the next tab
var $active = $('.wizard .nav-tabs li.active');
$active.next().removeClass('disabled');
nextTab($active);
}
})
// using the fail promise callback
.fail(function(data) {
// show any errors
// best to remove for production
console.log(data);
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
});
You are defining LdivList and GdivList inline with your code so they are defined on DOM ready. You have to wrap the definition of those inside a function and call it on click:
$(document).ready(function(){
$("button.LbtnSort").click(function() {
$("#sortThis").html(GenerateLdivList);
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GenerateGdivList());
});
});
function GenerateLdivList(){
var LdivList = $(".box");
LdivList.sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
}
function GenerateGdivList(){
var GdivList = $(".box");
GdivList.sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
}
As #theduke said, the lists are probably empty at the time you sort them. Here's a simple change that will read and sort the lists when you click the buttons instead. (Not tested.)
var LdivList = function () {
return $(".box").sort(function(a, b){
return $(a).data("level")-$(b).data("level")
});
};
var GdivList = function () {
return $(".box").sort(function(a, b){
return $(a).data("gender")-$(b).data("gender")
});
};
/* sort on button click */
$("button.LbtnSort").click(function() {
$("#sortThis").html(LdivList());
});
/* sort on button click */
$("button.GbtnSort").click(function() {
$("#sortThis").html(GdivList());
});
I know there are many questions/tutorials for this subject, but cannot solve my problem.
I have to ask for your help. Second day cannot find out the solution to this simple problem.
I am trying as in this tutorial - http://www.c-sharpcorner.com/UploadFile/abhikumarvatsa/cascading-dropdownlist-in-Asp-Net-mvc/
That is working fine, but once i try from DB, i am getting error "Uncaught ReferenceError: data is not defined"
Here is my web page
#model testEmpty.Models.Address
#{
ViewBag.Title = "Create";
}
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/myScripts/myScripts.js"></script>
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Address</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group col-md-10">
#Html.Label("Zone")
#Html.DropDownList("ZoneId", ViewBag.ZoneName as SelectList, "--Select a Zone--", new { id = "ZoneId" })
#Html.ValidationMessage("Zone", "*")
</div>
<div class="form-group">
<div class="col-md-10">
#Html.Label("Districts of SZ")
<select id="DistrictSZ" name="DistrictSZ"></select>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Controller
private myContext db = new myContext();
// GET: Addresses
public ActionResult Index()
{
var zones = db.Addresses.Include(a => a.Zone);
ViewBag.ZoneName = new SelectList(zones, "Value", "Text");
return View(zones.ToList());
}
public JsonResult DistrictList(int id)
{
var district = from s in db.Districts
where s.ZoneId == id
select s;
return Json(new SelectList(district.ToArray(), "ZoneId", "Name"), JsonRequestBehavior.AllowGet);
}
Script
$(function () {
$('#ZoneId').change(function () {
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts (data));
});
});
function getDistricts(data) {
var items = '<option>Select a District</option>';
$.each(data, function (i, district) {
items += "<option value='" + district.Value + "'>" + district.Text + "</option>";
});
$('#DistrictSZ').html(items);
}
As i understand, my problem is with JSON. what am I doing wrong?
Firstly you do not need to return a SelectList (javascript knows nothing about a c# class)
public JsonResult DistrictList(int id)
{
var district = db.Districts.Where(d => d.ZoneId == id).Select(d => new
{
Value = d.ZoneId, // this look wrong - see note below
Text = d.Name
});
return Json(district, JsonRequestBehavior.AllowGet);
}
Then in your script
var url = '#Url.Action("DistrictList")'; // ensure your url's are properly generated
var districts = $('#DistrictSZ'); // cache it
$('#ZoneId').change(function () {
$.getJSON(url, { id: $(this).val() }, function (data) {
districts.empty(); // remove existing options
districts.append($('</option>').val('').text('Select a District'));
$.each(data, function (i, district) {
districts.append($('</option>').val(district.Value).text(district.Text));
});
});
});
In fact, since ZoneId is always the same, you could just return a collection of the Name values
var district = db.Districts.Where(d => d.ZoneId == id).Select(d => d.Name);
and
$('#ZoneId').change(function () {
var zoneID = $(this).val();
$.getJSON(url, { id: zoneID }, function(data) {
districts.empty(); // remove existing options
districts.append($('</option>').val('').text('Select a District'));
$.each(data, function (i, district) {
districts.append($('</option>').val(zoneID).text(district));
});
});
});
However your code is generating all options with the same value (ZoneId) which does not make much sense, so I suspect you really want to use another property of District - i.e. its Id (or DistrictId?) property.
You're passing the returned value of getDistricts to the callback variable of $.getJSON.
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts (data));
You need to pass the function reference like this
$.getJSON('DistrictList/' + $('#ZoneId').val(), getDistricts);
maybe you should handle your callback function with a anonymous function like this:
$.getJSON('DistrictList/' + $('#ZoneId').val(), success(data){
getDistricts(data);
})
I have got a Kendo Grid with editable records:
When the user clicks the edit button, a Kendo Window opens with a form to edit the record.
I am achieving this by filling the Kendo Window from a controller method that fetches the data of the selected record via webservice: <- this is what I want to avoid. Instead, I want to take the data straight out from the table and put it into the input fields inside the Kendo Window, without any additional processing or html calls. The data is already on the table, I just don't know how to send it to the Kendo Window inputs.
Here's some code:
The javascript function called after clicking the edit button:
function openEdit() {
var window = $("#editWindow").getKendoWindow();
window.refresh({
url: '#Url.Action("_EditForm", "Controller")'
});
window.center().open();
}
The view contains a partial view call:
#Html.Partial("_EditWindow")
The called partial view contains the Kendo Window:
#(Html.Kendo().Window()
.Name("editWindow")
.Modal(true)
.Events(e => e.Open("drawWindow").Close("refresh").Refresh("hideLoading"))
.Iframe(true)
.Visible(false)
.Title("Edit Record")
)
How can the data from the selected row of the table be passed to the Kendo Window?
EDIT
I know how to get the values from the selected record in javascript:
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
I just don't know how to pass them into the Kendo Window inputs.
I came to a solution for my problem. I now send the selected model from the view to the controller. I use the fantastic JSON.stringify to achieve it.
function onChange() {
if (this.dataItem(this.select()) != null) {
var rowModel = this.dataItem(this.select());
// gets the model of the selected item in the grid
$.ajax({
url: 'sendGridRecord',
type: "POST",
data: JSON.stringify(rowModel),
contentType: 'application/json'
});
}
}
You can define a partial view as per the requirement and render that on a kendow window on edit button click.i.e
#(Html.Kendo().Window().Name("myWindow")
.Content(Html.Partial(#Url.Content("~/Views/_EditWindow.cshtml")).ToString())
.Visible(false).Title("XYZ").Modal(true).Actions(actions => actions
.Custom("custom")
.Minimize()
.Maximize()
.Close()
).Resizable().Draggable())
function openEdit() {
//Open the kendow window here.
//Get the seleceted item
var grid = $("#grid").data("kendoGrid");
var selectedItem = grid.dataItem(grid.select());
//populate the partial view fields using the selectedItem variable like
$('#name').val(selectedItem.Name);
}
You can use these two methods in order to pass the Kendo().Grid()'s selected row data:
Method I:
.ToolBar(toolbar =>
{
toolbar.Template(#<text>
<div class="toolbar">
#(Html.Kendo().Button()
.Name("myBtn")
.HtmlAttributes(new { type = "button", #class = "k-primary k-button k-button-icontext", onclick = "callActionBySelectedRowId('#GridMaster')" })
.Content("Add New")
)
</div>
</text>);
})
function callActionBySelectedRowId(grid) {
var grid = $(grid).data('kendoGrid');
id = grid.dataItem(grid.select()).ID;
window.location.href = '#Url.Action("YourAction", "YourController")/' + id;
}
Method II:
View:
#(Html.Kendo().Grid<KendoMVCWrappers.Models.Person>().Name("persons")
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(m => m.PersonID);
})
.Read(read => read.Action("GetPersons", "Home"))
.Update(up => up.Action("UpdatePerson", "Home"))
)
.Selectable(s => s.Mode(GridSelectionMode.Multiple))
.Columns(columns =>
{
columns.Bound(c => c.BirthDate);
columns.Bound(c => c.Name);
columns.Command(cmd => cmd.Edit());
})
.Pageable()
.Sortable()
)
<input type="button" id="btn" name="name" value="send to Server!" />
<script type="text/javascript">
$(function () {
$('#btn').click(function () {
var items = {};
var grid = $('#persons').data('kendoGrid');
var selectedElements = grid.select();
for (var j = 0; j < selectedElements.length; j++) {
var item = grid.dataItem(selectedElements[j]);
items['persons[' + j + '].Name'] = item.Name;
items['persons[' + j + '].PersonID'] = item.PersonID;
}
//If you want to pass single item parameter use this and comment out "for loop" & use the second "data" line below:
//var singleItem = grid.dataItem(selectedElements[0]);
$.ajax({
type: "POST",
data: items,
//data: { ID: singleItem.ID }, //for passing single item parameter
url: '#Url.Action("Test","Home")',
success: function (result) {
console.log(result);
}
})
})
})
Controller:
public ActionResult Test(Person[] persons)
{
return Json(persons);
}
Note: If the View called from Controller cannot be rendered use the javascript function as below by using window.location.href instead of $.ajax
<script type="text/javascript">
$(function () {
$('#btn').click(function () {
var items = {};
var grid = $('#persons').data('kendoGrid');
var selectedElements = grid.select();
var item = grid.dataItem(selectedElements[0]);
window.location.href = '#Url.Action("YourAction", "YourController")/' + item.ID;
})
})
</script>