AngularJS Ng-repeat, create dynamic dom with expressions - javascript

Here is The problem i am trying solve. I would like to create a JS script that uses angular to dynamically create div elements while adding an additional expression eg {{levelone}}.
Here is an an example of what i am expecting the output to be if i know i have 5 iterations of Dom elements.
<div ng-switch-when="0">{{levelZero}}</div>
<div ng-switch-when="1">{{levelOneA}}{{levelOneB}}</div>
<div ng-switch-when="2">{{levelTwoA}}{{levelTwoB}}{{levelTwoC}}</div>
etc.....
So as you can see i am adding an expression on each time. I just dont know how i can keep adding them on via a repeat loop and then get them to compile correctly with AngularJS. I am trying to make my DOM as Dynamic as possible.
EDIT
Every time i loop 1 more i am adding an expression ->{{expression}} to the div with JS or angular. I am not hard coding the expression into each div as each div is also dynamically created. But with a twist i am adding that extra expression ie 3 expressions from the previous div and adding one more expression making four. see example below.
<div ng-switch-when="3"{{levelTwoA}}{{levelTwoB}}{{levelTwoC}}</div>
This one below is dynamically generated
<div ng-switch-when="4"{{levelTwoA}}{{levelTwoB}}{{levelTwoC}}{{THIS EXPRESSION IS GENERATED IN js AND ADDED & COMPILED}}</div>

