jQuery: Conflict with removeData() executing at inadequate times - javascript

I have a modal window used to update or add a new object Store.
This modal is called remotely which information is loaded from a GET method constructed in ASP.NET.
Button that calls the modal:
<div class="btn-group" id="modalbutton">
<a id="createEditStoreModal" data-toggle="modal" asp-action="Create"
data-target="#modal-action-store" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> NEW STORE
</a>
</div>
Html of the modal:
#model Application.Models.ApplicationviewModels.StoreIndexData
#using Application.Models
<form asp-action="Create" role="form">
#await Html.PartialAsync("_ModalHeader", new ModalHeader
{ Heading = String.Format("Actualización de Modelo: Tiendas") })
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="modal-body form-horizontal">
<div class="form-group">
<label asp-for="DepartmentID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="DepartmentID" class="form-control"
asp-items="#(new SelectList(#ViewBag.ListofDepartment,"DepartmentID","DepartmentName"))"></select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Distrito</label>
<div class="col-md-10">
<select class="form-control" id="DistrictID" name="DistrictID" asp-for="DistrictID"
asp-items="#(new SelectList(#ViewBag.ListofDistrict,"DistrictID","DistrictName"))"></select>
</div>
</div>
{... more elements}
</div>
</form>
GET Method:
public IActionResult Create(int? id)
{
List<Department> DepartmentList = new List<Department>();
DepartmentList = (from department in _context.Departments
select department).ToList();
DepartmentList.Insert(0, new Department { DepartmentID = 0, DepartmentName = "-- Seleccione Departamento --" });
ViewBag.ListofDepartment = DepartmentList;
StoreIndexData edit = new StoreIndexData();
List<District> ListofDistrict = new List<District>();
ListofDistrict.Insert(0, new District { DistrictID = 0, DistrictName = "-- PRUEBA --" });
ViewBag.ListofDistrict = ListofDistrict;
return PartialView("~/Views/Shared/Stores/_Create.cshtml");
}
The problem:
I have the following jQuery which asigns a value to DistrictID once the modal opens:
<script type="text/javascript">
var wasclicked = 0;
var $this = this;
$(document).ready(function () {
document.getElementById("modalbutton").onclick = function () {
//is AddNew Store button is hitted, this var = 1
wasclicked = 1;
};
$('#modal-action-store').on('hidden.bs.modal', function () {
//global.wasclicked = 0;
wasclicked = 0;
$(this).removeData('bs.modal');
});
$('#modal-action-store').on('shown.bs.modal', function (e) {
console.log($('#DistrictID').length);
//if wasclicked equals 1 that means we are in the AddNew Store scenario.
if (wasclicked == 1) {
//a default value is sent to District dropdownlist
var items = "<option value='0'>-- Seleccione Distrito --</option>";
$('#DistrictID').html(items);
};
});
});
</script>
The problem right now is that after this line jQuery is executed, the value that was assigned to DistrictID gets overwritten by :
ViewBag.ListofDistrict = ListofDistrict; //"-- PRUEBA --"
And this line is lost:
var items = "<option value='0'>-- Seleccione Distrito --</option>";
What I suspect is that the information coming from the Controller overwrites any result from jQuery over the in the modal.
After debugging I have identified three diferent moments:
Moment 1: First time we open the modal
The modal hasn't opened yet and the jQuery executes
For this reason it does not identify DistrictID
The result from the GET Action fills the modal's inputs.
Moment 2 - Part 1: Second time we open the modal
This time the modal opens before the jQuery is executed
The DistrictID has the value from the GET Method before we assign the value from jQuery
Moment 2 - Part 2: When the value from jQuery is assigned
The value from jQuery is assigned to DistrictID
This value will be overwritten by the result of the GET Action
Question:
Can anyone explain or help me understand what might be causing this? What else can I do to identify the reason behind this?

