Reputation: 674
I want to pre fill fields of the form on load with existing data from database. On page load i am making an ajax call which queries the data and assign the returned data to a knockout observable array.
client.js:
function clientModel()
{
var self = this;
this.lastTenClients = ko.observableArray();
this.pendingClients = ko.observableArray();
this.foundCustomerResult = ko.observable();
this.shouldShowCustomerMessage = ko.observable(false);
this.foundCustomers = ko.observableArray();
var base_url = window.location.origin;
var pathArray = window.location.pathname.split( '/' );
if(base_url === "http://localhost"){
var url = base_url+"/"+pathArray[1]+"/client/";
} else {
var url = base_url+"/client/";
}
$.ajax({
url: url+"get_last_ten_clients",
type: "get",
cache: false,
success: function(client_list) {
var data = $.parseJSON(client_list);
self.lastTenClients(data);
}
});
$.ajax({
url: url+"get_pending_data_clients",
type: "get",
cache: false,
success: function(client_list) {
var data = $.parseJSON(client_list);
self.pendingClients(data);
}
});
this.search_client = function()
{
self.shouldShowCustomerMessage(false);
self.foundCustomers.removeAll();
crsf = $("input[name=csrf_test_name]").val();
dataString = $("#search_client_input").val();
$.ajax({
url: url+"search_client_database",
type: "post",
cache: false,
data: {csrf_test_name: crsf, search_client_input: dataString},
success: function(customer_details) {
var data = (customer_details);
self.foundCustomers(data);
},
error: function(xhr, ajaxOptions, thrownError)
{
alert(xhr.status);
alert(thrownError);
}
});
}
}
ko.applyBindings(new clientModel());
Sample data in observable after ajax call:
foundCustomers {"id":"1","nameMusicCompany":"Company","natureMusicCompany":"Music"}
In the view i am trying to assign the value using textInput binding like following:
<input type="text" class="form-control input-sm" name="nameMusicCompany" id="nameMusicCompany" placeholder="Name of the Music Company"
data-bind="textInput: nameMusicCompany">
But instead of showing the value "company" it displays [object HTMLInputElement] inside the input box.
Controller:
public function search_client_database()
{
if(!empty($this->input->post('search_client_input')))
{
$result = $this->client_model->get_client_data($this->input->post('search_client_input'));
echo json_encode($result);
}
}
Model:
public function get_client_data($client_name)
{
$client_name = strtoupper($client_name);
$sql = "SELECT * FROM client_data where UPPER(nameMusicCompany) = ?";
$query = $this->db->query($sql, array($client_name));
if($query->num_rows() > 0)
{
return $query->row();
}
return false;
}
Upvotes: 4
Views: 1961
Reputation: 23372
In your ajax success callbacks you're setting lastTenClients
and pendingClients
, which are both observable arrays.
If you mean to render several inputs:
If you want to render all items inside an observable array you'll have to use a foreach
data-bind. The HTML markup inside a foreach
cannot have a static id
property; it is used as a template and could be included many times. Reusing the same id on several HTML elements will get you in to trouble.
As an example, try:
If you mean to render an input for only one of the items that are returned
If the <input>
element you've specified only appears once in your page, you'll have to tell it which customer's nameMusicCompany
property it has to render. If the property does not exist in the current binding context, it will look for it someplace else and eventually end up in window
. (If I'm not mistaken, this is because knockout uses with: $data
internally). Because you've named your <input>
's id the same as the property's name, window will contain an HTMLInputElement
.
As an example, try:
<!-- ko with: foundCustomers()[0] -->
<input
type="text" name="nameMusicCompany" id="nameMusicCompany"
data-bind="textInput: nameMusicCompany">
<!-- /ko -->
Upvotes: 0
Reputation: 1074295
What's happening is that Knockout is picking up the predefined nameMusicCompany
global created by the browser because you gave your input
element an id
instead of the nameMusicCompany
property of your viewmodel.
You haven't shown us enough of your code for us to tell you how to fix it, but that's what's going on. It could be as simple as that your attribute should be data-bind="foundCustomers.nameMusicCompany"
, but that's a guess without seeing more of your code.
Upvotes: 5