Passing data from Javascript MVC controller - javascript

I'm really new to jQuery and Charts. This is my script, it works fine. It gives me the id of the checkboxes selected by the user. I have a Chart action in my controller which also works fine, but it creates a chart using all my values. I want it to create a chart based on the selected values that are in my script. I don't know how to pass the selected values to my controller.
var checkboxes = $("input[type='checkbox']");
$(function ()
{
function getValueUsingClass() {
/* declare an checkbox array */
var chkArray = [];
/* look for all checkboes that have a class 'chk' attached to it and check if it was checked */
$(".chk:checked").each(function () {
chkArray.push($(this).val());
});
/* we join the array separated by the comma */
var selected = chkArray.join(",") + ",";
/* check if there is selected checkboxes, by default the length is 1 as it contains one single comma */
if (selected.length > 1)
{
alert("You have selected " + selected);
}
else
{
alert("Please check at least one of the checkbox");
}
}
$("#Charter").click(function () {
getValueUsingClass();
});
});

Return the data you want in your js function after populating the variable using return selected; then send it back by posting a form or using ajax.
Bind your data to an element on your View page, for example:
<input name="foo" id="yourId" value="bar" />
then modify it's value:
$('#foo').val(getValueUsingClass());
and pass the model back by posting your form to your controller.
If you wish to send data to your controller async then you can look into Ajax.

You can use ajax to call your controller method within getValueUsingClass().
It would probably look something like this:
$.ajax({
url: "/YourControllerName/Chart",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: { arr: chkArray },
success: function () {
// do things upon success
},
error: function () {
alert("Error!");
}
});
That is, providing your Controller action has a parameter named arr, because json maps chkArray to it once it is passed to the Controller.

Related

Can't access form elements with onload() in JavaScript

I'm putting together dependent drop-downs (Teacher -> Class -> Student) and am having issues with setting the initial state of the drop-downs. Here's the code:
edit_contract.html
{% load crispy_forms_tags %}
<div>
<form method="post" id="contractForm" novalidate
data-teachers-url="{% url 'wakemeup:ajax_load_teachers' %}"
data-classes-url="{% url 'wakemeup:ajax_load_classes' %}"
data-students-url="{% url 'wakemeup:ajax_load_students' %}"
>
{% crispy form %}
</form>
</div>
<script>
// Update class drop-down when teacher changes
$("#id_teacheruserid").change(function () {
update_classes($(this))
});
// Update students drop-down when class changes
$("#id_classid").change(function () {
update_students($(this))
});
function update_teachers() {
// Get form values
var url = $("#contractForm").attr("data-teachers-url");
var contractId = $(document.getElementById("id_contractid")).val();
$.ajax({ // initialize AJAX request
url: url,
data: {
'contractid': contractId
},
success: function (data) {
$("#id_teacheruserid").html(data); // Update "teacheruserid" field
}
})
update_classes(); // Update classes drop-down
};
function update_classes() {
// Get form values
var url = $("#contractForm").attr("data-classes-url");
var teacherUserId = $(document.getElementById("id_teacheruserid")).val();
var contractId = $(document.getElementById("id_contractid")).val();
$.ajax({ // initialize AJAX request
url: url,
data: {
'teacheruserid': teacherUserId,
'contractid': contractId
},
success: function (data) {
$("#id_classid").html(data); // Update "classid" field
}
})
update_students(); // Update students drop-down
};
function update_students() {
// Get form values
var url = $("#contractForm").attr("data-students-url");
var classId = $(document.getElementById("id_classid")).val();
var contractId = $(document.getElementById("id_contractid")).val();
$.ajax({ // initialize AJAX request
url: url,
data: {
'classid': classId,
'contractid': contractId
},
success: function (data) {
$("#id_partyuserinfo").html(data); // Update "partyuserinfo" field
}
})
};
window.onload = function() {
// Initial load of drop-down menus
update_teachers(); // Cascades to update_classes() and update_students()
};
</script>
Flow summary
update_teacher()
- update HTML (drop-down options) for "id_teacheruserid" field
update_classes()
- read value from "id_teacheruserid" field (undefined for initial load)
- update HTML (drop-down options) for "id_classid" field
update_students()
- read value from "id_classid" field (undefined for initial load)
- update HTML (drop-down options) for "id_partyuserinfo" field
The problem
The problem I'm seeing is that the script can't access the values in the form fields in the onload() call. For example, this line in update_classes():
var teacherUserId = $(document.getElementById("id_teacheruserid")).val();
I added an alert(teacherUserId) directly after this line. On initial page load, it returns undefined. However, when I select a different value from the teacher drop-down, the alert displays the expected value.
My guess is that in the initial onload(), the referenced field values/options (i.e. id_teacheruserid) have not been loaded or made available yet. The fields themselves exist, but return undefined values. Once this function completes, though, it seems they are then accessible and the menus behave as expected.
How can I run update_teachers() to do the initial load and have it access the form field values?
First of all you can use
$("#id_teacheruserid").val();
instead of
$(document.getElementById("id_teacheruserid"))
Second
you need to grab the option selected value from the dropdown
$("#id_teacheruserid").find(":selected").val()
to get the selected ID
Third, you need to call next drop down fill function on success callback
$.ajax({ // initialize AJAX request
url: url,
data: {
'contractid': contractId
},
success: function (data) {
$("#id_teacheruserid").html(data); // Update "teacheruserid" field
update_classes();
}
})

