Closed laurensdijkstra closed 8 years ago
I'm not sure what problem you are having. This seems to work correctly for me:
<script id="myTmpl" type="text/x-jsrender">
{^{tabs tabCaption="first" width="200px"}}
one
{{else tabCaption="second"}}
<select data-link="selectedID">
<option value="0">Choose a person to edit</option>
{^{for people}}
<option data-link="{:name} value{:ID} selected{:ID === ~root.selectedID}">ss</option>
{{/for}}
</select>
{{/tabs}}
</script>
<script>
var people = [
{
ID: "Ad0",
name: "Adriana"
},
{
ID: "Ro0",
name: "Robert"
}
];
var myTmpl = $.templates("#myTmpl");
myTmpl.link("#tabsView", {
selectedID: "Ro0",
people: people,
});
</script>
Does it work for you? If there is still an issue, you would need to create a simple jsfiddle example so I can see what you are trying to do, and how you are doing it...
Yes this works for me aswell. I was not aware of the existence of a tabs "plugin". So maybe that is why this does work.
Excuse me for not giving a clearer example but reproducing the behaviour in a fiddle was taking too much time.
My code looks something like this:
{^{for project.scenarios}}
<tr data-link="selected{:~root.selectedScenario^id === id}">
<td>
<label>
Visible
<input type="checkbox" name="visibility" data-link="visible" />
</label>
</td>
<td><a href="javascript:void(0)" data-link="{:name} {on ~selectScenario}"></a></td>
</tr>
{{/for}}
{^{for selectedScenario^instances}}
<tr data-link="selected{:~isSelected(#data)}">
<label>
Template
<select data-link="templateId">
{^{for ~root.project.templates ~templateId=templateId}}
<option data-link="{:name} value{:id} selected{:id === ~templateId}"></option>
{{/for}}
</select>
</label>
{{/for}}
A declarative click handler on the scenario selector calls a helper function selectScenario. This in turn changes viewModel.selectedScenario (observably). A scenario contains a list of instances and an instance has a templateId property. viewModel.project has a templates array that is matched to the templateId to determine the selected template in the
Initially this works fine, but after having switched the selectedScenario, the select box is not updated or even blank in Firefox.
I would need to see the code in a running sample to know what is wrong. It is probable that it is not a bug in JsViews but an issue with the way you are using it. To know what that issue might be I would need the sample. Can you add some javascript code to the above and get it working in a jsfiddle?
Otherwise take a look at how tab.js with select works, and model yours after that (if the user experience you want is similar to switching tabs in my example).
(There are several tag control samples, including tabs: http://www.jsviews.com/#samples/tag-controls.)
That said - it looks as if you may have a problem with the option data-linking to ~templateId. To listen to changes in templateId, you need to pass in the object which is changing observably, not just a copy of the property ~templateId. For example you could write:
{^{for ~root.project.templates ~instance=#data}}
<option data-link="{:name} value{:id} selected{:id === ~instance.templateId}"></option>
{{/for}}
An equivalent alternative to that is:
{^{for selectedScenario^instances itemVar="~instance"}}
...
{^{for ~root.project.templates}}
<option data-link="{:name} value{:id} selected{:id === ~instance.templateId}"></option>
{{/for}}
One other thing - does your ~isSelected(#data)
computed observable have a isSelected.depends = ...
defined? I assume it does...
Thanks for responding.
I have created a fiddle that shows the problem: https://jsfiddle.net/q0d5t75k/1/ Then I tried the solution you gave in your response in https://jsfiddle.net/q0d5t75k/2/ but it still is not showing the correct value after switching tabs.
The depends
is indeed defined. It has now a twofold dependency. Both on the selectedInstances
property itself aswell as selectedInstances.length
.
OK - it looks like the issue is that you are using IDs of type number:
templateId: 1000,
and then you have:
<select data-link="templateId">
{^{for ~root.project.templates ~templateId=templateId}}
<option data-link="{:name} value{:id} selected{:id === ~templateId}"></option>
{{/for}}
</select>
When you select a different template in the drop-down it sets the instance.templateId
to the value property of the selected option element, which is a string - set by value{:id}
- (but an <option>
will coerce to string when you set its value
).
So then the test id === ~templateId
fails for all items since id is a number and templateId is a string.
Quick fix: use id == ~templateId
.
Alternatives: Use string IDs - or use a intToString and stringToInt converter like this sample: http://www.jsviews.com/#samples/form-els/array-binding
<select data-link="{intToStr:amount:strToInt} size{:listbox ? amounts.length : null}">
Ah yes that makes alot of sense :)
I really thought this was a bug so I posted it here. Next question will be on stackoverflow.
Thanks for the quick help.
Sorry but the solution works only in Chrome. Firefox does not keep the selection of the first item in the select box. Is this a bug then?
Well that is interesting. It was tricky, but I have figured it out - and have a fix.
Here is a repro:
<script id="myTmpl" type="text/x-jsrender">
<select id="ts" data-link="selectedID">
{^{for people}}
<option data-link="{:name} value{:ID} selected{:ID === ~root.selectedID}"></option>
{{/for}}
</select>
</script>
<script>
var people = [
{
ID: "Ad0",
sID: "ts1",
name: "Adriana"
},
{
ID: "Ro0",
sID: "ts2",
name: "Robert"
}
];
var myTmpl = $.templates("#myTmpl");
myTmpl.link("#result", {
selectedID: "Ad0",
people: people,
});
In Firefox, the above will not show the initial selection.
OTOH if you either set the selectedID to selectedID: "Ro0"
(the second option, rather than the first) or if you include a default option for when there are no selected ones:
<script id="myTmpl" type="text/x-jsrender">
<select id="ts" data-link="selectedID">
<option>Choose a person</option>
{^{for people}}
<option data-link="{:name} value{:ID} selected{:ID === ~root.selectedID}"></option>
{{/for}}
</select>
</script>
or (see below) you output the value="{{:id}}"
on the options, rather than data-linking, then it will work correctly in Firefox.
In my tests and samples, I had a default <option>
every time, so had not seen this issue until now.
What happens is that data-linking first executes the data-link="selectedID"
and subsequently the value{:ID}
and then selected{:ID === ~root.selectedID}
. So the first stage sets select element value to "Ad0" but the options don't yet have their values set. They are set in the second stage, and then in the third stage the first option has its selected
attribute set to "selected". At that point the browser should set the parent select
element to have the correct selectedIndex
: 0.
But jQuery - in the first step - sets the selectedIndex to -1, and other browsers happily set it back to 0 in the later stage. Firefox for some reason does not set it back to 0 - and this seems to be a bug. It leaves the selectedIndex at -1 and the visual selection to unselected, even though the option does have the selected
attribute set to "selected".
So you can fix the issue right now by using JsRender to initially render the values on the options instead of (or as well as) data-linking the value. I assume in fact your id will not change dynamically, so you don't need the data-linking:
<option value="{{:id}}" data-link="{:name} selected{:id == ~instance.templateId}"></option>
So there will be a fix for the above scenario in the next update...
This has been fixed in v0.9.72. This will work correctly now in Firefox. Also, changes have been made that simplify data-linking to select elements.
You can now data-link to the select without needing to data-link 'selected' on the options.
<script id="myTmpl" type="text/x-jsrender">
<select id="ts" data-link="selectedID">
{^{for people}}
<option data-link="{:name} value{:ID}"></option>
{{/for}}
</select>
</script>.
Sweet! Looks alot simpler and cleaner now :+1:
Sweet! Makes it alot simpler :) Op 28 jan. 2016 05:26 schreef "Boris Moore" notifications@github.com:
This has been fixed in v0.9.72. This will work correctly now in Firefox. Also, changes have been made that simplify data-linking to select elements.
You can now data-link to the select without needing to data-link 'selected' on the options.
. . — Reply to this email directly or view it on GitHub https://github.com/BorisMoore/jsviews/issues/330#issuecomment-175966929.
In a scenario where one has two tabs that contain select boxes, switching between the tabs (with an observable property) displays correctly the initially selected values. But after selecting a new option in a select box and then switching to the other tab and back, the value is not updated.