Not getting onchange event of dynamicly added dropdown in mvc3 - javascript

I have three dropdownlists.
$(document).ready(function () {
$("#DropDownList1").change(function () {
$("#Id1").val($(this).val());
$("#Name1").val($("#DropDownList1 option:selected").text());
$('#Div1').load('/Account/Dropdown2/?Id1=' + $("#Id1").val());
});
$("#DropDownList2").change(function () {
$("#routeId").val($(this).val());
$("#routeName").val($("#RouteDropDownList option:selected").text());
$('#Div2').load('/Account/Dropdown3/?Id2=' + $("#routeId").val());
});
$("#DropDownList3").change(function () {
$("#Id3").val($(this).val());
$("#Name3").val($("#DropDownList3 option:selected").text());
});
});
In this DropDownList2 and DropDownList3 are added dynamicly.The problem is the dynamicly added dropdowns are not got registered in the page .So I am not getting its selected value from the onchange event.I added these controls as partial view.
Controller.
public ActionResult DropDownList2 (string Id1)
{
List<Emp> empList = new List<Emp>();
Emp em= new Emp ()
{
Id = "1",
Name = "Doac"
};
empList .Add(em);
ViewBag.DropDownList2= new SelectList(empList , "Id", "Name");
return PartialView();
}
Generated Html
<script type="text/javascript">
$('#CreateSubscriber').removeClass('menuHolderli').addClass('selectedMenu');
$(document).ready(function () {
$("#DropDownList").change(function () {
$("#Organization_Id").val($(this).val());
$("#Organization_Name").val($("#DropDownList option:selected").text());
$('#routeDiv').load('/Account/RouteDropdown/?organizationId=' + $("#Organization_Id").val());
});
$(document).on('change', "#RouteDropDownList", function () {
alert("hi");
$("#routeId").val($(this).val());
$("#routeName").val($("#RouteDropDownList option:selected").text());
$('#locationDiv').load('/Account/LocationDropdown/?routeId=' + $("#routeId").val());
});
$("#LocationDropDownList").change(function () {
$("#locationId").val($(this).val());
$("#locationName").val($("#LocationDropDownList option:selected").text());
});
});
</script>
<p class="message-info">
Passwords are required to be a minimum of 6 characters in length.
</p>
<script src="/Scripts/jquery.validate.min.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.min.js"></script>
<form action="/Account/Register" method="post"> <fieldset>
<legend>Registration Form</legend>
<ol>
<li>
<label for="Organization_Name">Name</label>
<input id="Organization_Id" name="Organization.Id" type="hidden" value="" />
<input id="Organization_Name" name="Organization.Name" type="hidden" value="" />
<select id="DropDownList" name="DropDownList"><option value="">---Select---</option>
<option value="516c0a18c891870f107aa74a">Choice School</option>
<option value="516d277bc8918701a44c131e">New Org</option>
<option value="516d1f492e6bba07dc245cc7">Olive</option>
</select>
<span class="field-validation-valid" data-valmsg-for="Organization.Name" data-valmsg-replace="true"></span>
</li>
</ol>
<div id="routeDiv"></div>
<div id="locationDiv"></div>

Use jQuery .on()
$(document).on('change', "#DropDownList2", function(){your code})
Repeat for your dropdown 3