How to detect that my select form have been change by ajax success

I have two form input ( text and select form ).
The select form change by ajax success when user search the employee data.
Now, i want the other jquery function that can automatically detect when the select form have been change by ajax success and retrieve the new value of select form to use by other function to make new data in my input text.
my Search Employee Function
function search_personal_result(formObj, urlres, responseDIV, disable_data, modal_class,result_data)
{
disable_data=disable_data||false;
modal_class=modal_class||false;
result_data=result_data||false;
var loading = '<p>Loading ...</p>';
$.ajax({
url: site_url+'/'+urlres,
beforeSend: function(){
$(responseDIV).html(loading);
},
data: $(formObj).serialize(),
type: "post",
dataType: "html",
success: function(response){
//proceed data result here
if(result_data==false){
var obj = jQuery.parseJSON(response);
$.each(obj, function (index, value) {
if(result_data==false){
for(var j in value){
//My SELECT Form Changed here
$('#VCIDSBU').val('MY NEW VALUE');
}
}
});
}
},
error: function(){
alert("Terjadi kesalahan!");
},
});
}
If the user search the employee data using search_personal_result, my select form have been successfully changes.
Now that i need is, how to make the other jQuery function that can detect that my SELECT Form have been changed by search_personal_result
I have try using
$(function () {
$('#form_create_sp').on('change','SELECT#my_select_id',function(){
alert('it changes');
});
})
It can only detect when the user manually change the select form. but not working when the select form changed by search_personal_result
Thanks for all expert here
You could always do some sort of console.log("Success"); Function based on if it sent or not.

Adding an item to a dropdownlist which is in another partial view without refreshing the view