Trying moving the assigning of html to districtID from your main view to the document.ready of modal popUp view.
#model Application.Models.ApplicationviewModels.StoreIndexData
#using Application.Models
<form asp-action="Create" role="form">
#await Html.PartialAsync("_ModalHeader", new ModalHeader
{ Heading = String.Format("Actualización de Modelo: Tiendas") })
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="modal-body form-horizontal">
<div class="form-group">
<label asp-for="DepartmentID" class="col-md-2 control-label"></label>
<div class="col-md-10">
<select asp-for="DepartmentID" class="form-control"
asp-items="#(new SelectList(#ViewBag.ListofDepartment,"DepartmentID","DepartmentName"))"></select>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">Distrito</label>
<div class="col-md-10">
<select class="form-control" id="DistrictID" name="DistrictID" asp-for="DistrictID"
asp-items="#(new SelectList(#ViewBag.ListofDistrict,"DistrictID","DistrictName"))"></select>
</div>
</div>
{... more elements}
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
//if wasclicked equals 1 that means we are in the AddNew Store scenario.
if (wasclicked == 1) {
//a default value is sent to District dropdownlist
var items = "<option value='0'>-- Seleccione Distrito --</option>";
$('#DistrictID').html(items);
}
});
</script>
PS: Default option can be also be used. refer the below code.
<div class="form-group">
<label class="col-md-2 control-label">Distrito</label>
<div class="col-md-10">
<select class="form-control" id="DistrictID" name="DistrictID" asp-for="DistrictID" asp-items="#(new SelectList(#ViewBag.ListofDistrict,"DistrictID","DistrictName"))">
<option value='0'>-- Seleccione Distrito --</option>
</select>
</div>
</div>

