validation for either or dynamic textbox in mvc3 razor? - asp.net-mvc

I have a form that form loads a partial view when i select the dropdown values.Here the partialview loads two dynamic textbox with different ID values.
#model List<DataBaseModel.OrderQuoteTBvalues>
#{
ViewBag.Title = "_ingroundDynamic";
}
#if (Model.Count() > 0)
{
<table>
<tr>
<td valign="top">
<div>
<table border="0" cellpadding="3" cellspacing="3" width="20%">
<tr style="background-color: #808080; color: #fff; font-size: 14px;">
<th align="left" width="100px">Pool Shape Type</th>
<th align="center" width="20px">Feet<br>
<th align="left" width="20px">Inch</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.Shape_type</td>
<td>
<input style="width: 100px;" type="text" onkeydown="Integerkeydown(event)" id="PF:#item.Shape_type" name="PF:#item.Shape_type" /></td>
<td>
<input style="width: 100px;" type="text" onkeydown="Numerickeydown(event)" onchange="PIChange(this)" id="PI:#item.Shape_type" name="PI:#item.Shape_type" maxlength="4" /></td>
</tr>
}
}
Here the model is as follows:
public class OrderQuoteTBvalues
{
public string Shape_type { get; set; }
}
After that i have placed the next button onSubmit. if i click the Next button means i need to validate, either or textbox contains value. if it contains the value the validation true else false.
How to achieve that. Need to write any Custom Validation Method?.. If i give class="required" means all textbox is validated. but i need either or textbox to be validated.? Please help me to solve this issue. Thank you so much.

Try below Jquery
$("#validate").live({
click: function() {
var rows = $("#your_table tr:gt(0)"); // your_table is id of you table---gt(0) to skip first row
var i=true;
rows.each(function(index) {
var firsttext = $("td:nth-child(1) input", this).val();
var secondtext = $("td:nth-child(2) input", this).val();
if(firsttext=="" && secondtext=="")
i=false;
});
if(i==true)
alert('Valid');
else
alert("Invalid")
}
});
Child differ according to your order so correct that
Hope it helps leave comment if not understood

$("#btnNext").click( function() {
var valid = false;
if($("#table tr").length > 0) {
var textbox1 = $("table tr td:nth-child(1) input", this).val();
var textbox2 = $("table tr td:nth-child(2) input", this).val();
if(textbox1=="" && textbox2==""){
valid = false;
}
else if(textbox1 != "" && textbox2 != "") {
valid = false;
}
else {
valid = true;
}
}
});

the output will be like this friends.

Related

checkbox value always showing null value in mvc

