Kendo Window - LoadDataFrom finds argument value inline? - asp.net-mvc

I have a kendo window which I want to populate depending on a selection made in a dropdown. I've tried refreshing the window upon open, but I can't figure out how to make that work. Changing gears, I'm wondering if I can instead send a variable parameter to the controller within window declaration itself, and then do a simple window.refresh (instead of coding the refresh to hit a specific controller, which isn't working).
I mean something like this:
#(Html.Kendo().Window()
.Name("EditWindow")
.Title("Edit Contact")
.LoadContentFrom("_ContactEdit", "Contacts", new { selectedContact = $("#ContactId").data("kendoComboBox").value() })
.Content("Loading...")
.Visible(false)
.Draggable()
.Resizable()
.Width(400)
.Modal(true)
.Actions(actions => actions.Pin().Minimize().Maximize().Close())
)
Or this:
#(Html.Kendo().Window()
.Name("EditWindow")
.Title("Edit Contact")
.LoadContentFrom("_ContactEdit", "Contacts", new { selectedContact = getContact() })
.Content("Loading...")
.Visible(false)
.Draggable()
.Resizable()
.Width(400)
.Modal(true)
.Actions(actions => actions.Pin().Minimize().Maximize().Close())
)
Obviously neither of these work, but I'm wondering if there's another way to fill in this field?
Thank you!
edit: Adding relevant code from controller and window/partial view. My controller is now being hit, but my window is not pulling the correct data. Any ideas?
Window:
#model [taking out company info].Contact
#using Kendo.Mvc.Extensions
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset id="infoForm">Hello, world.
#Html.HiddenFor(model => model.ContactId, new { id = "EditWindowId" })
<br />
<label id ="ContactNameID" style="width: 130px;">Contact Name</label>
<span>
#Html.TextBoxFor(model => model.FullName, new { type = "text", id = "EditWindowName", #class = "k-textbox form-control", style = "width: 200px; cursor:default" })
</span><br />
</fieldset>
}
Controller:
[HttpGet]
public ActionResult _ContactEdit(int selectedContact)
{
var entities = from r in dbContext.Contacts
where r.ContactId == selectedContact
select r;
if (entities.Any())
{ return PartialView(entities.First()); }
else
{ return HttpNotFound("Contact does not exist."); }
}

You can leverage the change event of your dropdown list to grab the selected value. Once you have the selected value you can programmatically refresh the window with the appropriate action on your controller. For example, the code below defines a Kendo DropDownList with a subscription to the change event. In the change, the value is used to build a dynamic url, and the kendo window is refreshed with that url:
<%= Html.Kendo().DropDownList()
.Name("dropdownlist")
...
.Events(e =>
{
e.Change("onChange")
})
%>
<script type='text/javascript'>
function onChange(){
var value = this.value(),
window = $("#EditWindow").data("kendoWindow");
window.refresh({
url: "/Contact/_ContactEdit?selectedContact=" + value
});
}
</script>

Related

New value in HTML.DropDownListFor(...) not setting in Controller [Post] method?

