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();
}
})
Related
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.
I am having a form in which I have a drop down list. The drop down list is getting populated inside an AJAX call. There is a button, clicking on which sends an AJAX call and returns data to be filled as options to the drop down list.
Now, If the option is selected and the form is submitted successfully, then the selected value gets stored in the database.
But, If I select an option in the drop down and if there are some validation issues in my form, then on submit, the page shows the error and it "refreshes". This leads to the options which were populated during AJAX call to disappear since there is no ajax call again to populate the list.
So, How do I store the value during the first AJAX call such that on page refresh, the value is stored or populated.
If the list were populated manually i.e If I knew the options beforehand, I could have stored the selected value in a hidden variable but I can't do it here.
Here is my AJAX function:
$.ajax({
type: "POST",
dataType: 'json',
url: "/Controller/Action",
data: {
param: param,
},
success: function(data) {
if (data.Response == "Unsuccessful") {
console.log("Unsuccessful");
} else if (data.Response == "Successful" || data.Response == "ConditionallySuccessful") {
for (var i = 0; i < data.ExteriorColor.Data.length; i++) {
//This is the drop down list which is populated
$("#Exterior_Color").append($("<option></option>").val(data.ExteriorColor.Data[i]).html(data.ExteriorColor.Data[i]));
console.log(data.ExteriorColor.Data[i]);
}
}
},
error: function(result) {
console.log("Error while fetching data");
}
});
Try localstorage, use it after the success in ajax call.
Saving the dropdown object:
//SAVING (put after the ajax call)
var myList= $("#Exterior_Color");
// Put the object into storage
localStorage.setItem('myList', JSON.stringify(myList));
And the restore part:
//RESTORING (put after the page refresh)
// Retrieve the object from storage
var retrievedMyList = localStorage.getItem('myList');
console.log('myList: ', JSON.parse(retrievedMyList ));
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
}));
});
}
I am on the Update details screen and I have a Country and a state dropdown .I want to pre populate State dropdown on the basis of the selected Country.
On the initial page load I do have the selected Country,Country Collection and Selected State all I need is to fetch the State Collection using AJAX.
Country List: <select id="CountryDropdownList" data-bind="options: viewModel.CountryCollection,optionsText:'CountryName',optionsValue:'CountryName',value:viewModel.SelectedCountry"></select>
State List: <select id="StateDropdownList" data-bind="options: viewModel.StateCollection,optionsText:'StateName',optionsValue:'StateName',value:viewModel.SelectedState"></select>
<script>
var viewModel = ko.mapping.fromJS(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
console.log(viewModel.SelectedState()); //State3 the initial value
viewModel.SelectedCountry.subscribe(function (newSelectedCountry) {
alert(newSelectedCountry);
console.log(viewModel.SelectedState()); //undefined why?
$.ajax({
url: 'Home/GetStateList?Country=' + newSelectedCountry,
success: function (data) {
viewModel.StateCollection(ko.mapping.fromJS(data)());
console.log(viewModel.SelectedState()); //state0 why?
}
})
});
ko.applyBindings(viewModel);
$(function () {
viewModel.SelectedCountry.valueHasMutated();
})
</script>
But when I try to fetch the state list through AJAX request the Selected State value gets reset and the first value in the list becomes the default selected value. I am confused, why does KO update my selected State value when I am not changing it at all?
But if I set the Selected State again in AJAX Success callback it works fine
viewModel.SelectedCountry.subscribe(function (newSelectedCountry) {
alert(newSelectedCountry);
$.ajax({
url: 'Home/GetStateList?Country=' + newSelectedCountry,
success: function (data) {
viewModel.StateCollection(ko.mapping.fromJS(data.StateCollection)());
viewModel.SelectedState(data.SelectedState);
}
})
});
I am looking for a reason for this strange behavior.
I have tried simplifying the code as directed by you and now I think it might help you to point out the issue.
<script>
var viewModel = ko.mapping.fromJS(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
console.log(viewModel.SelectedState()); // o/p state3
$.ajax({
url: 'Home/GetStateList?Country=' + viewModel.SelectedCountry(),
success: function (data) {
viewModel.StateCollection(ko.mapping.fromJS(data)());
console.log(viewModel.SelectedState()); // o/p state0
}
})
ko.applyBindings(viewModel);
</script>
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.