Angular conditional based on depth of item in object - javascript

I don't know if i'm phrasing this correctly - but essentially what I'm trying basically say is :
If this item has no parent (or is the highest level) then don't display. So my thinking was to try if !$parent (if no parent). Here's what I am looking at -
<div ng-if-"!$parent">{{category.link}} </div>
(this does not work)
It is a recursive list tree (ng-repeats inside ng-repeats) and I basically don't want the top level to have the link attribute shown. I could set a boolean or something to just toggle it off on the most parent level BUT I'm wondering if it's possible to do it in this kind of way. Thanks!

Related

How to implement Touch Listener in Vue for items in loop

I have a translation system where a user can click on a word to get more information: translation, frequency, and so forth in a popover (using Floating UI). A single page can have up to 500 words or so. The very basic Vue code is as follows:
// parent
<template>
<div class='parser-wrap' v-touch:drag="onDrag">
<template v-for="(word, wid) in sentence">
<word-component
:id="childId(wid)"
:isHovering="isHovering(childId(wid))"
:word="word"></word-component>
</template>
</div>
</template>
//word-component (child)
<template>
<span v-html="output(word)"
#touchstart="doTouchStart"> // move this to parent ?
</span>
</template>
Now there are a couple of issues and approaches. For v-touch:drag using vue3-touch-events there is no option but to put the drag event in the parent rather than the child <word-component> (as there is no other way to detect touch enter).
My question is: what is the best place to put the listener for #touchstart? Putting in the child is the easiest approach but it means 500 listeners - does this impact performance?
On the other hand, if I put in the parent how do I detect which child <word-component> has been touched? At present, I'm using document.elementFromPoint getting the id from the child, then passing whether this matches the childId, and passing the isHovering prop back to the child. This seems janky to say the least :-)
In short, what is the most efficient way to have a touchevent on the parent, but communicate to the child 'you have been touched'. Or is it fine to have hundreds of listeners by putting them into the <word-component>.
(Note: words are not unique so I cannot use a word id, and going to the next page involves grabbing new sentences. In reality, the childId is a combination of 'pagecount-sentencecount-wordcount' but to simplify the above code I have just used childId(w) for illustration purposes).

Lit-element that is sorting dynamic childs

I have 2 lit-element components. The parent content is :
<s-sortablelist>
${this.renderChildren()}
</s-sortablelist>
The renderChildren function is looping over an array property children = [1, 2] and creating <div> elements. The rendered page might be something like :
<s-sortablelist>
<div id="1"></div>
<div id="2"></div>
</s-sortablelist>
The sortablelist component allows the user to reorder the <div> tags using drag and drop. After dnd, the rendered layout might become (2 and 1 are reverted) :
<s-sortablelist>
<div id="2"></div>
<div id="1"></div>
</s-sortablelist>
After the user changed the order, if I change the property children=[3,4], the result is different from my expectations :
I'm expecting to see a new list with the children 3,4
I'm seeing a list with 3,4, and some other elements (1, 2) depending on the dnd operations I made before
So my question is how is it supposed to work ?
If the children array changes, because it is a property, the parent component will render.
I'm expecting also the sotablelist component to be rerendered, but why would I have extra children from a previous render?
You can't mutate the DOM under control of lit-html this much. lit-html places comment nodes into the DOM to keep track of where the dynamic template parts are, and by moving elements around you're breaking the bookkeeping.
The right way to do this is to not move nodes in the drag and drop operation, but right before you would have actually changed the DOM, instead change the data that rendered the DOM. Then lit-html can render the list on the new order, but keep all the comment node and other internal data in sync.

CSS selector .find(">div.childCollapsible>div[data-onthemovecollapsible=true]") is not respecting parent restriction

