x-editable in recursive template - javascript

I'm using angular recursive templates to generate a tree structure. I want to use x-editable for single leaf renaming. But the whole tree gets to "edit state" instead.
Check the fiddle: http://jsfiddle.net/7bLhvjd5/
<ul>
<li ng-repeat="data in tree" ng-include="'tree_category_renderer.html'" />
</ul>
< script type="text/ng-template" id="tree_category_renderer.html">
< div>
<span class="name" editable-text="data.name" e-form="textBtnForm">{{data.name}}</span>
<button ng-hide="textBtnForm.$visible" ng-click="textBtnForm.$show()">edit</button>
</div>
<ul>
<li ng-repeat="data in data.children" ng-include="'tree_category_renderer.html'" />
</ul>
</script>
Any ideas how to fix this?

Related

Vue.js v-for with extra li doesn't render

I have a ul with items coming from the loop, and then extra li after that.
<ul>
<todo-item v-for="(todo,index) in todos" v-bind:todo="todo" :key="index" />
<li :key='"new_item"'>
<input placeholder="What needs to be done?" type="text" v-model="new_todo" >
<button v-on:click="add_todo()">Add</button>
</li>
</ul>
This doesn't show the extra line. But if I switch it so extra li is first it does.
<ul>
<li :key='"new_item"'>
<input placeholder="What needs to be done?" type="text" v-model="new_todo" >
<button v-on:click="add_todo()">Add</button>
</li>
<todo-item v-for="(todo,index) in todos" v-bind:todo="todo" :key="index" />
</ul>
So I'm probably doing something wrong with key, but I can't find what exactly.
The whole code is here.
The problem is that vue components require a closing tag and won't work properly just with self-closing tags.
Try like that:
<ul>
<todo-item v-for="(todo,index) in todos" v-bind:todo="todo" :key="index"></todo-item>
<li :key='"new_item"'>
<input placeholder="What needs to be done?" type="text" v-model="new_todo" >
<button v-on:click="add_todo()">Add</button>
</li>
</ul>
From the official Vue Style Guide:
Components that self-close communicate that they not only have no
content, but are meant to have no content. It’s the difference between
a blank page in a book and one labeled “This page intentionally left
blank.” Your code is also cleaner without the unnecessary closing tag.
Unfortunately, HTML doesn’t allow custom elements to be self-closing -
only official “void” elements. That’s why the strategy is only
possible when Vue’s template compiler can reach the template before
the DOM, then serve the DOM spec-compliant HTML.
You are not allowed to use self-closing tags, so instead of <todo-item /> use <todo-item></todo-item>
https://github.com/vuejs/vue/issues/1036
Not a valid HTML5 components it seems.
Do you use SFC or usual HTML files?
Maybe the problem is that HTML parser doesn't allow to use <todo-item> inside <ul>. Try to use <li :is="'todo-item'" v-for...> instead (it's works in your codepen)
<div id="app">
<h1>TODOs</h1>
<ul>
<li :is="'todo-item'" v-for="(todo,index) in todos" v-bind:todo="todo" :key="index"></li>
<li :key='"new_item"'>
<input placeholder="What needs to be done?" type="text" v-model="new_todo" >
<button v-on:click="add_todo()">Add</button>
</li>
</ul>
<p>You have finished {{ done }}/{{ total }}</p>
</div>
https://v2.vuejs.org/v2/guide/components.html#DOM-Template-Parsing-Caveats

Knockout JS - list items without the parent <ul> element

I have a simple demo application with a foreach binding of "li" elements inside an "ul" element.
<ul data-bind="foreach: sortedItems">
<li>
<div>
<span data-bind="text: name">
</div>
</li>
</ul>
Is there a way to create the same binding without a parent element?
Yes, you can use knockout's virtual element syntax for this purpose. See the first example on this page.
<!-- ko foreach: sortedItems -->
<li> ... </li>
<!-- /ko -->

Multiple Iterations with AngularJS ng-repeat

