Submit only first time knockout.js and bootstrap modal - javascript

I have problem, with knockout.js and bootstrap modal. On button click i open bootastrap modal, for creating new city. Then i submit form and save in base. Problem is because submiting works only first time. After that it doesn't work.
Here is how it look like
html file
> <!-- Modal add new city
> ==================================================-->
> <div class="modal fade" id="addCity" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
> <div class="modal-dialog">
> <form data-bind="submit: onSubmit">
> <div class="modal-content">
> <div class="modal-header">
> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
> <h4 class="modal-title">Dodaj novi grad</h4>
> </div>
> <div class="modal-body">
> <div class="input-group">
> <span class="input-group-addon">Ime grada</span>
> <input type="text" class="form-control" placeholder="Ime grada" data-bind="value : city_name">
> </div
>
>
> </div>
> <div class="modal-footer">
> <button type="button" class="btn btn-default" data-dismiss="modal">Zatvori</button>
> <button type="submit" class="btn btn-success">Sacuvaj</button>
> </div>
> </div><!-- /.modal-content -->
> </form>
> </div><!-- /.modal-dialog -->
> </div><!-- /.modal -->
js file
var viewModel = ko.computed(function()
{
var self = this;
var cities = getAllCities();
self.cities = ko.observableArray(cities);
self.city_name = ko.observable();
self.logo_path = ko.observable();
//add new city
self.onSubmit = function()
{
var data = JSON.stringify(
{
city_name : self.city_name(), logo_path : self.logo_path()
}); // prepare request data
var response = ajaxJsonPost("/services/private_service/add_city", data, false, false);
if (response.status === ResponseStatus.SUCCESS) {
$("#cityName").attr("value", "");
$('#addCity').modal('hide');
self.cities.push(data);
} else {
//handle error
}
};
});
ko.applyBindings(new viewModel());

Can you not just do an ajax request instead of a form submit? Something like:
$.ajax({
url: "/services/private_service/add_city",
data: data,
success: function (data) {
$("#cityName").attr("value", "");
$('#addCity').modal('hide');
self.cities.push(data);
}
});
Unless you have written script for this method, I'm not familiar with "ajaxJsonPost()".

Related

no ajax complexion inside bootstrap modal

