oj-select-one show undefined for all options - javascript

i have an observable array that get its values from REST
$.getJSON(rootModel.soho()).
then(function (StudentCourseView1) {
$.each(StudentCourseView1.items, function () {
self.data.push({
StudentId: this.StudentId,
CourseId: this.CourseId,
Enrollmentdate :this.Enrollmentdate,
Notes :this.Notes,
Id : this.Id,
CourseName : this.CourseName,
StudentName: this.StudentName
});
});
});
self.dataSource = new oj.ArrayTableDataSource(
self.data,
{idAttribute: 'Id'}
);
and i have created select-one like this
<oj-select-one id="select1" style="max-width:20em"
options={{data}}
value="{{data.Id}}"
options-keys="[[data.StudentName]]" >
</oj-select-one>
the select one show undefined for all it options

Are you sure the ajax call is working, and there are no errors in console? Is the drop-down showing a list of blank values?
If yes, then the only missing element is adding option-keys attribute, to explain what data to show the user, and the key for each piece of data.
<oj-select-one id="select1" style="max-width:20em"
options={{data}}
options-keys="{{optionKeys}}"
value="{{StudentId}}">
JS
//You can change this acc. to your convenience.
self.optionKeys = {value:"Id", label:"StudentName"};

Related

Why does my Django form show choice not available error?

I am trying to build a dynamic form in Django template.
I have two dropdown selections. When the user selects an option in the first one, the available choices in the second dropdown changes dynamically. Here is the jQuery code I use to change the choices in the second dropdown element.
$(document).on("change", "[id^=id_form][id$=brand]", function() {
var $value = $(this).val();
var $id_prefix = $(this).attr('id').slice(0, -5);
$auto_type = $("#" + $id_prefix + "auto_type");
$.ajax({
type: 'GET',
url: '/europarts/filter/auto/type/with/brand/' + String($value),
success: function(data) {
$auto_type.html(data);
}
});
});
You can see that it fetches some HTML from a link which is basically a bunch of options which will replace the current ones. Here is the code:
{% for auto_type in auto_types %}
<option value="{{ auto_type.id }}">{{ auto_type.name }}</option>
{% endfor %}
Here are my forms:
class ListForm(forms.ModelForm):
class Meta:
model = List
fields = ['ref_no']
class ProductCreateForm(forms.Form):
brand = forms.ModelChoiceField(queryset=Brand.objects.all(), initial=Brand.objects.first())
auto_type = forms.ModelChoiceField(queryset=AutoType.objects.filter(brand=Brand.objects.first()), empty_label=None)
part_no = forms.CharField(max_length=50)
description = forms.CharField(max_length=255)
quantity = forms.IntegerField()
unit = forms.CharField(max_length=20, initial='piece(s)')
cost_price = forms.IntegerField(required=False)
selling_price = forms.IntegerField(required=False)
I am using a dynamic formset jquery library to save multiple Products with a List.
This works fine till now!
However after I change the options like this and try to submit the form, the form page gets loaded again with the default options in the second dropdown and not the changed ones along with an error that says:
Select a valid choice. That choice is not one of the available choices.
Here is the request.POST value when the form is submitted.
<QueryDict: {'form-MAX_NUM_FORMS': ['1000'], 'form-1-description': ['lskdjf'], 'form-1-auto_type': ['3'], 'form-MIN_NUM_FORMS': ['0'], 'form-0-quantity': ['1'], 'form-0-brand': ['2'], 'form-0-part_no': ['293847'], 'form-0-auto_type': ['2'], 'form-0-unit': ['piece(s)'], 'form-0-description': ['slkdfj'], 'form-1-part_no': ['928374'], 'form-TOTAL_FORMS': ['2'], 'form-1-quantity': ['1'], 'form-INITIAL_FORMS': ['0'], 'ref_no': ['REF230498203948'], 'csrfmiddlewaretoken': ['WYN08Hi2YhwTSKPS8EnLaz94aOz33RVfFMjwYeHr3rMxBImxn7ggSLYHwguIbuL0'], 'form-1-brand': ['2'], 'form-1-unit': ['pieces']}>
You can see 'form-1-auto_type': ['3'] which was 'form-1-auto_type': ['1'] originally. The form is submitted when the original value is there, but after the dynamic change in value it shows the above error.
This error is shown for the second dropdown. How can I fix this?
When the form is being validated it checks whether the option exists in the choices for the field, in this case:
queryset=AutoType.objects.filter(brand=Brand.objects.first())
It works only when you select an option from the first brand.
To make it work you need to update the choices for the auto_type field before it validates the data or it might be easier not to limit the choices of auto_type to any brand and then update the select element in JavaScript when the page loads to show only the options of the first brand.

