I have 2 Telerik DatePicker's that I am using to filter my model by. However the problem I am having is on the action call for the partial view, both dates are null. I used the alert that is commented out to ensure that a date is actually being registered which it is. So I believe the problem has to do with the post back function .
The View:
<script type="text/javascript">
function filterChange() {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var startValue = $('#filterStart').data('tDatePicker').value();
var endValue = $('#filterEnd').data('tDatePicker').value();
//alert('Index: ' + startValue + ',' + endValue);
$.get('#Url.Action("DashboardPartial")',
{ start: startValue, end: endValue
}, function (data) {
$("#target").html(data);
});
}
</script>
<div style="width: 100%; height: 100%">
<fieldset>
<legend>Filters</legend>
<div>
#using (Html.BeginForm())
{
<div class="Filter-Div">
#Html.Telerik().DatePicker().Name("filterStart").Value((DateTime)#ViewBag.StartDate).ClientEvents(events => events.OnChange("filterChange"))
</div>
<div class="Filter-Div">
#Html.Telerik().DatePicker().Name("filterEnd").Value((DateTime)#ViewBag.EndDate).ClientEvents(events => events.OnChange("filterChange")).TodayButton()
</div>
}
</div>
</fieldset>
#(Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("telerik.common.js")
.Add("telerik.tabstrip.min.js")
.Add("telerik.calendar.min.js"))
.jQuery(false))
<div id="target">
#{ Html.RenderPartial("DashboardPartial"); }
</div>
The Controller
[OutputCache(Duration=5)]
public PartialViewResult DashboardPartial( DateTime? start, DateTime? end)
{
db = new DashboardEntities();
ViewBag.StartDate = start;
ViewBag.EndDate = end;
var job = db.Job.where(Job=>Job.startDate > start && Job.endDate < end);
return PartialView(prj);
}
Are the startValue and endValue variables in your Javascript code of type Date? If that's the case, convert them to string like this:
<script type="text/javascript">
function filterChange() {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var startValue = $('#filterStart').data('tDatePicker').value().toLocaleString();
var endValue = $('#filterEnd').data('tDatePicker').value().toLocaleString();
//alert('Index: ' + startValue + ',' + endValue);
$.get('#Url.Action("DashboardPartial")',
{ start: startValue, end: endValue
}, function (data) {
$("#target").html(data);
});
}
</script>
Also, in your form, remove '#' before ViewBag.StartDate and ViewBag.EndDate:
<div class="Filter-Div">
#Html.Telerik().DatePicker().Name("filterStart").Value((DateTime)ViewBag.StartDate).ClientEvents(events => events.OnChange("filterChange"))
</div>
<div class="Filter-Div">
#Html.Telerik().DatePicker().Name("filterEnd").Value((DateTime)ViewBag.EndDate).ClientEvents(events => events.OnChange("filterChange")).TodayButton()
</div>
Related
How to call c# function in cshtml(razor page) from inside js function
this is cshtml code
#model TreeWithUnity.Pages.Tree.TreeExampleModel
<form method="post">
<input type="checkbox"
onclick="requestMyAction('#Model.tree_List[0].board_id', this.checked,
'loader-#Model.tree_List[0].dataName',#Model.tree_List[0]);" />
<div class="loader" style="display: none;" id="loader-#Model.tree_List[0].dataName">#Model.tree_List[0]
</div>
</form>
#section scripts{
<script type="text/javascript">
function requestMyAction(itemId, isChecked, loaderId,tn)
{
document.getElementById(loaderId).style.display = "inline-block";
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
document.getElementById(loaderId).style.display = "none";
if (this.status === 200) {
document.getElementById(loaderId).style.display = "none";
}
}
};
var url = '#Url.Page("./TreeExample", "MyAction")';
xhr.open('POST', url);
xhr.setRequestHeader('RequestVerificationToken', '#Xsrf.GetAndStoreTokens(Model.HttpContext).RequestToken');
var data = new FormData();
data.append('itemName', itemId);
data.append('deploy', isChecked);
xhr.send(data);
#UpdateRecursiveData(tn)
}
}
</script>
}
#{
void UpdateRecursiveData(TreeWithUnity.Model.TreeNode tn)
{
if(tn.deployment)
{
<input type="checkbox"
onclick="requestMyAction('#tn.board_id', this.checked, 'loader-#tn.dataName');" />
<div class="loader" style="display: none;" id="loader-#tn.dataName">#tn.dataName</div>
<br />
for (int i = 0; i < tn.subTreeNodes.Count; i++)
RecursiveData(tn.subTreeNodes[i]);
}
}
}
#UpdateRecursiveData(tn) is not work
is it able to work in js c#func ?
I don't know how to implement this
UpdateRecursiveData should be executed later than MyAction of Tree Example. Is this possible?
how to call UpdateRecursiveData
public async Task<IActionResult> OnPostMyAction(string itemName,bool deploy)
{
if (TempData["TreeData"] != null)
tree_List = TempData.Get<List<TreeNode>>("TreeData");
TreeNode upTree=null;
foreach (var item in tree_List)
{
if (item.board_id == itemName)
{
upTree = item;
item.deployment = deploy;
}
}
if (deploy&&upTree.loadOn==false)
{
if(upTree!=null)
upTree.deployment = true;
IQueryable<tbl_tree> iqueryTree;
iqueryTree = _context.tbl_tree.Where(x => x.upcode == itemName);
var datas =await iqueryTree.ToListAsync();
for (int i = 0; i < datas.Count; i++)
{
TreeNode treeNode = new TreeNode(datas[i].name);
treeNode.board_id = datas[i].icd11;
tree_List.Add(treeNode);
}
TempData.Set("TreeData", tree_List);
}
return new OkResult();
}
Firstly,you cannot pass a js variable to c# function,you can try to use ajax to call c# handler,and handler returns html code,then put the html code to somewhere of the view.Here is a demo:
<form method="post">
</form>
<div id="data"></div>
#section scripts{
<script type="text/javascript">
$(function () {
$.ajax({
type: "POST",
url: '?handler=UpdateRecursiveData',
headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
data: {id:1},
success: function (data) {
document.getElementById("data").innerHTML = data;
},
error: function (result) {
alert("fail");
}
})
})
</script>
}
handler:
public JsonResult OnPostUpdateRecursiveData(int id)
{
return new JsonResult("<div>id="+id+"</div>");
}
result:
I want to check unchecked checkbox in based on data-id.
On drop down change i want to check unchecked checkbox in jstree.
I am Providing MY controller and Ajax Method bellow.
This is my jstree view.
Here is My Controller :
[HttpPost]
public ActionResult GetSingleUser(int id)
{
MachineShopDBEntities DB = new MachineShopDBEntities();
var SPresult = DB.GetSingleUser(id).FirstOrDefault();
return Json(SPresult);
}
Here is my Script:
$("#UserSelect").change(function () {
$.post("/MenuMaster/GetSingleUser?id=" + $(this).val(),
function (data, status) {
var databaseString = data.MenuEnable;
for (i = 0; i <= databaseString.length; i++) {
if (databaseString.substring(i, i + 1) == "1") {
$('.jstree-container-ul li[data-id=' + (i + 1) + ']').find('.jstree-anchor').addClass('jstree-clicked');
}
}
});
});
Here I created demo for you.
Make changes according to code snippet below
jQuery(function ($) {
$('.menux').jstree({
"core": { "check_callback": false },
"checkbox": { "keep_selected_style": false, "three_state": false, "tie_selection": false, "whole_node": false, },
"plugins": ["checkbox"]
}).bind("ready.jstree", function (event, data) {
$(this).jstree("open_all");
}).on("check_node.jstree uncheck_node.jstree", function (e, data) {
var currentNode = data.node;
var parent_node = $(".menux").jstree().get_node(currentNode).parents;
if (data.node.state.checked)
$(".menux").jstree().check_node(parent_node[0]);
else
$(".menux").jstree().uncheck_node(parent_node[0]);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.css" rel="stylesheet" />
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.5/jstree.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
<div class="menux">
<ul>
<li>
Root node 1
<ul>
<li data-id="1"><a href="#" >Child node 1</a> </li>
<li data-id="2"><a href="#" >Child node 2</a></li>
<li data-id="3"><a href="#" >Child node 3</a></li>
<li data-id="4"><a href="#" >Child node 4</a></li>
<li data-id="24"><a href="#" >Child node 24</a></li>
</ul>
</li>
</ul>
</div>
Edit:
First make sure you have disable three-state while initializing jsTree as mentioned in above code snippet.
Try to implement above $('.menux li').each function in your code.
The below code is only sample to where you have to put this $('.menux li').each.
$("#UserSelect").change(function () {
$.post("/MenuMaster/GetSingleUser?id=" + $(this).val(),
function (data, status) {
var databaseString = data.MenuEnable;
$('.menux li').each(function (index, value) {
var node = $(".menux").jstree().get_node(this.id);
var id = node.data.id;
for (i = 0; i <= databaseString.length; i++) {
if (databaseString.substring(i, i + 1) == "1") {
if ((i + 1) == id) {
$(".menux").jstree().check_node(this.id);
}
}
}
});
});
});
If you got any error like jsTree is not a function then you can replace above $('.menux li').each function with this
$('.menux li').each(function (index, value) {
for (i = 0; i <= databaseString.length; i++) {
if (databaseString.substring(i, i + 1) == "1") {
var dataid = $('#' + this.id).data('id');
if ((i + 1) == dataid) {
$('#' + this.id).find('.jstree-anchor').addClass('jstree-clicked');
}
}
}
});
I am currently working on a form using asp.net-mvc 4 that submits an object with a variable number of sub-objects stored in an IList.
I'm running in to an issue with validation messages being attached to the incorrect object in the IList if an error is returned. If the first object in the list is deleted and the second object (that then becomes the first) has errors in it, the incorrect object does not get the correct validation result on page reload. The object in the list that had an index of 3 is given an index of 2 when the error is returned, which also changes the previous (possibly correct) selections at the same time.
Is there any way to change which objects in a list the previous validation errors get attached to?
Edit: The validation messages are in the correct location because the "ValidationIndex" is working, the highlighting is where I'm having the issue.
I've tried adding in a "ValidationIndex" to the objects in the list to send the validation errors to the correct place. This has worked for the error message but the incorrect object is still having its fields highlighted and changed.
Removing the ability to delete anything except the last object would obviously be one way to solve this issue, but I'm really hoping to find a way to keep the functionality. I'd also like to avoid having to make an http request every time a new box is added if at all possible.
Here is an imgur album showing the issue:
http://imgur.com/a/borWG
Here is an example of the code I'm using:
The container class:
public class TestProduct : Product
{
public IList<TestItem> TItems { get; set; }
public TestProduct()
{
TItems = new List<TestItem>();
}
}
The class in the list:
public class TestItem : IValidatableObject
{
[Display(Name = "Select 1")]
public string select1 { get; set; }
[Display(Name = "Select 2")]
public string select2 { get; set; }
// Added to try and Identify where the validation errors need to go
public int ValidationIndex { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (select1 == null)
{
yield return new ValidationResult("Required", new string[] { "select1" });
}
if (select2 == null)
{
yield return new ValidationResult("Required", new string[] { "select2" });
}
if (select1 == select2)
{
yield return new ValidationResult("The options cannot be the same", new string[] { "select2", "select1" });
}
}
}
The View:
#model TestProduct
#{
List<SelectListItem> selectOptions = new List<SelectListItem>()
{
new SelectListItem { Text = "Choose...", Value = "" },
new SelectListItem { Text = "Option 1", Value = "o1" },
new SelectListItem { Text = "Option 2", Value = "o2" },
new SelectListItem { Text = "Option 3", Value = "o3" },
new SelectListItem { Text = "Option 4", Value = "o4" }
};
}
<script type="text/javascript">
$(document).ready(function () {
var itemContainer = $('#items');
var i = $('#items .item-option').length;
$('#addItem').on("click", function (e) {
if ($('#items .item-option').length <= 15) {
var newField = '<fieldset class="item-option"> ' +
'<legend>Item ' + (i + 1) + '</legend>' +
'<input type="hidden" name="TItems.Index" value="' + i + '" /> ' +
'<input type="hidden" name="TItems[' + i + '].ValidationIndex" value="' + i + '" /> ' +
'<div class="line"> ' +
'<div> ' +
'<div class="label"><label for="select1-' + i + '">#Html.DisplayNameFor(model => model.TItems[0].select1)</label></div> ' +
'<div> ' +
'<select id="select1-' + i + '" name="TItems[' + i + '].select1"> ' +
#foreach (SelectListItem so in selectOptions)
{
<text>
'<option value="#so.Value">#so.Text</option> ' +
</text>
}
'</select> ' +
'</div> ' +
'</div> ' +
'<div> ' +
'<div class="label"><label for="select2-' + i + '">#Html.DisplayNameFor(model => model.TItems[0].select2)</label></div> ' +
'<div>' +
'<select id="select2-' + i + '" name="TItems[' + i + '].select2"> ' +
#foreach (SelectListItem so2 in selectOptions)
{
<text>
'<option value="#so2.Value">#so2.Text</option> ' +
</text>
}
'</select> ' +
'</div> ' +
'</div> ' +
'</div> ' +
'<div class="pos-rb"><button class="remItem smalltext">Remove</button></div> ' +
'</fieldset>';
itemContainer.append(newField);
$('.remItem:hidden').show();
i++;
}
e.preventDefault();
});
$('#items').on("click", '.remItem', function (e) {
var n = $('#items .item-option').length;
if (n >= 2) {
$(this).closest('.item-option').remove();
}
if (n == 2) {
$('.remItem').hide();
}
e.preventDefault();
});
});
</script>
<h3>Test Product</h3>
<div class="indented">
<div id="items" class="items question">
#if (Model.TItems.Count > 0)
{
for (int i = 0; i < Model.TItems.Count; i++)
{
int validationIndex = Model.TItems[i].ValidationIndex;
<text>
<fieldset class="item-option">
<legend>Item #(i + 1)</legend>
<input type="hidden" name="TItems.Index" value="#i" />
<input type="hidden" name="TItems[#i].ValidationIndex" value="#i" />
<div class="line">
<div>
<div class="label">#Html.LabelFor(model => model.TItems[i].select1)</div>
<div>
#Html.DropDownListFor(model => model.TItems[i].select1, new SelectList(selectOptions, "Value", "Text", Model.TItems[i].select1))<br />
#Html.ValidationMessageFor(model => model.TItems[validationIndex].select1)
</div>
</div>
<div>
<div class="label">#Html.LabelFor(model => model.TItems[i].select2)</div>
<div>
#Html.DropDownListFor(model => model.TItems[i].select2, new SelectList(selectOptions, "Value", "Text", Model.TItems[i].select2))<br />
#Html.ValidationMessageFor(model => model.TItems[validationIndex].select2)
</div>
</div>
</div>
<div class="pos-rb">
<button class="remItem smalltext" #if (Model.TItems.Count == 1) { <text> style="display: none;" </text> }>Remove</button>
</div>
</fieldset>
</text>
}
}
else
{
<text>
<fieldset class="item-option">
<legend>Item 1</legend>
<input type="hidden" name="TItems.Index" value="0" />
<input type="hidden" name="TItems[0].ValidationIndex" value="0" />
<div class="line">
<div>
<div class="label">#Html.LabelFor(model => model.TItems[0].select1)</div>
<div>
#Html.DropDownListFor(model => model.TItems[0].select1, new SelectList(selectOptions, "Value", "Text"))
</div>
</div>
<div>
<div class="label">#Html.LabelFor(model => model.TItems[0].select2)</div>
<div>
#Html.DropDownListFor(model => model.TItems[0].select2, new SelectList(selectOptions, "Value", "Text"))
</div>
</div>
</div>
<div class="pos-rb"><button class="remItem smalltext" style="display: none;">Remove</button></div>
</fieldset>
</text>
}
</div>
<button id="addItem" class="smalltext" style="margin-left: 2em;">Add Another Item</button>
<br />
<div style="margin: 1em;"><input type="submit" value="Calculate" /></div>
</div>
Edit:
I figured out a rather messy work around using JavaScript. Every time an item is removed it goes through and replaces all the names, ids, and for fields for all the inputs and their labels in the form. It's not exactly elegant, but it's working so far...
Here's the new remove item event handler:
$('#items').on("click", ".remItem", function (e) {
var n = $("#items .item-option").length;
if (n >= 2) {
$(this).closest(".item-option").remove();
}
if (n == 2) {
$(".remItem").hide();
}
$("#items").find(".item-option").each(function (index) {
$(this).find(".item-index").val(index);
$(this).find("select, input, textarea").each(function () {
var name1 = $(this).attr('name');
if (name1 != null) {
var name2 = name1.replace(/TItems\[\d+\]/, "TItems[" + index + "]");
$(this).attr("name", name2);
}
var id1 = $(this).attr("id");
if (id1 != null) {
var id2 = id1.replace(/_\d+__/, "_" + index + "__");
$(this).attr("id", id2);
}
});
$(this).find("label").each(function () {
var for1 = $(this).attr("for");
if (for1 != null) {
var for2 = for1.replace(/_\d+__/, "_" + index + "__");
$(this).attr("for", for2);
}
});
$(this).find("legend").html("Item " + (index+1));
});
i--;
e.preventDefault();
});
I have a form on which I am adding rows dynamically using Jquery.
Please take a look: DEMO
Now I want to save the data of all rows that has been added in my database using Jquery Ajax call on click event of SAVE button. The point where I am stuck is .. I am not sure how should I extract data of all rows and send it to the webmethod. I mean had it been c# I could have used a DataTable to store data of all rows before sending it to DataBase. I think I should create a string seperated by commas and pipe with data of each row and send it to webmethod. I am not sure if its the right approach and also how this is to be done (ie. creating such a string).
HTML
<table id="field">
<tbody>
<tr id="row1" class="row">
<td> <span class='num'>1</span></td>
<td><input type="text" /></td>
<td><select class="myDropDownLisTId"> <input type="text" class="datepicker" /></select></td><td>
<input type="submit"></input>
</td>
</tr>
</tbody>
</table>
<button type="button" id="addField">Add Field</button>
<button type="button" id="deleteField">Delete Field</button>
<button type="button" id="btnsave">SAVE</button>
2 suggestions:
To keep it as close as what you already have, you could just enclose your table in a form tag, and then you could just submit the form (use something like the jQuery Form plugin to submit it via Ajax). The trickiest part will be to bind that data to action parameters. You may be able to receive it in the form of an array, or you could default to looping through properties of the Request.Form variable. Make sure you generate proper names for those fields.
I think the cleanest way to do it would be to have a JavaScript object holding your values, and having the table generated from that object, with 2-way bindings. Something like KnockoutJS would suit your needs. That way the user enters the data in the table and you'll have it ready to be Json-serialized and sent to the server. Here's a quick example I made.
I wouldn't recommend that approach, but if you wanted to create your own string, you could do something along those lines:
$("#btnsave").click(function () {
var result = "";
$("#field tr").each(function (iRow, row) {
$("td input", row).each(function (iField, field) {
result += $(field).val() + ",";
});
result = result + "|";
});
alert(result);
});
You will have problems if the users types in a comma. That why we use well known serialization formats.
use ajax call on save button event...
like this
$(document).ready(function () {
$('#reqinfo').click(function () {
// debugger;
var emailto = document.getElementById("emailid").value;
if (emailto != "") {
$.ajax({
type: "GET",
url: "/EmailService1.svc/EmailService1/emaildata?Email=" + emailto,
// data: dat,
Accept: 'application/json',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
// debugger;
},
error: function (result) {
// debugger;
}
});
}
else {
//your validation message goes here
return false;
}
});
});
and add you all data in quesry string and transfer it to webservice..
url: "/EmailService1.svc/EmailService1/emaildata?Email=" + emailto + "data1=" + data1,
<script type="text/javascript">
var _autoComplCounter = 0;
function initialize3(_id) {
var input_TO = document.getElementById(_id);
var options2 = { componentRestrictions: { country: 'ID' } };
new google.maps.places.Autocomplete(input_TO, options2);
}
google.maps.event.addDomListener(window, 'load', initialize3);
function incrementValue() {
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value++;
document.getElementById('number').value = value;
}
function GetDynamicTextBox(value) {
var _id = "AutoCompl" + _autoComplCounter;
_autoComplCounter++;
return '<input name = "DynamicTextBox" type="text" id="' + _id + '" value = "' + value + '" onkeypress = "calcRoute();" />' +
'<input type="button" class="superbutton orange" value="Remove" onclick = "RemoveTextBox(this)" />'
}
function AddTextBox() {
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value++;
if (document.getElementById('number').value < 3) {
document.getElementById('number').value = value;
var div = document.createElement('DIV');
var _id = "AutoCompl" + _autoComplCounter;
_autoComplCounter++;
var ht = '<input name = "DynamicTextBox" type="text" id="' + _id + '" value = "" onkeypress = "calcRoute();" class="clsgetids" for-action="' + _id + '" />' +
'<input type="button" class="superbutton orange" value="#Resources.SearchOfferRides.btnRemove" onclick = "RemoveTextBox(this); calcRoute();" />';
div.innerHTML = ht;
document.getElementById("TextBoxContainer").appendChild(div);
setTimeout(function () {
var input_TO = document.getElementById(_id);
var options2 = { componentRestrictions: { country: 'ID' } };
new google.maps.places.Autocomplete(input_TO, options2);
}, 100);
document.getElementById("TextBoxContainer").appendChild(div);
}
else {
alert('Enter only 3 stop point. !!');
}
}
function RemoveTextBox(div) {
//calcStopPointRoute();
var value = parseInt(document.getElementById('number').value, 10);
value = isNaN(value) ? 0 : value;
value--;
document.getElementById('number').value = value;
document.getElementById("TextBoxContainer").removeChild(div.parentNode);
}
function RecreateDynamicTextboxes() {
var values = eval('<%=Values%>');
if (values != null) {
var html = "";
for (var i = 0; i < values.length; i++) {
html += "<div>" + GetDynamicTextBox(values[i]) + "</div>";
}
document.getElementById("TextBoxContainer").innerHTML = html;
}
}
// window.onload = RecreateDynamicTextboxes;
</script>
And get the value from textbox:
#region stop point
string[] textboxValues = Request.Form.GetValues("DynamicTextBox");
if (textboxValues != null)
{
for (Int32 i = 0; i < textboxValues.Length; i++)
{
if (textboxValues.Length == 1)
{
model.OptionalRoot = textboxValues[0].ToString();
}
else if (textboxValues.Length == 2)
{
model.OptionalRoot = textboxValues[0].ToString();
model.OptionalRoot2 = textboxValues[1].ToString();
}
else if (textboxValues.Length == 3)
{
model.OptionalRoot = textboxValues[0].ToString();
model.OptionalRoot2 = textboxValues[1].ToString();
model.OptionalRoot3 = textboxValues[2].ToString();
}
else
{
model.OptionalRoot = "";
model.OptionalRoot2 = "";
model.OptionalRoot3 = "";
}
}
}
#endregion
Short answer:
DataTable equivalent in javascript is Array of custom object (not exact equivalent but we can say that)
or
you roll your own DataTable js class which will have all the functions and properties supported by DataTable class in .NET
Long answer:
on client side(aspx)
you define a class MyClass and store all your values in array of objects of that class
and then pass that array after stingyfying it to web method
JSON.stringify(myArray);
on the server side(codebehind)
you just define the web method to accept a list of objects List<MyClass>
PS: When calling web method, Asp.net automatically converts json array into List<Object> or Object[]
Loooong answer (WHOLE Solution)
Page aspx:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="App_Themes/SeaBlue/jquery-ui-1.9.2.custom.css" rel="stylesheet" type="text/css" />
<script src="Scripts/jquery-1.8.3.js" type="text/javascript"></script>
<script src="Scripts/jquery-ui-1.9.2.custom.min.js" type="text/javascript"></script>
<script src="Scripts/json2.js" type="text/javascript"></script>
<script type="text/javascript">
function MyClass(title,option,date) {
this.Title = title;
this.Option = option;
this.Date = date;
}
function GetJsonData() {
var myCollection = new Array();
$(".row").each(function () {
var curRow = $(this);
var title = curRow.find(".title").val();
var option = curRow.find(".myDropDownLisTId").val();
var date = curRow.find(".datepicker").val();
var myObj = new MyClass(title, option, date);
myCollection.push(myObj);
});
return JSON.stringify(myCollection);
}
function SubmitData() {
var data = GetJsonData();
$.ajax({
url: "testForm.aspx/PostData",
data: "{ 'myCollection': " + data + " }",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function () {
alert("Success");
}
});
}
$(document).ready(function () {
filldd();
CreateDP();
var rowstring = "<tr class='row'><td class='number'></td><td><input type='text' class='title'/></td><td><select class='myDropDownLisTId'/><input type='text' class='datepicker'/></td><td><input type='submit'></input></td></tr>";
$("#addField").click(function (event) {
$("#field tbody").append(rowstring);
filldd();
CreateDP();
if ($("td").hasClass("number")) {
var i = parseInt($(".num:last").text()) + 1;
$('.row').last().attr("id", "row" + i);
$($("<span class='num'> " + i + " </span>")).appendTo($(".number")).closest("td").removeClass('number');
}
event.preventDefault();
});
$("#deleteField").click(function (event) {
var lengthRow = $("#field tbody tr").length;
if (lengthRow > 1)
$("#field tbody tr:last").remove();
event.preventDefault();
});
$("#btnsave").click(function () {
SubmitData();
});
});
function filldd() {
var data = [
{ id: '0', name: 'test 0' },
{ id: '1', name: 'test 1' },
{ id: '2', name: 'test 2' },
{ id: '3', name: 'test 3' },
{ id: '4', name: 'test 4' },
];
for (i = 0; i < data.length; i++) {
$(".myDropDownLisTId").last().append(
$('<option />', {
'value': data[i].id,
'name': data[i].name,
'text': data[i].name
})
);
}
}
function CreateDP() {
$(".datepicker").last().datepicker();
}
$(document).on('click', 'input[type="submit"]', function () {
alert($(this).closest('tr')[0].sectionRowIndex);
alert($(this).closest('tr').find('.myDropDownLisTId').val());
});
</script>
</head>
<body>
<form id="frmMain" runat="server">
<table id="field">
<tbody>
<tr id="row1" class="row">
<td>
<span class='num'>1</span>
</td>
<td>
<input type="text" class="title"/>
</td>
<td>
<select class="myDropDownLisTId">
</select>
<input type="text" class="datepicker" />
</td>
<td>
<input type="submit"></input>
</td>
</tr>
</tbody>
</table>
<button type="button" id="addField">
Add Field</button>
<button type="button" id="deleteField">
Delete Field</button>
<button type="button" id="btnsave">
SAVE</button>
</form>
</body>
</html>
CodeBehind:
public partial class testForm : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static void PostData(List<MyClass> myCollection)
{
Console.WriteLine(myCollection.Count);
}
}
public class MyClass
{
string title;
public string Title
{
get { return title; }
set { title = value; }
}
string option;
public string Option
{
get { return option; }
set { option = value; }
}
string date;
public string Date
{
get { return date; }
set { date = value; }
}
}
Hope this helps
References:
Json2.js file
stringify method
define a class in js
I have a server control as below:
[DefaultProperty("ContentKey")]
[ToolboxData("<{0}:ContentRating runat=server></{0}:ContentRating>")]
public class ContentRating : WebControl
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string ContentKey
{
get
{
String s = (String)ViewState["ContentKey"];
return ((s == null) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["ContentKey"] = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
StringBuilder builder = new StringBuilder(#"<div id=""divContentRating"">
<div id=""divAskForRating"">
#Question
<br />
<a id=""likeIcon""><img src=""~/Content/Images/like.jpg""/></a>
<a id=""neutralIcon""><img src=""~/Content/Images/neutral.jpg""/></a>
<a id=""unlikeIcon""><img src=""~/Content/Images/unlike.jpg""/></a>
</div>
<div id=""divPositiveRating"">
<div>
<img src=""~/Content/Images/like.jpg""/> #PositiveAnswerMessage <br />
Güncelle
</div>
</div>
<div id=""divNegativeRating"">
<div>
<img src=""~/Content/Images/unlike.jpg""/> #NegativeAnswerMessage <br />
Güncelle
</div>
</div>
<div id=""divNeutralRating"">
<div>
<img src=""~/Content/Images/neutral.jpg""/> #NeutralAnswerMessage <br />
Güncelle
</div>
</div>
<input type=""hidden"" id=""HasRated"" value=""False"">
<input type=""hidden"" id=""Rate"" value=""Rate"">
<input type=""hidden"" id=""ContentKey"" value=""#ContentKey"">
<input type=""hidden"" id=""RatingId"" value=""RatingId"">
<script type=""text/javascript"">
$(document).ready(function () {
var protocol = location.protocol;
var host = window.location.host;
if ($(""#HasRated"").val() == """"True"")
{
var rate = $(""#Rate"").val();
if (rate == 1) {
setPositiveRatedView();
}
else if (rate == 0) {
setNeutralRatedView();
}
else if (rate == -1) {
setNegativeRatedView();
}
else {
setNotRatedView();
}
}
else {
setNotRatedView();
}
$(""#likeIcon"").click(function () {
alert(""like"");
setPositiveRatedView();
ratePage(1, """");
});
$(""#neutralIcon"").click(function () {
alert(""neutral"");
setNeutralRatedView();
ratePage(0, """");
});
$(""#unlikeIcon"").click(function () {
alert(""unlike"");
setNegativeRatedView();
//mkMPopClc('NegativeRatingReason', 200, 300, 0, 0);
});
$("".updateRate"").click(function () {
setNotRatedView();
});
// $('.clsStl').click(function () {
// ratePage(-1, """");
// $('.mkMPop').fadeOut();
// });
//
// $('#ShareComment').click(function () {
// ratePage(-1, $(""#Comment"").val());
// $('.mkMPop').fadeOut();
// });
function setNotRatedView() {
$(""#divNeutralRating"").fadeOut();
$(""#divPositiveRating"").fadeOut();
$(""#divAskForRating"").fadeIn();
$(""#divNegativeRating"").fadeOut();
}
function setPositiveRatedView()
{
$(""#divNegativeRating"").fadeOut();
$(""#divNeutralRating"").fadeOut();
$(""#divAskForRating"").fadeOut();
$(""#divPositiveRating"").fadeIn();
}
function setNegativeRatedView() {
$(""#divNeutralRating"").fadeOut();
$(""#divPositiveRating"").fadeOut();
$(""#divAskForRating"").fadeOut();
$(""#divNegativeRating"").fadeIn();
}
function setNeutralRatedView() {
$(""#divNegativeRating"").fadeOut();
$(""#divPositiveRating"").fadeOut();
$(""#divAskForRating"").fadeOut();
$(""#divNeutralRating"").fadeIn();
}
function ratePage(rating, comment)
{
//alert(rating + """" """" + comment);
var contentKey = $(""#ContentKey"").val();
var hasRated = $(""#HasRated"").val();
var ratingId = $(""#RatingId"").val();
$.getJSON(protocol + '//' + host + '/tr/Rating/RatePage?contentKey=' + contentKey + '&rating=' + rating + '&ratingUpdate=' + hasRated + '&ratingId=' + ratingId + '&comment=' + comment, function (data) {
$(""#HasRated"").val(data.HasRated);
$(""#Rate"").val(data.Rate);
$(""#ContentKey"").val(data.ContentKey);
$(""#RatingId"").val(data.RatingId);
$(""#Comment"").val(data.Comment);
});
}
});
</script>
</div>");
builder.Replace("#ContentKey", this.ContentKey);
output.Write(builder);
}
}
When I add my control to my web page, I see that control is rendering as I am expecting but the jquery scripts doesn't work. Is it wrong to keep scripting code in a server control? What can I do to solve this problem?
if ($(""#HasRated"").val() == """"True"")
I think you have too many quote characters there...