Hopefully someone can see how to go about this, because I've tried everything I can think of. When the Create() View in my MVC5 application loads I first populate several [SelectList(...)]'s in my Controller (ex.):
ViewBag.Model_Id = new SelectList(db.DBT_MODELS.OrderBy(x => x.MODEL_DESCRIPTION), "MODEL_ID", "MODEL_DESCRIPTION");
I then on my Create() View use this [SelectList(...)] to Populate an Html.DropDownListFor(...):
<div class="form-group">
<span class="control-label col-md-2">Model:</span>
<div class="col-md-4">
#Html.DropDownListFor(model => model.MODEL_ID, (SelectList)ViewBag.Model_Id, htmlAttributes: new { #class = "form-control dropdown", #id = "selectModel" })
#Html.ValidationMessageFor(model => model.MODEL_ID, "", new { #class = "text-danger" })
</div>
<div class="col-md-2">
<div class="btn-group">
<button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
</div>
</div>
<div class="col-md-4">
<div id="createModelFormContainer" style="display:none">
<form action="/createNewModel">
<input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
<input type="button" id="submitNewModel" value="Submit" />
<input type="button" id="cancelNewModel" value="Cancel" />
</form>
</div>
</div>
</div>
Simple enough, and this all works as expected. The problem lies in a bit of extended functionality I've tried to incorporate. My main class has several of these properties which are basically Foreign Key's in my DB. When a User goes in to Create/Edit() an entity in my main Model, I wanted to allow them to be able to add new entities to these foreign tables without needing to navigate away from the current View.
As such, I added (for each foreign property, using (Model) as an example) the code shown above and again directly below with a button to Show/Hide a small form for users to insert a new value and have it added to the DropDownList:
<div class="col-md-2">
<div class="btn-group">
<button id="createNewModel" type="button" class="btn btn-success" aria-expanded="false">CREATE NEW</button>
</div>
</div>
<div class="col-md-4">
<div id="createModelFormContainer" style="display:none">
<form action="/createNewModel">
<input type="text" id="textNewModel" name="model_description" placeholder="New Model" />
<input type="button" id="submitNewModel" value="Submit" />
<input type="button" id="cancelNewModel" value="Cancel" />
</form>
</div>
</div>
My submitNewModel() click event below gets the user's inputted new value and then uses a JSON call to a Controller Method to add it in the Database Table. This new value (and new ID for it) are then returned, the form for the DropDownList is reset, and I set the DropDownList's current value as the newly added one:
$('#createNewModel').click(function () {
$('#createModelFormContainer').show();
})
$('#cancelNewModel').click(function () {
$('#createModelFormContainer').hide();
})
$('#submitNewModel').click(function () {
var form = $(this).closest('form');
var data = { description: document.getElementById('textNewModel').value };
$.ajax({
type: "POST",
dataType: "JSON",
url: '#Url.Action("createNewModel", "INV_ASSETS")',
data: data,
success: function (resp) {
if (resp.ModelExists)
{
alert("Model [" + resp.Text + "] already exists. Please select from the DropDown.");
} else {
$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
form[0].reset();
$('#createModelFormContainer').hide();
var count = $('#selectModel option').size();
$('#selectModel').prop('selectedIndex', count - 1);
$('#selectModel').val(resp.MODEL_ID);
//document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed.
}
},
error: function () {
alert("ERROR - Something went wrong adding new Model [" + resp.Text + "]!");
$('#createModelFormContainer').hide();
}
});
//reloadForNewEntity();
});
The createNewModel() method that is called in my Controller:
public JsonResult createNewModel(string description)
{
DBT_MODELS model = new DBT_MODELS()
{
// ID auto-set during save.
MODEL_DESCRIPTION = description.Trim(),
CREATED_DATE = DateTime.Now,
CREATED_BY = System.Environment.UserName
};
var duplicateModel = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper());
try
{
if (duplicateModel == null)
{
if (ModelState.IsValid)
{
db.DBT_MODELS.Add(model);
db.SaveChanges();
// Ensure the [model.ID] is properly set after having been saved to and auto-generated in the database.
model.MODEL_ID = db.DBT_MODELS.FirstOrDefault(x => x.MODEL_DESCRIPTION.ToUpper() == model.MODEL_DESCRIPTION.ToUpper()).MODEL_ID;
}
}
else
{
model = duplicateModel;
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
return Json(new { ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION, ModelExists = (duplicateModel != null) }, JsonRequestBehavior.AllowGet);
}
Visually speaking, everything works as intended up to this point. The problem is when I go to Save the main entity I am Creating/Editing.
Any value that was already in the Foreign Tables, and thus in the DropDownList when the View loads, saves just fine; but if I add a new Foreign Table value for these main entity properties (though visually added and the currently selected values for the individual DropDownLists) the [POST] method then executes with each foreign id value set as 0 (ex. MainClass.Model_ID = "0" vs expected MainClass.Model_ID = "625", MainClass.Type_ID = "0" vs expected MainClass.Type_ID = "17", MainClass.Location_ID = "0" vs expected MainClass.Location_ID = "82", etc.)
Basically if the value selected in the Html.DropDownListFor() is one of my newly added values, the POST controller method always renders the MainClass.*_ID value which the selected Html.DropDownListFor() value corresponds to as "0".
Can anyone point me to how to get this working? I have tried:
Changing how my JavaScript sets the value in the DropDownList after the the JSON call to my Controller Actions returns (ex): //document.getElementById('selectModel').value = resp.MODEL_ID; - Shows dropdown as blank [ ] once executed. vs $('#selectModel').val(resp.MODEL_ID); which visually renders the expected new value in the DropDownList.
On return from the Controller method, setting a new ViewBag variable and then hoping to reference the saved value in the POST method (did not work, the JavaScript rendered my #Viewbag.PostModelID = resp.ModelID as "= resp.ModelID" and threw many expected errors).
EDIT:
[Redacted for N/A]
EDIT2: Good to go. Thanks everyone for the suggestions!
The json data you are returning from your action method is in this format.
{
"ID": 24,
"Text": "IOS",
"ModelExists": false
}
But in your code, you are trying to access MODEL_ID property which does not exist in the resp object.
$('#selectModel').append($('<option></option>').val(resp.MODEL_ID).text(resp.Text));
Change your code to use ID property value
$('#selectModel').append($('<option></option>').val(resp.ID).text(resp.Text));
$('#selectModel').val(resp.ID);
In your controller where you create the new model.. your json object that you're returning is ID, Text, ModelExists, but in your javascript you're setting the val property of the new <option> to MODEL_ID.. these 2 need to match..
So change your javascript to be
.val(resp.ID)
or change the return value in your controller action to
return Json(new { MODEL_ID = model.MODEL_ID, Text = model.MODEL_DESCRIPTION
You're also referencing MODEL_ID here
$('#selectModel').val(resp.MODEL_ID);
so make sure if you don't change your controller action, you update this also

Using Kendo UI MVC DropDownListFor, how do i pass the selected text along to the controller during the submit form?

Im using Ajax.BeginForm and I need to pass the selected text to the controller on the submit. Right now it is passing the Value(id) but I need the Text. Any ideas?
#using (Ajax.BeginFrom("Index", "Home", new AjaxOptions { HttpMethod = "Post" }))
{
<fieldset>
<ol>
<li>
#(Html.Kendo().DropDownListFor(m => m.Office)
.Name("officeDropDownList")
.DataValueField("Value")
.DataTextField("Text")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetOffices", "Home");
});
})
)
</li>
</ol>
</fieldset>
}
To get the value text of a dropdown:
$("#ddl").data("kendoDropDownList").text();
**Edit**
In order to return this data to the Controller I believe you need to change the .Name of the ddl to match the ViewModel property. So in your case change to .Name("Office").