Value in object returns to empty

I'm using a select form with data retrieved from a JSON url. When I select something, I want the value to be put into $scope.afspraak.groep. For some reason, the value returns to the original value which is empty.
Here is my code:
<select id="selectgroep" name="selectgroep" class="form-control" size='5' ng-model="afspraak.groep" ng-options="t.id as t.id for t in objecten" ng-click="test()">
</select>
$scope.afspraak = {
groep: '',
};
$scope.passData = function(data) {
$scope.afspraak.groep = data;
}
$scope.test = function() {
console.log($scope.afspraak);
}
I have used various methods such as changing ng-click to passData(afspraak.groep), but it still doesn't work. The weird thing is that in another partial, I have the exact similar code and that does work shown here:
<select id="selectvak" name="selectvak" class="form-control" size='5' ng-model="user.vakid" ng-options="t.id as t.id for t in vak" ng-click="getKlas(user.vakid); test()">
</select>
$scope.user = {
vakid: '',
};
$scope.test = function() {
console.log($scope.user);
}
$scope.getKlas = function (ID){
afsprakenService.getKlassen(ID)
.success(function (klas){
$scope.klas = klas;
$scope.alerts.push({ type: 'success', msg: 'Retrieved'});
})
.error(function (error) {
$scope.alerts.push({ type: 'danger', msg: 'Error retrieving! ' + error.message});
});
};
What am I doing wrong here? The only difference that I see is the method in the second select form which is getKlas where I pass the ng-model to use in another function.
Edit: this is now solved! It turns out that a label class is what was causing the deletion. I removed it by accident and it works now!
To set a models value from a select it is sufficient to have a ng-model on it. In case you want to do some extra action when selecting an option you should use ng-change and not ng-click.
A good way to debug your models, to check in real time if it was updated and view its values do something like this
<pre>{{ myModel | json }}</pre>
Here is a working fiddle example: http://jsfiddle.net/jub58sem/2/

changing data of select2 with x-editable without re-setting source option