I am new to asp.net mvc and I am facing this issue with dropdownlist now.
Sorry if I am asking a stupid question.
I have a main View AbcView which is bound to a Controller AbcController which passes an AbcModel to the view.
I have 2 partial views inside this AbcView which are loaded on button clicks.
Inside the second partial view, I have this code :
#Html.DropDownListFor(model => Model.TrajectoryName, new SelectList(#Model.Trajectories, "Value", "Text"),
new { #class = "dropdown-leftandright", id = drpTrajectory" })
Inside the first partial view, I have some data which is being added to database on some button click like this :
function deleteAction(trajID) {
$.ajax({
type: "POST",
url: "/AbcView/DeleteAction",
data: JSON.stringify({ deleteTraj: trajID }),
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: function (data) {
// I want to update the drpTrajectory dropdownlist here
},
error: function (e) {
return "error";
}
});
}
My issue is I want to access the drpTrajectory in second partial view inside this function. I want to add some item to this particular drop down list.
I tried to access the dropdownlist by using $('#drpTrajectory') and tried to add an item. But it is failing.
I tried to add data like this
$('#drpTrajectory ').add(val(data.x).text(data.y));
data will be a member from a IEnumerable<SomeClass> dataList and SomeClass contains id and name which could be the value and text respectively.
I am already updating the model data during the button click ie #Model.Trajectories is getting updated.
So please help me to add an item to this dropdownlist which is in second partial view from my first partial view without refreshing the entire view.
Any idea?
Assuming your method is returning a collection of objects, then to create and append an option to a <select> you need
var select = $('#drpTrajectory') // cache it
$.ajax({
type: "POST",
url: '#Url.Action("DeleteAction", "AbcView")',
data: { deleteTraj: trajID },
dataType: "json",
success: function (data) {
select.empty() // if you need to remove the existing options
$.each(data, function (index, item) {
// Create an option element
var option = $('<option></option>').val(item.id).text(item.name);
// append it to the select element
select.append(option);
})
},
....
});
Side notes
Always use #Url.Action() to ensure that your url's are correctly
generated
There is no need to stringify() the data and then add the
contentType` option
Your controller method should be returning a collection of anonymous
objects containing just the 2 properties you need (there is no point
sending back extra data that's not use)
var data = dataList.Select(x => new { id = x.id, name = x.name });
return Json(data)
Your use of new SelectList(#Model.Trajectories, "Value", "Text")
suggests that the property Trajectories is already
IEnumerable<SelectListItem>. If that is the case, there is no
point creating an identical SelectList from the original one, so
just use
#Html.DropDownListFor(model => Model.TrajectoryName, Model.Trajectories, new { #class = "dropdown-leftandright", id = drpTrajectory" })
The DropDownListFor() method is already creating
id="TrajectoryName" so there is no real need to overwrite it by
using new { id = drpTrajectory" }
Here is your solution:
success: function (data) {
// I want to update the drpTrajectory dropdownlist here
$.each(data, function (i, item) {
$('#drpTrajectory').append($('<option>', {
value: item.id,
text : item.name
}));
});
}

jQuery adding CSS class to dynamically created elements

I know this question has been asked before but I have some serious weird behaviour here...
I have a DIV containing a list of anchors which are pulled via ajax from a php file (mysqli). I can dynamically add, edit and delete the items (categories) on this list. This works fine. It looks like this:
However, after a category is created I want to automatically select it. Same goes for edited categories.
And, after the page first loads, the category "Alle" should be selected by default.
I have an external categories-management.js file which contains these functions amongst other things:
function selectRootCategory () {
selectedcategoryname = "Alle";
categegorySelected = 0;
$("#training_management_categories_items>ul>li>a").removeClass('categories_selected');
$('#training_management_categories_list_a_all').addClass('categories_selected');
}
function selectEditedCategory() {
categorySelected = 1;
categoryid = 'training_management_categories_list_a_' + selectedcategoryid.toString();
$("#training_management_categories_items>ul>li>a").removeClass('categories_selected');
$('#'+categoryid).addClass('categories_selected');
}
On the main page I call this function:
$(document).ready(function() {
GetCategories();
CheckIfCategoryChecked();
selectRootCategory();
});
So basically, what should happen when the page first loads, the category "Alle" should be selected. This doesn't work though.
I would think I got the function wrong, BUT if I delete an Item, the selectRootCategory()-function is called, too and then it works. This is the function in which it works (housing in categories-management.js, too):
function submitDeleteCategory() {
var url = './ajax/training_management_data.php';
$('#delete_category_dialog_error').hide();
$.ajax({
url: url,
type: "POST",
data: {
action: 'delete_category',
category_id: selectedcategoryid,
},
dataType: 'JSON',
success: function (data) {
if (data == 'success') {
GetCategories();
CheckIfCategoryChecked();
selectRootCategory(); //THIS WORKS
categorySelected = 0;
$('#delete_category_dialog').dialog('close');
}
else {
$('#delete_category_dialog_error').html('<b>Fehler:</b><br>Fehler beim Löschen der Kategorie.')
$('#delete_category_dialog_error').show( "blind" ,300);
}
}
});
}
However, the selectEditedCategory()-function never works (which is called after you edited or created a category so it gets selected) though the given variable (categoryid) is correct, tested with alert. The function that calls selectEditedCategory is also placed in categories-management.js.
So my questions are:
Why does selectRootCategory() work when it is called via success-function in the delete-dialog but not when called via $document.ready()?
Why doesn't selectEditedCategory() work at all?
BTW don't get fooled by the categegorySelected variable, this is meant to determine if the edit- and delete-button are enabled or not. "Alle" is a fake category which contains all items from all categories and cannot be deleted or edited ("Alle" means "all" in German).
I'm using jquery-1.10.2.
Edit: To make things more clear: The ids on the items are correctly set when I call GetCategories();. This function does the following:
function GetCategories()
{
var url = './ajax/training_management_data.php';
$('#training_management_categories_items').html('<ul style="list-style: none; margin-left:0px; margin-top:0px; padding:0px;" id="training_management_categories_items_ul"></ul>');
$('#training_management_categories_items_ul').append(' \
<li class="training_management_categories_list"> \
Alle \
</li> \
');
$.ajax({
url: url,
type: "POST",
data: {
action: 'get_categories',
},
dataType: 'JSON',
success: function (data) {
$.each(data, function(index, data) {
$('#training_management_categories_items_ul').append(' \
<li class="training_management_categories_list"> \
'+data.name+' \
</li> \
');
});
}
});
}
It works fine which is proven by the fact that I can delete and edit the categories (the functions to do so require the id of the element. However I read the ID not via the ID field as this contains a string but by the attribute "data-id" which only contains the ID (as you see in above code). So the problem lies solely at the jQuery part and not at the ajax-part.
Edit2: When I add selectRootCategory() to the success-function of GetCategories(), it works on page load. But I still don't get why it doesn't work with document.ready(). I cannot use it in GetCategories(), though because it would de-select any item and select "Alle" instead.
I can still not get selectedEditedCategory to work.
The var categoryid contains a valid ID though, e.g. training_management_categories_list_a_70.
You have to parse the data coming back from the server and add a class to it.
like
$.ajax({
...
success:function(data){
$.each(data,function(singleData){
$(singleData).addClass('blahblah');
});
}
...
});
Hope this helps

Can't send array from jQuery to MVC 4 controller

I've googled this up and checked all over StackOverflow but I must be missing something... I have unobtrusive jQuery that hijaks a simple button click. It counts up the checkboxes and adds each checked boxes value to an array. The list is correct when I use an alert box in jQuery but the array never makes it to the controller side. The code flows to the controller but I break on var resolutionViewModel=new ResolutionViewModel(); and check trans - the argument is null. I'm new to jQuery and could really use the help here.
jQuery
// Return the selected transactions
function resolveTransactions() {
$('#btnResolve').click(function() {
var selectedTransactions = new Array();
$('input[name="chkTransaction"]:checked').each(function() {
selectedTransactions.push(this.value);
});
if (selectedTransactions.length > 0) {
$.ajax({
type: 'POST',
dataType: 'json',
url: 'http://localhost/AuditLog/Home/ResolutionFormDisplay',
contentType: 'application/json; charset=utf-8',
data: {trans : selectedTransactions},
traditional: true,
success: function (data) { alert(data); },
error: function(xhr, status, errorThrown) { alert("Error: " + errorThrown); }
});
}
});
};
Controller side
[HttpPost]
public PartialViewResult ResolutionFormDisplay(List<string> trans)
{
var resolutionViewModel = new ResolutionViewModel();
// fill Usernames dropdown selector in ViewModel
// fill Status dropdown selector in ViewModel
// fill list of transactionIds in ViewModel
return PartialView("_ResolutionDialog", resolutionViewModel);
}
Try having your controller accept a List, rather than just a single string (since you're not passing a single string):
[HttpPost]
public PartialViewResult ResolutionFormDisplay(List<string> value)
{
var resolutionViewModel = new ResolutionViewModel();
// fill Usernames dropdown selector in ViewModel
// fill Status dropdown selector in ViewModel
// fill list of transactionIds in ViewModel
return PartialView("_ResolutionDialog", resolutionViewModel);
}
Posted JSON needs to have named properties matching parameters in your controller method. Check the 'network' tab in Chrome dev tools and see exactly what you're posting, it's probably something like this:
"{\"value\":\"...\"}"
There is no value property to pass to your controller method's value parameter. I think the best would be just to get rid of the `JSON.stringify" and accept a list like Colin's answer, but if you want to take it as a string, the JSON string needs to be the value property of an object, not the other way around:
data: {value : JSON.stringify(selectedTransactions)},
Try passing your array as follows:
data:"{'trans':" + JSON.stringify(selectedTransactions)+"}"
Your method should be as follows:
public void Method(List<string> trans)
{
//Your implementation
}
SOLUTION:
The $.ajax postback was not sending properly formatted data to the controller. I discovered this by using the network tab in IE and looking at the Request Body of the POSTed http. It looked like this:transaction_table_length=10&chkTransaction=22&chkTransaction=23 -- It should have looked like this: {"trans":["22","23"]}. To solve this issue I stringified the property name and array as shown below, changed the dataType to 'text', and made the parameter on the controller action method take a String[] trans.
jQuery
// Return the selected transactions
function resolveTransactions() {
$('#btnResolve').click(function() {
var selectedTransactions = new Array();
$('input[name="chkTransaction"]:checked').each(function() {
selectedTransactions.push(this.value);
});
if (selectedTransactions.length > 0) {
$.ajax({
type: 'POST',
dataType: 'text',
url: 'http://localhost/AuditLog/Home/ResolutionFormDisplay',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ trans:selectedTransactions }),
traditional: true,
success: function (data) { alert(data); },
error: function(xhr, status, errorThrown) { alert(" Error: " + errorThrown); }
});
} else {
alert('You must select (check) at least one transaction to apply a resolution.');
return false;
}
return false;
});
};
MVC 4 controller action
[HttpPost]
public PartialViewResult ResolutionFormDisplay(string[] trans)
{
var resolutionViewModel = new ResolutionViewModel();
// fill Usernames dropdown selector in ViewModel
// fill Status dropdown selector in ViewModel
// fill list of transactionIds in ViewModel
return PartialView("_ResolutionDialog", resolutionViewModel);
}

Categories

Resources