Fire validation of asp.net razor view page input controls on kendo ui upload select file button

I have an asp.net mvc application with Kendo UI controls. I have an upload file razor view with few input controls on the page.
My requirement is to fire the page validation on the file select button for all the other input controls in the page. (at least required validation has to get fired)
I can have a submit button and fire the validation. But I need to have that functionality on the Kendo UI upload select button. i.e,User can select / browse file to upload only after filling valid values for all the input controls.
I have done many searches and trial and error methods in my code but nothing helped.
I am new to Kendo UI controls so please help
Thanks in advance,
I am attaching sample code below:
#{
ViewBag.Title = "Kendo Validate";
}
#model KendoInputs_Validation.Models.ViewModel
#using(Html.BeginForm())
{
<div id="tickets">
<h3>Book Tickets</h3>
<ul id="innerList">
<li>
#Html.LabelFor(m => m.ComboBox)
#Html.Kendo().ComboBoxFor(m => m.ComboBox)
#Html.ValidationMessageFor(m => m.ComboBox)
</li>
<li>
#Html.LabelFor(m => m.DropDownList)
#(Html.Kendo().DropDownListFor(m => m.DropDownList)
.OptionLabel("Select item...")
.BindTo(new SelectList(new string[] { "Item1", "Item2", "Item3" }))
)
#Html.ValidationMessageFor(m => m.DropDownList)
</li>
<li>
#Html.LabelFor(m => m.DatePicker)
#Html.Kendo().DatePickerFor(m => m.DatePicker)
#Html.ValidationMessageFor(m => m.DatePicker)
</li>
<li>
#Html.LabelFor(m => m.Number)
#Html.Kendo().NumericTextBoxFor(m => m.Number)
#Html.ValidationMessageFor(m => m.Number)
</li>
<li class="accept">
<button class="k-button" type="submit">Submit</button>
</li>
<li>
#(Html.Kendo().Upload()
.Name("files")
.Messages(msg => msg
.Select("Browse")
))
</li>
</ul>
</div>
}
<script>
$(document).ready(function () {
/* Bind Mutation Events */
var elements = $("#tickets").find("[data-role=combobox],[data-role=dropdownlist],[data-role=numerictextbox],[data-role^=date], [data-role^=upload]");
//correct mutation event detection
var hasMutationEvents = ("MutationEvent" in window),
MutationObserver = window.WebKitMutationObserver || window.MutationObserver;
if (MutationObserver) {
var observer = new MutationObserver(function (mutations) {
var idx = 0,
mutation,
length = mutations.length;
for (; idx < length; idx++) {
mutation = mutations[idx];
if (mutation.attributeName === "class") {
updateCssOnPropertyChange(mutation);
}
}
}),
config = { attributes: true, childList: false, characterData: false };
elements.each(function () {
observer.observe(this, config);
});
} else if (hasMutationEvents) {
elements.bind("DOMAttrModified", updateCssOnPropertyChange);
} else {
elements.each(function () {
this.attachEvent("onpropertychange", updateCssOnPropertyChange);
});
}
});
function updateCssOnPropertyChange (e) {
var element = $(e.target);
element.siblings("span.k-dropdown-wrap")
.add(element.parent("span.k-numeric-wrap"))
.add(element.parent("span.k-picker-wrap"))
.toggleClass("k-invalid", element.hasClass("input-validation-error"));
}
</script>
<style type="text/css">
.k-widget > span.k-invalid,
input.k-invalid
{
background: red;
}
#innerList li
{
margin: 10px 10px;
}
</style>
Edit:- I can write an Select event for the upload control as below:
#(Html.Kendo().Upload()
.Name("files")
.Events(events => events
.Select("onSelect")
)
)
But in this case user has to select a file for getting the validation errors.
Our requirement is that when user clicks the select button validation errors should pop up. if no errors then only file select window opens.
Thanks
You can bind a click function to your upload during initialization and check your custom vale before the default behavior, the browse fro dialog, window is invoked.
$(document).ready(function () {
$("#yourUploadName").click(function (e) {
var valid=myValidationFunction();
if (!valid) {
alert("Bad");
//This will cancel the showing of the search dialog
e.preventDefault();
}
});
});

