I have a form, and some the fields are set inside 3 groups of collapsible divs, I wan't after the validation that if any field has errors the parent div receive a class to unfold it.
<div class="panel-group" id="fields_panel">
<div class="panel panel-primary">
<div id="basic_info_fields" class="panel-collapse collapse in"> <!-- add class "in" -->>
<div class="panel-body">
<div class="row clearfix">
<div class="col-md-12 m-b-0">
<div class="form-group">
<div class="form-line error"> <!-- if this div has "error" -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I have two more panels with the same structure, eacho one with a couple of fields, I'm trying to find if any form-line has error and append to the panel-collapse parent the class in to unfold it.
Right now I have the following jquery code:
$(function () {
var elem = $('.panel').find('.form-line');
if (elem.hasClass('error')) {
elem.closest('.panel-collapse').addClass('in');
};
});
But it apply the in class to all panel-collapse.
What should I do to apply it only to the top level parent that have a child element with that class, and not to all parents?
Your hasClass won't work as elem is an array of jQuery objects - not just one.
Why do you need it - why not just include the class in your selector:
$('.panel').find('.form-line.error').closest('.panel-collapse').addClass('in');
This also stops you looping through elements in the array that doesn't have the class thus improving efficiency
Use following code:
$('.panel').find('.form-line.error').each(function(){
$(this).closest('.panel-collapse').addClass('in');
});
$(this) refers to the specified element which has the error class.
Related
I implemented drag and drop functionality using ng2-dnd for my Angular 4 application. I have containers which can be sorted and items within each container which can also be sorted.
I want to restrict items within each containers from being re-assigned to another container.
There is a Container 1 and Container 2. Container 1 has Item1, Item2 and Container 2 has Item3, Item4. I want to restrict Item1 from being dropped into Container 2.
I tried using [allowDrop]="allowDropFunction()" but it did not work. What function can i use to restrict the drop?
You can use dropzones to allow dropping of an element into a target container. For example on the element you want to drag:
<div class="panel panel-default" dnd-draggable [dragEnabled]="true" [dropZones]="['zone1', 'zone2']">
<div class="panel-body">
<div>Drag Me</div>
<div>Zone 1 & 2</div>
</div>
</div>
And then on the target container(s):
<div dnd-droppable class="panel panel-info" [dropZones]="['zone1']" (onDropSuccess)="restrictedDrop1=$event">
<div class="panel-heading">Zone 1</div>
<div class="panel-body">
<div *ngIf="restrictedDrop1">Item was dropped here</div>
</div>
</div>
<div dnd-droppable class="panel panel-warning" [dropZones]="['zone2']" (onDropSuccess)="restrictedDrop2=$event">
<div class="panel-heading">Zone 2</div>
<div class="panel-body">
<div *ngIf="restrictedDrop2">Item was dropped here</div>
</div>
</div>
As long as the element that you want to drag has a matching dropzone in its dropZones property (which can be a string or an array), then the element can be dropped into the target container.
If want to change the dropzones you can do so dynamically using property binding.
I'm creating a website and I'm having some trouble with javascript. I have this function:
function offerboxclick(obj) {
obj.classList.toggle("menuelementclicked");
}
and my html looks like this:
<div class="menuelement" onclick="offerboxclick(this)">
<div class="arrowbox">
<div class="stripe1"></div>
<div class="stripe2"></div>
</div>
<div class="menutext">Menu level 0</div>
<level>
<div class="menuelement" onclick="offerboxclick(this)">
<div class="arrowbox">
<div class="stripe1"></div>
<div class="stripe2"></div>
</div>
<div class="menutext">Menu level 1</div>
</div>
<div class="menuelement" onclick="offerboxclick(this)">
<div class="arrowbox">
<div class="stripe1"></div>
<div class="stripe2"></div>
</div>
<div class="menutext">Menu level 1</div>
</div>
</level>
</div>
<div class="menuelement" onclick="offerboxclick(this)">
<div class="arrowbox">
<div class="stripe1"></div>
<div class="stripe2"></div>
</div>
<div class="menutext">Menu level 0</div>
</div>
The css code I think isn't relevant, because the problem is probably with the js function. As you can see, I have a multi level menu, and it works just fine when I'm clicking on the level 0 element to show hidden level 1 elements. But when I click any of the level 1 elements, the js function does work properly on the object, because it toggles "menuelementclicked" class on it. The problem is that it also toggles this class in parent menu element, so at the same time it opens level 2 and closes whole menu. I don't really know what to do now. Any help would be appreciated!
P.S. I tried putting my code on jsfiddle to show you all of it but for some reason on it doesn't work there at all 0_o
I am dynamically giving elements IDs with *ngFor like this:
<div *ngFor="let section of questionsBySubCat" class="col-md-12">
<div class="subcat-container">
<h4 class="sub-cat">{{ section?.subcategory }}</h4>
</div>
<div *ngFor="let question of section?.questions; let i = index" class="row">
<div class="col-md-11 col-xs-10">
<h5 (click)="toggleAnswer(question)" class="question">{{ question?.question }}</h5>
<div class="answer-div" id="ques-{{question?.subcategory.split(' ').join('')}}-{{question?.num}}">
<br> // DYNAMIC ID HERE ^^
<p [innerHtml]="question?.answer" class="answer-text"></p>
<hr>
<br>
</div>
</div>
</div>
</div>
When I check the elements in the console the IDs are created correctly. When I use jQuery to log out the inner html of the element it works perfectly but when I use jQuery to change the elements css (display to none) it does not work at all. Why is this?
Put your jQuery code for changing css elements in setTimeOut() function.
It is not working because you are trying to access dom element and modify their css before they gets created dynamically. So you should let your jQuery code(which change css element) in setTimeOut().
setTimeout(function () {
$('your dynamic dom element').addClass('in');
}, 1000);
Hope this helps.
I have a page hierarchy like this:
<div class="panel" attribute-id="1">
<button class="delete">
<div class="panel" attribute-id="2" association-id="20">
<button class="delete">
</div>
</div>
....
So I have a bunch of these panels with nested panels inside, and I'm trying to create on on click handler for the delete buttons of the top level panels only (so the ones immediately inside panels that do not have an association id). The only different between the parent and child panels is that the child ones have the extra attribute "association-id".
So I can select the top level panels only like so:
$('.panel[attribute-id]:not([association-id]')
But if I try to get the delete buttons from from these like:
$('.panel[attribute-id]:not([association-id] .delete')
Obviously I'm still going to get the child buttons.
I can't modify the html in anyway, how could I go about doing this?
$(':not(.panel[attribute-id][association-id]) > .delete')
seems to do the trick.
jsfiddle
I've changed .panel-group to .panel to get it to work with the HTML provided.
Wrap them all in a div and assign that div a unique class. Then you can use jquery selector ".panel-group > .panel" to get only direct children of top level.
<div class="panel-group">
<div class="panel" attribute-id="1">
<button class="delete">
<div class="panel" attribute-id="2" association-id="20">
<button class="delete">
</div>
</div>
<div class="panel" attribute-id="11">
<button class="delete">
<div class="panel" attribute-id="12" association-id="120">
<button class="delete">
</div>
</div>
</div>
You can use the children method:
$('.panel-group[attribute-id]').children('button').first()
I've created a test page, where inside each blocks the divs are sortable. But how is it possible, to let the user drag the div out of it's parent, and put inside an another sortable div?
JSFiddle: http://jsfiddle.net/zq8bqufs/
Code:
$( ".sortable, body" ).sortable();
You can use the items option to determine which items inside the element should be sortable.
JSFIDDLE
HTML
<div class="sortable">
<div class="items">
<div class="items">asd</div>
<div class="items">eee</div>
<div class="items">fff</div>
</div>
<div class="items">asd</div>
<div class="items">
<div class="items">vvv</div>
<div class="items">abbsd</div>
<div class="items">mmm</div>
</div>
<div class="items">dsa</div>
</div>
Javascript
$('.sortable').sortable({
items: '.items'
});
You need to use connectWith, more about that here.
I updated (and simplified) your fiddle with that functionality here: http://jsfiddle.net/vrx6r264/