I'm using Knockout Validation and when I post the view model to the controller I'm getting the exception "Uncaught RangeError: Maximum call stack size exceeded". I have one Main View Model because I'm using the CustomerViewModel in the same view (2 bootstrap modals), the first is to create a customer and the other one is to edit customer. Any idea of why is throwing the exception?
[HttpPost]
public JsonResult SaveCustomer(Customer model)
{
string status = "ok";
return Json(status, JsonRequestBehavior.AllowGet);
}
public class Customer
{
public string Name { get; set; }
}
$(document).ready(function () {
var CustomerSetupViewModel = function () {
var self = this;
self.Name = ko.observable("");
self.Validation = ko.validatedObservable([
self.Name.extend({
required: true
})
]);
var CustomerSetup = {
Name: self.Name
};
self.CustomerSetup = ko.observable();
self.GetCustomer = function () {
var data = { Name: "ToBeUpdated" };
self.CustomerSetup(data);
}
self.Save = function () {
if (self.Validation.isValid()) {
$.post("/Home/SaveCustomer", self, function (data) {
if (data == "ok")
alert("successful");
else
alert("error");
});
}
else {
self.Validation.errors.showAllMessages();
}
}
self.Update = function () {
var name = self.CustomerSetup().Name;
alert(name);
}
}
var MainViewModel = function () {
self = this;
self.NewCustomer = new CustomerSetupViewModel();
self.EditCustomer = new CustomerSetupViewModel();
}
vm = new MainViewModel();
ko.applyBindings(vm);
$("#updateCustomer").click(function () {
vm.EditCustomer.GetCustomer();
});
$("#NewCustomer").on("show.bs.modal", function (e) {
vm.NewCustomer.Name("");
vm.NewCustomer.Validation.errors.showAllMessages(false);
})
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<hr />
<a id="addCustomer" class="btn btn-default" data-toggle="modal" data-target="#NewCustomer">Add Customer</a>
<a id="updateCustomer" class="btn btn-default" data-toggle="modal" data-target="#UpdateCustomer">Update Customer</a>
<!-- Modal -->
<div id="NewCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="NewModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="NewModalLabel">New Customer</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading"></div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<label>Customer Name</label>
<input type="text" id="Name" class="form-control" data-bind="value: NewCustomer.Name" />
</div>
</div>
</div>
<div class="modal-footer">
<a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
<a role="button" class="btn btn-primary" data-bind="click: NewCustomer.Save()">Save</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div id="UpdateCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="UpdateModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="UpdateModalLabel">Update Customer</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading"></div>
<div class="panel-body" data-bind="foreach: EditCustomer.CustomerSetup">
<div class="row">
<div class="col-md-4">
<label>Customer Name</label>
<input type="text" id="Name" class="form-control" data-bind="value: Name" />
</div>
</div>
</div>
<div class="modal-footer">
<a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
<a role="button" class="btn btn-primary" data-bind="click: EditCustomer.Update">Update</a>
</div>
</div>
</div>
</div>
</div>
</div>
<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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout-validation/2.0.3/knockout.validation.js"></script>
I found the solution after using ko.toJSON() in the Save function. ko.toJSON() produces a JavaScript object with no Knockout constructs. And in that way I avoid the infinite loop.
self.Save = function () {
if (self.Validation.isValid()) {
$.post("/Home/SaveCustomer", ko.toJSON(self), function (data) {
if (data == "ok")
alert("successful");
else
alert("error");
});
}
else {
self.Validation.errors.showAllMessages();
}
}
Related
$('form').submit(function () {
value = true;
var schoolName = $('#addSchoolName').val();
if (schoolName.trim() == '') {
$('#addSchoolName').addClass('border border-danger');
value = false;
}
if (value) {
return true;
}
else { return false;}
});
$("form").bind('ajax:complete', function () {
window.location.reload();
});
$('#close').on('click', function () {
$('#addSchoolName').removeClass('border border-danger');
$('#addSchoolName').val('');
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="modal fade" id="addSchool" tabindex="-1" role="dialog" aria-labelledby="addSchoolTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered cls" role="document">
<div class="modal-content">
<div class="modal-header">
<label class="modal-title" id="addSchoolTitle">Add School Details</label>
</div>
<form asp-action="AddNewSchool" asp-controller="School" asp-antiforgery="true" method="post">
<div class="modal-body form-group row align-items-center">
<div class="col-md-4">
<label for="Name">School Name</label>
</div>
<div class="col-md-8">
<input class="form-control" name="Name" id="addSchoolName" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary " id="close" data-dismiss="modal">Close</button>
<button type="submit" id="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
I am using form inside modal and submitting that form. I want to reload my page So that after form submission the list behind that modal will update. I do not want to use Ajax call for form submission.
<div class="modal fade" id="addSchool" tabindex="-1" role="dialog" aria-labelledby="addSchoolTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered cls" role="document">
<div class="modal-content">
<div class="modal-header">
<label class="modal-title" id="addSchoolTitle">Add School Details</label>
</div>
<form asp-action="AddNewSchool" asp-controller="School" asp-antiforgery="true" method="post">
<div class="modal-body form-group row align-items-center">
<div class="col-md-4">
<label for="Name">School Name</label>
</div>
<div class="col-md-8">
<input class="form-control" name="Name" id="addSchoolName" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary " id="close" data-dismiss="modal">Close</button>
<button type="submit" id="submit" class="btn btn-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
and write now I am applying this validation on the form.
#section scripts{
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script type="text/javascript">
$('form').submit(function () {
value = true;
var schoolName = $('#addSchoolName').val();
if (schoolName.trim() == '') {
$('#addSchoolName').addClass('border border-danger');
value = false;
}
if (value) {
return true;
}
else { return false;}
});
$("form").bind('ajax:complete', function () {
window.location.reload();
});
$('#close').on('click', function () {
$('#addSchoolName').removeClass('border border-danger');
$('#addSchoolName').val('');
});
</script>
I do not wants to use ajax call for form submission, I want to reload the page after submitting the form inside modal so that the list behind that modal will be updated.
I'm a bit confused because by default it should be reloading on the submit function. This is why we use event.preventDefault at the end. but if you want there is always location.reload
https://www.w3schools.com/jsref/met_loc_reload.asp
I want to use search bar inside bootstrap 4 modal header and display the search results in modal body with ajax get request.
Request is successful but,I can't get the results to show in the modal.
How do I display the results from request preview in a modal?
Controller:
public function index()
{
....
//MODAL IS A PARTIAL ON THE INDEX PAGE
return view('friends.index',compact('friends','friendRequests'));
}
public function search(Request $request)
{
if ($request->has('name')) {
$name = $request->query('name');
$results = User::where('name','like','%'.$name.'%')->get();
} else {
$results = User::all();
}
//RETURNING THE MODEL PARTIAL,BUT WITH RESULTS
return view('layouts.partials.friends.modal',compact('results'));
}
Relevant routes:
Route::get('/friends','FriendsController#index')->name('friends');
Route::get('/friends/search','FriendsController#search')
->name('searchFriend');
Index view:
<div class="container my-5">
<div class="row">
<h4><i class="fas fa-user-friends"> Friends:</i></h4>
</div>
<div class="row">
<button type="button" class="btn btn-outline-success mx-auto btn-lg"
data-toggle="modal" data-target=".add-friends-modal">
Add new <i class="fas fa-user-plus"></i>
</button>
</div>
//MODAL PARTIAL IS INCLUDED HERE
#include('layouts.partials.friends.modal')
<hr>
#include('layouts.partials.friends.friends-list')
Modal partial:
<div class="modal fade add-friends-modal" tabindex="-1" role="dialog"
aria-labelledby="friends-modal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header ">
<div class="container">
<div class="row">
<div class="col-6 offset-3">
<h5 class="modal-title text-center">Add new friend:</h5>
</div>
<div class="row mx-auto">
<form class="form-inline mt-4 mb-4" action="javascript:search();">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"
id="search-input">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">
<i class="fas fa-search"></i>
</button>
</form>
</div>
</div>
</div>
<button type="button" class="close pull-right" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
//RESULTS SHOULD BE DISPLAYED HERE
#if(isset($results) && count($results)>0)
<ul>
#foreach($results as $result)
<li>{{ $result->name }}</li>
#endforeach
</ul>
#endif
</div>
</div>
searchAJAX.js
function search() {
var userInput = document.getElementById("search-input").value;
var xhttp = new XMLHttpRequest();
xhttp.open('GET','/friends/search?name='+userInput,true);
xhttp.send();
}
I suggest return just data instead of view. You can do something like that.
public function index()
{
....
//MODAL IS A PARTIAL ON THE INDEX PAGE
return view('friends.index',compact('friends','friendRequests'));
}
public function search(Request $request)
{
if ($request->has('name')) {
return User::where('name','like','%'.$name.'%')->get();
}
return response([]);
}
Modal Partial
<div class="modal fade add-friends-modal" tabindex="-1" role="dialog"
aria-labelledby="friends-modal" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header ">
<div class="container">
<div class="row">
<div class="col-6 offset-3">
<h5 class="modal-title text-center">Add new friend:</h5>
</div>
<div class="row mx-auto">
<form class="form-inline mt-4 mb-4" action="javascript:search();">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search"
id="search-input">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">
<i class="fas fa-search"></i>
</button>
</form>
</div>
</div>
</div>
<button type="button" class="close pull-right" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="results"></div>
</div>
</div>
And JS File
function search() {
var resultsDiv = document.getElementById("results");
var req = new XMLHttpRequest();
req.responseType = "json";
req.open("GET", url, true);
req.onload = function() {
var users = req.response;
var content = "<ul>";
for (var user in users) {
content += "<li>" + user.name + "</li>";
}
content += "</ul>";
resultsDiv.innerHTML = content;
};
req.send(null);
}
Hi I have the same problem as this thread twitter bootstrap modal won't work on first call
I tried to follow the answer and replace $('#modal').modal('toggle') to $('#modal').modal('show'). It still only registers on the second click. (you have to click on the poster 2 times to show modal, and you have to click on 'Select' button 2 times to close it).
Here's my code: Javascript
var zipcode = 92660;
var showDate = '2018-06-10';
var selectedMovieTitles = [];
var selectedMoviePosters = [];
var selectState = false;
var tmsURL = 'http://data.tmsapi.com/v1.1/movies/showings?startDate=' + showDate + '&zip=' + zipcode + '&api_key=' + tmsAPIKey;
$('#button').on('click', function () {
getMovieList();
});
function litmitMovieSelect() {
$('#limitSelection').modal('show');
}
function selectMovie() {
$(this).on('click', function () {
$('#movieInfoModal').modal('hide');
if (selectedMovieTitles.length >= 3) {
litmitMovieSelect();
}
else {
selectState = true;
selectedMovieTitles.push($(this).attr('data-title'));
selectedMoviePosters.push($(this).attr('data-poster'));
$(`.posters[data-title='${$(this).attr('data-title')}']`).css('border', '3px solid #008000');
$(`.posters[data-title='${$(this).attr('data-title')}']`).attr('data-state-selected', selectState);
console.log('selected movie titles: ' + selectedMovieTitles);
}
});
}
function launchModal() {
$(this).on('click', function () {
selectState = false;
$(this).css('border', '');
var titleToBeRemove = $(this).attr('data-title');
if (selectedMovieTitles.indexOf(titleToBeRemove) !== -1) {
selectedMovieTitles.splice(selectedMovieTitles.indexOf(titleToBeRemove), 1);
}
$('.modal-title').text($(this).attr('data-title'));
var movieInfoDiv = $(`<div>
<p><strong>Actors:</strong> ${$(this).attr('data-actors')}</p>
<p><strong>Director:</strong> ${$(this).attr('data-director')}</p>
<p><strong>Genre:</strong> ${$(this).attr('data-genre')}</p>
<p><strong>Year:</strong> ${$(this).attr('data-year')}</p>
<p><strong>Duration:</strong> ${$(this).attr('data-runtime')}</p>
<p><strong>Rating:</strong> ${$(this).attr('data-rating')}</p>
<p><strong>Plot:</strong> ${$(this).attr('data-plot')}</p>
</div>`)
$('.modal-body').html(movieInfoDiv);
var selectButton = $(` <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" data-title="${$(this).attr('data-title')}" data-poster="${$(this).attr('data-poster')}">
Select
</button>`)
selectButton.on('click', selectMovie);
$('#movieInfoModalFooter').html(selectButton);
$('#movieInfoModal').modal('show');
});
}
function getMovieList() {
var movieTitles = [];
axios.get(tmsURL)
.then(function (tmsResp) {
console.log(tmsResp);
tmsResp.data.forEach(function (element) {
movieTitles.push(element.title);
});
console.log(movieTitles);
movieTitles.forEach(function (element) {
var omdbURL = 'https://omdbapi.com/?t=' + element + '&apikey={}';
axios.get(omdbURL)
.then(function (omdbResp) {
console.log(omdbResp);
var posterDiv = $(`<img class='posters m-3' id='${omdbResp.data.imdbID}'
data-title='${omdbResp.data.Title}'
data-actors='${omdbResp.data.Actors}'
data-director='${omdbResp.data.Director}'
data-genre='${omdbResp.data.Genre}'
data-plot='${omdbResp.data.Plot}'
data-year='${omdbResp.data.Year}'
data-runtime='${omdbResp.data.Runtime}'
data-rating='${omdbResp.data.imdbRating}'
data-poster='${omdbResp.data.Poster}'
src=${omdbResp.data.Poster}
>`);
posterDiv.on('click', launchModal);
$('#movie-display').append(posterDiv);
})
.catch(function (err) {
console.error(err);
});
});
}).catch(function (err) {
console.error(err);
});
}
Here's the HTML:
<div class="modal fade" id="litmitSelection" tabindex="-1" role="dialog" aria-labelledby="litmitSelection" aria-hidden="true">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-body">
Sorry, You Can Only Select Up To 3 Movies.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Movie Info Modal -->
<div class="modal fade" id="movieInfoModal" tabindex="-1" role="dialog" aria-labelledby="movieInfoModal" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">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" id="movieInfoModalFooter">
<!-- <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> -->
<!-- <button type="button" class="btn btn-primary">Select</button> -->
</div>
</div>
</div>
</div>
Something like this would suffice.
Note: I assume you are using bootstrap 4 for your project, although bootstrap 3 would work too, just tweak it a bit to suit your needs
$(document).ready(function() {
/**
* for showing edit item popup
*/
$(document).on('click', "#edit-item", function() {
$(this).addClass('edit-item-trigger-clicked'); //useful for identifying which trigger was clicked and consequently grab data from the correct row and not the wrong one.
var options = {
'backdrop': 'static'
};
$('#edit-modal').modal(options)
})
// on modal show
$('#edit-modal').on('show.bs.modal', function() {
var el = $(".edit-item-trigger-clicked"); // See how its usefull right here?
/*
You now have a reference to which element caused the modal to showup , you can use this to do anything as shown below
*/
var row = el.closest(".data-row");
// get the data
var id = el.data('item-id');
var name = row.children(".name").text();
var description = row.children(".description").text();
// fill the data in the input fields
$("#modal-input-id").val(id);
$("#modal-input-name").val(name);
$("#modal-input-description").val(description);
})
// on modal hide
$('#edit-modal').on('hide.bs.modal', function() {
$('.edit-item-trigger-clicked').removeClass('edit-item-trigger-clicked')
$("#edit-form").trigger("reset");
})
})
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<div class="main-container container-fluid">
<!-- heading -->
<div class="container-fluid">
<div class="row">
<div class="col">
<h1 class="text-primary mr-auto">Example list</h1>
</div>
</div>
</div>
<!-- /heading -->
<!-- table -->
<table class="table table-striped table-bordered" id="myTable" cellspacing="0" width="100%">
<thead class="thead-dark">
<tr>
<th>#</th>
<th> Name</th>
<th> Description</th>
<th> Action</th>
</tr>
</thead>
<tbody>
<tr class="data-row">
<td class="align-middle iteration">1</td>
<td class="align-middle name">Name 1</td>
<td class="align-middle word-break description">Description 1</td>
<td class="align-middle">
<button type="button" class="btn btn-success" id="edit-item" data-item-id="1">edit</button>
</td>
</tr>
</tbody>
</table>
<!-- /table -->
</div>
<!-- Attachment Modal -->
<div class="modal fade" id="edit-modal" tabindex="-1" role="dialog" aria-labelledby="edit-modal-label" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="edit-modal-label">Edit Data</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="attachment-body-content">
<form id="edit-form" class="form-horizontal" method="POST" action="">
<div class="card text-white bg-dark mb-0">
<div class="card-header">
<h2 class="m-0">Edit</h2>
</div>
<div class="card-body">
<!-- id -->
<div class="form-group">
<label class="col-form-label" for="modal-input-id">Id (just for reference not meant to be shown to the general public) </label>
<input type="text" name="modal-input-id" class="form-control" id="modal-input-id" required>
</div>
<!-- /id -->
<!-- name -->
<div class="form-group">
<label class="col-form-label" for="modal-input-name">Name</label>
<input type="text" name="modal-input-name" class="form-control" id="modal-input-name" required autofocus>
</div>
<!-- /name -->
<!-- description -->
<div class="form-group">
<label class="col-form-label" for="modal-input-description">Email</label>
<input type="text" name="modal-input-description" class="form-control" id="modal-input-description" required>
</div>
<!-- /description -->
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Done</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- /Attachment Modal -->
I have the following code, is an example of one view model that I'm using in two sections (2 bootstrap modals). But I can't access the value from the second view model "UpdateviewModel". When I click Save button in the first Modal there is no problem, I get the Name value, but when I click Update button in the second modal the Name value is undefined. What am I doing wrong?
$(document).ready(function () {
CustomerSetupViewModel = function () {
var self = this;
self.Name = ko.observable();
var CustomerSetup = {
Name: self.Name
};
self.CustomerSetup = ko.observable();
self.GetCustomer = function () {
var data = { Name: "A00622" };
self.CustomerSetup(data);
}
Save = function () {
var test = viewModel.Name();
}
Update = function () {
var test2 = UpdateviewModel.Name();
}
}
var viewModel = new CustomerSetupViewModel();
var UpdateviewModel = new CustomerSetupViewModel();
ko.applyBindings(viewModel, document.getElementById("NewCustomer"));
ko.applyBindings(UpdateviewModel, document.getElementById("UpdateCustomer"));
$("#updateCustomer").click(function () {
UpdateviewModel.GetCustomer();
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<a id="addCustomer" class="btn btn-default" data-toggle="modal" data-target="#NewCustomer">Add Customer</a>
<a id="updateCustomer" class="btn btn-default" data-toggle="modal" data-target="#UpdateCustomer">Update Customer</a>
<!-- Modal -->
<div id="NewCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="NewModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="NewModalLabel">New Customer</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading"></div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<label>Customer Name</label>
<input type="text" id="Name" class="form-control" data-bind="value: Name" />
</div>
</div>
</div>
<div class="modal-footer">
<a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
<a role="button" class="btn btn-primary" data-bind="click: Save">Save</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div id="UpdateCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="NewModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="NewModalLabel">New Customer</h4>
</div>
<div class="modal-body" data-bind="foreach: CustomerSetup">
<div class="panel panel-default">
<div class="panel-heading"></div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<label>Customer Name</label>
<input type="text" id="Name" class="form-control" data-bind="value: Name" />
</div>
</div>
</div>
<div class="modal-footer">
<a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
<a id="Update" class="btn btn-default" data-bind="click: Update">Update</a>
</div>
</div>
</div>
</div>
</div>
</div>
I am not sure about the problem, as I tried to log your UpdateviewModel it was an empty object.
I made your code works but there will be changes just for coding structure using mainViewModel and its subViewModel contents.
$(document).ready(function () {
var CustomerSetupViewModel = function () {
var self = this;
self.Name = ko.observable("");
self.Save = function () {
var test = self.Name();
alert(test);
}
self.Update = function () {
var test2 = self.Name();
alert(test2);
}
}
var MainViewModel = function () {
console.log("init")
self = this;
self.CustAdd = new CustomerSetupViewModel();
self.CustUpd = new CustomerSetupViewModel();
}
vm = new MainViewModel();
ko.applyBindings(vm);
$("#updateCustomer").click(function () {
vm.CustUpd.Name("ToBeUpdated");
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<a id="addCustomer" class="btn btn-default" data-toggle="modal" data-target="#NewCustomer">Add Customer</a>
<a id="updateCustomer" class="btn btn-default" data-toggle="modal" data-target="#UpdateCustomer">Update Customer</a>
<!-- Modal -->
<div id="NewCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="NewModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="NewModalLabel">New Customer</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading"></div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<label>Customer Name</label>
<input type="text" id="Name" class="form-control" data-bind="value: CustAdd.Name" />
</div>
</div>
</div>
<div class="modal-footer">
<a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
<a role="button" class="btn btn-primary" data-bind="click: CustAdd.Save">Save</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div id="UpdateCustomer" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="UpdateModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="UpdateModalLabel">Update Customer</h4>
</div>
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading"></div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<label>Customer Name</label>
<input type="text" id="Name" class="form-control" data-bind="value: CustUpd.Name" />
</div>
</div>
</div>
<div class="modal-footer">
<a role="button" class="btn btn-default" data-dismiss="modal">Close</a>
<a role="button" class="btn btn-primary" data-bind="click: CustUpd.Update">Update</a>
</div>
</div>
</div>
</div>
</div>
</div>
Trying to have a delete confirm modal with a javascript function callback and passing the variable key. The .click doesn't seem to pick up the button within the modal.
<div class="modal fade" id="confirm_delete_escalation" tabindex="-1" role="dialog" aria-labelledby="myModalLabel2" 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" id="myModalLabel2">Confirm Delete</h4>
</div>
<div class="modal-body">
<p>Are you sure?</p>
<p class="debug-url"></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger btn-ok">Delete</button>
</div>
</div>
</div>
</div>
function confirm(message, key, callback) {
var modalWindow = document.getElementById("confirm_delete_escalation");
$(modalWindow).modal({
onShow: function (dialog) {
var modal = this;
$(".message", dialog.data[0]).append(message);
$(".btn-ok", dialog.data[0]).click(function () {
modal.close(); $.modal.close();
callback(key);
return true;
});
}
});
}
I have used this in the past and it works ok
<div class="container">
Delete<br>
</div>
<div id="myModal" class="modal hide">
<div class="modal-header">
×
<h3>Delete</h3>
</div>
<div class="modal-body">
<p>You are about to delete.</p>
<p>Do you want to proceed?</p>
</div>
<div class="modal-footer">
Yes
No
</div>
here is an example of the JS
$('#myModal').on('show', function() {
var id = $(this).data('id'),
removeBtn = $(this).find('.danger');
})
$('.confirm-delete').on('click', function(e) {
e.preventDefault();
var id = $(this).data('id');
$('#myModal').data('id', id).modal('show');
});
$('#btnYes').click(function() {
// handle deletion here
var id = $('#myModal').data('id');
$('[data-id='+id+']').remove();
$('#myModal').modal('hide');
});