cascaded dropdown prepopulate knockout MVC - javascript

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>

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.

Passing Select Option to POST request

I'm very new to web development and I'm trying to pass what the user has selected in a field called accesslevel_id to a POST request, so I can pass it to my database. I'm following the example in my book, but it doesn't seem to work as intended.
My script is the following:
<script>
$(document).ready(function () {
$('#accesslevel_id').on('change', function () {
alert($('#accesslevel_id').val());
});
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<select class="form-control" id="accesslevel_id" onchange="accesslevel_id" title="">
<option>Facility</option>
<option>Division</option>
<option>Corporate</option>
<option>Market</option>
<option>Group</option>
</select>
When on the site and a user selects an option it currently displays None for my print function defined as accesslevel_id = request.POST.get('accesslevel_id'). The next step, which i'm not at yet is to convert the option name into numbers to store into the database. I'm looking for advice on how to accomplish this.
I think you need to post the value of option value when it changes right?
$(document).ready(function () {
$('#accesslevel_id').on('change', function () {
var accesslevel_id = $(this).val();
$.ajax({url: "action-page",
data:"accesslevel_id="+accesslevel_id,
type: "POST",
success: function(result){
alert(result);
}
});
});
});

Passing data from Javascript MVC controller

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.

AJAXed Select form element defaults to first option even if changed

Updated: The DOM is creating a second select instance of #dockhouse-reservation-vessel. It's overriding the first which is the "real" one with the right value
The events are triggered, data retrieved and replaced. #dockhouse-reservation-vessel's value shows in an alert() but not in $_POST. If I comment out the second block of jQuery, the problematic select's value is remembered correctly.
$('form').delegate('#dockhouse-reservation-owner','change', function(){
$.ajax({
url: '/dockhouse/ajax/vessels/' + $(this).val() + '/',
success: function(data){
$('#dockhouse-reservation-vessel').empty();
$('#dockhouse-reservation-vessel').append(data);
}
});
});
data represents option elements:
<!DOCTYPE html>
<option value="">Choose a vessel</option>
<option value="1744">Stinkpot</option>
<option value="1726">Poopy Snoop</option>
<option value="1704">Catchup</option>
The data below represents a table.
$('form').delegate('#dockhouse-reservation-vessel','change',function(){
$.ajax({
url: '/dockhouse/ajax/locations-by-reservation-criteria/' + $(this).val() + '/',
success: function(data){
$('#assign-location').empty();
$('#assign-location').append(data);
}
});
});
Any ideas?
As you are removing and reinserting the whole select box, the state is removed.
You can save the old value in a temp variable and apply it in the callback:
$('form').delegate('#dockhouse-reservation-vessel','change',function(){
// save the value
var oldValue = $(this).val();
$.ajax({
url: '/dockhouse/ajax/locations-by-reservation-criteria/' + oldValue + '/',
success: function(data){
$('#assign-location').empty();
$('#assign-location').append(data);
// select the old value
$('#dockhouse-reservation-vessel').val(oldValue);
}
});
});
WOW, stupid mistake. There was a select field with the same name being pulled in with the table ajax response. Walks away in shame...

Categories

Resources