Submitting jquery dialog box using ajax call

I'm attempting to do a search using a jquery ui dialog box, and have the results also appear in a dialog box without any redirection on the actual page. I'm thinking an easy way of doing this is just to create my ui and have a < div id > surrounding the content, then replace the div with a view using an ajax call.
I've gotten the basics of this working, but... I have no clue how to pass the input field parameters to the incoming view/controller! It's currently not using submit() in any shape or form as this causes an unavoidable page redirect afaik.
My dialog contains standard text fields such as:
#Html.HiddenFor(model => model.Id)
<label>Customer Name</label>
#Html.TextBoxFor(m => m.Name, new { #class = "text ui-widget-content ui-corner-all" })
<label>EIN</label>
#Html.TextBoxFor(m => m.Ein, new { #class = "text ui-widget-content ui-corner-all" })
<label>State Tax ID Number</label>
#Html.TextBoxFor(m => m.StateTaxId, new { #class = "text ui-widget-content ui-corner-all" })
I have a placeholder for the dialog div
<div id="dialog-searchResults" title="Search Results" class="hide">
#using (Html.BeginForm("searchResults", "Customers", FormMethod.Post, new { #id = "searchResultForm" }))
{
<div id="SearchContents">a</div>
}
</div>
The ajax call
function InsertDialogDiv(ajaxUrl, divTable) {
var jsonData = {
"id": 0
};
$.ajax({
type: 'POST',
url: BASE_URL + ajaxUrl,
data: JSON.stringify(jsonData),
success: function (data) {
$(divTable).replaceWith(data);
},
error: function (xhr, ajaxOptions, thrownError) {
$(divTable).replaceWith(xhr.responseText);
}
});
}
Where ajaxUrl='Customer/SearchResults' as the path of the view.
Replacing the div in this way does trigger the Customer's controller to hit the SearchResults function, but as I'm not submitting, the model has all null values. How do I get my precious nuggets of information?
TY & Rat's off to ya!
PS: ASP.NET C# MVC4 Razor