I am always getting null value through checkbox in mvc. If the checkbox is checked or uncheck it contain null value only.
Here is my code,
View Page
#model IEnumerable<SchoolWebApplication.Models.EventMaster>
<table id="tblEvent" class="table" cellpadding="0" cellspacing="0">
<tr>
<th style="width:100px; display:none">Event Id</th>
<th style="width:150px">Event</th>
<th style="width:150px">Active</th>
</tr>
#if(Model != null)
{
foreach (SchoolWebApplication.Models.EventMaster eventMaster in Model)
{
<tr>
<td class="EventID" style="display:none">
<span>#eventMaster.EventID</span>
</td>
<td class="Event">
<span style="color:darkgreen">#eventMaster.Event</span>
<input type="text" value="#eventMaster.Event" style="display:none; color:darkgreen" />
</td>
<td class="IsActive">
<span style="color:darkgreen">#eventMaster.IsActive</span>
#if (#eventMaster.IsActive == true)
{
<input type="checkbox" value="#eventMaster.IsActive" style="display:none; color:darkgreen" checked="checked" name="abc"/>
}
else
{
<input type="checkbox" value="#eventMaster.IsActive" style="display:none; color:darkgreen" name="abc"/>
}
</td>
<td>
<a class="Edit" href="javascript:;">Edit</a>
<a class="Update" href="javascript:;" style="display:none">Update</a>
<a class="Cancel" href="javascript:;" style="display:none">Cancel</a>
</td>
</tr>
}
}
</table>
<script type="text/javascript">
function AppendRow(row, EventID, Event, IsActive) {
//Bind EventID.
$(".EventID", row).find("span").html(EventID);
//Bind Event.
$(".Event", row).find("span").html(Event);
$(".Event", row).find("input").val(Event);
//Bind IsActive.
$(".IsActive", row).find("span").html(IsActive);
$(".IsActive", row).find("input").val(IsActive);
$("#tblEvent").append(row);
};
//Edit event handler.
$("body").on("click", "#tblEvent .Edit", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find("input").length >= 0) {
$(this).find("input").show();
$(this).find("span").hide();
}
});
row.find(".Update").show();
row.find(".Cancel").show();
$(this).hide();
});
//Update event handler.
$("body").on("click", "#tblEvent .Update", function () {
var row = $(this).closest("tr");
$("td", row).each(function () {
if ($(this).find("input").length >= 0) {
var span = $(this).find("span");
var input = $(this).find("input");
span.html(input.val());
span.show();
input.hide();
}
});
row.find(".Edit").show();
row.find(".Cancel").hide();
$(this).hide();
var event = {};
event.EventID = row.find(".EventID").find("span").html();
event.Event = row.find(".Event").find("span").html();
event.IsActive = row.find(".IsActive").find("span").html();
$.ajax({
type: "POST",
url: "/Event/Update",
data: JSON.stringify({ eventMaster: event }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response.IsActive);
}
});
});
</script>
Controller
try
{
EventMaster updatedEvent = (from c in entities.eventMaster
where c.EventID == eventMaster.EventID
select c).FirstOrDefault();
updatedEvent.Event = eventMaster.Event;
updatedEvent.IsActive = eventMaster.IsActive;
entities.SaveChanges();
return new EmptyResult();
}
catch (Exception ex)
{
return View();
}
Now, in table there is a three field EventID, Event and Active. In active there is a checkbox containing at update time.
Now, the issue is coming that if the checkbox is check or not check it is containing null value only.
So thats why at the fetch time it showing uncheck only.
Thank You.
Asking for the .val of a checkbox will get you the contents (if any) of the value attribute on the input element - this will not change when the user checks the box.
To check if a checkbox is checked in jQuery you should use something like:
if (input.is(":checked")){}
At the moment, you're storing the current value of .IsActive in the span and the value of the checkbox, and then when the update method runs, just grabbing that same value and putting it into the span - resulting in not updating anything.
Looking further at your code though - you should confirm what your method is actually posting back to the server - looking at it you are passing raw HTML into some parameters on the object:
event.IsActive = row.find(".IsActive").find("span").html();
At best, event.IsActive will be the string "True" (or False), rather than an actual boolean that your model is expecting. You would be better off changing that line to something like:
event.IsActive = row.find(".IsActive").find("input").is(":checked");
And then confirm what is being sent to the server in the network tab of your browser.

MVC- drop down values not binding for all the rows in a table