Since, DropDownList2 and DropDownList3 are added dynamicly, you need to do this:
$(document).on('change', '#DropDownList1', (function () {
$("#Id1").val($(this).val());
$("#Name1").val($("#DropDownList1 option:selected").text());
$('#Div1').load('/Account/Dropdown2/?Id1=' + $("#Id1").val());
});
Similarly call other dyanmically added dropdowns also.

If you are adding the select options dynamically, why not use AJAX within AJAX?
$(function() {
$('#DropDownList').each(function () {
var dropdown = $(this);
dropdown.change(function() {
$.ajax({
url: 'Account/GetDropDownOptions',
type: 'GET',
data: {dropdownID: dropdown.attr('id'), value: dropdown.val()},
dataType: 'html',
cache: false,
success: function (data) {
var dropdown2 = $('#DropDownList2');
dropdown2.html(data);
dropdown2.change(function() {
$.ajax({
url: 'Account/GetDropDownOptions',
type: 'GET',
data: {dropdownID: dropdown2.attr('id'), value: dropdown2.val()},
dataType: 'html',
cache: false,
success: function (data) {
var dropdown3 = $('#DropDownList3');
dropdown3.html(data);
dropdown3.change(function() {
//....same thing as above pretty much
});
}
});
});
}
});
});
});
});
Then your controller action, GetDropDownOptions, would examine the DDL ID and selected value, understand what options it needed, then return the options as HTML. Or as a more elegant solution, you could have it return an object as json ( return Json(object) ) and then programatically create the elements in your javascript. You'd have to switch the dataType in the $.ajax to 'json'.
This way you have the dropdown change event after it has loaded the options. This change event loads DropDownList2's options and change event, which will load DDL3's options.
Haven't tested the code, but this idea will work. This sample assumes you already have the first DDL options loaded, but it seems you'll have to have add another layer of ajax to load those in as well. It also assumes the and DDL3 are already on the DOM at page load. You could add them to the DOM in your html to get this example to work, or change the IDs in the javascript to some container.

Related

Update CHOSEN select box with jquery and javascript

I'm using Unify template which has jquery chosen library for select boxes. My html code is as follows:
<div>
<select class="select-evaluation-makes js-evaluation-custom-select u-select-v1 g-min-width-200 g-brd-none g-bg-secondary g-color-main g-color-primary--hover g-py-12"
required
data-placeholder="{% trans "Select brand" %}"
data-open-icon="fa fa-angle-down"
data-close-icon="fa fa-angle-up">
</select>
<select class="select-evaluation-models js-evaluation-custom-select u-select-v1 g-min-width-200 g-brd-none g-bg-secondary g-color-main g-color-primary--hover g-py-12"
required disabled
data-placeholder="{% trans "Seect model" %}"
data-open-icon="fa fa-angle-down"
data-close-icon="fa fa-angle-up">
</select>
<select class="select-evaluation-years js-evaluation-custom-select u-select-v1 g-min-width-200 g-brd-none g-bg-secondary g-color-main g-color-primary--hover g-py-12"
required disabled
data-placeholder="{% trans "Select year" %}"
data-open-icon="fa fa-angle-down"
data-close-icon="fa fa-angle-up">
</select>
</div>
And my JS is as follows:
<script>
const select_makes_selector = $(".select-evaluation-makes");
const select_models_selector = $(".select-evaluation-models");
const error_box = $("#error-box");
const error_message = $("#error-message");
$(document).ready(function () {
loadMakesOnPageLoad();
//Get models on make change
select_makes_selector.on('change', function (e, params) {
loadModels(parseInt(params["selected"]))
});
});
function loadMakesOnPageLoad() {
$.ajax({
type: "GET",
url: "/vehicle-evaluation/get-makes/",
beforeSend: function () {
},
success: function (result) {
let makes = result['makes'];
select_makes_selector.append("<option></option>");
_.forEach(makes, function (make) {
select_makes_selector.append("<option class=\"evaluation-make g-brd-none g-color-main g-color-white--hover g-color-white--active g-bg-primary--hover g-bg-primary--active\" value=\"" + make.id + "\">" + make.name + "</option>")
});
$.HSCore.components.HSSelect.init('.select-evaluation-makes');
},
error: function (response) {
error_box.removeClass("hidden");
error_message.html('<strong>' + gettext("Oh snap!") + '</strong>' + gettext("Something went wrong. Makes couldn't be fetched"))
}
});
}
function loadModels(make_id) {
$.ajax({
type: "GET",
url: "/vehicle-evaluation/get-models/" + make_id + '/',
beforeSend: function () {
},
success: function (result) {
let models = result['models'];
select_models_selector.attr('disabled', false).trigger("chosen:updated");
select_models_selector.append("<option></option>");
_.forEach(models, function (model) {
select_models_selector.append("<option class=\"evaluation-model g-brd-none g-color-main g-color-white--hover g-color-white--active g-bg-primary--hover g-bg-primary--active\" value=\"" + model.id + "\">" + model.name + "</option>")
});
$.HSCore.components.HSSelect.init('.select-evaluation-models');
},
error: function (response) {
error_box.removeClass("hidden");
error_message.html('<strong>' + gettext("Oh snap!") + '</strong>' + gettext("Something went wrong. Models couldn't be fetched"))
}
});
}
</script>
The problem is with the initialisation of those select boxes. They can be initialised only once if I get it right.
With my code I get:
Thus only the first one is initialised with $.HSCore.components.HSSelect.init('.select-evaluation-makes'); in loadMakesOnPageLoad function. But that is not what I want. All three need to be initialised.
If I change brands select box, then the models select box is also initialised. But If I change the brands select box again, then the model select box doesn't work and it isn't updated. It's probably because it hits $.HSCore.components.HSSelect.init('.select-evaluation-models'); again in ajax success call of loadModels function.
If I initialise them with common class as follows: $.HSCore.components.HSSelect.init('.js-evaluation-custom-select'); they are initialised:
But then onChange event on brands select box doesn't work. If the brands select box is changed then the models select box isn't updated, probably the same reason as above. It tries to initialise it again, this time with $.HSCore.components.HSSelect.init('.select-evaluation-models');
Any idea what is going on and how can I solve it? It drives me crazy.
After you updated the select with ajax response put on the next line:
$(".select-evaluation-makes").trigger("chosen:updated");
You must trigger "chosen:updated" event as per chosen docs show

Jquery Flask capturing checkbox value

I am trying to capture the data from checkbox by assigning value in jquery and passing it to backend each time search is run by the user. It is not working for me, tried several ways.
Use case: As a user I would like to search and be able to check for various search options.
template:
$('a#process_input').bind('click', function () {
$.getJSON('/background_process', {
checkbox1: $('input[name="checkbox1"]').val(),
input_search: $('input[name="input_search"]').val(),
},
function (data) {
ul.empty();
$.each(data.result, function (index, element) {
...
... <some irrelevant code...>
<input type=text size=40 name=input_search>
<a href=# id=process_input>
<button class='btn btn-default'>Submit</button>
</a>
</form>
<form method="POST" action="/">
<p>Please select allergy options below:</p>
<input type="checkbox" name="checkbox1"/>Allergy 1
backend
#app.route('/background_process', methods=['GET', 'POST'])
def background_process():
try:
checkbox1 = request.args.get("something")
search_word = request.args.get('input_search', 0, type=str)
if search_word:
return jsonify(result=yummly_search(search_word, checkbox1))
else:
return jsonify(result='Try again.')
except Exception as e:
return str(e)
I am not comfortable with getJSON function but the other way to do it is ajax. Here is a runnable code, I hope it helps:
html:
<input type=text size=40 name="input_search">
<a href=# id=process_input>
<button class='btn btn-default'>Submit</button>
</a>
<p>Please select allergy options below:</p>
<input type="checkbox" name="checkbox1"/>Allergy 1
<div id="login_result"></div>
javascript:
<script>
$(document).ready(function () {
$("#process_input").bind('click', function () {
var login_result = $('#login_result');
var input_search = $('[name="input_search"]').val();
var checkbox1 = $('[name="checkbox1"]').is(":checked");
console.log(input_search);
console.log(checkbox1);
var list = new FormData()
list.append("input_search", input_search)
list.append("checkbox1", checkbox1)
var urlBackgroundProcess = "{{ url_for('background_process') }}";
var ajaxRequest = $.ajax({
type: "POST",
url: urlBackgroundProcess,
data: list,
contentType: false,
cache: false,
processData: false,
success: function (msg) {
login_result.html(msg.data);
console.log("AJAX ok 2!");
}
});
});
});
</script>
and the flask back end:
#app.route('/background_process',methods=['GET','POST'])
def background_process():
msg=''
if request.form.get("input_search"):
msg=('I got that search pattern at the back end: \'%s\' \n the checkbox value is set to: \'%s\' ') \
% (request.form.get("input_search"),request.form.get("checkbox1"))
else:
msg='I got the Ajax call but cannot read the data, try again! :('
return jsonify(data=msg)

How to replace basic HTML dropdown created by ajax call with the HtmlDropdown helper

So, I have two drodpowns, both dropdowns are working as expected. So, entry in second dropdowns determined by the entry selected in first drodpown. Also, I have added a script call CountrySelectionChanged on the page reload too so that second dropdown gets populated as per the intitial value of first dropdown.
<script type="text/javascript">
$(function () {
CountrySelectionChanged();
});
</script>
<div id="Admin">
Select an account:
#Html.DropDownList("countrySelection", (List<SelectListItem>)ViewBag.AvailableAccounts, new { onchange = "CountrySelectionChanged()"})
<p id="Temp">
Select a city:
<select id="City" name="City"></select>
</p>
</div>
AJAX CALL:
function CountrySelectionChanged() {
// logic taken out for brevity
$.ajax({
type: 'POST',
url: '/Settings/GetCity',
data: { accountId: accountId },
success: function (data) {
debugger;
var locationDropdown = '';
for (var x = 0; x < data.length; x++) {
locationDropdown += '<option value="' + data[x].Value + '">' + data[x].Text + '</option>';
}
$('#City').html(locationDropdown);
},
error: function () {
DisplayError('Failed to load the data.');
}
});
}
Question: Is there a way that I can use HTML Helper to display second dropdown too? Can I somehow inject the ajax return to a HTML Helper (Even if it's not strongly bound).

Load Partial view after page is loaded

I have a view that contains a dropdown on load, when the dropdown value is changed it loads a partial view blow the dropdown containing an input form. This works correctly.
Now when i open the page, but the dropdown value has already been selected i need to load that same partial view.
But when i do this the entire layout get's loaded again and not my partial view.
Both these post back to the same action. Does anyone have an idea.
Please look at the images below for the outputs.
$('#DbDropdown').on('change', function (evt) {
LoadBody();
});
$(window).bind("load", function () {
var e = document.getElementById("DbDropdown");
var text = e.options[e.selectedIndex].value;
if (text != "Please select")
{
LoadBody();
}
});
function LoadBody()
{
var url = "GetHeader";
var $Detail = $("#HeaderSection")
$.ajax({
data: $("#PRForm").serialize(),
type: 'GET',
cache: false,
dataType: 'html',
url: url,
success: function (result) {
$Detail.html(result);
},
error: function (ex) {
alert(ex);
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#model PRHeaderVM
<section>
<h2>Purchase Requesition #Model.PrNumber
</h2>
<form asp-action="SubmitPR" role="form" id="PRForm" style="width: 100%;top:0;right:0;left: 10px; bottom:10px" enctype="multipart/form-data">
#Html.HiddenFor(x => x.PrNumber)
#Html.HiddenFor(x => x.Status)
<div style="margin-top : 10px; position:fixed;top:50px;right:50px;width : 150px">
#if (Model.Status == 1)
{
Html.RenderPartial("_CreateButtonTemplate");
}
#if (Model.Status == 2)
{
Html.RenderPartial("_ApproveButtonTemplate");
}
</div>
<div class="form-horizontal">
<div class="row">
<div class="col-lg-3">
<div class="form-group">
<div style="padding-bottom: 40px;">
<label class="col-lg-4 control-label">Company</label>
<div class="col-lg-8">
<select id="DbDropdown" asp-for="CompanyID" asp-items="#Model.Companies" class="form-control">
<option>Please select</option>
</select>
</div>
</div>
</div>
</div>
</div>
<div id="HeaderSection">
</div>
</div>
</form>
</section>
Selecting the value myself
Selecting the value myself
Value loaded from model
Value loaded from model
The answer below should do it (was deleted, see comments). One more input:
As of jQuery 3.0, .bind() has been deprecated.
You are using on your first line .on and on the 4th line .bind. .on has replaced .live and .bind so you should use .on on every element for future development.
$('#DbDropdown') *.on* ('change', function (evt) {
LoadBody();
});
$(window) *.bind* ("load", function () {
Resolved by Specifying the url for the on form load ajax call.
function LoadPRBody(url) {
var $Detail = $("#HeaderSection");
alert($("#PRForm").serialize().toString());
$.ajax({
data: $("#PRForm").serialize(),
type: 'GET',
cache: false,
dataType: 'html',
url: url,
success: function (result) {
$Detail.html(result);
},
error: function (ex) {
alert(ex);
}
});
}
$('#DbDropdown').on('change', function (evt) {
LoadPRBody("GetHeader");
});
$(window).on("load", function () {
var val = $('#DbDropdown').val();
alert(val);
if (val != 0) {
LoadPRBody("#Url.Action("GetHeader", "Requests")");
}
});
The issue seemed to be that the url was not being loaded correctly that the point when the ajax reqest was made, thus not knowing in which controller to look for the action.

How to enter all multi-selection options into database

I have multi-selection functionality similar to this (see link): http://jsfiddle.net/eUDRV/341/.
HTML code:
<section class="container" >
<div>
<select id="list" name="list"size="15">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</div>
<div>
<br><br><br>
<input type="button" id="button_left" value="<--"/>
<input type="button" id="button_right" value="-->" />
</div>
<div>
<select id="selected_values" size="15"></select>
<input name="selected_values" type="hidden"/>
</div>
jQuery/Javascript code:
$(document).ready(function () {
$("#button_right").click(function () {
var selectedItem = $("#list option:selected");
var added = false;
$("#selected_values > option").each(function() {
if ($(this).text() > $(selectedItem).text()) {
$(selectedItem).insertBefore($(this));
added = true;
return false;
}
});
if(!added) $(selectedItem).appendTo($("#selected_values"));
updateHiddenField();
});
$("#button_left").click(function () {
var selectedItem = $("#selected_values option:selected"), activeValues;
var added = false;
$("#list > option").each(function() {
if ($(this).text() > $(selectedItem).text()) {
$(selectedItem).insertBefore($(this));
added = true;
return false;
}
});
if(!added) $(selectedItem).appendTo($("#list"));
updateHiddenField();
});
function updateHiddenField () {
$('input[name="selected_values"]').val(
$.map($('#selected_values option:selected').toArray(), function (e) {
return e.value;
})
);
}
});
PHP code:
if(!empty($_POST['selected_values'])) {
$_POST['selected_values'] = explode(',', $_POST['selected_values']);
foreach($_POST['selected_values'] as $x) {
$query = "INSERT INTO $table (id1, id2) VALUES ($id1Value, $x)";
db_query($query);
My goal is to iterate through all of the values that are moved into the left column and enter them into a database using PHP. I'm able to get this functionality to work, however, I'm having the exact same issue as seen referenced here: how can I get all options in a multi-options select using PHP?. I'm accessing the values using $_POST["leftValues"] but if the user clicks on one of the options, only that one will be entered into the database. Unfortunately, the accepted solution isn't working for me.
$("form:has(#leftValues)").on('submit', function () {
$("#leftValues option").prop('selected', true);
});
Can someone please explain to me how I can get this solution to work for me or an alternative way of ensuring $_POST["leftValues"] will contain all the options instead of only the selected/highlighted? Any response is greatly appreciated.
You could add a hidden field and update that whenever the lists change.
You'd need to update your html:
<div>
<select id="leftValues" size="5" multiple></select>
<input name="leftValues" type="hidden" />
</div>
and add a function to do the updating:
function updateHiddenField () {
$('input[name="leftValues[]"]').val(
$.map($('#leftValues option:selected').toArray(), function (e) {
return e.value;
})
);
}
And call it in each of your click handlers:
$("#btnLeft").click(function () {
var selectedItem = $("#rightValues option:selected");
$("#leftValues").append(selectedItem);
updateHiddenField();
});
$("#btnRight").click(function () {
var selectedItem = $("#leftValues option:selected"), activeValues;
$("#rightValues").append(selectedItem);
updateHiddenField();
});
Finally, you can do this in your PHP to get what you originally expected:
$_POST['leftValues'] = explode(',', $_POST['leftValues']);
Finally got it to work. I edited the submit callback, as the original solution suggested.
Added an id to my form tag:
<form id="form" method="post">
When the form is submitted, select/highlight all options in the selected_values list:
$(#form).submit(function () {
$("#selected_values > option").each(function () {
$(this).attr('selected', 'selected');
});
return true;
});

Categories