Can I stop the cdkDropList from expanding in Angular12 - drag-and-drop

I am using Angular 12 drag and drop to move a mat-list-item to "dropzone" (cdkDropList) in another component.
When I drag the item over the droplist, the droplist expands as if to make room for the item. Since this is not really a list, this behavior is undesirable. How can I stop it from expanding?
<mat-list-item
cdkDrag
[cdkDragDisabled]="!isDraggable"
[cdkDragData]="r.id"
(click)="selectRecord(r, i)"
*ngFor="
let r of recordList | filterList: searchText:filterField;
let i = index">
<p id="{{ 'Item-' + r.id }}" [innerHTML]="lineTitle(r)"
matLine></p>
</mat-list-item>
<div
(cdkDropListDropped)="svc.dropSub1($event)"
*ngIf="!svc.sub1"
cdkDropList
class="drag-here-column text-center"
style="border: 1px grey dotted; line-height: 300px; font-size: smaller; font-style: italic;">
Drag preferred subject here
</div>

I tried to used dragula but although is easier to configure I ended up having the same issue, where dragula will just add more elements when the destination is full and changing that behaviour was not obvious to me
After searching in many places about how to avoid cdkDropList from autoexpading or growing, I ended up doing a custom drag/drop approach, especially because I need to have placeholders as destination of my objects.
Is really useful to set HTML IDs to each element that is going to be dragged, in this way you can recognize origin and destination based on those id (for example concatenating a prefix of the container with the position ('contA_1','contB_9')
Here is one basic example that once you understand can help you setup your drag/drop event handlers and how to update the model to reflect the drop operation
https://idkblogs.com/angular2/2/Implement-Drag-and-Drop-in-Angular-2-4-5-6

Related

Conditional processing within a Sightly/HTL component dependent upon position within a page

I've recently begun as an Ops dev on an AEM project, and we have a component (a table, that has a title, some copy and a field where the author can author some HTML to represent the contents of a table, with and elements. This, for whatever reason, has to sit within a component, called ArticleContainer. The title should have an H1 tag if the table is at the top of the page, and an H2 tag if it's anywhere lower down. I've tried using data-sly-test thus:
<sly data-sly-test.topOfPage="${table.firstPosition==true}">
<h1 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>
</sly>
<sly data-sly-test="${!topOfPage}">
<h2 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h2>
</sly>
Now, this kind of processing has worked elsewhere where the component doesn't sit within a container, but it seems that if it's in a container it always picks up the non-topOfPage condition. I assume there might be a way to maybe do the test within the container component & pass it down into the table component? How would one go about this, or if it's not possible, is there another method by which one might achieve this?
There are two things here:
What does table.firstPosition return? You should be able to debug this in your Sling Model or POJO and probably need to adjust the logic to account for intermediary containers.
HTL/Sightly has a data-sly-element that allows you to change the HTML element based on an expression, you could make your code shorter (and easier to maintain):
<h1 data-sly-test="${table.headerCopy}" data-sly-element="${table.firstPosition ? 'h1' : 'h2'}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>

Selenium-Webdriver JAVA:- i am getting error ""org.openqa.selenium.NoSuchElementException: no such element""" but Appointment Icon is present

I want to verify the tool tip but getting error no such element. I have confirmed that element is exist.
Java Code:
String toolTipTextAppointment = driver
.findElement(By
.id("//*[#id='EditView_NOTE_POPUP']/table/tbody/tr[2]/td/table/tbody/tr[3]/td[2]/table/tbody/tr/td[1]/a/img")).getAttribute("title");
System.out.println(toolTipTextAppointment);
HTML Code:
<td nowrap="nowrap" style="border:0px;">
<a class="" href="javascript:void(0);" onclick="showPopupActivity('Meetings','activityPopupFormAraContent',440,600);">
<img style="border: 6px none;" title="Appointment" src="themes/AutoAccelerator/images/calender_icon.gif"/>
</a>
</td>
Try
driver.findElement(By.cssSelector("img[src*='calender_icon.gif']")).getAttribute("title")
you have used findElement(By.id("")) but you passed xpath in it that is why it is not working
String toolTipTextAppointment = driver.findElement(By.xpath("/html/body/table/tbody/tr/td/a/img")).getAttribute("title");
System.out.println(toolTipTextAppointment);
The problem is visibility. There are two different concepts, existence and visibility (reachable to click or see).
You need to check if the element is visible, not sure about the syntax as I use the clojure library (clj-webdriver) but as far as I know should be shomething like this
e=driver.findElement(By.id("idOfElement")).isDisplayed();
Take into account that the driver will find hidden element but they are not visible. In this particular case you may need to scroll down the page to make the element visible, I suggest retrieve its e.location and use the coordinates with a javascript snippet
((JavascriptExecutor)driver).executeScript("window.scrollTo(" + e.location + ")");
Then the element will be visible and you will be able to interact with it, I usually have this code embedded in a helper function as it's a quite common issue.
Disclaimer: code is just an orientation, I don't know the syntax as I don't use Java. Hope it helps

Applying just one property from a CSS class to an element

I'm working with a number of large interchangeable style sheets. I need to use the border colour from one of the classes as the border for a div. The class in question has a number of properties, I only want the border.
Is there any way of doing this with CSS? I'd be happy with a CSS3 solution if it degrades nicely.
Of course I can use JS to do it, I know how with JQuery. But I was hoping to avoid that.
Lyle
Update: As I feared not possible, why hasn't CSS3 provided a solution to this? As I said I'm working with a number of large interchangeable style sheets, the re-factoring suggestions simply aren't workable and they'd not only be a large job in themselves, but have far reaching implications :( I'll just have to do it with JQuery.
JQuery solution (JQuery.css doesn't like shorthand, like border or border-color):
var border = $('.class').css('border-top-color');
$('div').css('border-color', border);
This is simply not possible in CSS alone, unless you alter the way the CSS declarations work.
For example:
.class1 {
background: green;
}
.class1, .class2 {
border: 1px solid red;
}
...and the HTML:
<div class="class1"></div>
<div class="class2"></div>
Or:
.class1 {
background: green;
}
.class2 {
border: 1px solid red;
}
...and then in your HTML:
<div class="class1 class2"></div>
<div class="class2"></div>
Nope. Try to refactor your stylesheets. You can add multiple classes to one element.
<div id="mydiv" class="borders black"></div>

Span inside text input field?

Is it somehow possible to place a span as the value of a text input field?
I am making a mailing system for a website and want a nice looking receivers input field, where added receivers are contained and added to the value of input text field. At the moment i use a separate "adding field" while showing added receivers in a span-container. I want to merge these to fields together. Just like any input field in regular e-mail software.
Help would be most appreciated! Thanks in advance!
Short answer: no, you cannot include a <span /> within an <input />.
You have a few options. You could use javascript to emulate behaviour like the email To: field. E.g. listen to key presses and handle actions like backspace after a ;.
Another option would be to make a list appear (css styled) like a textbox. Have the last <li /> contain a textbox with cleared styles. Every time the user adds a new email then insert a new <li /> before the textbox.
E.G.
html:
<ul class="email-textbox">
<li>bob#email.com;</li>
<li>jane#email.com;</li>
<li><input type="text" /></li>
</ul>
css:
.email-textbox {
background-color: #fff;
border: 1px solid #ccc;
padding: 2px 4px;
}
.email-textbox li {
display: inline-block;
list-style: none;
margin-left: 5px;
}
.email-textbox input {
background: none;
border: none;
}
javascript (jQuery, can change to vanilla)
$(function () {
$('.email-textbox').find('input').focus();
});
You will need to extend this javascript to include a keypress handler etc, but it gives the general idea.
Demo: http://jsfiddle.net/UeTDw/1/
Any option will require some javascript however.
If you can use jQuery, you could check out jQuery UI autocomplete
One way to do it would be to layer a text input on top of a div that is styled to look like a text input.
<div id="fake-input">
<span class="input-item">John Doe</span>
<span class="input-item">Jane Deere</span>
<input id="receiver-input" type="text" />
</div>
You can strip all styling off of receiver-input, and add borders, background colors, and such to fake-input so that it appears to be a text field. When a receiver is added, you can create a new input-item span and append it to the list.
Input text fields are typically used to accept raw text input. Attempting to wrap input text inside of a text field opens you to user error and potential difficulties with parsing data if the person is able to manipulate the tags.
Personally I would suggest keeping your current method but enabling some form of AJAX support to make things more dynamic and less error-prone to the user.
(My $0.02)
TextExtjs is probably what you want. It's a jquery plugin for allowing removable tags with autocompletion etc in a textarea.
And here is a related SO discussion - where I found this plugin - on mimicking the similar behavior found in some inputs on facebook.

jQuery select image in div if image parent does't have a certain class

Wordpress wraps images with captions in a div with a class of .wp-caption.
I'm looking for a way to select images that don't have this div so I can wrap them in different div. (to keep a consistent border around all the images)
<div class="blog-post-content">
<div id="attachment_220" class="wp-caption alignleft" style="width: 310px">
<img class="size-medium wp-image-220" src="/path/to/image" alt="" width="300" height="280" />
<p class="wp-caption-text">Caption Text</p>
</div>
<p>This is the body of the post</p>
</div>
To test my selector, I'm just trying to add a green border. I can handle the .wrap() once the selector is working.
The most promising of my attempts is:
$('.blog-post-content img').parent('div:not(".wp-caption")').css('border', '2px solid green');
... but no luck.
How about this: (untested)
$('.blog-post-content img').filter(function(){
return !$(this).parents('div').hasClass('wp-caption');
}).css('border', '2px solid green');
try:
$('.blog-post-content img').parent(':not("div.wp-caption")')
Not if what Matti says abotu the a element in the hierarchy then the above wont work.
I know this question was asked a long time ago, but I would like to suggest the following:
$('.blog-post-content img').closest('div:not(".wp-caption")')
Untested, but I think that should work, and is shorter than the answer above that works. Using closest means the a is ignored.