How to keep the source of option values updated in x-editable
without re-initialising the editable element with source.
Here is the sandbox : http://jsfiddle.net/wQysh/322/
HTML
<p>X-editable (dev)</p>
<div>
<button id="controller">Add</button>
</div>
<div>
<button id="controller1">Remove</button>
</div>
<div>
<button id="controller2">Update</button>
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
JS :
$.fn.editable.defaults.mode = 'inline';
var count = 4, sources = [];
for(var i = 1; i <= count; i++){
sources.push({ id : i, text : String(i) })
}
var getSource = function() {
//i want this function must be called whenever available options is rendred. to ensure i used JSON.parse
return JSON.parse(JSON.stringify(sources));
};
$('#controller2').click(function(e){
count++;
sources[2].text = String(count);
//to verify live changes, if a new record updated in sources and used instantly
$('#username').editable('setValue', [1, count]); $('#username2').editable('setValue', count);
});
$('#controller').click(function(e){
count++;
sources.push( {id : count, text :String(count) });
//to verify live changes, what if a new record added in sources and used instantly
$('#username').editable('setValue', [1, count]); $('#username2').editable('setValue', count);
});
$('#controller1').click(function(e){
count++;
var a = sources.pop();
//to verify live changes by selecting value that is not present in the list. It should escape those, print the rest all if available in list
$('#username').editable('setValue', [1, a.id]); $('#username2').editable('setValue', a.id);
});
$('#username').editable({ //to keep track of selected values in multi select
type: 'select2',
url: '/post',
autotext : 'always',
value : [1,2],
source : getSource,
emptytext: 'None',
select2: {
multiple : true
}
});
$('#username2').editable({ //to keep track of selected values in single select
type: 'select2',
url: '/post',
autotext : 'always',
value : 2,
source : getSource,
emptytext: 'None',
select2: {
multiple : false
}
});
$('#username3').editable({ //to keep track of available values in multi select
type: 'select2',
url: '/post',
autotext : 'always',
value : null,
source : getSource,
emptytext: 'None',
select2: {
multiple : true
}
});
$('#username4').editable({ //to keep track of available values in single select
type: 'select2',
url: '/post',
autotext : 'always',
value : null,
source : getSource,
emptytext: 'None',
select2: {
multiple : false
}
});
//ajax emulation. Type "err" to see error message
$.mockjax({
url: '/post',
responseTime: 400,
response: function(settings) {
if(settings.data.value == 'err') {
this.status = 500;
this.responseText = 'Validation error!';
} else {
this.responseText = '';
}
}
});
Requirement :
Whenever i add new item in sources, if item is not selected then it should be updated in available options otherwise if selected then view should have updated value at element.
Whenever i update an item in sources, if item is not selected then it should be updated in available options otherwise if selected then view should have updated value at element.
Whenever i delete an item in sources, if item is not selected then it should be removed from the available options otherwise if selected then view should have "None" value (if single select) and rest element values (if multi select) at element.
Not allowed:
to reinit the widget
to reinit the source option
I hope this is possible. But struggling to get the result.
EDIT2 : code did not worked when i used JSON.parse over stringified 'sources' Problem is still unresolved. New fiddle : http://jsfiddle.net/wQysh/322/
(EDIT1 was misleading this question so removed EDIT1)
EDIT3 : so far i am able to achieve this http://jsfiddle.net/wQysh/324/
Here problem is that previous selected values are not rendered, so can't remove the items if selected previously in multi-select
EDIT4: not completely solved, http://jsfiddle.net/wQysh/339/. After add or update the available option does change but after setting that new record, does not reflect in html element after submit.
the answer is to use a custom display function
here is the updated fiddle. http://jsfiddle.net/wQysh/357/
Every time we 'setValue' to editable or on close event editable's 'display' function is called.
in display function existing values is checked by this function
$.fn.editableutils.itemsByValue
where the third parameter accepts the idKey. If we do not provide third parameter while calling this function, it by default takes 'value' as idKey. and 'value' as idKey should not be used when we are using to load array data. ref : http://ivaynberg.github.io/select2/#data_array.
I added display function in which third parameter is 'id'.
and i got the desired result

delete row(s) from ng-grid table from button

