I'm using Angular UI Bootstrap datepicker popup with the option datepicker-append-to-body="true". Thus the popup is rendered to the <body>.
In my particular scenario I need to remove the DOM element containing the datepicker. Once the element is removed (with element.remove()) the popup stays in the body.
How should I remove the datepicker, so that popup will be also properly removed?
Here is the plunker demonstrating the issue:
http://plnkr.co/edit/zFew72PpY0E2ETwMKRpv?p=preview
I know that removing an element like this in Angular is not the right way, but I'm working on integration of existing jQuery widget with Angular, and this is done in the existing code. I'm trying to find a way to fix this.
Any help is appreciated.
Edit
Sorry, I believe some additional info is needed to clarify the case:
As I mentioned, I integrate a jQuery plugin with Angular. This is grid.
Grid can have editing row. Grid user can put a Angular UI Datepicker in the editing row to edit date field. Once a user clicks Save (or Cancel), the editing row is removed with $element.remove(). So this happens in the external lib code. What I can do, is to patch removing code and call some cleaning up code. The question is what this cleaning up code could be, so it will clean up the datepicker.
ng-if, unfortunately, is not an option, because patching code knows nothing about the content of the cell and fields of the scope. This code is generic, while datepicker is put in the cell by grid user. In fact it could be any other widget.
You could use ng-if to remove or add back to your html. here is a plunker:
$scope.showDatePanel = true;
$scope.removePanel = function() {
$scope.showDatePanel = false;
}
in your html:
<div id="panelToBeRemoved" ng-if="showDatePanel" class="row">
<div class="col-md-6">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup ng-model="dt" datepicker-append-to-body="true" is-open="popup.opened" />
</p>
</div>
</div>
hope it helps.
uib-datepicker use ng-if. it's mean if you assign true in is-open attribute is dynamically append into your body and if assign false then it's automatically destroy in your body tag. So when you press remove element button than assign is-open false. change in your example.js file ->
$scope.open = function() {
if($window.document.getElementById("panelToBeRemoved") != null){
$scope.popup.opened = true;
}
};
Related
I'm using ui.bootstrap.datepickerPopup in a filter header template inside ui.grid. This lets me filter rows by date. I also have a button inside the grid menu that toggles grid.options.enableFiltering.
Due to alignment issues with ui-grid, I have datepicker-append-to-body set to true for my datepickers. The first time I enable filtering, everything works fine. However, when I disable filtering and re-enable it, I get duplicate datepickers.
This is what the problem looks like:
I think the problem is that each time the filters are enabled, the following div is appended to the DOM and never removed when the filters are disabled.
<div uib-datepicker-popup-wrap=""
ng-model="date"
ng-change="dateSelection(date)"
template-url="uib/template/datepickerPopup/popup.html"
class="ng-pristine ng-untouched ng-valid ng-scope ng-empty ng-valid-date-disabled"
>
<!-- ngIf: isOpen -->
</div>
Here's a simplified plunker: http://plnkr.co/edit/eYZt87j2O6A5xhjHj5ZG
I get the same issue if I only use one datepicker inside the Time Range filter header.
Any ideas are greatly appreciated! Don't want to use jQuery.
I don't have an answer on why this is happening but a solution without jQuery would be to remove the pop-up when triggering the filter toggle using document.querySelectorAll()
var elements = document.querySelectorAll("div[uib-datepicker-popup-wrap]");
Array.prototype.forEach.call(elements, function(node) {
node.parentNode.removeChild(node);
});
Plunker here
I have my code on Plnkr:
http://plnkr.co/edit/6wz4zub2sEOfhrqps0c8
The html code is quite simple:
<div ng-app="myApp" ng-controller="MainCtrl">
<div ng-dropdown-multiselect="" options="myData" selected-model="myModel" extra-settings="mySettings" events="myEvents"></div>
<div ng-repeat="item in Items">
<item-input></item-input>
</div>
</div>
</div>
Basically, the problem is my function in ng-if gets called every time I click anywhere on the page. I think it has something to do with the multi-select control but I'm not sure where I should fix it. Any help is appreciated.
Thanks.
UPDATED
What I don't really understand is why this behavior stops when I comment out the multi-select dropdown (<div ng-dropdown-multiselect="" options="myData" selected-model="myModel" extra-settings="mySettings" events="myEvents"></div>)?
As shown in the picture below, taken from Chrome DevTools, the multi-select dropdown is generating two click event handlers :
One event is on the button and one on the whole document. Therefore, a click on the document is triggering at least that last event handler, which potentially changes the model. Angular then do a digest cycle, and that implies that the displayMe function bound to the ngIf directive is evaluated in case the element should be removed of the DOM or not.
If you remove the dropdown component, and thus these two click handlers, you are left with 3 text inputs. Indeed, now there are no digest after a click on the document because no handler are executed, but you can still trigger digests essentialy by typing inside the input elements.
This answer by Miško Hevery has some valuable info about the dirty-checking process in Angular 1.x.
I am trying to use the HTML Select tag along with AngularJs using the ng-options directive to create a drop down options menu. On top of this I am using Bootstrap 3. I also have ui-bootstrap imported into the project.
Everything works functionally but I have an odd issue where when a user opens the Select dropdown for the first time after visiting the page then the last option in the drop down menu is cut off as in this image:
Once the user selects something and selects the drop down again then everything displays properly.
Here is the code I am using:
<!-- Select -->
<div class="form-group">
<label class="col-md-4 control-label" for="selectThemePark">Theme Park</label>
<div class="col-md-4">
<select id="selectThemePark" name="selectThemePark" class="form-control"
ng-model="tip.theme_park_id"
ng-options="themepark.id as themepark.theme_park_name for themepark in all_themeparks | orderBy:'+theme_park_name'">
</select>
</div>
</div>
I am not a web developer by trade so I'm not sure if there is something I am doing wrong with the HTML select tag or if there is a CSS quirk in Bootstrap 3 that I need to overwrite for the Select tag? Any pointers to what might be causing this behaviour?
I've had a time using bootstrap with angular around drop down menus. From what I have seen part of the issue is associated to the javascript interacting with the DOM once the page has rendered. Remember angular/js is applied after the DOM is rendered. The reason it is working after the click event is because the menu is refreshing and rebuilding the DOM to account for the injected items(options). This has been a huge issue for me with drop downs. One thing that I have done to correct this build my menus/navigation in an angular directive using angular transclude. This allows me to attach the menu at the time angular is initialized. You may want to give the transclude directive a look. There are a number of blogs and articles out there discussing this topic. Just search for bootstrap angular drop down transclude. There is also a SO question around drop downs not working in angular here. Hopefully this will help get you on the right track.
I'm using a check box in the heading of the accordion control in bootstrap, but the model will only update the first time it's clicked. Here's the HTML for the accordion:
<accordion ng-repeat="timesheet in timesheets">
<accordion-group>
<accordion-heading>
Title
<input type="checkbox" ng-model="approvals.rejected" ng-click="approvals.timesheetChecked($event)"/>
</accordion-heading>
</accordion-group>
</accordion>
the click method is in my typescript controller:
timesheetChecked($event: Event) {
$event.stopPropagation();
$event.preventDefault();
}
If I just use the stopPropagation() method by itself it updates the model correctly and the check box is checked, however, it will then refresh the page. The preventDefault() method stops this from happening, but then it will then only update the model once and not check the check box.
I have tried using ng-bind and that will actually update the model with correctly, but it will not change the check box to checked.
If I use the check box outside of the accordion it works as expected and I have no problems with it. I'm not really sure what I am doing wrong here?
I believe your code would work, but it only works with Angularjs 1.2.x and ui-bootstrap-tpls version 0.11 (earlier versions may work).
Your code is similar to the following post...
https://stackoverflow.com/a/24502123/3807872
If you are using Angular 1.3.x, then you will want to add the stop propagation inside of the ng-click...
<input type="checkbox" ng-model="approvals.rejected" ng-click="approvals.timesheetChecked($event);$event.stopPropagation();"/>
This example was in thanks to the following post...
https://stackoverflow.com/a/14545010/3807872
This really worked for my situation as well.
By the way, I don't know if you have fixed this issue but I have the same problem, however for displaying the right checked checkbox I've added this:
ng-checked="approvals.rejected == 'true'"
and I only stopPropagation method.
But actually it doesn't work for the first click!
I want to use some Custom directive in editable-text
<span ui-Blur="testfn(price);" editable-text="entry.product_id"
e-name="product_id" e-style="width: 200px" e-form="sentryform"
e-required>
</span>
I want to trigger some event on blur on the above text box I have written the directive for that which is working with normal text boxes but not with above shown "editable-text".
x-editable has nice feature were all directives prefixed with an "e-" get appended to the actual edit control (with the "e-" striped of course). For example to add style in the input box you add:
e-style="color:red"
So adding:
e-ui-Blur="testfn(price)" on the span element you talk about, would result in that being added to the input dom element generated when entering edit mode.