I have a page that populates its fields(dropdowns and textboxes) from the DB when the page loads via VIEWDATA object from controller.
I am using KnockoutJS for data-binding, below is the scenario
HTML & JS(dropdown)
#if (Filter!= null)
{
<select data-bind="options: RsnAdmAct,
value: selectedRsnAdmAct,
optionsCaption:'Choose...',
optionsValue:'RsnAdminActionID',
optionsText:'RsnAdminActionDescp',
optionsAfterRender: function()
{
setOptionRSN(#Filter.RsnForAdminAction);
}">
</select>
}
self.RsnAdmAct = ko.observableArray([]);
self.selectedRsnAdmAct = ko.observable();
$.getJSON("GetRAA", null, function (data) {
self.RsnAdmAct(data);
});
self.selectedRsnAdmAct = ko.observable();
self.setOptionRSN = function (x) {//reason for admin action dd
self.selectedRsnAdmAct(x);
};
this does update the drop-down with the assigned value "X".
But the same does not assign value for the text-boxes as below
HTML & JS(textbox)
#if (#Filter != null)
{
<input placeholder="Downstream"
data-bind="value: DownStream,
optionsAfterRender:function()
{
setOptionDstream(#Filter.DownstreamNumber);
}">
}
self.DownStream = ko.observable();
self.setOptionDstream = function (x) {//down stream number
self.DownStream(x);
};
optionsAfterRender applies to options; a text input has no options. Setting the value of DownStream will set the value of the text box, because that's how the value binding works.
I tried to search for a proper way to do this but below is the way it works and no other alternative worked.I had to move the function which assigns the value to the texbox observable into the options after render attribute of the drop down as below
#if (Filter!= null)
{
<select data-bind="options: RsnAdmAct,
value: selectedRsnAdmAct,
optionsCaption:'Choose...',
optionsValue:'RsnAdminActionID',
optionsText:'RsnAdminActionDescp',
optionsAfterRender: function()
{
setOptionRSN(#Filter.RsnForAdminAction);
setOptionDstream(#Filter.DownstreamNumber);
}">
</select>
}
This is the only way it worked for me.Thank you for the posts and comments
Related
I'm trying to filter my Gantt Chart using a drop-down checkbox list. this is my code
index.html
<label class="text-primary" for="department">Select by Departments: </label>
<select id="department" style="width:200px; height:20px; " mode="checkbox">
<option value="ALL" selected="1" >ALL</option>
<option value="ARTIST">ARTIST</option>
<option value="ADMIN">ADMIN</option>
<option value="LEAD">LEAD</option>
<option value="HR">HR</option>
<option value="PRODUCTION">PRODUCTION</option>
<option value="MANAGEMENT">MANAGEMENT</option>
<option value="TECHNOLOGY">TECHNOLOGY</option>
</select>
function
<script>
var myCombo;
function checkbox_department() {
myCombo = dhtmlXComboFromSelect("department");
myCombo.attachEvent("onCheck", function(value, state){
gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
var department_value = value
if (task.job_category == department_value || department_value == 'ALL') {
console.log(value);
return true;
}
});
gantt.render();
});
}
</script>
the job_category came from a JSON file.
so far I manage to filter the gantt chart with any first checkbox I checked but when I check another checkbox, let say i check artist and production everything disappear and in the console log it'll display
3PRODUCTION
7ARTIST
2PRODUCTION
52ARTIST
PRODUCTION
51ARTIST
2PRODUCTION
3ARTIST
PRODUCTION
22ARTIST
It will turn out like that, it would be easier if i just print screen the whole thing here but I'm using my office desktop and file uploading is blocked. Can anyone help me solves this issue, thanks in advance
Your combo adds an onBeforeTaskDisplay handler each time user checks combo value, while never removing previously added handlers when an option becomes unchecked/unselected.
I'd suggest to store combobox selection in some scope variable and declare only one onBeforeTaskDisplay handler which will filter gantt by the value of that variable.
Then, inside onCheck handler of combo you update a scope variable with the selection state of the combo and call gantt repaint in order to invoke filtering
Your code may look following:
var myCombo;
function checkbox_department() {
var department_value = 'ALL';
myCombo = dhtmlXComboFromSelect("department");
myCombo.attachEvent("onCheck", function(value, state){
department_value = value;// put combo value into scope variable
gantt.render();// and repaint gantt
});
// filter gantt by value of the scope variable
gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
if (task.job_category == department_value || department_value == 'ALL') {
console.log(value);
return true;
}
});
}
and here is a simplified demo in case i got something wrong with the explanation and code sample
http://docs.dhtmlx.com/gantt/snippet/b6053d50
Update:
If you have a multiselect combo, you may need a bit different code. Something following should work:
var myCombo;
function checkbox_department() {
var department_value = {'ALL': true};
myCombo = dhtmlXComboFromSelect("department");
myCombo.attachEvent("onCheck", function(value, state){
var values = myCombo.getChecked();
department_value = {};// put combo value into scope variable
for(var i = 0; i < values.length; i++){
department_value[values[i]] = true;// build hash for easy check later
}
gantt.render();// and repaint gantt
});
// filter gantt by value of the scope variable
gantt.attachEvent("onBeforeTaskDisplay", function (id, task) {
if(department_value['ALL'])
return true;
return !!department_value[task.job_category];
});
}
I have a select tag in my html with knockout js binding.
<select class="form-control " data-bind="options: loanTimesBorrower,
optionsText: loanTimesBorrower(),
value: loanTimeBorrower,
selectedOptions: loanTimesBorrowerini,
optionsCaption: 'Choose dates'">
</select>
Instead of choose date I want to show the default value as 180, since I have a array which stores this loantime as 180 days, 360 days etc.
this is the array
self.loanTimesBorrower = ko.observableArray();
self.loanTimesBorrowerini = ko.observableArray(self.loanTimesBorrower()[0]);
and I get this array populated by a foreach loop which is getting the loantimes from db like this.
$.each(items.investTimes, function (index, item) {
self.loanTimesBorrower.push(item.Loantime);
});
So I am not sure how the default value can be put as 180 instead of choose dates
Remove
optionsCaption: 'Choose dates'
It would default to the option you provided.
You can use it like this:
<select id="selectDate" class="form-control " data-bind="options: loanTimesBorrower,
optionsText: loanTimesBorrower(),
value: loanTimeBorrower,
selectedOptions: loanTimeBorrower[0],
optionsAfterRender: $root.setDefaultDate">
</select>
And in your javascript you can do something like:
self.setDefaultDate= function (option, object) {
if (typeof object !== "undefined" && object !== null) {
if(object.value === 180) {
$("#selectDate").find(option).prop('selected', true);
}
}
};
if you show me what the object in your array looks like I can edit the answer for a better fit. But that should help you to find your way
I'm using Knockout 3.2 and i'm trying to display a multiple select dropdown with some selected values, but the values are not being selected. The problem is that KO does not populate the 'value' attribute of the options:
<select data-bind="options: availableCountries, selectedOptions: chosenCountries, optionsText: 'name'" size="5" multiple="true">
<option value="">France</option>
<option value="">Germany</option>
<option value="">Spain</option>
</select>
VM:
var viewModel = {
availableCountries : ko.observableArray([{name:'France'}, {name:'Germany'}, {name:'Spain'}]),
chosenCountries : ko.observableArray(['Germany'])
};
If instead of object i turn availableCountries into a simple strings array, it works.
You can see a live sample here
var viewModel = {
availableCountries : ko.observableArray([{name:'France'}, {name:'Germany'}, {name:'Spain'}]),
chosenCountries : ko.observableArray(['Germany'])
};
['Germany'] is not {name: 'Germany'}!
And also if you, would write chosenCountries : ko.observableArray([{name: 'Germany'}]), this would lead to two different objects, with the same property name and the value 'Germany'.
var viewModel = (function() {
var self = {};
self.availableCountries = ko.observableArray([{name:'France'}, {name:'Germany'}, {name:'Spain'}]);
self.chosenCountries = ko.observableArray([self.availableCountries()[1]]);
return self;
})();
ko.applyBindings(viewModel);
I changed the viewModel, to an instand called function which returns the viewModel.
(function () {...})()<-call
http://jsbin.com/monasijufaya/1/edit?html,js,output
I'm using ASP.NET MVC 4
Let's puttig this way, this is my Html:
<select id="cmbProducts" name="Products" class="form-control">
<option value="1">Product1</option>
<option value="2">Product2</option>
<option value="3">Product3</option>
</select>
<button id="cmdAddProduct" type="button">Add selected product</button>
<select id="cmbAddedProducts" name="AddedProducts" size="8" class="form-control">
<!-- These options are added dinamically on click via jQuery -->
</select>
And this is my jQuery function
$(function () {
$("#cmdAddProduct").click(function (e) {
var productName = $('#cmbProducts :selected').text();
var productValue = $('#cmbProducts :selected').val();
var exists = false;
$("#cmbAddedProducts > option").each(function () {
if (this.text == productName) {
exists = true;
}
});
if (!exists) {
$('#cmbAddedProducts').append($('<option>', {
value: productValue,
text: productName
}));
}
});
It works perfect adding elements to my list.
My problem is I'm trying to get the options array which were added dinamically on 'cmbAddedProducts' (these are being added using .append on my function).
On my controller, I'm using an ActionResult to retrieve the options on the <select>
public ActionResult AEventos(FormCollection form) {
string[] AddedProducts = Request.Form.GetValues("AddedProducts");
}
But it only retrieves the <option>'s that I added directly on html code, not the added dynamically using jQuery on my buttons click.
I think this is related to the DOM not updating but I've been searching for help without success, and still have no idea about how to solve this.
Update your javascript to
$('#cmbAddedProducts').append($('<option>', {
value: productValue,
text: productName,
selected: true
}));
so that option you add will get selected in your DOM and thus this will be getting accessed from your controller.
I am working on a drop down menu within a TR .. I have true, false or none as the value that I receive from server and I want that to change the drop down option as in example below.
The first one is working but I want the second one to function as the first one
Example is here: http://jsfiddle.net/3xLgJ/
This is my HTML:
<div data-bind='text: incomingValue'></div>
<select data-bind="value: incomingValue">
<option value="true">Yes</option>
<option value="false">No</option>
<option value="none">Don't Know</option>
</select>
How can I implment this as above as this is within a tr and to function as above
<select data-bind='options: yesno, value: incomingValue'/>
Here is my knockout
var myModelView = function () {
self = this;
self.yesno = ko.observableArray(['Yes', 'No', 'Don\'t know']);
self.incomingValue = ko.observable('none');
};
var moView = new myModelView();
ko.applyBindings(moView);
Thanks
Thanks
The best solution is probably to slightly reconstruct the view model to use objects instead of simple strings:
// Create a "class" that represents an option
var Option = function(id, caption) {
this.id = id;
this.caption = caption;
};
Now you populate the observable array with objects constructed from this function:
self.yesno = ko.observableArray([
new Option('true', 'Yes'),
new Option('false', 'No'),
new Option('none', 'Don\'t know')
]);
You can use the "optionsText" binding to correctly bind these objects to the markup:
<select data-bind="options: yesno,
optionsText: 'caption',
value: selectedItem"></select>
If you receive a string "none" from the server, you need to find the object representing this option:
var incomingValue = 'none';
// Find the first object that is a match in the observable array "yesno"
var incomingItem = ko.utils.arrayFirst(self.yesno(), function(item) {
return item.id == incomingValue;
});
self.selectedItem = ko.observable(incomingItem);
When displaying the selection somewhere else you'll need to consider that the selection is represented by an object:
<div data-bind='text: selectedItem().caption'></div>
Demo: http://jsfiddle.net/3xLgJ/2/
You need to use the optionsText and optionsValue bindings. You'll need to make an observable array of values and text:
self.yesno = ko.observableArray([
{value:"true",text:"Yes"},
{value:"false",text:"No"},
{value:"none",text:"Don't Know"}]);
then, you need to do something like this in your html:
<select data-bind="options: yesno2, optionsText: 'text',optionsValue: 'value', value: incomingValue"></select>
See here for a working example