I create a modal and inside I insert an input field. When I write inside this input field a product name term, it must appear all the terms.
On blank page, I can see for ap (apple terms) all the apple products, no problem my ajax works fine
Now inside a page with some html element, I call a modal when there is my input fields. In this case, the ajax complexion does not work and inside the console log / result, I see my input field and not the result about my request.
I do not understand where my error below the result with a picture.
My modal call : works very fine
<!-- Link trigger modal -->
<div class="row">
<div class="col-md-12">
<div class="form-group row">
<label for="<?php echo $this->getDef('text_select_products'); ?>" class="col-5 col-form-label"><?php echo $this->getDef('text_select_products'); ?></label>
<div class="col-md-5">
<a
href="<?php echo $this->link('SelectPopUpProducts'); ?>"
data-bs-toggle="modal" data-refresh="true"
data-bs-target="#myModal"><?php echo '<h4><i class="bi bi-plus-circle" title="' . $this->getDef('icon_edit') . '"></i></h4>'; ?></a>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<div class="te"></div>
</div>
</div> <!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</div>
</div>
</div>
</div>
<script src="<?php echo this->link('modal_popup.js'); ?>"></script>
now my modal with the field displayed
<div class="col-md-12">
<div class="form-group row">
<label for="<?php echo $this->getDef('text_products_name') ; ?>" class="col-5 col-form-label"><?php echo $this->getDef('text_products_name') ; ?></label>
<div class="col-md-7">
<?php echo HTML::inputField('products_name', '', 'id="ajax_products_name" list="products_list" class="form-control"'); ?>
<datalist id="products_list"></datalist>
</div>
</div>
</div>
<?php $products_ajax = $this->link('ajax/products.php'); ?>
<script>
window.addEventListener("load", function(){
// Add a keyup event listener to our input element
document.getElementById('ajax_products_name').addEventListener("keyup", function(event){hinterManufacturer(event)});
// create one global XHR object
// so we can abort old requests when a new one is make
window.hinterManufacturerXHR = new XMLHttpRequest();
});
// Autocomplete for form
function hinterManufacturer(event) {
var input = event.target;
var ajax_products_name = document.getElementById('products_list'); //datalist id
// minimum number of characters before we start to generate suggestions
var min_characters = 0;
if (!isNaN(input.value) || input.value.length < min_characters ) {
return;
} else {
window.hinterManufacturerXHR.abort();
window.hinterManufacturerXHR.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse( this.responseText );
ajax_products_name.innerHTML = "";
response.forEach(function(item) {
// Create a new <option> element.
var option = document.createElement('option');
option.value = item.id + ' - ' + item.name;//get name
option.hidden = item.id; //get id
ajax_products_name.appendChild(option);
});
}
};
window.hinterManufacturerXHR.open("GET", "<?php echo $products_ajax ; ?>?q=" + input.value, true);
window.hinterManufacturerXHR.send()
}
}
</script>
Addedd js open modal
$( document ).ready(function() {
$("#myModal").on("show.bs.modal", function(e) {
const link = $(e.relatedTarget);
$(this).find(".modal-body").load(link.attr("href"));
});
});
there the screen shot of the result.
console result
Maybe the event keyup never fires because the input ajax_products_name doesn't exists until shown.bs.modal event is fired.
Try:
$("#myModal").on("shown.bs.modal", function(ev) {
document.getElementById('ajax_products_name').addEventListener("keyup", function(event) {
hinterManufacturer(event)
});
})
Let's set up an example
$('#exampleModal').on('shown.bs.modal', function() {
// $('#myInput').trigger('focus')
console.log("modal opened, *now* can addEventListener to stuff within modal")
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/jquery#3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
Anyway, The idea is to do the addEventListener on the ajax_products_name only after it's loaded. So given your new snippet, try this:
// instead of
$(this).find(".modal-body").load(link.attr("href"));
// do:
$(this).find(".modal-body").load(link.attr("href"), function(responseTxt, statusTxt, xhr) {
if (statusTxt == "success") {
// now that modal is opened AND content loaded
document.getElementById('ajax_products_name').addEventListener("keyup", function(event) {
hinterManufacturer(event)
})
}
});

Change text in modal boostrap

I'm using modal bootstrap in my asp.net web site.
Since I need to modify the text according to the errors to return in the code behind I change the text value of the control before making the call but it doesn't work. Message don't change.
This my HTML:
<!-- /.modal error-->
<div id="ModalError" class="modal fade bs-example-modal-center" tabindex="-1" role="dialog" aria-labelledby="myCenterModalLabel" aria-hidden="true" style="display: none;">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content alert-primary">
<div class="modal-header">
<h4 class="modal-title text-danger" id="CenterModalLabel">Errore</h4>
<i class="mdi mdi-alert-octagon-outline" style="font-size:30px"></i>
</div>
<div class="modal-body">
<asp:Label runat="server" ID="ltlErrormsg" Text="Errore"></asp:Label>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-danger" data-dismiss="modal">Ok</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<script>
function openModal() {
$('#ModalInfo').modal('show');
}
function openModalErr() {
$('#ModalError').modal('show');
}
ValidatorUpdateIsValid = function () {
Page_IsValid = AllValidatorsValid(Page_Validators);
SetValidatorStyles();
}
SetValidatorStyles = function () {
var i;
// clear all
for (i = 0; i < Page_Validators.length; i++) {
var inputControl = document.getElementById(Page_Validators[i].controltovalidate);
if (null != inputControl) {
WebForm_RemoveClassName(inputControl, 'parsley-error');
}
}
// set invalid
for (i = 0; i < Page_Validators.length; i++) {
inputControl = document.getElementById(Page_Validators[i].controltovalidate);
if (null != inputControl && !Page_Validators[i].isvalid) {
WebForm_AppendToClassName(inputControl, 'parsley-error');
}
}
}
</script>
This my code behind:
Private Sub cmdCambiaPwd_Click(sender As Object, e As EventArgs) Handles cmdCambiaPwd.Click
Dim strOldPassword As String
If txtPassword.Value = "" Then
ltlErrormsg.Text = "Compilare le password"
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "Pop", "openModalErr();", True)
Exit Sub
End If
I've found problem.
Modal windows are out of an update panel in my page.
So I move them in updatepanel and work.

How to pass a parameter to a modal form using Ajax

I have a razor page that displays a list of expenses for the Report selected. I have an "Add Expense" button on the page that brings up a modal. The modal is a partial View of the form. What i need to do is pass the ExpenseId to the modal. I can get the Id from the url like this
#{ var expenseId = Request.Url.Segments[3]; }
the button currently looks like this
<button type="button" data-toggle="modal" data-target="#expenseModal_#expenseId" data-id="#expenseId" class="btn btn-primary" id="addExpenses">
Add Expense
</button>
There are a few things in this that i do not know if i even need them. I was trying different things.
Modal
<!-- MODAL -->
<div class="modal fade" id="expenseModal_#expenseId" tabindex="-1" role="dialog" aria-labelledby="expenseModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="expenseModalLabel"> Expences </h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div> <!-- MODEL HEADER-->
<div class="modal-body">
</div> <!-- MODAL BODY-->
</div>
</div>
Javascript
<script type="text/javascript">
$(document).ready(function () {
$("#addExpenses").click(function () {
$(".modal-body").html('');
$.ajax({
type: 'GET',
url: '#Url.Action("_ExpenseForm", "Admin")',
data: { type: $(this).attr("data-type") },
success: function (response) {
$(".modal-body").html(response);
$("#expenseModal").modal('show');
},
error: function () {
alert("Something went wrong");
}
});
});
});
</script>
The expense Id has to be inserted in the form so that when it is saved it saves it to the correct Expense report.
Controller actions
ExpensesDataAcessLayer objexpense = new ExpensesDataAcessLayer();
public ActionResult ExpenseReports()
{
return View(db.ExpenseReports.ToList());
}
public ActionResult Expenses(int ExpenseId)
{
return View(db.Expenses.Where(x => x.ExpenseId == ExpenseId).ToList());
}
public ActionResult _ExpenseForm()
{
CustomerEntities customerEntities = new CustomerEntities();
List<SelectListItem> categoryItem = new List<SelectListItem>();
ExpensesViewModel casModel = new ExpensesViewModel();
List<ExpenseTypes> expensetypes = customerEntities.ExpenseType.ToList();
expensetypes.ForEach(x =>
{
categoryItem.Add(new SelectListItem { Text = x.CategoryItem, Value = x.ItemCategoryId.ToString() });
});
casModel.ExpenseTypes = categoryItem;
return View(casModel);
}
Thanks for your help!
You can store expenseId into hidden field, like this
<input id="expenseId" name="expenseId" type="hidden" value="#Request.Url.Segments[3]">
Then you can get like this
$("#addExpenses").click(function () {
var expenseId = $("#expenseId").val();
// after code here
Updated
You can get expenseId like this
var expenseId = $(this).attr("data-id")
Then you can assign it to hidden field or anywhere in Model, Like this
<!-adding aditional input into HTML in MODEL-!>
<input id="expenseId" name="expenseId" type="hidden" value="">
<!- Javascript-!>
var expenseId = $(this).attr("data-id")
expenseId.val(expenseId );

Uncaught RangeError: Maximum call stack size exceeded and [Violation] 'click' handler took

I checked other post like this but honestly I don't find a solution. I have a button "test", and when I hit the button theoretically I gotta open up a new window showing a query result but, I'm getting this error and honestly I'm not understanding why!
In item_action.php I wrote this code just for test:
if ($_POST['btn_action'] == 'item_view') { //View Item details
echo "test";
}
Below the code in the javascript file
//OPEN DETAIL ITEM WINDOW IN MODE VIEW
$('#test').on('click', function() {
//var item_id = $(this).attr("id");
//Declare 2 vars
var item_id = 3;
var btn_action = 'item_view';
$('#productModalView').modal('show');
$.ajax({
url: "item_action.php",
method: "POST",
data: {
product_id: product_id,
btn_action: btn_action
},
success: function(critto) {
$('#itemview').html(critto);
},
error: function() {
$('<div>').html('Found an error!');
}
});
});
<div id="productModalView" class="modal fade">
<div class="modal-dialog">
<form method="post" id="product_form_view">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"><i class="fa fa-plus"></i>Item Product</h4>
</div>
<!-- Close Modal Header -->
<div class="modal-body">
<div id="itemview"></div>
</div>
<!-- Close Modal Body-->
<div class="modal-footer">
<input type="hidden" name="product_id" id="product_id" />
<input type="hidden" name="btn_action" id="btn_action" />
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
<!-- Close Modal Footer -->
</div>
<!-- Close Modal Content -->
</form>
<!-- Close Form -->
</div>
<!-- Close Modal-Dialog -->
</div>
<!-- Close Product Modal -->
Any idea how to fix it???

Can't load 2 different modal forms with JQuery Trigger

I have some modal forms to complete some fields, in this case I have 2 modal forms, 1 for Jury and 1 for Contact, when I press 'Add' link, in both cases works fine, but the problem is when I want to edit contact.
When I press Edit in both cases I call controller to complete the Java form and then, return to view and simulate a click in "Add" button with JQuery. In jury case works fine, but in Contact I only get a dark screen (like if modal works), but modal window never appear. Other problem is, when I press Edit button in Jury and then close the jury modal form, when I press Edit in Contact it launch the jury modal form...
Contact Modal and Add link (Edit link doesn't works)
<div class="row margin-top-10">
<div class="col-xs-2 col-md-2 col-md-push-10">
<a id="btnAddCForm" href="#modal-cForm-form" data-toggle="modal" class="btn fpa btn-block pull-right">AÑADIR NUEVO</a>
</div>
</div>
<div id="modal-cForm-form" class="modal fade" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"></button>
<h4 class="modal-title">Nuevo/Editar Forma de contacto</h4>
</div>
<div class="modal-body">
<div class="scroller" style="height:390px" data-always-visible="1" data-rail-visible1="1">
Some fields
</div>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn default">CANCELAR</button>
<button type="button" onclick="addContactForm();" class="btn fpa">ACEPTAR</button>
</div>
</div>
</div>
</div>
Jury Modal and Add link (Works fine)
<div class="row margin-top-10">
<div class="col-xs-2 col-md-2 col-md-push-10">
<a id="btnAddJurado" href="#modal-jury-form" data-toggle="modal" class="btn fpa btn-block pull-right">AÑADIR NUEVO</a>
</div>
</div>
<div id="modal-jury-form" class="modal fade" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" onclick="resetValues();"></button>
<h4 class="modal-title">Nuevo/Editar Jurado</h4>
</div>
<div class="modal-body">
<div class="scroller" style="height:300px" data-always-visible="1" data-rail-visible1="1">
Some Fields
</div>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" onclick="resetValues();" class="btn default">CANCELAR</button>
<button type="button" onclick="addJury();" class="btn fpa">ACEPTAR</button>
</div>
</div>
</div>
</div>
Onload (In main html document)
window.onload = function () {
/*<![CDATA[*/
var idJuryAux = /*[[${person.juryAux.id}]]*/
null;
var idContactFormAux = /*[[${person.contactFormAux.id}]]*/
null;
/*]]>*/
var idProvincia = $('#provinceField').val();
var idPais = $('#countryField').val();
if (idPais == '-1') {
$('#provinceField').attr("readonly", true);
} else {
$('#provinceField').attr("readonly", false);
}
if (idProvincia == '-1') {
$('#cityField').attr("readonly", true);
} else {
$('#cityField').attr("readonly", false);
}
if (idJuryAux != null) {
/*<![CDATA[*/
var idCat = /*[[${person.juryAux.category}]]*/
null;
var idCargo = /*[[${person.juryAux.juryType}]]*/
null;
var catName = /*[[${person.juryAux.categoryName}]]*/
null;
var cargoName = /*[[${person.juryAux.juryTypeName}]]*/
null;
/*]]>*/
$('#btnAddJurado').trigger('click');
$("#categoryField").select2('data', {
id: idCat,
text: catName
});
$("#juryTypeField").select2('data', {
id: idCargo,
text: cargoName
});
}
if (idContactFormAux != null) {
/*<![CDATA[*/
var idType = /*[[${person.contactFormAux.type}]]*/
null;
var typeName = /*[[${person.contactFormAux.typeName}]]*/
null;
var idTag = /*[[${person.contactFormAux.tag}]]*/
null;
var tagName = /*[[${person.contactFormAux.tagName}]]*/
null;
var idPais = /*[[${person.contactFormAux.country}]]*/
null;
var paisName = /*[[${person.contactFormAux.countryName}]]*/
null;
var idProvincia = /*[[${person.contactFormAux.province}]]*/
null;
var provName = /*[[${person.contactFormAux.provinceName}]]*/
null;
var idCity = /*[[${person.contactFormAux.city}]]*/
null;
var cityName = /*[[${person.contactFormAux.cityName}]]*/
null;
var idInst = /*[[${person.contactFormAux.institution}]]*/
null;
var instName = /*[[${person.contactFormAux.institutionNme}]]*/
null;
/*]]>*/
$('#btnAddCForm').trigger('click');
$("#typeField").select2('data', {
id: idType,
text: typeName
});
$("#tagField").select2('data', {
id: idTag,
text: tagName
});
$("#countryField").select2('data', {
id: idPais,
text: paisName
});
$("#provinceField").select2('data', {
id: idProvincia,
text: provName
});
$("#cityField").select2('data', {
id: idCity,
text: cityName
});
$("#institutionField").select2('data', {
id: idInst,
text: instName
});
}
}
P.S. addJury(); and addContactForm(); only closes modal window, both works fine!
EDIT: I'm still waiting for a response...

Categories

Resources