I've searched for a while and did find a lot about multiple iterations. The problem is that i don't see a plain solution for my problem.
I have a list of checkbox that is filled dinamically with ng-repeat. Due to layout purposes i need to create a new div inline-block whenever i reach 3 checkboxes. Like that:
CheckBoxList = {1,2,3,4,5}
<div class="form-group-content">
<div class="form-col-secondary">
<ul class="list-checkboxes">
<li>
<input type="checkbox"/>1
</li>
<li>
<input type="checkbox"/>2
</li>
<li>
<input type="checkbox"/>3
</li>
</ul>
</div>
<div class="form-col-secondary">
<ul class="list-checkboxes">
<li>
<input type="checkbox"/>4
</li>
<li>
<input type="checkbox"/>5
</li>
</ul>
</div>
</div>
I tried using a iterator and two ng-repeat but didn't work like i wanted to.
If somebody already had this struggle and could help i would appreciate it.
To achieve this you will have to make 2 updates.
2 ng-repeat
Change structure
HTML Code
<div class="form-group-content">
<div class="form-col-secondary" ng-repeat="block in blocks">
<ul class="list-checkboxes">
<li ng-repeat="checkbox in block">
<input type="checkbox{{$index + 1}}"/>
</li>
</ul>
</div>
</div>
JS Code
$scope.blocks = [
['1','2','3'],
['4','5']
];
Here is a plunker for you - http://plnkr.co/edit/BWcFI5d02yPkAYDiQxvO?p=preview
If you split your CheckBoxList in parts of 3, you can use your ng-repeat on each div.
So change checkboxlist to something like:
divs = [[1,2,3],[4,5,6]];
then your html:
<div class="form-col-secondary" ng-repeat="div in divs">
<ul class="list-checkboxes">
<li ng-repeat="checkbox in div">
<input type="checkbox" ng-attr-id="{{checkbox}}">
</li>
</ul>
</div>
This might nog exactly match what you want as result, but it reflects the principle on which you should be able to create your own working version :-)
Edit
Worth noting: As far as I am aware, you can't have <input type="checkbox1" />, I think you mean <input type="checkbox" id="1" name="checkbox1" /> instead.
You'll have to track by $index in your ng-repeat and either ng-if or ng-show and $index < 3 for your first set and $index > 2 for the second set.

Access parent index in nested ng-repeat

I would like to do this really basic example :
<div ng-controller="ctrl">
<li ng-repeat="config in configs">
<span >Config : {{config}}</span>
<li ng-repeat="version in versions">
{{config}}
</li>
</li>
</div>
So basically, I got 2 imbricated ng-repeat loop, and I would like to access a value of the first loop from the second one.
I thought it was really basic, but no way to make it work. My result of that is 1 liwith the config printed, and 3 empty sub lis
I already tried a lot of combination list {{$parent.index}}, {{$parent.config}} etc ...
I'm pretty sure this has to do with the structure of your HTML.
Here is a working plunker.
Since you are omitting the <ul> tags that are required for lists. The nested <li> is causing a display issue.
I have simple wrapped the <li> with <ul> and it seems to work fine:
<div ng-controller="ctrl">
<ul>
<li ng-repeat="config in configs">
<span >Config : {{ config }}</span>
<ul>
<li ng-repeat="version in versions">
VersionConfig: {{ config }}
</li>
</ul>
</li>
</ul>
</div>

Angular ng-repeat without html element

I'm in trouble with a foreach that I need to do with Angular.
Thats's what I want to do :
<ul>
<div ng-repeat="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li class="divider"></li>
</div>
</ul>
How can I do something like that, but in valid HTML structure ? (without a <div> between <ul> and <li>)
I see only one solution :
Replace the <div> with a <ul> and make a lot of css rules to make it like it doesn't exists
In addition, I use Angular 1.4.8.
Thanks !
You shouldn't have to alter your data structure at all. Instead just utilize the ng-repeat-start & ng-repeat-end directive. You'll have separate <ul>s but in terms of rendering, you can easily modify the CSS to make it appear to be a seamless list.
<ul ng-repeat-start="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li ng-repeat-end class="divider"></li>
</ul>
http://codepen.io/jusopi/pen/KVZBLv
Probably the easiest way is to use a custom collection groupedCommands that is bound to the angular scope in code and contains the items in the correct order.
Then use ng-repeat-start for the enhanced repeat directive. There is a special ng-repeat-start and ng-repeat-end attribute combination that you can use for this case:
<ul>
<li ng-repeat-start="c in groupedCommands">{{c.text}}</li>
<li class="divider" ng-repeat-end></li>
</ul>
Try This one,
<ul>
<!-- ng-repeat: g in groups -->
<span ng-repeat="g in groups">
<li ng-repeat="c in g.commands">{{c.text}}</li>
<li class="divider"></li>
</span>
</ul>
This may solve your problem.
Caution : It is not a good way to use <span> between <ul> and <li>.

Categories