I am new to Knockout.js, i have 2 viewModel EmployeeviewModel and DepartmentViewModel, i am binding my first view using EmployeeviewModel its working perfect, now i need make click so i can navigate to second page which is department and in frist i need to display click EmployeeName and his department, secondly i need to display all the EmployeeName related to that department how to achive this, how i can pass my first page value to second page display related to departmentID.
function EmployeeViewModel()
{
var self =this;
var Allemployee =ko.observableArray([])
self.getEmployeedetails=function ()
$.ajax({
type: "GET",
dataType: "json",
url: baseUrl + 'xxx/xxxxxx',
success: function (data) {
self.Allemployee($.map(data, function (item) {
return new EmployeeModel(item);
}));
},
error: function (error) {
}
});
self.getDepartment=function()
{
//here i need to navigate to Department page with all department ID
}
}
function EmployeeModel(data)
{
var self =this;
self.employeeName = ko.observable(data.employeeName )
self.employeeMobile= ko.observable(data.employeeMobile)
self.employeeemail = ko.observable(data.employeeemail )
self.employeedepartmentId= ko.observable(data.employeedepartmentId)
}
function DepartmentViewModel()
{
var self =this;
var AllDepartmentemployee =ko.observableArray([])
self.getEmployeedetails=function ()
$.ajax({
type: "GET",
dataType: "json",
url: baseUrl + 'xxx/xxxxxx',
success: function (data) {
self.AllDepartmentemployee ($.map(data, function (item) {
return new DepartmentModel(item);
}));
},
error: function (error) {
}
});
}
function DepartmentModel (item)
{
self.departmentId= ko.observable(data.departmentId)
self.departmentName=ko.observable(data.departmentName)
self.employeeName=ko.observable(data.employeeName)
}
var viewModel=new EmployeeViewModel()
ko.applyBindings(EmployeeViewModel,document.getElementById("employeeDetails"))
var viewModel 2=new DepartmentViewModel()
ko.applyBindings(viewModel,document.getElementById("department"))
//html//
//First view
<div data-role="view" id="employeeDetails">
<ul>
<li>
<div data-bind="text:employeeName"></div>
<div data-bind="text:employeeMobile"></div>
<div data-bind="text:employeeemail "></div>
<div data-bind="text:employeedepartmentId"></div>
</li>
</ul>
<div>
//second View
<div data-role="view" id="department">
<div data-bind="text:employeeName">
<div>
<div data-bind="text:departmentName">
<div>
<ul data-bind:"foreach:AllDepartmentemployee">
<li>
<div data-bind="text:employeeName">
<div data-bind="text:departmentName"></div>
</li>
<ul>
<div>
You need to have a Main view model and have two sub view models for your departments and employees. Then every time you click on any employee you will have the departmentId then based on your logic you can either send a request to the server along with Id and get back all the employees under that department or you already have all departments and you just filter them based on departmentId that has been passed.
Below is an example how to handle: https://jsfiddle.net/kyr6w2x3/124/
HTML:
<div data-role="view" id="employeeDetails">
<ul >
<li>
<span class="info">Name</span>
<span class="info">Mobile</span>
<span class="info">Email</span>
<span class="info">Dept.NO</span>
</li>
<hr>
<!-- ko foreach: AllEmployee -->
<li>
<span data-bind="text:EmployeeName" class="info"></span>
<span data-bind="text:EmployeeMobile" class="info"></span>
<span data-bind="text:EmployeeEmail " class="info"></span>
<span data-bind="text:EmployeeDepartmentId" class="info"></span>
Click
</li>
<!-- /ko -->
</ul>
<div>
//second View
<div data-role="view" id="department">
<h1 data-bind="text:SelectedEmployeeName"></h1>
<div data-bind="if:AllDepartmentEmployee().length > 0">
<h3 data-bind ="text:AllDepartmentEmployee()[0].DepartmentName()"></h3>
</div>
<ul data-bind ="foreach:AllDepartmentEmployee">
<li>
<div data-bind="text:EmployeeName"></div>
<!-- <div data-bind="text:DepartmentName"></div> -->
</li>
<ul>
<div>
VM:
var employeesList = [{
employeeId : 1,
employeeName:"Mike" ,
employeeMobile :1234561 ,
employeeEmail:"Mike#example.com",
employeeDepartmentId:1},
{
employeeId : 2,
employeeName:"Alex" ,
employeeMobile :1234562 ,
employeeEmail:"Alex#example.com",
employeeDepartmentId:1
},
{
employeeId : 3,
employeeName:"Dave" ,
employeeMobile :1234563 ,
employeeEmail:"Dave#example.com",
employeeDepartmentId:1
},
{
employeeId : 4,
employeeName:"Dani" ,
employeeMobile :1234564 ,
employeeEmail:"Dani#example.com",
employeeDepartmentId:2},
{
employeeId : 5,
employeeName:"Chris" ,
employeeMobile :1234565 ,
employeeEmail:"Chris#example.com",
employeeDepartmentId:2
},
{
employeeId : 6,
employeeName:"Matt" ,
employeeMobile :1234566 ,
employeeEmail:"Matt#example.com",
employeeDepartmentId:2
}
]
var departmentsList = [
{departmentId:1,
departmentName:"Dept #1",
employeeName:"Mike"
},
{departmentId:1,
departmentName:"Dept #1",
employeeName:"Alex"
},
{departmentId:1,
departmentName:"Dept #1",
employeeName:"Dave"}
,
{departmentId:2,
departmentName:"Dept #2",
employeeName:"Matt "
},
{departmentId:2,
departmentName:"Dept #2",
employeeName:"Dani"
},
{departmentId:2,
departmentName:"Dept #2",
employeeName:"Chris "}
]
function MainViewModel(){
var self = this;
self.AllEmployee = ko.observableArray([]);
self.AllDepartmentEmployee= ko.observableArray([]);
self.SelectedEmployeeName = ko.observable();
self.LoadEmployees = function (){
// Ajax goes here to load uncomment below
// $.ajax({
// type: "GET",
// dataType: "json",
// url: baseUrl + 'xxx/xxxxxx',
// success: function (data) {
self.AllEmployee($.map(employeesList, function (item) {
return new EmployeeModel(item);
}));
// },
// error: function (error) {
// }
//});
}
self.GetDepartment = function(employee){
self.SelectedEmployeeName(employee.EmployeeName())
data = {departmentId:employee.EmployeeDepartmentId()}
// $.ajax({
// type: "GET",
// data:data,
// dataType: "json",
// url: baseUrl + 'xxx/xxxxxx',
// success: function (data) {
// HERE YOU MAY JUST GET THE LIST OF EMPLOEES FOR THIS DEPARTMENT OR YOU GET ALL AND HERE YOU FILTER
self.AllDepartmentEmployee ($.map(departmentsList, function (item) {
if(item.departmentId == employee.EmployeeDepartmentId()){
return new DepartmentModel(item);
}
}));
// },
// error: function (error) {
// }
// });
}
}
function EmployeeModel(data){
var self = this;
self.EmployeeId = ko.observable(data.employeeId);
self.EmployeeName = ko.observable(data.employeeName);
self.EmployeeMobile= ko.observable(data.employeeMobile);
self.EmployeeEmail = ko.observable(data.employeeEmail );
self.EmployeeDepartmentId= ko.observable(data.employeeDepartmentId);
}
function DepartmentModel (data){
var self = this;
self.DepartmentId = ko.observable(data.departmentId)
self.DepartmentName = ko.observable(data.departmentName)
self.EmployeeName = ko.observable(data.employeeName)
}
var viewModel = new MainViewModel();
ko.applyBindings(viewModel);
viewModel.LoadEmployees();
Related
Let me explain to you what I'm doing here. I have one modal. Expenses are entered here.The modal has 3 input text(starting km, ending km and price) and 1 drop-down list. After entering the starting km and ending km, I select the fuel type. The calculation calculated in the method is written in the price and I'm recording.enter image description here,enter image description here.
I calculate another fuel, but it does not print the price even though it is successful.enter image description here. How do you know you are successful? I post an alert below where I bring the price and it works.And when you type console.log, the price comes there.the weird thing is it returns the method i wrote to the control 3 times.there is no loop in the javascript i wrote.If you have an idea I would like to try...
$('.tab-travel.add').click(function (event) {
var url = '/Expense/CreateNewLine/?index=' + input_index;
$('.modal.new-expense-modal').modal({
autofocus: false,
onHidden: function () {
$('.modal.new-expense-modal').empty();
$('.modal.new-expense-modal').append(
`<div class="ui placeholder">
<div class= "header" >
<div class="line"></div>
<div class="line"></div>
</div >
<div class="paragraph">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div class="paragraph">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div class="paragraph">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<div class="paragraph">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>`)
}
})
.modal('show');
$.get(url).done(function (a) {
$(".modal.new-expense-modal").html(a);
//$('#mstandart_calendar').calendar(calendarOptions);
$('#popup_calendar').calendar(CalendarOptions);
$('.ui.dropdown').dropdown();
plateNo();
fuelamount();
});
var prolist = []
function plateNo() {
$(document).on("change", '#plateNumber', function () {
$("#StartKm").removeAttr("disabled");
$("#FinishKm").removeAttr("disabled");
$("#StartKm").focus();
});
}
function fuelamount() {
$(document).on("change", '#FuelType', function () {
var fueltype = $("#FuelType").val();
var startkm = $("#StartKm").val();
var finishkm = $("#FinishKm").val();
var amount = 1;
var data = new FormData();
data.append("fueltype", fueltype);
data.append("startkm", startkm);
data.append("finishkm", finishkm);
data.append("amount", amount);
$.ajax({
type: "POST",
url: "/expense/FuelAmount",
contentType: false,
processData: false,
data: data,
success: function (data) {
debugger;
console.log(data.amount);
$("#Amount").val(data.amount);
$('body').toast({
displayTime: 1000,
class: 'green t-left',
message: data.message,
position: 'top right',
});
},
error: function (xhr, status, error) {
$('body').toast({
displayTime: 3000,
class: 'error t-left',
message: error,
position: 'top right',
});
}
});
});
}
});
public ActionResult FuelAmount(string fueltype,decimal startkm,decimal finishkm, string amount)
{
var fueldef = fuelDefinitionRepository.GetAll().ToList();
if (startkm.ToString() != null && finishkm.ToString() != null && startkm<finishkm)
{
foreach (var item in fueldef)
{
if (item.FuelType.ToString() == fueltype)
{
var sumrev = finishkm - startkm;
var fuelamount = sumrev * item.PricePerKm;
amount = fuelamount.ToString();
}
}
return Json(new { success = true, message = ExpenseRes.FuelDefinitionSuccessfully,amount }, JsonRequestBehavior.AllowGet);
}
return Json(new { error = true, message =ExpenseRes.FuelDefinitionError }, JsonRequestBehavior.AllowGet);
}
Thanks:)
I am new to Knockout JS and think it is great. The documentation is great but I cannot seem to use it to solve my current problem.
The Summary of my Code
I have two viewmodels represented by two js scripts. They are unified in a parent js file. The save button's event is outside
both foreach binders. I can save all data in the details foreach.
My Problem
I need to be able to include the value from the contacts foreach binder with the values from the details foreach binder.
What I have tried
I have tried accessig the data from both viewmodels from the parent viewmodel and sending the POST request to the controller from there but the observeableArrays show undefined.
Create.CSHTML (Using MVC5 no razor)
<div id="container1" data-bind="foreach: contacts">
<input type="text" data-bind="value: contactname" />
</div>
<div data-bind="foreach: details" class="card-body">
<input type="text" data-bind="value: itemValue" />
</div>
The save is outside of both foreach binders
<div class="card-footer">
<button type="button" data-bind="click: $root.save" class="btn
btn-success">Send Notification</button>
</div>
<script src="~/Scripts/ViewScripts/ParentVM.js" type="text/javascript"></script>
<script src="~/Scripts/ViewScripts/ViewModel1.js" type="text/javascript"></script>
<script src="~/Scripts/ViewScripts/ViewModel2.js" type="text/javascript"></script>
ViewModel1
var ViewModel1 = function (contacts) {
var self = this;
self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (contact) {
return {
contactName: contact.contactName
};
}));
}
ViewModel2
var ViewModel2 = function (details) {
var self = this;
self.details = ko.observableArray(ko.utils.arrayMap(details, function (detail) {
return {
itemNumber: detail.itemValue
};
}));
}
self.save = function () {
$.ajax({
url: baseURI,
type: "POST",
data: ko.toJSON(self.details),
dataType: "json",
contentType: "application/json",
success: function (data) {
console.log(data);
window.location.href = "/Home/Create/";
},
error: function (error) {
console.log(error);
window.location.href = "/Homel/Create/";
}
});
};
ParentViewModel
var VM1;
var VM2;
var initialContactInfo = [
{
contactPhone: ""
}
]
var initialForm = [
{
itemValue: ""
]
}
$(document).ready(function () {
if ($.isEmptyObject(VM1)) {
ArnMasterData = new ViewModel1(initialContactInfo);
ko.applyBindings(VM1, document.getElementById("container1"));
}
if ($.isEmptyObject(VM2)) {
VM2 = new ViewModel2(initialForm);
ko.applyBindings(VM2, document.getElementById("container2"));
}
});
I need to render my template templates/page.html:
<section class="section">
<div class="container">
<h1 class="title"><%= title %></h1>
<div><%= content %></div>
<div><%= pages %></div>
</div>
</section>
into my div element with page-content id:
// Underscore mixins
_.mixin({templateFromUrl: function (url, data, settings) {
var templateHtml = "";
this.cache = this.cache || {};
if (this.cache[url]) {
templateHtml = this.cache[url];
} else {
$.ajax({
url: url,
method: "GET",
async: false,
success: function(data) {
templateHtml = data;
}
});
this.cache[url] = templateHtml;
}
return _.template(templateHtml, data, settings);
}});
// Models
var PageState = Backbone.Model.extend({
defaults: {
title: "",
subtitle: "",
content: "",
pages: "",
state: "games"
}
});
var pageState = new PageState();
// Routers
var PageRouter = Backbone.Router.extend({
routes: {
"": "games",
"!/": "games",
"!/games": "games",
"!/users": "users",
"!/add-user": "add_user"
},
games: function () {
select_item($("#games"));
console.log("games");
pageState.set({ state: "games" });
},
users: function () {
select_item($("#users"));
console.log("users");
pageState.set({ state: "users" });
},
add_user: function () {
console.log("add_user");
}
});
var pageRouter = new PageRouter();
// Views
var Page = Backbone.View.extend({
templates: {
"page": _.templateFromUrl("/templates/page.html")
},
initialize: function () {
this.render();
},
render: function () {
var template = this.templates["page"](this.model.toJSON());
this.$el.html(template);
return this;
}
});
$(function () {
var page = new Page({
el: '#page-content',
model: pageState
});
});
// Run backbone.js
Backbone.history.start();
// Close mobile & tablet menu on item click
$('.navbar-item').each(function(e) {
$(this).click(function() {
if($('#navbar-burger-id').hasClass('is-active')) {
$('#navbar-burger-id').removeClass('is-active');
$('#navbar-menu-id').removeClass('is-active');
}
});
});
// Open or Close mobile & tablet menu
$('#navbar-burger-id').click(function () {
if($('#navbar-burger-id').hasClass('is-active')) {
$('#navbar-burger-id').removeClass('is-active');
$('#navbar-menu-id').removeClass('is-active');
} else {
$('#navbar-burger-id').addClass('is-active');
$('#navbar-menu-id').addClass('is-active');
}
});
// Highlights an item in the main menu
function select_item(sender) {
$("a.v-menu-item").removeClass("is-active");
sender.addClass("is-active");
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.6.2/css/bulma.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<body>
<section class="hero is-primary is-medium">
<div class="hero-head">
<nav id="navMenu" class="navbar">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item is-size-2">Virto</a>
<span id="navbar-burger-id" class="navbar-burger burger" data-target="navbar-menu-id">
<span></span>
<span></span>
<span></span>
</span>
</div>
<div id="navbar-menu-id" class="navbar-menu">
<div class="navbar-end">
<a id="games" href="#!/games" class="navbar-item v-menu-item is-active">Games</a>
<a id="users" href="#!/users" class="navbar-item v-menu-item">Users</a>
<span class="navbar-item">
<a href="#!/add-user" class="button is-primary is-inverted">
<span class="icon">
<i class="fas fa-user-circle"></i>
</span>
<span>Add user</span>
</a>
</span>
<div>
</div>
</div>
</nav>
</div>
</section>
<div id="page-content"></div>
</body>
But my content doesn't load... I'm a noobie in backbone.js still so can someone explain what do I doing wrong and how to fix?
ADDED
I have checked my script in debugger. It loads a template and finds my div in the render() function but I can't see any result in browser after, my div is empty still.
I created a plunker with your code, and it works fine for me: link
I think you only forgot to initialize your model:
// Models
var PageState = Backbone.Model.extend({
defaults: {
title: "Title - 1",
subtitle: "Subtitle - 1",
content: "Content",
pages: "1",
state: "games"
}
});
I have finish autocomplete with a jquery library which is
using jquery-ui-1.12.1.min.js
. I have modified it to make to get the search with username and full name. it will show as below image
when I select the value it will paste the whole text into an input box.
here is my question how do it modify it to show as the image but when I select the value it will only paste the username into input box?
how i only want nonstop00000 paste it into input box when i select the 1st value
here is my javascript
$(document).ready(function () {
$("#id").autocomplete({
source: function(request,response) {
$.ajax({
url: '#Url.Content("~/UserManagement/AutoCompleteUser")/',
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return [{ label: item.Username + " | " + item.FullName, value: item.id }];
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
})
here is my search controller
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.Username.Trim().Contains(searchString.Trim())
|| s.FullName.Trim().Contains(searchString.Trim()));
}
here is my autocomplete controller
public JsonResult AutoCompleteUser(string term)
{
var result = (from r in db.UserTables
where ((r.Status == "Active") && (r.Username.ToLower().Contains(term.ToLower()) || (r.FullName.ToLower().Contains(term.ToLower()))))
select new { Username = r.Username, FullName = r.FullName }).Distinct();
return Json(result);
}
here is my view
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-12 search-panel">
#using (Html.BeginForm("Index", "UserManagement", FormMethod.Get))
{
<div class="input-group form-group ui-widget">
#Html.TextBox("id", ViewBag.CurrentFilter as string, new { #class = "form-control autocomplete", #placeholder = "Search for..." })
<span class="input-group-btn">
<input type="submit" value="Search" class="form-control autocomplete " />
</span>
</div>
}
</div>
To achieve this you can use the select event to amend the value to be placed in to the input. Try this:
$("#id").autocomplete({
// your settings...
select: function(e, ui) {
e.preventDefault();
$('#id').val(ui.item.label.split('|')[0].trim());
}
});
I am developing MVC application and using razor syntax.
In this application I am giving comment facility.
I have added a partial view, which loads the comment/Records from DB.
In below image, we can see the comment box which is called run-time for employee index view.
Now as we can see comment box, I called at run-time, which is partial view, but problem is I can add comment for only on first record...after first record that button wont work at all...
anything is missing ?
Is there separate process when we call any partial view run-time and make in action on it ?
See the pic...
Here is the code....
#model PagedList.IPagedList<CRMEntities.Customer>
<link href="../../Content/Paging.css" rel="stylesheet" type="text/css" />
<link href="../../Content/EventEntity.css" rel="stylesheet" type="text/css" />
<script src="<%=Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")%>" type="text/javascript"></script>
<div id="ListBox">
<div id="ListHeader">
All customers(#Model.TotalItemCount)
</div>
#foreach (var item in Model)
{
<div id="ListContent">
<span class="ContentTitleField">#Html.ActionLink(item.Name, "Details", new { id = item.Id }, new { #style="color:#1A6690;" })</span>
#if (item.Owner != null)
{
<span class="ContentSecondaryField">#Html.ActionLink(item.Owner.FullName, "Details", "Employee", new { id = item.OwnerId }, new { #style = "color:#1A6690;" })</span>
}
<span class="ContentSecondaryField">#Html.DisplayFor(modelItem => item.Address)</span>
<span id="flagMenus">
#Html.Action("ShowFlag", "Flagging", new { entityId=item.Id, entityType="Customer"})
</span>
#if (item.Opportunities.Count > 0)
{
<span class="FlagOpportunity">#Html.ActionLink("opportunities(" + item.Opportunities.Count + ")", "Index", "Opportunity", new { custid = item.Id }, new { #style = "color:#fff;" })</span>
}
<div style="float:right;">
#Html.Action("SetRate", "Rating", new { entityId = item.Id, rating = item.Rating, entityname = "Customer" })
</div>
<div id="subscribeStatus" style="float:right;">
#Html.Action("ShowSubscribedStatus", "Subscribing", new { entityId = item.Id, entityType = "Customer" })
</div>
<div class="ListLinks">
<span class="ListEditLinks">
<span style="float:left;">#Html.ActionLink("edit", "Edit", new { id = item.Id })</span>
<span class="LinkSeparator"></span>
</span>
<span class="ListAddLinks">
<span style="float:left;">#Html.ActionLink("+opportunity", "Create", "Opportunity", new { custid = item.Id }, null)</span>
<span class="LinkSeparator"></span>
<span>#Ajax.ActionLink("+Comment", null, null, null, new { id = item.Id, #class = "addremark" })</span>
</span>
<div class="RemarkBox"></div>
</div>
<span class="CommentAdd">
</span>
<div class="CommentBlock">
</div>
<span>#Ajax.ActionLink("Add Comment", null, null, null, new { id = item.Id, #class = "addremark" })</span>
</div>
}
<div class="PagingBox">
#Html.Action("CreateLinks", "Pager", new { hasPreviousPage = Model.HasPreviousPage, hasNextPage = Model.HasNextPage, pageNumber = Model.PageNumber, pageCount = Model.PageCount })
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$('.RemarkBox').hide();
$('a.addremark').click(function () {
var url="#Html.Raw(Url.Action("ShowCommentBox", "Comment", new { Id = "idValue", EntityType = "Customer" }))";
url=url.replace("idValue",event.target.id);
$('.RemarkBox').load(url);
$(this).closest('div').find('div.RemarkBox').slideToggle(300);
return false;
});
$("a.pagenumber").click(function () {
var page = 0;
page = parseInt($(this).attr("id"));
$.ajax({
url: '#Url.Action("GetPagedCustomers")',
data: { "page": page },
success: function (data) { $("#customerlist").html(data); }
});
return false;
});
});
</script>
To expand on what Alberto León is saying, the partial page load will not cause the document ready event to fire, so the re-rendered elements will not have the javascript event handlers registered after the first comment is added.
To resolve this, you could put the event registration code into a function, and call this both from the document ready event and the success handler of the AJAX call. Something like this:
function AssignEventHandlers() {
$('a.addremark').click(function () {
....
});
$("a.pagenumber").click(function () {
var page = 0;
page = parseInt($(this).attr("id"));
$.ajax({
url: '#Url.Action("GetPagedCustomers")',
data: { "page": page },
success: function (data) {
$("#customerlist").html(data);
AssignEventHandlers();
}
});
return false;
});
}
$(document).ready(function () {
$('.RemarkBox').hide();
AssignEventHandlers();
}
In success function you need to recall the javascript, or the jquery code that makes the button work. Is an error that taked me a lot of time. Anything uploaded by ajax or any renderpartiAl needs to recall javascript.
$('.RemarkBox').load(url, function() {
//RECALL JAVASCRIPT
});