modal() only accepts an options object or a string. To append elements to your modal, we can append them when the show.bs.modal is triggered:
$('#modal-action-store').on('show.bs.modal', function(e){
var items = "<option value='0'>-- Seleccione Distrito --</option>";
$('#DistrictID').html(items);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="btn-group" id="modalbutton">
<a id="createEditStoreModal" data-toggle="modal" asp-action="Create"
data-target="#modal-action-store" class="btn btn-primary">
<i class="glyphicon glyphicon-plus"></i> NEW STORE
</a>
</div>
<div class="modal" id="modal-action-store">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<select class="form-control" id="DistrictID" name="DistrictID">
</select>
</div>
</div>
</div>
</div>

I would update your http://plataformafantasypark.azurewebsites.net/Stores/create to contain <option value='0'>-- Seleccione Distrito --</option> by default. This would limit the options to overwrite the element with zero entries.
This would make your js code easier too.
By the way, why do you use document.getElementById("modalbutton").onclick when you can use $("#modalbutton").on("click", function(){}); because you are using jQuery for everything else.

Related

RedirectToAction in Loop process [.Net Core 3.1]

I've been struggling to finish the app I'm developing,
here is the scenario:
I have a Razor page where the user will input customer number, Company Code, and Date. Users can input multiple customer numbers and the app will split them by comma.
once the user inputted the details a button with asp-action pointed to the action named GenerateSoa, it will run a foreach statement that will RedirectToAction for every customer that is inputted on the GUI
The problem starts here when the loop runs it only opens one tab even if there are 3 customers inputted.
It should open 3 tabs with their details for 3 different customers. below is my code
I did not however include the SoaLooper cshtml file.
SoaController.cs
public IActionResult GenerateSoa()
{
ClearAmounts();
#region Date management for SOA
// First day of Current Month
var FirstDateOfCurrentMonth = new DateTime(SD.DateToday.Year, SD.DateToday.Month, 1);
var PreviousMonthFirstDay = FirstDateOfCurrentMonth.AddMonths(-1);
var PreviousMonthLastDay = DateTime.DaysInMonth(SD.DateToday.Year, PreviousMonthFirstDay.Month);
****** Ommitted some code *****
// Get last day of Previews month
var PreviewsBalanceDate = PreviousMonthFirstDay.Month.ToString() + "/" +
PreviousMonthLastDay.ToString() + "/" + PreviousMonthFirstDay.Year.ToString();
#endregion Date management for SOA
//SD.GuiCustomerNum = customer.ToString();
var bsid_unpaid_payments = _context.BSIDs.Where(l =>
(l.UMSKZ == "" || l.UMSKZ != "C") && l.BLART == "DJ");
foreach (var payments in bsid_unpaid_payments)
{
SD.PAmount += Convert.ToDouble(payments.DMBTR);
}
SD.UPTotalAmount = SD.UPAmount - SD.PAmount;
return View();
}
public IActionResult SoaLooper(string customer, int company, DateTime asof)
{
string[] customerNum = customer.Split(',');
SD.GuiCompany = company.ToString();
SD.DateToday = asof;
foreach (var item in customerNum)
{
SD.GuiCustomerNumSelected = item.ToString();
RedirectToAction(nameof(GenerateSoa));
}
return View();
}
Index.cshtml
<div class="container h-100">
<div class="row h-100 justify-content-center align-items-center border">
<form method="post" class="col-12 text-center">
<div class="col-12 border-bottom">
<h2 class="text-primary">Statement of Account</h2>
</div>
<div class="col-8 pt-4">
<div class="form-group row">
<div class="col-4">
<label class="float-right">Customer</label>
</div>
<div class="col-8">
<input id="customer" name="customer" class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label class="float-right">Company Code</label>
</div>
<div class="col-8">
<select id="company" name="company" class="form-control">
<option value="">Select a number</option>
<option value="2000">2000</option>
<option value="3000">3000</option>
</select>
</div>
</div>
<div class="form-group row">
<div class="col-4">
<label class="float-right">Statement as of</label>
</div>
<div class="col-8">
<input id="asof" name="asof" type="date" class="form-control" />
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-4">
<div class="row">
<div class="col">
<button type="submit" formtarget="_blank" id="btnCheck"
class="btn btn-primary form-control" asp-action="SoaLooper">Generate</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
RedirectToAction doesn't open a new tab, it just returns a status code of 302 to tell the client to redirect.
If you really want to open multiple new tabs, you should do something like return a list of urls and then use window.open when the page loads.
I haven't tested it but you could do something like this:
Add your url to a list:
SoaController.cs
var newTabUrls = new List<string>();
foreach (var item in customerNum)
{
SD.GuiCustomerNumSelected = item.ToString();
newTabUrls.Add(nameof(GenerateSoa));
}
return View(newTabUrls);
Index.cshtml
<script type="text/javascript">
#if(Model?.Any() ?? false)
{
#foreach(var url in Model)
{
#:window.open(url, "_blank");
}
}
</script>
Open a URL in a new tab (and not a new window)
how to open a page in new tab on button click in asp.net?

Already sucess to add select form dyamically , but the data from success ajax cannot be send to the new select form

I'm trying to make a dependent dropdown, and it already works.
The problem is, the user want the second dropdown (in a different div) to be added dynamically but when we try to add a new dropdown, the new dropdown doesn't show any data when I choose value from first dropdown.
How to make the new dropdown contain data from ajax?
P.S: the option value is in another html where the ajax call the html if it succeeds.
This is the html:
$(document).ready(function() {
$("#dataselect").change(function() {
var urls = "{% url 'polls:load-column' %}";
var column = $(this).val();
$.ajax({
url: urls,
data: {
'column': column
},
success: function(data) {
$("#columnselect").html(data);
},
error: function(data) {
alert("error occured");
}
});
});
});
function appendBox() {
$('#test').append('<select id ="columnselect" style="width:425px;background-color:white;height:30px;font-color:red;text-align-last:center;"></select>')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="form-group">
<label class="control-label col-md-3">Table Name</label>
<div class="col-md-4">
<div class="input-group bootstrap-timepicker">
<div class="btn-group">
<select id="dataselect" style="width:425px;background-color:white;height:30px;font-color:red;text-align-last:center;">
</select>
</div>
</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-theme" onclick="appendBox()">Add</button>
<label class="control-label col-md-3">Column Name</label>
<div class="col-md-4" id="test">
<div class="input-group bootstrap-timepicker">
<div class="btn-group">
<select id="columnselect" style="width:425px;background-color:white;height:30px;font-color:red;text-align-last:center;">
</select>
</div>
</div>
</div>
</div>

how can I clone ajax dropdown

I've got a dropdown box which is populated with ajax according to what option i choose from another dropdown. I need to duplicate the dropdown box keeping the same options loaded via ajax, this is what i've done o far. Many thanks for your help
This is the code to get tha value from the first dropbox and then use it for ajax
$('#flatGroup').on('change',function(){
var countryID = $(this).val();
console.log(countryID);
if(countryID){
$.ajax({
type:'POST',
url:'../controllers/ctrl_admin_group_table_app/ctrl_admin_get_building_table.php',
data: {
group_id: countryID
},
success:function(html){
$('#flatTable-1').html(html);
$(".bs-select").selectpicker('refresh');
}
});
}
});
This is the code i'm using to close the second dropbox that receive the option from ajax
// start repeating form tabelle
//Start repeating form group add limit
var maxGroup1 = 5;
//add more fields group
var fieldGroup1= $(".fieldGroup1").clone();
$(".addMore1").click(function() {
var fgc1 = $('body').find('.fieldGroup1').length;
if (fgc1 < maxGroup1) {
var fieldHTML1 = '<div class="form-group fieldGroup1">' + fieldGroup1.html() + '<div class="col-md-1"><label class="control-label"> </label><i class="fa fa-close"></i></div></div>';
fieldHTML1 = fieldHTML1.replace('flatTable-1', 'flatTable-' + (fgc1 + 1));
fieldHTML1 = fieldHTML1.replace('flatMillesimi-1', 'flatMillesimi-' + (fgc1 + 1));
$('body').find('.fieldGroup1:last').after(fieldHTML1);
$('.bs-select').selectpicker({
iconBase: 'fa',
tickIcon: 'fa-check'
});
} else {
swal("Operazione Annullata", "Hai raggiunto il massimo numero di proprietari registrabili", "error");
}
});
//remove fields group
$("body").on("click", ".remove", function() {
$(this).parents(".fieldGroup1").remove();
});
// end repeating form
This is the HTML code
<div class="row">
<div class="col-md-9">
<div class="portlet-body form">
<div class="col-md-9">
<div class="mt-repeater">
<div data-repeater-list="group-b">
<div data-repeater-item class="row">
<div class="form-group fieldGroup1">
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Tabella</label>
<select class="form-control bs-select" id="flatTable-1" name="flatTable[]" title="Seleziona tabella millesimale"></select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">
<i class="fa fa-info-circle red tooltips" data-placement="top" data-original-title="Quota del titolare dell'immobile" ></i>Millessimi<span class="required"> * </span>
</label>
<input type="text" id="flatMillesimi-1" name="flatMillesimi[]" class="form-control" placeholder="Millessimi dell'immobile" >
</div>
</div>
</div> <!-- Fine field group -->
</div>
</div>
<!-- <hr> -->
<a href="javascript:;" data-repeater-create class="btn btn-info mt-repeater-add addMore1">
<i class="fa fa-plus"></i> Aggiungi tabella</a>
<br>
<br>
</div>
</div>
</div>
</div>
</div>

Set selected value of dropdowns from cookie

I have three dropdowns in my form, and I would like to not lose the data that the user has selected, even if I refresh or I navigate in other page and come back.
This is my view where I have the 3 dropdowns:
#using (Ajax.BeginForm("SearchForCars", "Home", null, new AjaxOptions { UpdateTargetId = "DivCategoriesTree", OnSuccess = "success", HttpMethod = "Post" }, new { make = "makes" }))
{
<div>
<div class="col-sm-4" style="height: 10em;display: flex;align-items: center ; padding-top:25px;">
<i class="fa fa-car" style="font-size:60px;color:red; padding-left:20px;"></i>
<strong style="padding-left:20px;">Vă rugăm să selectați vehiculul dumneavoastră!</strong>
</div>
<div class="col-sm-4">
<div style="padding-top:15px;">
<form class="form-control-static">
<div class="form-group">
<div class="row">
<div class="col-sm-10">
#if (ViewData.ContainsKey("makes"))
{
#Html.DropDownList("makes", ViewData["makes"] as List<SelectListItem>, "--Select car--", new { #class = "dropdown-toggle form-control" })
}
</div>
</div>
<div class="row">
<div class="col-sm-10">
<p></p>
#Html.DropDownList("models", new SelectList(string.Empty, "Value", "Text"), "--Select model--", new { #class = "dropdown-toggle form-control" })
</div>
</div>
<div class="row">
<p></p>
<div class="col-sm-10">
#Html.DropDownList("engines", new SelectList(string.Empty, "Value", "Text"), "--Select engine--", new { #class = "dropdown-toggle form-control" })
</div>
</div>
</div>
</form>
</div>
</div>
<div class="col-sm-4" style="height: 10em;display: flex;align-items: center ; padding-top:25px;">
<input type="submit" id="btnSearch" class="btn btn-default active" value="Cauta" disabled="disabled" style="width:150px;" />
</div>
</div>
}
</div>
Here are the 3 dropdowns:
I use cookies to store the data that the user has selected.
I tried to set the dropdown from the controller in this way:
public ActionResult Index()
{
var asa = HttpContext.Request.Cookies.Get("make_model_engine");
var model = asa.Values["model"].ToString();
var make = asa.Values["make"].ToString();
var makeList = new SelectList(makeRepository.GetMakes(), "ID", "Name");
ViewData["makes"] = makeList;
**var selected = makeList.Where(x => x.Value == make).First();
selected.Selected = true;**
return View();
}
Although it seems that the selected value is set correctly from cookies, it does not work, the dropdowns are not showing the selected value.
I guess that I should fix this in the view with javascript, but I'm new to javascript and I don't know what would be the best fix for this.
Can you please help me how can I resolve this?
Thank you!
You can pass the selected value you read from the cookie as the last parameter of the SelectList constructor:
var makeList = new SelectList(makeRepository.GetMakes(), "ID", "Name", make);

How To pass the modified data from dual listbox to controller?

I have created a form with two listboxes in which it is possible to move the items from one listbox into another.
The view also loads correctly, but I haven't figured out how to send the modified listbox data back to controller.
The view code is the following:
<script>
$(function() {
$(document)
.on("click", "#MoveRight", function() {
$("#SelectLeft :selected").remove().appendTo("#SelectRight");
})
.on("click","#MoveLeft", function() {
$("#SelectRight :selected").remove().appendTo("#SelectLeft");
});
});
#Html.Hidden("RedirectTo", Url.Action("UserManagement", "Admin"));
<h2>User</h2>
<div class="container">
<form role="form">
<div class="container">
<div class="row">
<div class="col-md-5">
<div class="form-group">
<label for="SelectLeft">User Access:</label>
<select class="form-control" id="SelectLeft" multiple="multiple" data-bind="options : ownership, selectedOptions:ownership, optionsText:'FirstName'">
</select>
</div>
</div>
<div class="col-md-2">
<div class="btn-group-vertical">
<input class="btn btn-primary" id="MoveLeft" type="button" value=" << " />
<input class="btn btn-primary" id="MoveRight" type="button" value=" >> " />
</div>
</div>
<div class="col-md-5">
<div class="form-group">
<label for="SelectRight">Owners:</label>
<select class="form-control" multiple="multiple" id="SelectRight" multiple="multiple" data-bind="options : availableOwners, selectedOptions:availableOwners, optionsText:'FirstName'">
</select>
</div>
</div>
</div>
</div>
</form>
</div>
<script>
var data=#(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
var selectedOwners = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.AccessOwners));
var availableOwners = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.Owners));
function viewModel() {
this.username=ko.observable(data.Username);
this.password=ko.observable(data.Password);
this.email=ko.observable(data.Email);
this.isActive=ko.observable(data.IsActive);
this.userId = ko.observable(data.UserId);
this.ownership=ko.observableArray(selectedOwners);
this.availableOwners = ko.observableArray(availableOwners);
this.submit = function()
{
$.ajax({
url: '#Url.Action("UserSave", "Admin")',
type: 'POST',
data: ko.toJSON(this),
contentType: 'application/json',
});
window.location.href = url;
return false;
}
this.cancel = function()
{
window.location.href = url;
return false;
}
};
ko.applyBindings(new viewModel());
var url = $("#RedirectTo").val();
I would be very thankful if anyone could suggest the way to pass all the selected options back to controller by populating the data with modified lists when the submit function is executed.
Thanks!
Before form submission save one side items values in an hidden input element. (comma separated values of listbox items.) The value of hidden element is sent to server by submitting the form. In controller you can do the next things.

Categories