pass model from view to controller with html.actionlink

I am trying to get the model data from a strongly typed view to a controller.
Using the submit button is ok, I can get the data. Now I want to achieve the same with html.actionlink.
This is what I have:
View:
#model WordAutomation.Models.Document
#{
ViewBag.Title = "Document";
}
<script type="text/javascript">
$(function () {
$("#dialog").dialog();
});
</script>
<h2>Document</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Document</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ClientTitle)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientTitle)
#Html.ValidationMessageFor(model => model.ClientTitle)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ClientFullName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientFullName)
#Html.ValidationMessageFor(model => model.ClientFullName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ClientCustomSSN)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ClientCustomSSN)
#Html.ValidationMessageFor(model => model.ClientCustomSSN)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Preview", "PreviewWordDocument", "Home", null, new { id = "previewLink" })
</div>
<div id="dialogcontainer">
<div id="dialogcontent"><input type="submit" value="Create" /> </div>
</div>
#section Scripts {
<script type="text/javascript">
$(document).ready(function() {
$("#dialogcontainer").dialog({
width: 400,
autoOpen:false,
resizable: false,
title: 'Test dialog',
open: function (event, ui) {
$("#dialogcontent").load("#Url.Action("PreviewWordDocument", "Home")");
},
buttons: {
"Close": function () {
$(this).dialog("close");
}
}
});
$("#previewLink").click(function(e) {
e.preventDefault();
$("#dialogcontainer").dialog('open');
});
});
</script>
}
Controller:
public ActionResult Document()
{
return View();
}
[HttpPost]
public ActionResult Document(WordAutomation.Models.Document model)
{
Models.Utility.EditWord word = new Models.Utility.EditWord();
word.EditWordDoc(model);
return View("Display", model);
}
public ActionResult PreviewWordDocument()
{
var image = Url.Content("~/Content/preview.jpeg");
return PartialView((object)image);
}
The document actionresult can get the model, but I want to know how can I get the values from the actionlink which will trigger the PreviewWordDocument action.
Thanks in advance, Laziale
The form can only be posted using the submit button to the URL given by its action attribute.
You can however send the form data to a different URL using the jQuery post method, manually validating the form before it is sent.
That way you can send the form data to the PreviewWordDocument controller method and handle the response in order to show the preview in the desired div.
(It will be helpful if you give an id to the form, so you can easily find it using jQuery)
So your click event handler for the preview link will look like this:
$("#previewLink").click(function(e) {
e.preventDefault();
if($("#YourFormId").valid()){
$("#dialogcontainer").dialog('open');
}
});
In the open function of the dialog you will post the form (which was already validated) to the preview controller method, using the jQuery ajax function. The response will be loaded into the dialogContent div:
$.ajax({
type: "POST",
url: $("#previewLink").attr("href"), //the preview controller method
data: $("#YourFormId").serialize(),
success: function (data) {
//load ajax response into the dialogContent div
$("#dialogcontent").html(data);
},
error: function(xhr, error) {
$("#YourFormId").prepend('<div id="ajaxErrors"></div>')
.html(xhr.responseText);
}
});
Now you will now be able to receive the whole document in the PreviewWordDocument action:
public ActionResult PreviewWordDocument(WordAutomation.Models.Document model)
{
var image = Url.Content("~/Content/preview.jpeg");
return PartialView((object)image);
}
in a HTML page when you click on a submit button all the input elements inside the form which the submit button resides in will posted to server, but when you click on a anchor (<a> tag ). you only send a request with a Get method and without posting any value.but if you want to send particular value to the server with this approach you can do it by query string.you have used following to make a request :
#Html.ActionLink("Preview", "PreviewWordDocument", "Home", null,
new { id = "previewLink" })
this will produce :
<a id="previewLink" href="/Home/PreviewWordDocument"> Preview </a>
which is incorrect.to pass any value to the server with ActionLink use 4th parameter like this :
#Html.ActionLink("Preview", "PreviewWordDocument", "Home",
new { id = "previewLink" }, null)
the result from this code would be :
Preview
cheers!

Resources