Actual case is much more complicated but please play along. I am trying to select siblings of element that has class 'sss', by using
$('.sss').parent().parent().find(">div.childCollapsible>div[data-onthemovecollapsible=true]")
I can only use CSS selectors (this is part of Selenium thest). I expected to get only siblings of 'sss' however I am getting all the children of sub elements too.
How could I restrict it only to siblings?
or any other workaround that can get me from any element in the tree siblings only of any
data-onthemovecollapsible="true"
attribute holder.
EDIT: Firstly I would like apologise for failing to express myself clearly. The structure that I am working with is 'infinite tree structure' that has unknown amount of nodes on each layer, mechanism I am looking for is ability to get siblings on the same level that I am starting search from is and only children of his parent (his brothers + himself). All levels of tree have identical HTML syntax, so looking at them relatively from element one starts from, each layer is identical, hence the CSS selector should be identical too. I cannot use any other Jquery method but 'find', and only can use CSS selectors, as mechanism is part of selenium test so only By.CssSelector("...") can be used. I can traverse up the elements by using element.FindElements(By.XPath("..")) that gets me parent as I know how many levels up parent is, but from parent position I need to get all siblings without children (that have identical html syntax) in one go, so i would assume selector with only certain layer should do (like one in jsfiddle below), however it selects all the children nodes too - does not respect '>' for some reason. This would do nicely if I could use all JQuery functions.
$('.sss').parent().parent().children().children()
what I need is same result but with CSS selector.
http://jsfiddle.net/2a46U/
I think this will work for you:
.find("body>div>div>div>div.childCollapsible>div[data-onthemovecollapsible=true]")
If I'm understanding this correctly, you have two different restrictions here. One is that you only want siblings of an .sss element. The other is that the parent of the element is div.childCollapsible. I don't believe you will be able to do this with a single selector/find. You would need something like this:
// get the siblings of .sss with appropriate data attribute
var $els = $('.sss').siblings("div[data-onthemovecollapsible=true]");
// filter the collection to only those with appropriate parent
$els = $els.filter(function(){
return $(this).parent().is("div.childCollapsible");
});
http://jsfiddle.net/2a46U/4/
I've updated your jsfiddle with two options (check the console please):
Get all the siblings:
$('.sss').siblings();
Get specific siblings:
$('.sss').siblings("div.AppletBase")
If you need to set styles you can use the siblings selector in CSS3:
.sss ~ div.AppletBase {/* Your styles in here */}
Anything please leave a comment and I will review it again if is needed

Rapid repeated traversing within a div

I have a number of divs, each of which contain an instance of a number of different items, each with their own unique classes and/or ids.
A lot of .js code applies to the elements within each of these parent divs, and my .js is getting bloated by the constant need to do things like:
// Stuff like this occurs 15-20 times for similar but different actions
$(this).parent().nextAll('.target').eq(0).find('.toggle').slideToggle();
$(this).next('.alert').html('Success');
In the context of the document, I see why this code is necessary. However, I feel that if I were only able to redefine the reference point as being the parent div instead of the whole document, I could replace the convoluted code above with the MUCH easier:
function keepingCodeWithinParentDiv(){
$('.toggle').slideToggle();
$('.alert').html('Success');
}
So, is there a way to say in Javascript: for this part nothing exists outside this div?
If you have a parent element (let's name it element) that you want to confine your jQuery selector operations to, you can just pass it as a context to any jQuery select:
$(".toggle", element).slideToggle();
See jQuery doc for more info.
If you show us your actual HTML and describe what you're trying to get, we could give more specific advice.

How to change attribute of surrounding div/parent effectively?

I have a table with some radiobuttons in it. When i click on a radiobutton, i want to update two of the sorrounding containers ID attribute (a div and a table). The problem is, i need to go 4 and 6 levels up, and the only way i know how to do this is parent().parent().parent().parent() etc.
I am looking for a better solution, and was hoping someone could point me in the right direction. You can see an image of how the "parent-child" tree is here:
http://imageshack.us/photo/my-images/834/imgkz.png/
I already have a clickhandler etc set up.
Basicly i need to check if the table's id attribute is "answeredTable", if not i need to change it. Also i need to check if the div two levels up from the table is "answered", if not, i need to change that too.
Thanks
You can use .closest('#answeredTable') or .parents('#answeredTable').
Using .parent() only selects the first parent element upon the DOM tree, selecting .closest() will allow you to walk up to DOM tree and match until it finds the element, while .parents() will return the whole parentset of the DOM and match the element in the whole parentset.
You need to use .parents() that go through multiple level of the DOM
For instance, in your example, you could get the surrounding div with this code:
$("#Q_18_2015").parents("div#answered")
By the way, id should be unique, or else, your code might probably not work. You should use classes instead.
<div class="answered">
Thus, the code would become:
$("#Q_18_2015").parents("div.answered")
provided that Q_18_2015 is really a unique id
I think what you want to use is closest http://api.jquery.com/closest/
you can use .parents
$("element").parent(".parentClass")
parents will go up the DOM until finds the parent with class parentClass

Categories

Resources