borismoore / jsviews Goto Github PK
View Code? Open in Web Editor NEWInteractive data-driven views, MVVM and MVP, built on top of JsRender templates
Home Page: http://www.jsviews.com/#jsviews
License: MIT License
Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
Home Page: http://www.jsviews.com/#jsviews
License: MIT License
Hi,
I'd like to add support for link to textarea elements. Could you give some hints about ?
/Currently the following scenarios do work:
$.observable(model).setProperty("a.b", "bar");
$.observable(model.a).setProperty("b", "bar");
TODO Add support for $.observable(model).setProperty("a", { b: "bar" });
Need to iterate over paths paths = getLinkFromDataInfo( target, source ).paths - in addition to the one whose key is sourcePath
That's not a issue, but i can't find a place to ask (maybe an IRC channel, forum, or else ?)
I used first jsRender to create a simple uploader UI widget.
The goal is to get the same features as the Google+ upload widget.
Especially this feature :
1/ When a file is added for upload, an element with a progress bar is appended
2/ When a file upload is done, the current element is replaced by another one, the final uploaded file (2 different templates)
My tests with jsRender were successful, so i told myself, maybe you can add to this more dynamism by using jsViews (i mean by letting jsViews automatically update the dom when data is updated).
The thing is i can't in that case, because i have to different templates (one while upload is in progress, and one after it's done) that can't be appended to the same container element.
We can't link two data structures to the same element. Maybe that's logic by nature, but still, i have to ask, can i have the behaviour i expect with jsViews ?
Thanks.
Benjamin.
Ive built some custom helpers and some templates to pivot tables
.
This requires me to open the table tag, check proceeding rows to see if they belong to they table and add them , when the next proceeding row does now match, close the table.
This works fine and beautifully with jsrender, no errors, nice clean code.
However when I use jsview's data-getfrom="[dataName]"
type tag it falls over.
The error in console is - "template is undefined" - template = template.split( "=" ) - line 236..
To ensure that the problem is the tags not being closed, i used the same helpers and removed all the table stuff and just wrapped the data with <div></div>
. This works as expected
However if I was to wrap the data with only the starting <div>
tag, it breaks..
What is the reason for this, does jsviews check or rely on the structure of the fields parent html elements?
I hope my message is clear and understandable.
Line 150
triggerArrayEvent( this._data, { change: "move", oldIndex: oldIndex, index: index, items: items });
index is not defined anywhere. was this supposed to be newIndex?
If fromHandler is "html" and $source is a textarea element, the value is picked up from the textarea element property "text".
However, this is the old unchanged value, so the linking does not work properly.
(The new value is found in the "value" property of textarea. Changing "text" to "value" seems to work fine.)
Update: although, it seems to introduce problems in IE8...
Hi Boris,
In your custom tags for rendering demo,
http://borismoore.github.com/jsviews/demos/jQueryConfDemosOct2011/14_custom-tags.html
the "Orginal order" list is also reversed.
Looks like you updated the text of the slide to say this.reverse === "true"
, but not the Javascript code.
Fixed here: https://gist.github.com/1597908
Keep up the good work!
->> Josh W <<-
Dear All,
I have the following example:
<div id="rr" style="background-color: Lime">
</div>
<script id="rrTemplate" type="text/x-jquery-tmpl">
<p>
<span>Number of full rounds:</span>
<input data-getfrom="[NumOfFullRounds]" data-to="[NumOfFullRounds]" class="numericValue"/>
</p>
<p>
Reps in partial round:
</p>
{{#each RepetitionItems}}
<div>
<span><input id="txtRep{{=Id}}" data-getfrom="[Value]" data-to="[Value]" class="numericValue XXX"/></span>
<span data-getfrom="[Value]"></span>
</div>
{{/each}}
</script>
<script type="text/javascript">
$(document).ready(function () {
var regVM = {"NumOfFullRounds":5,"RepetitionItems":[{"Max":2,"Value":0,"Id":"A1"},{"Max":4,"Value":0,"Id":"A2"},{"Max":6,"Value":0,"Id":"A3"}]};
alert('start');
$("#rr").link(regVM, "#rrTemplate", {
onAfterCreate: function(view) {
if(view.parent.path == "$data.RepetitionItems")
{
var actRep = view.data;
$("#txtRep" + actRep.Id).jStepper({minValue:actRep.Min, maxValue:actRep.Max}); //this code breaks the 'binding', underlying model will not be updated anymore!
}
}
});
});
</script>
jStepper is a 'plugin' which allows minvalue and maxvalue definitions for textboxes. These textboxes in this example have data-from and data-to attriutes pointing to the same property of a RepetitionItem.
After the jStepper code is executed, and I change values in the textbox, the jstepper code runs properly, but the underlying model is not updated (spans after the textbox listen to the model).
What is the best-practice for this scenario?
Also, doing the "if(view.parent.path == "$data.RepetitionItems")" statement in the event handler seems hacky, what happens if I have more complex templates, is there an easier way to accomplish this?
Or shall I put the {{each}}-content into different template, and then I can somehow hook for its onAfterCreate event?
Thanks!
A tmpl comment will not be correctly detected by the regex if the template tag param included a function call.
rTmplOrItemComment = /^(\/?)(?:(item)|(?:(tmpl)(?:\(([^,)]*),([^,)]*)\))?(?:\s+([^\s]+))?))$/,
The path portion of this expression ends if it sees a ), but the path could have a ) if a function was called.
$view.itemNumber starts at 1
$view[index] (in a data-getfrom) starts at 0
they should both start at 0 or provide a different property / name
This was working very good until pre beta commit #2. I have this issue only with Chrome. After I saw this problem, I returned to the previous version.
If you want to see my code here it is:
view.off("click", ".showMore").on("click", ".showMore", function () {
var item = this;
//Get delta data.
oAjax.CallAsyncMethod(JSON.stringify(param), false, serviceURL + '/Activity/GetDelta', "POST", function (data) {
//insert it to client data.
$.observable(exData.ViewData).insert(exData.ViewData.length, data.GetDeltaResult);
param.DisplayCount += 20;
});
});
P.S: I can insert to exData.ViewData.length-1 or anywhere inside of current array, but not at the end. I think there is a problem with the last item of view/context etc. I don't know.
Do you consider to add an 'elementchange' to the ArrayObservable event types in jquery.observable.js
? That "change" should be fired when an element of an Array changes its value. Please take a look how it's implemented in competitive project.
e.g. MIT? GPL? none? etc. I can't seem to find it indicated anywhere.
Thank you!
First of all I wan't to compliment you on your work on JSViews. I think data-driven views are the future off building web-application and that it will provide lot's of help with implementing your information-models within a information-system.
when you have got data like an order (see below), a properties like Total_Price and Total_lines depends on the data in the Orderlines array.
When rendering jsviews triggers a function that calculates the total price and the total amount of lines (this goes well).
However when changing a value within the orderlines, or add a line to the array with the array observable, jsviews doesn't trigger the functions depending on the property orderlines within the parent, so the amount of lines and the total price won't get updated.
If you need a full example please ask.
P.S. Is it possible to create nested context's or context's that are linked to just ONE property? And what are the possibilities of linking a model to your data to be sure a field contains validated values (creating toLinks should work fine, but can these links also be nested...)?
Thanks in advance,
Dennis
/*--- tmpl: #orderlineTemplate --*/ <script> </script>/-- tmpl: #orderTemplate --/
<script> {{each Orderlines content="#orderlineTemplate"}}
Totaal: |
var OrderData = {
Orderlines : [
{
Product : "Product X",
Amount : 1,
Price_each : 1,
Price : 1
},
{
Product : "Product X",
Amount : 2,
Price_each : 2,
Price : 4
}
],
Total_price : 0,
Total_lines : 0
}
$("#orderContainer").link(OrderData,"#orderTemplate")
$( "#addOrderlineBtn" ).click( function() {
$.observable( OrderData.Orderlines ).insert( OrderData.Orderlines.length, {
Product : "Product",
Amount : 1,
Price_each : 1,
Price : 1
});
});
Simple code to produce the bug:
$.templates("tpl", "#tpl");
// Link to a simple data structure
$.link.tpl(".result", [[1], [2]]);
<script id="tpl" type="text/x-jsrender">
{{for #data}}{{for #data}}}{{:#data}}{{/for}}{{/for}}
</script>
<div class="result"></div>
Then we can have the following script error in Webkit,
Uncaught TypeError: Cannot call method 'push' of undefined jquery.views.js:507
something like this
<input data-getfrom='$ctx.to_ui([sample])' data-to='$ctx.from_ui([sample])' />
Say, the user enters '2.5' or '2,5' meaning two and half hours, but we store minutes etc.
It may be possible to fix this so JsRender has knowledge of the current index where the insert is happening, and increments $itemNumber accordingly
If I have an {{#if}}... {{else}} ... {{/if}} block in a template and somewhere in the javascript code I make a "setProperty" method call on a data property that my {{#if}}/{{else}} code uses for rendering some texts, then I have to call the render() method on the view so that the {{#if}}/{{else}} block is evaluated again with the new data property value (because the template itself is rendered again).
Here is my sample code:
<script id="myTemplate" type="text/x-jquery-tmpl">
<tr>
<td data-getfrom="[Age]"></td> @This td will be updated without calling "render()" on the view.@
<td> @But this td will not be updated without calling "render()" on the view:@
{{#if Age > 25}}
Greater!
{{else}}
Not greater!
{{/if}}
</td>
<td><input type="button" id="btnSetAgeProperty" value="Set age property"/></td>
</tr>
</script>
<table>
<tbody>
<tr>
<th>Age</th>
<th>Is greater than 25?</th>
<th>Set age property</th>
</tr>
</tbody>
<tbody id="myList">
</tbody>
</table>
<script type="text/javascript">
var ages = [{ Age: 5 }];
var myTemplate = $("#myTemplate").template();
$("#myList").link(ages, myTemplate)
.delegate("#btnSetAgeProperty", "click", function () {
$.observable($.view(this).data).setProperty("Age", 30);
$.view(this).render(); // This needs to be called for the "Greater"/"Not greater" text to be updated!
});
</script>
Is it possible that the content of the {{#if}}/{{else}} block (the "Greater"/"Not greater" text) is refreshed without calling the
$.view(this).render() anyway?
Dear All,
I have the following template:
<script id="rrTemplate" type="text/x-jquery-tmpl">
<p>
<span>Number of full rounds:</span>
<input data-getfrom="[NumOfFullRounds]" data-to="[NumOfFullRounds]" class="numericValue"/>
</p>
<p>
Reps in partial round:
</p>
{{#each RepetitionItems}}
<div>
<span><input id="txtRep{{=Id}}" data-getfrom="[Value]" data-to="[Value]" class="numericValue XXX"/></span>
<span data-getfrom="[Value]"></span>
</div>
{{/each}}
</script>
The problem is, that in the each-block, if the user types anything into the input-field (textbox), the span next to it (which is bound to the same property) is updated only when the textbox loses focus. How to make it possible to updated on-the-fly?
Thanks!
If I use IE 8 to run your jsViews demo at the following URL :
http://borismoore.github.com/jsviews/demos/step-by-step/01_rendering-and-linking.html
or after downloading and running on my machine, I receive an "Illegal Assignment" error in IE 8 in jquery.views.js, on line containing : window = window | global. After commenting out this line, it works fine in IE 8.
Is this expected behavior? Can I continue using jsViews with that line commented out? I would like to use jsViews in IE 8 if possible. It works fine in FF and Chrome, IE only has that error.
Thank you,
JJ
Hi Boris,
I am glad to see that you are making good progress with the new library and hope it will make it past beta this time.
I am binding to descendant leaf objects and making use of converter functions like so:
TEST
var data = {
Level1: {
Level2: 'ABC'
}
}
$("#element").link(data);
When I bind it first time the converter function gets called as expected
However when I change the underlying value, the converter function is not called:
$.observable(data).setProperty('Level1', { Level2: 'XVZ' });
I was digging around and narrowed the problem to the following code (jquery.views.js function addLinksFromData line 513)
// If 'from' path points to a property of a descendant 'leaf object',
// link not only from leaf object, but also from intermediate objects
while ( innerPath.length > 1 ) {
innerOb = innerOb[ innerPath.shift() ];
if ( innerOb ) {
addLinkFromData( innerOb, link, innerPath.join( "." ), cnvt, attr );
}
}
// The last trigger of get bindings will be called on adding the link (to get/initialize the value)
addLinkFromData( fromOb, link, 'Level1'/path/, cnvt, attr, !l && get );
As you can see in the last call to addLinkFromData, the path is ‘Level1.Level2’ but if I change it to the name of the root propery, which is 'Level1' in my case - everything works fine.
Please let me know if you agree that in the last call to the addLinkFromData the name of the root property property should be used in case of descendant leaf objects as it will be then used in addLinkFromData:
$(Level1).bind("propertyChange", handler);
Thanks
The syntax to get the view index should be the same when using the JavaScript directly or the data-getfrom:
data-key="{{=$view.itemNumber-1}}" data-getfrom="class:$ctx.myFunction($view[index])"
This is more an advice question instead of an issue. I created an table and use the link function to render the rows. Then when an edit button is clicked I change a row to an edit template. I took this technique from the accordion example and it works perfectly.
In the row there is also an cancel button when in edit mode. However because of the datalinking I no longer have the original object and thus I cannot change back to the original values.
I have several options here. I can request the original object from the server or I can use one of the clone scripts to store a copy of data on the view object. Both these options have their disadvantages. Is there a better way of implementing a "cancel" functionality? Maybe there is an option for delayed binding with an hook or something....
Consider a test template:
<script id="movieTemplate" type="text/x-jquery-tmpl"> <tr> <td>{{=Title}}</td> <td> {{#each $ctx.objectPropertiesToArray(Properties)}} <div> <em>{{=key}}</em> <em>{{=value}}</em> </div> {{/each}} </td> </tr> </script>
along with a registered helper function to support this template:
var helperFuncs = {
objectPropertiesToArray : function( object ){
var ret = [];
for (key in object) {
if (!object.hasOwnProperty(key)) continue;
ret.push({"key" : key, "value" : object[key]});
}
return ret;
}
};
jQuery.views.registerHelpers(helperFuncs);
and then you render this template:
$( "#movieList" ).html($( "#movieTemplate" ).render( movies ));
everything works fine.
However, if you "link()" this same call:
jQuery("#movieList").link(movies,"#movieTemplate");
then the template is rendered correctly, but the following error ocurrs in the console log
$ctx.objectPropertiesToArray is not a function
[Break On This Error] "with($data){return [" + paramString + "];}")( $, source, view, view.ctx );
jquery.views.js (line 353)
The workaround is to pass any used $ctx functions into the "link()" call on the context object:
jQuery("#movieList").link(movies,"#movieTemplate",helperFuncs);
I believe the intended fix here is to augment the link()-ed context object with the "$ctx" so that both items passed in via the "context" argument to link() are available, as well as having the registered helper functions available in the view evaluation context.
I try to use the link function with jsView to update the value of an array.
Here is the javascript (I am using backbone.js so the this.el is the current html element for the view):
that.viewModel = new Role();
that.viewModel.ModuleAccessList = [];
_.each(col.toJSON(), function (obj) {
//col is a backbone collection that I convert to an json array with the toJSON()
that.viewModel.ModuleAccessList.push({ Module: obj, Access: "" });
});
var content = $("#AddRoleTemplate").render(this.viewModel);
$(this.el).html(content);
$(this.el).link(this.viewModel);
And the HTML:
><table>
> {{#each ModuleAccessList}}
> <tr>
> <td>
> {{=Module.Name}}
> </td>
> <td>
> <select data-to="[ModuleAccessList[{{=$itemNumber}}].Access]">
> <option value="none">none</option>
> <option value="readonly">readonly</option>
> <option value="full">full</option>
> </select>
> </td>
> </tr>
> {{/each}}
></table>
></pre>
The value of the viewModel updates like :
ModuleAccessList[1].Access = "readonly" where ModuleAccessList[1].Access is a field.
Is there anyway to update the array directly with data-to and link ?
After browsing through jsviews, I was thinking about a different syntax for the changeArray function.
I forked the code to here:
https://github.com/wiredprairie/jsviews
In particular:
https://github.com/wiredprairie/jsviews/blob/master/demos/2_views/2_editable-data.html
My idea:
$.array($.view(this).data.Languages).push(
{
Name: "NewLanguage"
});
Or this:
$.array(app.selectedItem.data.Languages).splice($.view(this).index, 1);
//$.changeArray(app.selectedItem.data.Languages, "splice", $.view(this).index, 1);
My suggestion is to use a more function based approach that could/might work better with VS2010 (and other IDEs) code completion and be a bit more natural. Here, I changed the syntax from the parameter based "push" to a full function that is called after accessing the array. This follows the jquery pattern of "selector", then function/action.
An exception is thrown when removeViews is called a template tag has its link property set to false. The line in removeView
parentElViews = parentElViews || jsViewsData( view.nextNode.parentNode, viewStr ),
will throw an exception in some cases because view.nextNode is undefined.
Are there any plans to provide shortcuts for data-getfrom and data-to bindings to the same property?
Event onAfterCreate raise on each /tmpl or /item, maybe this event must raise on adding new item?
Hi,
I am using backbone.js, jsRender and jsView and I get a problem with the new version of jsView, my binding is no more working.
I have an input element and I am trying to link it with a viewModel (a json object) like
view.el.innerHTML = $.render["current"](view.viewModel);
$.link("#WorkingArea",view.viewModel);
with the input
<input data-link="Name" tabindex="1" placeholder="Company Inc." class="medium" type="text" />
<a href="#" class="save">save</a>
When I click on the save button, I get the view.viewModel and it's not updated with the value entered in the input.
NOTE : if I try with the old version of jsView (with the data-to in place of the data-link and by executing $("#WorkingArea").link(view.viewModel)),
it is working fine.
Any idea???
Here is the full code :
Company.Views.Create = Backbone.View.extend({
el: "#WorkingArea",
template: "app/templates/company/create.html",
events: {
"click .cancel": "close",
"click .save": "save"
},
initialize: function () {
this.model = new Company.Model();
_.bindAll(this, "render");
},
render: function (done) {
var view = this;
// Fetch the template, render it to the View element and call done.
MyApp.fetchTemplate(this.template, function (tmpl) {
view.viewModel = view.model.toJSON();
view.el.innerHTML = $.render["current"](view.viewModel);
$.link("#WorkingArea",view.viewModel);
popWrapper.Pop($(view.el));
});
},
save: function (event) {
event.preventDefault();
alert(this.viewModel.Name);
},
close: function (event) {
this.remove();
event.preventDefault();
popWrapper.Close();
popWrapper.CreateWorkingArea();
}
});
In line 11: window = window || global;
Open http://borismoore.github.com/jsviews/demos/step-by-step/10_todos.html in IE 8. IE 9 seems to work correctly.
Hi,
I've tried to use to use a template that is not directly as a script tag in the dom. E.g. modified jsrender demo 01_inserting-data.html like:
< script id="movieTemplate" type="text/x-jquery-tmpl" src="t.html" >
This doesnt work.
But what are templates good for if they can't
Or am I missing something? In any case, there is no demo that shows how to do that and the way above doesnt do it.
Best
no gece
While trying on the demo: http://borismoore.github.com/jsviews/demos/step-by-step/01_rendering-and-linking.html
i get the following error on the firebug console:
movieTemplate is not defined
[Break On This Error] $.render( movieTemplate, movies )
01_ren...ng.html (line 56)
Clicking on the buttons yields no effect.
Browser: firefox v7.0.1
Hi!
I changed the Accordion Demo to allow editing using data-linking. Everything works fine:
http://jsfiddle.net/webwurst/A33LN/
Then I placed the button-header-row in a separate template and called it from all the other templates. The event-handler of the buttons has to change their parents view and it seems to work fine:
http://jsfiddle.net/webwurst/Z4vHX/
^But editing gives an Error now. It gives:
"$.observable(target).setProperty is not a function"
Bug? Or am I doing something wrong?
Regards!
Is it possible to get View-objects by data? For example: If i create 3 views linked to the variable data, is it possible to find the 3 views with the observable $.observable(data)?
Hi Boris,
Your step-by-step samples seem to be using the folowing data-link syntax:
css-attrName{:~helperFunc(dataPropertyPath)}
This works for the first-time linking via
On the other hand I found that if I move the semicolon before the opening curly bracket it seems to work better and not only dislplays the first-time value but subsequent value changes as well.
css-attrName:{~helperFunc(dataPropertyPath)}
Any idea what is going on here and which is the right to use?
Thanks again.
Why was demo "19 Custom tag for jQuery plugin: Datepicker" deleted from the latest Samples from jQuery Conference, Boston, October 2011?
My code that worked with the previous version now returns the following message "Error: Object doesn't support property or method 'apply'.
ChrisWF
I'm trying to build a page that has a template that contains multiple radio button groups. The problem is that when the template renders the radio buttons that have the checked property in the source HTML are not visually checked in the browser. Unfortunately I cannot include a screenshot here to show it, but my test page is below. Groups with names ending in 1 to 3 are rendered by the template engine. 4 to 6 are plain HTML. 4 to 6 show fine 1-3 do not. This behavior is the same across Firefox, chrome and IE9. During my test I noticed that some browsers (FF) were showing the same problem in rendering checked on the no-template HTML groups if I omitted the form tags. Maybe I'm missing something obvious, If so don't hesitate to point it out to me.
btw. the missing docs on jsrender and view plugin forces me to look thru the source code of the plugins to identify the features and figure out their use. I have learned a few thing things from that! It's a great plugin.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script>
<script src="/Scripts/jsrender.js" type="text/javascript"></script>
<script src="/Scripts/jquery.observable.js" type="text/javascript"></script>
<script src="/Scripts/jquery.views.js" type="text/javascript"></script>
<script src="Scripts/date-en-US.js" type="text/javascript"></script>
</head>
<body>
<script id="TemplateTest" type="text/x-jquery-tmpl">
<div data-getfrom="css-background-color:bgColor($view[index])">
<input type="radio" name="Price{{=Id}}" data-getfrom="checked:[PriceType] == 2" /><span>Not Specified</span>
<br />
<input type="radio" name="Price{{=Id}}" data-getfrom="checked:[PriceType] == 0" />10
<br />
<input type="radio" name="Price{{=Id}}" data-getfrom="checked:[PriceType] == 1" />20
<br/>
<br/>
<input type="radio" name="SearchArea{{=Id}}" data-getfrom="checked:[SearchAreaType] == 2" /><span>Not Specified</span>
<br />
<input type="radio" name="SearchArea{{=Id}}" data-getfrom="checked:[SearchAreaType] == 0" />30
<br />
<input type="radio" name="SearchArea{{=Id}}" data-getfrom="checked:[SearchAreaType] == 1" />40
<br/><br/>
<input type="radio" name="AdvertisementKind{{=Id}}" data-getfrom="checked:[AdvertisementKind] == 0" />All<br />
<input type="radio" name="AdvertisementKind{{=Id}}" data-getfrom="checked:[AdvertisementKind] == 1" />Offered<br />
<input type="radio" name="AdvertisementKind{{=Id}}" data-getfrom="checked:[AdvertisementKind] == 2" />Wanted<br />
<br/>
</div>
</script>
<script type="text/javascript">
$().ready(function () {
$("#TemplateTest").template("TemplateTest");
var ads = [
{ Id: 1, AdvertisementKind: 0, SearchAreaType: 2, PriceType: 1},
{ Id: 2, AdvertisementKind: 1, SearchAreaType: 0, PriceType: 2 },
{ Id: 3, AdvertisementKind: 2, SearchAreaType: 1, PriceType: 0 }
];
$("#testContainer").link(ads, "TemplateTest");
});
function bgColor(index) {
return (index % 2 ? "yellow" : "red");
}
</script>
<form action="About.aspx">
<div id="testContainer"></div>
<div id="Div4">
<div style="background-color: blue;">
<input type="radio" name="Price4"/><span>Not Specified</span>
<br/>
<input type="radio" name="Price4"/>40
<br/>
<input type="radio" name="Price4" checked="checked"/>50
<br/>
<br/>
<input type="radio" name="SearchArea4" checked="checked"/><span>Not Specified</span>
<br/>
<input type="radio" name="SearchArea4"/>60
<br/>
<input type="radio" name="SearchArea4"/>40
<br/><br/>
<input type="radio" name="AdvertisementKind4" checked="checked"/>All<br/>
<input type="radio" name="AdvertisementKind4"/>Offered<br/>
<input type="radio" name="AdvertisementKind4"/>Wanted<br/>
<br/>
</div>
<div style="background-color: yellow;">
<input type="radio" name="Price5" checked="checked"/><span>Not Specified</span>
<br/>
<input type="radio" name="Price5"/>40
<br/>
<input type="radio" name="Price5"/>50
<br/>
<br/>
<input type="radio" name="SearchArea5"/><span>Not Specified</span>
<br/>
<input type="radio" name="SearchArea5" checked="checked"/>60
<br/>
<input type="radio" name="SearchArea5"/>40
<br/><br/>
<input type="radio" name="AdvertisementKind5"/>All<br/>
<input type="radio" name="AdvertisementKind5" checked="checked"/>Offered<br/>
<input type="radio" name="AdvertisementKind5"/>Wanted<br/>
<br/>
</div>
<div style="background-color: blue;">
<input type="radio" name="Price6"/><span>Not Specified</span>
<br/>
<input type="radio" name="Price6" checked="checked"/>40
<br/>
<input type="radio" name="Price6"/>50
<br/>
<br/>
<input type="radio" name="SearchArea6"/><span>Not Specified</span>
<br/>
<input type="radio" name="SearchArea6"/>60
<br/>
<input type="radio" name="SearchArea6" checked="checked"/>40
<br/><br/>
<input type="radio" name="AdvertisementKind6"/>All<br/>
<input type="radio" name="AdvertisementKind6"/>Offered<br/>
<input type="radio" name="AdvertisementKind6" checked="checked"/>Wanted<br/>
<br/>
</div>
</div>
</form>
</body>
</html>
Hi,
I really like JsRender/JsViews, but I'm puzzled about one thing.
When using {{#each}}, it seems I can only access data from the array I'm iteration over. In the example below I cannot access "CurrentValue" within the each iterator.
This is how my json data looks:
tasks = [
{
CurrentValue: { Id: 0, Description: "some value" },
ValidValues: [
{ Id: 0, Description: "some value" },
{ Id: 1, Description: "second value" },
{ Id: 2, Description: "third value" }
]
}]
Inside the template:
Acessing CurrentValue is no problem:
Value:{{=CurrentValue.Id}}
Dear All,
I like the templating thing, but I want to create a little bit more complex UI, eg. using jQuery sliders in the templates or using min-max values for textboxes (via jstepper) etc.
All these things require javascript/jquery code to be executed.
My problem is that neither via Helpers nor via delegates I can't achieve this.
My example code is (SORRY, I don't know why does gitHub screw the formatting!):
<div id="rr" style="background-color: Lime">
</div>
<script id="rrTemplate" type="text/x-jquery-tmpl">
<p>
<span>Number of full rounds:</span>
<input data-getfrom="[NumOfFullRounds]" data-to="[NumOfFullRounds]" class="numericValue"/>
</p>
<p>
Reps in partial round:
</p>
{{#each RepetitionItems}}
<div>
<span><input id="txtRep{{=Id}}" data-getfrom="[Value]" data-to="[Value]" class="numericValue XXX"/></span>
{{=$ctx.setMinAndMaxValue("#txtRep" + Id, 0, Max)}}
<span data-getfrom="[Value]"></span>
</div>
{{/each}}
</script>
<script type="text/javascript">
$.views.registerHelpers({
setMinAndMaxValue: function(selector, minVal, maxVal){
alert("setMinAndMaxValue called, but jQuery selector will not work :( ");
$(selector).click(function(){alert("jQuery worked in the template!");}); //the jQuery selector will find nothing
$(selector).jStepper({minValue:minVal, maxValue:maxVal}); //the jQuery selector will find nothing
return "";
},
});
$(document).ready(function () {
var regVM = {"NumOfFullRounds":5,"RepetitionItems":[{"Max":2,"Value":0,"Id":"A1"},{"Max":4,"Value":0,"Id":"A2"},{"Max":6,"Value":0,"Id":"A3"}]};
var templi = $("#rrTemplate").template();
$("#rr").link(regVM, templi)
.on("load", ".XXX", function(s)
{
alert("textbox loaded!"); //this line never executed
$(selector).jStepper({minValue:minVal, maxValue:maxVal}); //so this line can't attach anything also :(
});
});
</script>
When the setMinAndMax values are executed, jQuery can't find the elements defined in the selector.
Via the "on" I can't make it work to fire when the textboxes are displayed (via the templates).
I know that helpers are for generating output, but I think it would be much better to hold the template and jquery ui-displaying code in one place, than separated all over.
I'd appreciate any replies.
Thanks!
In previous version (before Mar 6 update), I used this syntax to get and set value for checkbox:
<input data-getfrom="checked:Alarm" data-to="Alarm" type="checkbox"/>
If I use the new syntax like this:
<input data-link="Alarm" type="checkbox" />
If Alarm property is set to true, it doesn't show as checked at the checkbox. However, I can see that in the view model, the property can be updated when user check or uncheck the checkbox.
What should I do for the new version?
I was needing to store some data about the object in the element. <table data-getfrom="id:$view[index]" data-getfrom="tblid:ID" for example. Not only does it not parse it but it completely removes the 2nd data-getfrom from the output.
http://jsbin.com/ajisef/24/edit
Look at the template named tbltmpl
Hi Boris,
Trying to upgrade from the previous version I encountered the following issue.
I use data-link converter functions as follows:
data-link="{:~formatterFunc('Showing {0} items in {1} folder', ItemCount, FolderName)}"
Where formatterFunc helper is something similar to String.Format in .NET.
With your latest bits I get an error during a call to $.link("#container", data)
“Unterminated string constant”.
If I remove the {0} and {1} from the string, it works fine. Also if was working with the last version of jsViews.
Error is coming form
function linkViews( node, parent, nextNode, depth, data, context, prevNode, index ) { .. }, which seems to be parsing the string literals.
It is turning out to be a great library so far, keep up the great work.
Thanks.
Im encountering an issue where "node is undefined".
After stepping through the code I found this occurs after the "createNestedViews" function has run through all of my elements.
node is undefined
node = node.nextSibling;
Any suggestions / known issues to what may be causing this?
I am using Tags, Helpers & nested templates.
Can post some code if required.
Just a rare case, but it is worth adding a type check on primitive types.
In my case the code is used under some bigger projects, and the project is built upon a framework that overrides the primitive string type.
To make it easy, the var a = "";" will render a as class
Stringinstead of the plain
""`.
And specifically it will affect the code in jquery.views.js at line 472:
cnvt = cnvt ? (cnvt + "." + param) : param;
While cnvt ?
will return true because cnvt
is an object of type String
.
I have edited the line as follow, and things are running just fine now.
cnvt = typeof cvnt == "string" && cnvt.length ? (cnvt + "." + param) : param;
$.link.templateName('#no_element_with_this_id_exists', { 'data' : 'something'} );
results in attempt to dereference a null. This is because the link function( container, data, context, parentView, template ) does not verify that the selector actually selects any elements at line 759:
container = $( container )
.bind( "change", dataToElem );
if ( template ) {
// TODO/BUG Currently this will re-render if called a second time, and will leave stale views under the parentView.views.
// So TODO: make it smart about when to render and when to link on already rendered content
container.empty().append( template.render( data, context, parentView )); // Supply non-jQuery version of this...
// Using append, rather than html, as workaround for issues in IE compat mode. (Using innerHTML leads to initial comments being stripped)
}
linkViews( container[0], parentView, undefined, undefined, data, context ); // <<<---- container[0] is undefined
The browser will insert <tbody>
or <colgroup>
dynamically, which will break JsViews.
Currently JsViews provides an error message during data linking, for the first case. (See #157). This issue concerns either supporting the data-linking without error, or adding more generic error message handling for all such cases at data-link time, or adding validation at template compile time (including tooling for compiling on the server), to detect this as invalid template markup.
See also BorisMoore/jsrender#47 and BorisMoore/jsrender#30
JsViews seems to work fine when binding data from a simple array with #data (which basically is a short cut to access the data attribute directly.) However, this doesn't work when the array item has been updated in an input, since jsviews try to trigger setProperty on a simple property. Results in changes not reflected to the original array.
http://jsfiddle.net/cXZP6/10/ - in compat mode, activate then insert
<ul id="myfolderlist" style="display:inline">
<!--tmpl() folderTemplate-->
<!--item-->
<li data-getfrom="[name]">[s]Folder 1</li>
<!--/item-->
<!--/tmpl-->
</ul>
The problem is that in initial page parsing, IE puts and as child nodes of the li, and then getfrom replaces the li content with the [name] data, before the IE7 fixup code reaches the and nodes.
Need to support the concat method in the array for observable array. This will help to add a bunch of items and update the view with a single render call. I guess currently we need to add one item at a time to the array and this will trigger the array change event for every item added resulting in too many dom changes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.