The DOM will be dynamic as long as your data bindings are. I need more info (data model, expectations) to be more accurate but if you set up your data and bind it correctly, it should work. for example if your data looked like this
var data = {
"levelOne" : {},
"levelTwo" : {
"elements" : ["<span id="firstEl"></span>, ...]
},
"levelThree" : {
"elements" : ["<span id="firstEl"></span>, <span id="secondEl"></span>, ...]
}
Then in your template do what #paulgoblin suggested.
}

You could ng-repeat within each switch case. Eg.
<div ng-switch-when="0">
<span>{{levelZero}}</span>
</div>
<div ng-switch-when="1">
<span ng-repeat="expression in levelOne">{{expression}}</span>
</div>
<div ng-switch-when="2">
<span ng-repeat="expression in levelTwo">{{expression}}</span>
</div>

You might want do this with scope function.
<div ng-switch="assignment.id">
<div ng-switch-when="1">{{ getExpressions(assignment.id) }}</div>
<div ng-switch-when="2">{{ getExpressions(assignment.id) }}</div>
</div>

Related

Remove parent element with Javascript using parentNode.removeChild when I only have 1 parent?

I'm working on a project where I have to delete en element in a certain condition (if). My code generates a <li> in which data is inserted via an array. I need to delete that <li> if some conditions are met.
Since removeParent() doesn't exist I've found different methods saying to use
e.parentNode.parentNode.removeChild(e.parentNode);
Rings a bell, it works in certains cases of course.
BUT
In my case, this is dynamically rendered elements in an array inside the <li> and there is no parent of the parent, so I get an error.
My script looks for an element in the <li>, in my test I use a <div> found by its class.
$(node).find('.results-name')[0].parentNode.remove();
Does NOT work unfortunately so I'm looking for other ideas...
Any clue?
Thanks a lot!
The thing is the code is huge and I can't copy/paste everything here.
Here's more info:
- in the page I have a template that's used by the javascript to populate a div with all the contents. I have ~20 results.
The template starts like this :
<script id="itemtemplate" type="geowacht/template">
<div class="results-name">
<h4 class="show-more-name itemaponaam" data-target="#result"></h4>
<div class="d-block" id="result">
<div class="itemaddress"></div>
<div class="itemgeodesc"></div>
<div class="itemphone"></div>
The pages calls a script that queries an API and returns 20 results. These results are parsed and added to the page using the template.
Here's the beginning of the code:
apiconfig.default_populateItemNode = function(node, apotheekData, wachtPeriodeData, authenticationData) {
$(node).find('.itemaponaam')[0].setAttribute('data-target', '#result-' + itemPos);
$(node).find('.buttons')[0].setAttribute('id', 'result-' + itemPos + '-buttons');
$(node).find('.buttons')[0].setAttribute('data-apbnb', apotheekData.pharmacy.id);

VueJS 2 conditional rendering in value binding

I simply try to let VueJS 2 render a inline condition while I add a value to an dom element. I know, that it is possible to use v-if to let elements appear or disappear based on conditions, but how can I use a inline-condition?
I will give an example. The following html describe my idea and I know that this lines generates an error. Both <span> elements are controlled by conditions which lets them appear or not and this works fine.
Now, I try to bind a value to the href attribute depending on a condition (which are in the parentheses for example).
<div id="vuemain">
<span v-if="diced < 6">Looser</span>
<span v-if="diced == 6">Winner</span>
<a :href="'https://link-to-whatever.com/'+{diced==6 : 'winner', diced<6 : 'looser'} ">LINK</a>
</div>
So after rendering by VueJS the <a> tag should be like:
<a href="https://link-to-whatever.com/winner"> <!-- If diced == 6 -->
OR
<a href="https://link-to-whatever.com/looser"> <!-- If diced < 6 -->
Do you understand what my problem is and is that somehow possible?
Many thanks in advance
Allan
This should work.
<a :href="'https://link-to-whatever.com/'+ (diced==6 ? 'winner' : 'looser')">LINK</a>
It looks like you were trying to use the object syntax, which won't really work in this case. Instead, just use the ternary above.

Angular appending html with directives from within a directive

I'm trying to write a small directive that will append the validation tags and ngMessages dynamically to the input. But I'm having trouble appending the ng-message attribute to the div.
The idea is to have this,
<div validator validations="{json_data containing error messages}">
<input name='fieldName'>
</div>
Turned in to the following according to the provided JSON.
<div validator>
<input required="required"></input>
<div ng-message="fieldName" ng-if="fieldName.$dirty>
<p ng-message="required"> scope.message </p>
</div>
</div>
I've currently managed to get the ng-required appeneded using the answer to this answer. But I can't seem to append the ng-message tag using the same technique. What should be done differently to solve this issue?
The final directive should be able to generate something like this Fiddle
The current version can be found in the Fiddle here the example works as expected until 'scope' is added. But as soon as 'scope' is added, the example stops working.
Update
I've realized that this only occurse when you add a local scope. This error doesn't occure when using the global scope and accessing the variable using scope.$eval(attrs.message)

knockout - set visible only one item in a list generated by json

hi it's a cordova app that use devexpress framework based on knockout i need to set visible only one item in a list
the item should correspond to the param.id or this
id_agenzia:ko.observable(params.id),
i've tryed with jquery (setting the id "#"+$data.id_agenzia visible if == id_agenzia ) but if i integrate it doesn't work
the goal is to do something like this
if i put this line it ignores
how is the right way to set visible only the div that corresponds to $data.id_agenzia is valid for $data.id_agenzia==id_agenzia ?
thank you for help
this is the js code with jsfiddle code added
self.selected_id_agenzia = ko.observable('two');
self.jsonLista = ko.observableArray([
{id_agenzia:ko.observable('one'), nome:'N1'},
{id_agenzia:ko.observable('two'), nome:'N2'}
noDataLabel: noDataLabel,
this is the html code with jsfiddle code added
<div class="list-indentation" data-bind="foreach:jsonLista" style="padding-bottom:60px;">
<div id="$data.id_agenzia" data-bind="visible: id_agenzia()==selected_id_agenzia()">
<div class="agency-description-box" >
<span data-bind="text: $data.id_agenzia" class="agency-name"></span>
<span data-bind="text: $data.nome" class="agency-name"></span>
</div>
</div>
</div>
I think I misunderstood what you were doing with the variables. I have made a simplified fiddle to do what I think you want. To make it work:
I assumed a dxList was more or less like a foreach
I changed the name of the outer id_agenzia to selected_id_agenzia, as I was not able to get the comparison to work using $data and $root to distinguish them
I made both items ko.observables, and used the function call on each in the comparison
</div>
The code is all at the fiddle:
http://jsfiddle.net/3ktq4b9s/

Understanding the usage of get() in my sorting script

I recently found a code snippet that I would really like to understand:
var buttons = $('#fruit,#vegetable,#meat').click(function() {
$(this).toggleClass('active');
var classes = buttons.filter('.active').map(function() {
return this.id;
}).get().join(',.');
$('div.fruit,div.vegetable,div.meat').hide().
filter('.' + (classes || 'none')).show();
});
The HTML code :
<div style="float:right; padding:25px;">
<button id="fruit" class="active"><span>fruit</span></button>
<button id="vegetable" class="active">vegetable</button>
<button id="meat" class="active">meat</button>
</div>
<div>
<p>Trying to use buttons as an "or" case rather than "and." When choosing fuit or vegetable, I want to see tomato as part of each list, <em>not just</em> when both are selected.</p>
<div class="fruit">
<p>apple</p>
</div>
<div class="vegetable">
<p>pumpkin</p>
</div>
<div class="vegetable">
<p>okra</p>
</div>
<div class="fruit">
<p>orange</p>
</div>
<div class="meat">
<p>beef</p>
</div>
<div class="fruit vegetable">
<p>tomato</p>
</div>
</div>
The fiddle is here.
I do understand how all the methods work in jQuery like toggleclass, filter and map, I also understand how join works in JS, but in this particular example, I am not able to figure out how get() is working or rather what is it's usage in the script is.
I went through the jQuery documentation for get() and I came across this method for the first time; to me, it seems it's very much similar to eq() in jQuery, but I am still not able to figure out why exactly get is being used in my example.
Can somebody explain this to me ?
.get is used here, because .map returns a jquery style object which contains some functions and information about the contained data. But in this scenario only the values stored within the object (the class names of the active buttons) are wanted. .get is used to get an array containing the raw values and with .join(",.") the values from the array get concatenated to a string. This string then get's used to show all div's that should be active according to the selected buttons.

Categories