Where is this "Too Many Characters in String literal" message coming from? - asp.net

Good morning all,
I'm sure this is a gimme, but I have no idea where this issue is coming from.
I have the following lines in a view:
<fieldset>
<dl>
<dt>
<label for="FormTypes">Form Type:</label>
</dt>
<dd>
<% =Html.DropDownList("FormTypes", "All") %>
</dd>
</dl>
</fieldset>
<fieldset>
<dl>
<dt>
<label for="Parts">Form Part:</label>
</dt>
<dd>
<% =Html.DropDownList("Parts", "All") %>
</dd>
</dl>
</fieldset>
This causes no problems, but when adding the following script to the top of to update Parts based on the selection of form type (following the answer to this SO question Bind DropDownlists with JQuery in Asp.Net)
<script type="text/javascript">
<!--
$('#FormTypes').change(function() {
var val = $(this).val();
$parts = $('#Parts');
$.ajax({
url: '<%= Url.Action('FormParts') %>',
dataType: 'json',
data: { ID: val },
success: function(parts) {
$.each(parts, function(i, part) {
$parts.append('option value="' + part.ID+ '">' + part.Code + '</option>');
});
},
error: function() {
alert('Failed to retrieve parts list.');
}
});
});
//-->
</script>
(where the FormParts action will return a new object to populate the parts drop down list)
I get the message: Too many characters in character literal on the line
<% =Html.DropDownList("Types") %>
It appears this issue is caused by the javascript being added, but why and why the error is on the previously good line of code in the markup and not in the script?
Thanks in advance.

While there's nothing wrong with the line you seperated out, this part in the original code does bother me:
<%= Url.Action('FormParts') %>
You used single quotes for the string in ASP. This marks it as a character literal, and not a string. Replace them with double quotes and you should be fine.
<%= Url.Action("FormParts") %>

I'm not sure where that issue was coming from, I've updated the script to the following and it works.
<script type="text/javascript">
<!--
$(function() {
$('#FormTypes').change(function() {
//clear all items in list and replace "All" option
$parts = $('#FormParts');
$parts.html("");
$parts.append('<option value="">All</option>');
var selectedValue = $(this).val();
if (selectedValue != "") {
$.ajax({
url: '<%= Url.Action("FormParts") %>',
dataType: 'json',
data: { FormTypeID: selectedValue },
success: function(parts) {
//repopulate list with JSON objects
$.each(parts, function(i, part) {
$parts.append('<option value="' + part.ID + '">' + part.Code + '</option>');
});
},
error: function() {
alert('Parts list could not be retreived. \n Please use the feedback link to inform us');
}
});
}
});
});
//-->
</script>
For anyone using this code, in future, please note I've added the evaluation
if (selectedValue != "")
this has been added if the option "All" is selected in the first FormTypes drop down list, there is no dependent part list that should be populated.

Related