The model:
public class EdituserModel : IEnumerable<EdituserModel>
{
public int UserID { get; set; }
public string Status { get; set; }
public IEnumerator<EdituserModel> GetEnumerator()
{
return ((IEnumerable<EdituserModel>)editUser).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<EdituserModel>)editUser).GetEnumerator();
}
}
The View:
<table id="tbltbl_usertable" class="tableasd" cellpadding="0" cellspacing="0">
<tr>
<th style="width:115px;text-align: center; ">User Id</th>
<th style="width:100px;text-align: center;">Status</th>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
#foreach (var user in Model)
{
<tr>
<td class="UserID" style="text-align: center; ">
<span style="text-align: center;">#user.UserID</span>
</td>
<td class="Status" style="text-align: center;">
<select id="SelectedStatusId" name="SelectedStatusId" value="#user.Status" >
<option value="A" selected="selected">Admin</option>
<option value="U">Dashboard user</option>
</select>
</td>
</tr>
}
</table>
From the above code, the UserID is being displayed properly (8 rows for 8 users). But only one drop down is being displayed for the first row and not the subsequent rows. Is there something I'm missing?
The way you're binding to the select is wrong. You can't set an option in the dropdown by setting the value attribute of select (try it). Besides, you're setting selected="selected" on the first option. I'm guessing that is selected in all the dropdowns.
"Only one drop down is being displayed for the first row and not the subsequent rows":
I don't know how this is possible. I have tested this in my system and it wasn't reproducible.
So, how to bind your value to the dropdown? You should use MVC's DropdownListFor HTML Helper.
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td class="UserID" style="text-align: center; ">
<span style="text-align: center;">Model.editUser[i].UserID</span>
</td>
<td class="Status" style="text-align: center;">
#Html.DropDownListFor(m => Model.editUser[i].Status, new SelectList(new[] {
new { Text = "Admin", Value = "A" },
new { Text = "Dashboard user", Value = "U" },
}, "Value", "Text", Model.editUser[i].Status))
</td>
</tr>
}
You should use a for loop instead of foreach whenever you're looping and creating form elements in MVC (Why though?). This generates appropriate name attribute which are important when submitting forms.
(We usually get the SelectListItems in a ViewBag and bind. But there is an issue in MVC with DropDownList helper when we are looping)
"BUT I DONT CARE ABOUT GIVING PROPER NAMES TO FORM ELEMENTS
OR DROPDOWNLISTFOR OR ANY OF THAT STUFF. I JUST WANT TO BIND MY DROPDOWN OKAY?":
Then:
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td class="UserID" style="text-align: center; ">
<span style="text-align: center;">#Model.editUser[i].UserID</span>
</td>
<td class="Status" style="text-align: center;">
<select id="SelectedStatusId" name="SelectedStatusId">
<option value="A" #(Model.editUser[i].Status == "A" ? "selected" : "" )>Admin</option>
<option value="U" #(Model.editUser[i].Status =="U" ? "selected" : "" )>Dashboard user</option>
</select>
</td>
</tr>
}
UPDATE: I saw your update now reagarding the Enumerator. See, this is why I asked you post all the relevant code. You said your model for the page was IEnumerable<EdituserModel>. My asnwer would still work. Replace all the Model[i] with Model.editUser[i] (otherwise you'd have implement IList as well)

Paging issue in ASP.Net Mvc Application

I am developing an MVC application in which I use a DropdownList to select "vendor". When I select a vendor from the dropdown then the view shows products related to the selected vendor.
I use paging to display multiple pages of particular vendor's products.
My issue is when I select a vendor from dropdown, at change event it displays products on all pages properly. If I select 2nd page it shows products from 2nd page. But next time if I select another vendor from dropdown, it shows 2nd page of selected vendor. But what I want is to display first page of selected vendor initially.
Controller code as below
public ActionResult Index(int? page ,int VendorId = 0)
{
var pageNumber = (page ?? 1);
var pagesize = 2;
if (VendorId == 0)
{
VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
VendorService vendorService = new VendorService();
SelectList SelectList = new SelectList(vendorService.GetAll().OrderBy(t => t.Name), "Id", "Name", VendorId);
ViewData["list"] = SelectList;
int id = Convert.ToInt32(Session["loggedEmpId"]);
CommonService.SetEmployeeId(id);
if (VendorId != 0)
{
Session["InventoryVendorId"] = VendorId;
ProductService ProductService = new ProductService();
var productList = ProductService.GetProductInventory().Where(x=>x.VendorId == VendorId);
return View(productList.ToPagedList(pageNumber, pagesize));
}
else
{
return View();
}
}
code for view as below
#model PagedList.IPagedList<StockWatch.DTO.ProductDTO>
#using PagedList.Mvc;
#using System.Web.UI.WebControls
#{
ViewBag.Title = "Index";
int VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
<link href="~/Content/PagedList.css" rel="stylesheet" />
<div class="row-fluid">
<div id="vendorDropdownDiv4" class="span12 " style="margin-left:0px;margin-top:10px;">
<div class="span6" >
<div class="span4" style="margin-left:1px;" >
<label >Vendor</label>
</div>
<div class="span6" >
#Html.DropDownList("VendorId", ViewData["list"] as SelectList, "-- Select vendor --", new { #id = "vendorIdforInventory", #name = "VendorId" })
</div>
</div>
<div class="span3" style="text-align:right">
#* <input class="btn btn-primary" type="submit" value="Load" id="create"/>*#
#*<input class="btn btn-default" value="Cancel" style="width:45px;" onclick="window.location.href='#Url.Action("index") '"/>*#
</div>
</div>
</div>
<div id="Newindexview"></div>
#if(Model != null)
{
</div>
<div class="span12" style="margin-left:0px;">
<table>
<thead>
<tr >
<th style="width:250px;" >Product Name
</th>
<th style="width:180px; text-align:left;" >Product Code
</th>
<th style="border-right: solid #e8eef4 thick; width: 0px; text-align:right;">Avg. Weight
</th>
#{
foreach (var location in ViewBag.loc)
{
<th style="width:10px;text-align:right;">#location.Name</th>
}
}
</tr>
</thead>
<tbody>
#foreach (var p in Model)
{
<tr>
<td style="width:250px;">
#p.Name
</td>
<td style="width:180px;text-align:left;">
#p.ProductCode
</td>
<td style="border-right: solid #e8eef4 thick; width: 15px; text-align:right">
#p.AvgWeight
</td>
#foreach (var location in ViewBag.loc)
{
flag = false;
if(p.Inventory != null)
{
foreach (var loc in p.Inventory)
{
if (location.Name == loc.LocationName)
{
<td style="width:10px; text-align:right;">#loc.Quantity</td>
flag = true;
}
}
}
if (flag == false)
{
<td style="width:10px; text-align:right;">0</td>
}
}
</tr>
}
</tbody>
</table>
</div>
<div class="span12" style="margin-left:0px;">
<div class="span6" style="margin-left:0px;">
#Html.PagedListPager(Model, page => Url.Action("Index", new {page ,searchContent=searchcontent}))
</div>
</div>
</div>
}
and jquery code as below
$("#vendorIdforInventory").change(function () {
var vendorid = $('#vendorIdforInventory').val();
$.ajax({
url: '#Url.Action("Index", "Inventory")',
data: {
VendorId: vendorid
},
type: "POST",
success: function (data) {
location.reload();
$('#modeldiv1').empty();
$('#vendorDropdownDiv4').hide();
$('#Newindexview').html("");
$('#Newindexview').html(data);
}
});
});
How to solve this paging issue?
You need to pass the currentFilter from your view back into your controller (which you have with VendorID), and set the page accordingly. Details are in the ASP.NET tutorial on paging at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.
Look at how they've implemented filtering using the searchString and currentFilter variable, that's what will make sure that when a new string is entered (or selected from a drop down list in your case) that the paging responds accordingly.
Specifically, this is what I think you're missing in your code
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
...
int pageNumber = (page ?? 1);

How to sort HTML table in MVC based on value selected in dropdown

I have a requirement where I have to sort the HTML table in MVC on the basis of value selected in dropdownlist.
The dropdownlist is having 2 values: Sort by Number and Sort By Description.
Following is the code:
#{
Layout = T4MVC.SharedController.ViewNames._Ctx;
}
#section brandcrambs{
<div id="breadcrumbs">#{Html.RenderPartial(T4MVC.SharedController.ViewNames._ProductCatalogBrandCrambs, Model);}</div>
}
#Html.DropDownList("SortBy", new List<SelectListItem>
{
new SelectListItem{ Text="Sort By Number", Value="0", Selected=true},
new SelectListItem{ Text="Sort By Description", Value = "1" }
})
#{
var s = #ViewData["currentNode"];
}
<div style="font-size: 14px; font-weight: bold">
#Convert.ToString(s)
</div>
#foreach (SubSectionNodesVM n in Model.Nodes)
{
<h4>
#if (n.CurrentNode.Key.Contains("Specification"))
{
Html.RenderPartial(T4MVC.SharedController.ViewNames._PrintButtons, n.CurrentNode);
}
</h4>
var matchValue = n.Nodes as IEnumerable<SiteMapNodeBase>;
var resultSet = from dtRow in matchValue.AsEnumerable()
group dtRow by dtRow.Prefix into newGroup
orderby newGroup.Key
select newGroup;
var datamodel = resultSet as IEnumerable<SiteMapNodeBase>;
var k = 0;
<div id="#n.CurrentNode.Key.Replace("Specification|", "").Replace("Section|", "")" >
<table>
#foreach (var item in resultSet)
{
k++;
var match = item.Select(m => m.DefaultValue);
string resultDefaultValue = string.Empty;
if (match != null)
{
if (match.Count() > 0)
{
resultDefaultValue = match.ToList()[0];
}
}
<tr style="background-color:#(k % 2 == 1 ? "white" : "rgb(246,246,246)")">
<td colspan="4" style="font-size: 12px; font-weight: bold">#resultDefaultValue</td>
</tr>
var i = 0;
foreach (var inneritem in item)
{
k++;
<tr style="background-color:#(k % 2 == 1 ? "white" : "rgb(246,246,246)")">
<td style="width: 250px">#inneritem.Number</td>
#if (#inneritem.RangeStart == null || #inneritem.RangeStart == "")
{
<td style="width: 250px"></td>
}
else
{
<td style="width: 250px">From: #inneritem.RangeStart</td>
}
#if (#inneritem.RangeEnd == null || #inneritem.RangeEnd == "")
{
<td style="width: 250px"></td>
}
else
{
<td style="width: 250px">To: #inneritem.RangeEnd</td>
}
<td style="width: 800px">#inneritem.Description</td>
</tr>
}
}
</table>
<script>
$(document).ready(function () {
$('#SortBy').change(function () {
var value = $("#SortBy option:selected").val();
alert(value);
});
})
</script>
I strongly recommend that you read this article:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
It will explain how to sort (and filter etc) data from Entity Framework based on input. The sample does not use a Dropdown to demonstrate this, but if you understand the sample, you should be able to get it to work with a DropDown.
This is a server side approach, which I would always recommend when it comes to searching, sorting and paging.
If you chose to sort things on the client side, then it requires a different approach. There are many plugins for it, you can also do it yourself with pure javascript, or jQuery
Examples for client side sorting plugins:
https://datatables.net/
http://tablesorter.com/
http://joequery.github.io/Stupid-Table-Plugin/
...

Can not save data 2nd time knockout mvc

I am new in knockout and asp.net mvc both.
I am trying to Insert update delete data in database with knockout. My knockout model is
function City(data) {
this.CityId = ko.observable(data.CityId);
this.CityName = ko.observable(data.CityName);
}
function CityViewModel() {
var self = this;
self.Citys = ko.observableArray([]);
self.CityId = ko.observable();
self.CityName = ko.observable();
self.selectedCity = ko.observable();
// self.City = ko.observable();
selectCity = function (item) {
self.selectedCity(item);
}
//load
loadCitys = function () {
$.getJSON("/Admin/GetCitys", {}, function (result) {
var mappedCitys = ko.utils.arrayMap(result.Data, function (item) {
return new City(item);
});
self.Citys([]);
self.Citys.push.apply(self.Citys, mappedCitys);
});
}
//edit
EditCity = function (item) {
//what need to do here
// is it possible to fill the hidden fild and the text box ??
}
//save
SaveCity = function (item) {
City = new City(item);
$.ajax({
type: "POST",
url: "/Admin/SaveCity",
data: ko.toJSON({ City: City }),
contentType: "application/json",
success: function (result) {
if (result.Edit) {
City.CityId = result.Success;
City.CityName = item.CityName;
self.Citys.push(City);
toastr.success('City Information Save Successfully', 'Success');
}
else if (result.Edit == false) {
toastr.success('City Information Update Successfully', 'Success');
}
else {
toastr.error('There is an error please try again later', 'Errror');
}
}
});
}
//delete
DeleteCity = function (City) {
$.ajax("/Admin/DeleteCity", {
data: ko.toJSON({ CityId: City.CityId }),
type: "POST", contentType: "application/json",
success: function (result) {
if (result.Success) {
self.Citys.remove(City);
toastr.success('City Remove Successfully', 'Success');
}
else {
alert("Error..");
}
}
});
}
}
(function () {
ko.applyBindings(new CityViewModel, document.getElementById("Citys"));
loadCitys();
});
And my Html codes are
<table class="table table-striped">
<thead>
<tr>
<th>City Id</th>
<th>City Name</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: $root.Citys">
<tr data-bind="click: selectCity">
<td><span data-bind="text:CityId"></span></td>
<td><span data-bind="text:CityName"></span></td>
<td><button data-bind="click: EditCity" class="btn btn-primary">Edit</button></td>
<td><button data-bind="click: DeleteCity" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
<fieldset>
<legend>Add new / Edit City</legend>
<label>City name</label>
<input type="hidden" data-bind="value: CityId" />
<input type="text" data-bind="value: CityName" placeholder="Type city nameā€¦">
<button type="submit" data-bind="click: SaveCity" class="btn">Submit</button>
</fieldset>
With this codes I can get data form database display them successfully in my view file,
I delete the data from database, and I also can Insert data to database but here is a problem I can save data only 1st time when I change the textbox value (without page refresh) and try to save city information then it say (in Firebug on my javascript code):
TypeError: City is not a constructor
City = new City(item);
My question is what have I done wrong in this codes, and I am trying to fill the textbox and the hidden field when edit button click, how can I do this?
Thanks in advance.
There are a number of faults with your javascript, including:
The methods on your viewmodel, such as SaveCity, DeleteCity, EditCity are all being defined without the 'this/self' prefixes, therefore they are being added to the global namespace.
In your SaveCity method, your are assigning a new instance of the City class to a variable called 'City', therefore destroying the City class. It will work the first time, but any other attempts to create an instance of a City will yield an exception.
Anyway, this should be a working version of your script and HTML without the ajax stuff. You will need to adapt that yourself. I have also created a working JsFiddle here..
function City(data) {
this.CityId = ko.observable(data.CityId);
this.CityName = ko.observable(data.CityName);
}
function CityViewModel() {
var self = this;
self.Citys = ko.observableArray([]);
self.SelectedCity = ko.observable();
self.EditingCity = ko.observable(new City({CityId: null, CityName: ''}));
self.EditCity = function(city){
self.EditingCity(new City(ko.toJSON(city)));
};
//load
self.loadCitys = function () {
self.Citys().push(new City({CityId: '1245', CityName: 'Los Angeles'}));
self.Citys().push(new City({CityId: '45678', CityName: 'San Diego'}));
};
//save
self.SaveCity = function () {
var city = self.EditingCity();
if(city.CityId()){
var cityIndex;
for(var i = 0; i < self.Citys().length; i++) {
if(self.Citys()[i].CityId() === city.CityId()) {
cityIndex = i;
break;
}
}
self.Citys[cityIndex] = city;
}
else{
city.CityId(Math.floor((Math.random()*1000000)+1));
self.Citys.push(city);
}
self.EditingCity(new City({CityId: null, CityName: ''}));
}
//delete
self.DeleteCity = function (city) {
self.Citys.remove(city);
};
}
var viewModel = new CityViewModel();
viewModel.loadCitys();
ko.applyBindings(viewModel, document.getElementById("Citys"));
HTML
<table class="table table-striped">
<thead>
<tr>
<th>City Id</th>
<th>City Name</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: Citys">
<tr data-bind="click: $root.SelectedCity">
<td><span data-bind="text:CityId"></span></td>
<td><span data-bind="text:CityName"></span></td>
<td><button data-bind="click: $root.EditCity" class="btn btn-primary">Edit</button></td>
<td><button data-bind="click: $root.DeleteCity" class="btn btn-danger">Delete</button></td>
</tr>
</tbody>
</table>
<fieldset data-bind='with:EditingCity'>
<legend>Add new / Edit City</legend>
<label>City name</label>
<input type="hidden" data-bind="value: CityId" />
<input type="text" data-bind="value: CityName" placeholder="Type city name" />
<button type="submit" data-bind="click: $root.SaveCity" class="btn">Submit</button>
</fieldset>

Resources