I have a table with ng-grid, and the problem is that i'm not sure how to collect the selected row(s) id or variable to pass into my delete function.
here is a quick mockup of what i'm trying to do
http://plnkr.co/edit/zy653RrqHmBiRJ7xDHlV?p=preview
the following code is from my html, a clickable delete button that takes in 2 parameters, the array of checkbox ids and the index at the corresponding table. This delete method was obtained from this tutorial : http://alexpotrykus.com/blog/2013/12/07/angularjs-with-rails-4-part-1/
<div class="btn-group">
<button class="my-btn btn-default button-row-provider-medical-services" ng-click="deleteProviderMedicalService([], $index)">Delete</button>
</button>
</div>
<div class="gridStyle ngGridTable" ng-grid="gridOptions">
</div>
The following code grabs the json data from a url, queries it and returns it. It also contains the delete function that gets called from the controller in the html page.
app.factory('ProviderMedicalService', ['$resource', function($resource) {
function ProviderMedicalService() {
this.service = $resource('/api/provider_medical_services/:providerMedicalServiceId', {providerMedicalServiceId: '#id'});
};
ProviderMedicalService.prototype.all = function() {
return this.service.query();
};
ProviderMedicalService.prototype.delete = function(providerId) {
this.service.remove({providerMedicalServiceId: providerId});
};
return new ProviderMedicalService;
}]);
The following is my controller(not everything, just the most important bits). $scope.provider_medical_services gets the json data and puts it into the ng-grid gridOptions.
After reading the ng-grid docs, i must somehow pass the checkbox ids from the selectedItems array and pass it into html doc to the delete function. Or, i'm just doing this completely wrong, as i hacked this together. Solutions and suggestions are greatly appreciated
(function() {
app.controller('ModalDemoCtrl', ['$scope', 'ProviderMedicalService', '$resource', '$modal', function($scope, ProviderMedicalService, $resource, $modal) {
var checkBoxCellTemplate = '<div class="ngSelectionCell"><input tabindex="-1" class="ngSelectionCheckbox" type="checkbox" ng-checked="row.selected" /></div>';
$scope.provider_medical_services = ProviderMedicalService.all();
$scope.deleteProviderMedicalService = function(ids,idx) {
$scope.provider_medical_services.splice(idx, 1);
return ProviderMedicalService.delete(ids);
};
$scope.gridOptions = {
columnDefs: [
{
cellTemplate: checkBoxCellTemplate,
showSelectionCheckbox: true
},{
field: 'name',
displayName: 'CPT Code/Description'
},{
field: 'cash_price',
displayName: 'Cash Price'
},{
field: 'average_price',
displayName: 'Average Price'
},
],
data: 'provider_medical_services',
selectedItems: []
};
i think the easiest option is pass an (array index) as data-id to your dom, which u can pick it from there.
{{$index}} is a variable you can use in ng-repeat
======= ignore what i said above, since i normaly writes my own custom stuff ======
I just had a look at ng-grid, i took their example. i've added a delete all selected function, as well as someone elses delete current row function ( these is pure angular way ) to see the code, hover over the top right corner < edit in jsbin >
http://jsbin.com/huyodove/1/
Honestsly i don't like it this way, you would be better off use something like lodash to manage your arrays and do your own custom grid. Using foreach to find the row index isn't good performance.
In their doc, it says you can change the row template, and which you should, so you can add the {{index}} to that row, and filter your data through that index rather which is a little bit better. anyway beware of deleting cells after you have filter your table.
I don't quite get much your question, but you can access to selectedItems of ng-grid as following: $scope.gridOptions.$gridScope.selectedItems (see ng-grid API for more information, but technically this array holds the list of selected items in multiple mode - or only one item in single mode)
For your case, the deleteAll() function could be someething like this:
$scope.deleteAll = function() {
$scope.myData = [];
}
The delete() function which delete selected items can be:
$scope.delete = function() {
$.each($scope.gridOptions.$gridScope.selectedItems, function(index, selectedItem) {
//remove the selected item from 'myData' - it is 2-ways binding to any modification to myData will be reflected in ng-grid table
//you could check by either name or unique id of item
});
}

Dojo: dijit.form.filteringselect dynamically add options from Json

I am getting data from json file, now i want to add it to filteringselect. i tried below code but its not adding, please help me
HTML code==
<select data-dojo-type="dijit/form/FilteringSelect"
id="education"></select>
Javascrip code==
request.get("/json/education.json", {
handleAs: "json"
}).then(function(data) {
var node = dijit.byId('education');
dojo.forEach(data.items, function(desc, index){
node.addOption({
label: desc.name,
value: desc.value
});
});
},
function(error){});
Json code
{
"title":"Education",
"items":[
{"name":"Select Education","value":"0"},
{"name":"B.A", "value":"1"},
{"name":"B.Sc" ,"value":"2"},
...........................
The store of FilteringSelect can be set dynamically, based on the ajax call.
var str = new dojo.store.Memory(optionData);
dijit.byId('widgetId').set('store',str);
But, your json data must be like this:-
var optionData={
data:[
{id:'aaaaaa',name:'aaaaaa'},
{id:'bbbbbb',name:'bbbbbb'}
]
};
The above example will actually replace the store. If, the new data from ajax call need to be appended to the existing options, then
//str is the existing store of FilteringSelect field above
dojo.forEach(result.data, function(optionSet, index){
str.add(optionSet);
});
Note to remember: 'addOption' is available only for Select. Not for FilteringSelect.
I hope this helps:
dijit.byId("select_id").store.root.add(dojo.create("option",{ value: "some", innerHTML: "label of option"}));
To remove the existing elements did just that:
var size = dijit.byId("select_id").store.root.removeChild.length;
for(var i=size; i>=0; i--){ dijit.byId("select_id").store.root.removeChild(dijit.byId("select_id").store.root.children[size-1]);
}

Categories

Resources