Ajax - How to get percentage of progress of page load (Dotnetnuke C#)

Script:
$(document).ready(function () {
$('#btnNext').click(function (e) {
e.preventDefault();
});
var options = {
beforeSend: function () {
$("#progress").show();
//clear everything
$("#bar").width('0%');
$("#message").html("");
$("#percent").html("0%");
},
uploadProgress: function (event, position, total, percentComplete) {
$("#bar").width(percentComplete + '%');
$("#percent").html(percentComplete + '%');
},
success: function () {
$("#bar").width('100%');
$("#percent").html('100%');
},
complete: function (response) {
$("#message").html("<font color='green'>" + response.responseText + "</font>");
},
error: function () {
$("#message").html("<font color='red'> ERROR: unable to upload files</font>");
}
};
$("#form1").ajaxForm(options);
});
HTML:
<form id="form1" method="post" enctype="multipart/form-data">
<div>
<input type="file" size="60" name="myfile" />
<input type="submit" value="Ajax File Upload" />
<div id="progress">
<div id="bar"></div>
<div id="percent">0%</div>
</div>
<br />
<div id="message"></div>
</div>
I was tested with Webform (C#). It worked. But, Dotnetnuke not working. (Postback and nothing is changed). Have a different way for Dotnetnuke to get percentage of progress of page load?
-- Thank for reading--
Try removing the <form> tag around your module because DNN is already writing a form tag to the page surrounding the theme and modules. You can change the last line in your jquery logic to reference the form already loaded by DNN.
$("form:first").ajaxForm(options);

How to read arrays generated by EditorFor using jQuery

I am quite confused with technique that I am using. I am using EditorFor to display values.
The code for the values to be generated are as follows:
<tr>
<td>#Html.HiddenFor(m => m.ID)#Html.CheckBoxFor(m => m.Authorized)</td>
<td>#Html.DisplayFor(m => m.ID)</td>
<td>#Html.DisplayFor(m=>m.UserName) </td>
</tr>
My aim here is upon the Checkbox is being checked, I need to post the ID value as follows:
$("input:checkbox").live('click', function () {
if ($(this).attr('checked')) {
var ID = $(this).parent().parent().find('#ID').val();
$.ajax({
type: "POST",
url: '<%=Url.Action("Edit","Employee") %>',
data: JSON.stringify(ID),
contentType: "application/json; charset=utf-8",
dataType: "html",
success: function () {
},
error: function (request, status, error) {
alert("Error: " & request.responseText);
}
});
} });
However, var ID = $(this).parent().parent().find('#ID').val(); is undefined. How can I he read the ID value from the following generated HTML:
<td><input id="Employee_0__ID" name="Employee[0].ID" type="hidden" value="1100" /><input id="Employee_0__Authorized" name="Employee[0].Authorized" type="checkbox" value="true" /><input name="Employee[0].Authorized" type="hidden" value="false" /></td>
<td>user </td>
Not sure I understand what value you looking for?
Would this.
var ID = $(this).parent().parent().find('#ID').attr('value');
or this
var ID = $(this).parent().parent().find('#ID').attr('id');
work?
For the HTML specified this should suffice as the hidden element is the previous sibling of the checkbox in the DOM
var ID = $(this).prev().val();

KnockoutJS, updating ViewModel after ajax call

I am using Knockout and the Knockout Mapping plugin.
My MVC3 Action returns a View and not JSON directly as such I convert my Model into JSON.
This is a data entry form and due to the nature of the system validation is all done in the Service Layer, with warnings returned in a Response object within the ViewModel.
The initial bindings and updates work correctly its the "post-update" behavior that is causing me a problem.
My problem is after calling the AJAX POST and and receiving my JSON response knockout is not updating all of my bindings... as if the observable/mappings have dropped off
If I include an additional ko.applyBindings(viewModel); in the success things do work... however issues then arise with multiple bindings and am certain this is not the correct solution.
This is the HTML/Template/Bindings
<!-- Start Form -->
<form action="#Url.Action("Edit")" data-bind="submit: save">
<div id="editListing" data-bind="template: 'editListingTemplate'"></div>
<div id="saveListing" class="end-actions">
<button type="submit">Save Listings</button>
</div>
</form>
<!-- End Form -->
<!-- Templates -->
<script type="text/html" id="editListingTemplate">
<div class="warning message error" data-bind="visible: Response.HasWarning">
<span>Correct the Following to Save</span>
<ul>
{{each(i, warning) Response.BusinessWarnings}}
<li data-bind="text: Message"></li>
{{/each}}
</ul>
</div>
<fieldset>
<legend>Key Information</legend>
<div class="editor-label">
<label>Project Name</label>
</div>
<div class="editor-field">
<input data-bind="value: Project_Name" class="title" />
</div>
</fieldset>
</script>
<!-- End templates -->
And this is the Knockout/Script
<script type="text/javascript">
#{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model)); }
var initialData = #jsonData;
var viewModel = ko.mapping.fromJS(initialData);
viewModel.save = function ()
{
this.Response = null;
var data = ko.toJSON(this);
$.ajax({
url: '#Url.Action("Edit")',
contentType: 'application/json',
type: "POST",
data: data,
dataType: 'json',
success: function (result) {
ko.mapping.updateFromJS(viewModel, result);
}
});
}
$(function() {
ko.applyBindings(viewModel);
});
</script>
And this is the response JSON returned from the successful request including validation messages.
{
"Id": 440,
"Project_Name": "",
"Response": {
"HasWarning": true,
"BusinessWarnings": [
{
"ExceptionType": 2,
"Message": "Project is invalid."
}, {
"ExceptionType": 1,
"Message": "Project_Name may not be null"
}
]
}
}
UPDATE
Fiddler Demo Is a trimmed live example of what I am experiencing. I have the Project_Name updating with the returned JSON but the viewModel.Response object and properties are not being updated through their data bindings. Specifically Response.HasWarning().
I've changed back to ko.mapping.updateFromJS because in my controller I am specifically returning Json(viewModel).
Cleaned up my initial code/question to match the demo.
I guess Response is reserved, when I change "Response" to "resp", everything went fine. See http://jsfiddle.net/BBzVm/
Should't you use ko.mapping.updateFromJSON on your success event? Chapter Working with JSON strings on Knockout Mapping site says:
If your Ajax call returns a JSON string (and does not deserialize it into a JavaScript object), then you can use the functions ko.mapping.fromJSON and ko.mapping.updateFromJSON to create and update your view model instead.

Load dynamic list of elements AFTER FINISHED loading of several form elements

I have...
a dynamic populated select box
several input boxes
a submit button
form fields are loaded initially using cookies
several dynamic populated divs
I want...
start loading the content of my DIVs after all FORM elements have been loaded completely (= filled with data, select boxes are populated)
Sample code:
<script type="text/javascript">
$(document).ready(function() {
// Populate <select>
var options ='';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + i + '">' + i + '</option>';
}
$("select#myid").html(options);
})
...
</script>
<form>
<select id="myselect></select>
<input id="mytext" type="text" value="" />
<input type="submit" value="Search" />
</form>
<% foreach( MyElement element in MyListing) { %>
<div>
<script type="text/javascript">
$(document).ready(function() {
DoSomething($(select#myid).val());
})
</script>
</div>
<% } %>
Any help is very appreciated.
Edited for the extra information:
jQuery(function($) { // note that this is equivalent to $(document).load()
// if we are here, then all your page and form elements have loaded.
// Populate <select> as per your code above
$('div').each(function(index) { // perhaps give them a class?
$(this).load(<<someURL>>);
// it's not clear from your question how you intend to get the
// dynamic content, ie: what url to use?
});
});

How to return Nested PartialViews (including their javascript) from an AJAX call in ASP.Net MVC

I have created a treeview of Categories using nested partial views:
my Index page (that displays the treeview):
<div>
Category Menu:
<input type="button" value="1" name='selectCat_btn' />
<input type="button" value="2" name='selectCat_btn' />
</div>
<!-- Treeview -->
<% Html.RenderPartial("ItemCats_UL", Model); %>
<div id="CatSelectorOutput">
</div>
ItemCats_UL:
<div>
<ul id="catsTree">
<% Html.RenderPartial("ItemCats_LI", Model); %>
</ul>
</div>
<script type="text/javascript" >
$(document).ready(function() {
$("#catsTree").treeview();
</script>
ItemCats_LI:
<%foreach (ItemCategory itemCat in Model)
{ %>
<li>
<%= itemCat.Name %>
<%if (itemCat.Children != null && itemCat.Children.Count() > 0)
{ %>
<ul>
<% Html.RenderPartial("ItemCats_LI", itemCat.Children); %>
</ul>
<%} %>
</li>
<%} %>
Now this treeview works perfectly when I return the basic View("Index", Model) from my controllers Index action on page load.
The trouble comes when I want to change the Categories Model displayed in my Treeview (the nested partialViews) from an AJAX call...
For example: I click one the 'Cats2' button and the page should display Categories with ParentID of 2 in the Treeview. I attempted this by returning a JsonResult of the html of the ItemCats_UL PartialView (using a RenderPartialToString method found here) from my Controller Action. As some of you might know Javascript won't run in your partial view when you use an AJAX form to return a PartialViewResult, and I need Javascript in my Treeview which is why I'm using the RenderPartialToString.
The category select button click handler:
<script type="text/javascript">
$("[name='selectCat_btn']").click(function() {
var CID = $(this).attr('value');
$.ajax({
type: "POST",
url: "SelectCat",
dataType: "json",
data: { "CID": CID },
success: function(result) { $("#CatSelectorOutput").html(result.output); }
});
return false;
});
</script>
My Controller Action:
[AcceptVerbs(HttpVerbs.Post)]
[UrlRoute(Name = "SelectCat", Path = "selectCat")]
public ActionResult SelectCat(int CID)
{
IQueryable<ItemCategory> cats;
cats = ItemRepo.GetItemCats().WithCID(CID);
JsonResult result = null;
result = new JsonResult
{
Data = new
{
success = true,
output =
Helpers.RenderHelper
.RenderPartialToString("~/Views/Admin/AdminItemCatsUL.ascx",
cats)
}
};
return result;
}
The result:
The ItemCats_UL partialView displays! BUT the nested PartialViews (ItemCats_LI) don't!
Error I receive when I step through the markup in the ItemCats_UL.ascx and hover over the 'Html' part of the following code:
<ul id="catsTree">
<% Html.RenderPartial("ItemCats_LI", Model); %>
</ul>
Value cannot be null.
Parameter name: viewContext
Html = 'Html' threw an exception of type 'System.ArgumentNullException'
I'm wondering if there's a clever guy out there who can extend the RenderPartialToString method to include nested partialviews? Or am I missing something simple?
You need to hook the newly returned HTML / JavaScript back into the DOM upon loading it.
I'm sure there are lots of ways to do this, but I found a nice jQuery add-on called LiveQuery (link)
that helps me do it.
To make it work in your case, you'd set up a jQuery document.ready function in the parent page that looks something like this:
$("#catsTree").livequery(function () { this.treeview(); }, function () { /* code to destroy the treeview here */ });

Resources