Re-usable popup solution in AngularJS - javascript

I am doing a project where there are about a dozen templates ( there will be more in future ) which i need to display in popup/modal dialog boxes. I've googled but i didnt quite like the solutions i saw (example) so i've decided to make my own.
I am working towards having an interface like this in my controller.
$scope.popup1Buttonclicked = function(){
dialogService.showdialog("popup1",$scope.popup1data,function(result,data){
if(result == "OK"){
//save data
}
});
};
And in my dialog service i am doing something like this:
myApp.service("dialogService",function($compile){
this.showdialog = function(popupid,data,callback){
var html = "<div>name: {{data.name}}</div>";
var element = $compile(html)(data);
$("#pop").append(element);
//$("#pop").showDialog(element);
};
});
I want two way binding on the popup so that after the dialog box is closed, i can pass the updated data to callback function.
Please check out plunker : http://plnkr.co/edit/uhZ0r0rXCacnvoyCP7nQ?p=preview
Can anyone point me in the right direction ?

After reviewing you code example:
$compile(html)(data);
data - should be $scope here.

have a look at this: http://plnkr.co/edit/SUQnUhX0wyi9UDMc4Vpl?p=preview
I created a directive to manage popups. This triggers the controller callback on close button click and passes data from the input box to it. From my understanding, this does roughly what you wanted to achieve.

Related

Hide and Show a div when a tab is active ( selected )

I have this tabs built.
When I click on Round Trip, I want to make disappear that Flight 2 form.
But since that is needed on multi-city, I want it to show back on
multi-city.
I used this
jQuery('#rdbOneWay').attr("class","onewaybuttonchecked");
jQuery('#rdbRoundTrip').attr("class","roundwaybuttonchecked");
jQuery('#rdbMultiCity').attr("class","multiwaybuttonchecked");
jQuery('.ret_date_block').attr("id","noreturndate");
$("#noreturndate").hide();
$(".onewaybuttonchecked").on("click", function(){
$("#noreturndate").hide();
});
$(".roundwaybuttonchecked").on("click", function(){
$("#noreturndate").show();
});
$(".multiwaybuttonchecked").on("click", function(){
$("#noreturndate").show();
});
});
I used this to hide something on the One Way tab.
If:
$(".roundwaybuttonchecked").on("click", function(){
$("#noreturndate").show();
});
If I use here the correct id of Flights 2 to hide it on the Round-Trip, it does its job but when I switch between One-Way and Round-Trip it shows nothing.
This line get's in action when I go from Multi City to Round-Trip.
Any ideas?
You definitely need a conditional in here.
In your JQuery function, try something like this:
function radioButton() {
if (document.getElementById('htmlElement1').checked) {
document.getElementById('htmlElement2').style.visibility = 'visible';
} else {
document.getElementById('htmlElement').style.visibility = 'hidden';
}
Please note that since I cannot view your HTML - I am not sure what elements you are using so where i say htmlElement 1 (or 2) please fill that in with the appropriate elements.
Let me know you results!
Never mind.
I used same code as above
jQuery('#rdbOneWay').attr("class","onewaybuttonchecked");
jQuery('#rdbRoundTrip').attr("class","roundwaybuttonchecked");
jQuery('#rdbMultiCity').attr("class","multiwaybuttonchecked");
jQuery('.pnlFlight2').attr("id","pnlFlight2");
$("#pnlFlight2").hide();
$(".onewaybuttonchecked").on("click", function(){
$("#pnlFlight2").hide();
});
$(".roundwaybuttonchecked").on("click", function(){
$("#pnlFlight2").hide();
});
$(".multiwaybuttonchecked").on("click", function(){
$("#pnlFlight2").show();
});
and it did the trick, I don't know why it didn't work earlier but glad it did now.

Sitecore 8 Speak UI - Call Pagecode Javascript from HTMLTemplate link

I am working on ListControl and one of the columns has Delete link which I am formatting using HTMLTemplate as follows:
<a href="javascript: app.showConfirmation()" >Delete</a>
My Javascript looks as follows:
define(["sitecore", function (Sitecore) {
var DestinationRules = Sitecore.Definitions.App.extend({
initialized: function () {
this.processDestinationRules();
},
showConfirmation: function () {
alert('here');
},
});
return DestinationRules;
});
For some reason, I am not able to call showConfirmation(). It says is undefined. I even tried Sitecore.Speak.app.showconfirmation() but not working.
I tried my best to search online but not able to find much help around calling function through controls embedded inside HTMLTemplate.
My next step is to call DialogWindow.
Please if you can help me with the syntax of the above. Thanks in advance.
Fixed it in a different way.
I wanted to show in-line Delete button in each row of the Listcontrol. Could not figure out way to call the
javascript: app.showConfirmation()
I changed the way to delete the record:
Have one Delete button outside the ListControl.
Enable/Disable the Delete button based on binding ListControl.HasSelectedItem.
On click of the Delete button, call showConfirmation()
As of now seems to be a better way. Sitecore itself uses similar approach for "Kicking off" users. Can be found here:
/sitecore/client/Applications/LicenseOptions/KickUser
Hope that helps. Thanks.
Finally, managed to do this. Always knew that it can be done this way but did not like the way its done.
The Delete link in List control opens up a confirmation Dialogue window. And if user selects Yes then it calls the app.onDeleteYes()
The HtmlMarkup for the column:
Delete
Added a button called btnDelete with visibility set to false.
Added following function, outside the scope of App:
var destinationRulePage = (function () {
var self = this;
self.showDeleteDialog = function (id) {
$("button[data-sc-id='btnYes']").attr("data-sc-click",
"javascript:app.onDeleteYes(" + id + ");");
$("button[data-sc-id='btnDelete']").click();
}
return self;
}())
This does the job for me. Thanks.

Save dynamic variables on page close

I'm currently building a website for a school project that loads json data into the page dynamically as the user navigates. Here's the code I'm working with right now:
$(function () {
var $divs = $(".divs > div"),
N = $divs.length,
C = 0; // Current
$divs.hide().eq(C).show();
$("#next, #prev").click(function () {
$divs.stop().fadeOut().eq((this.id == 'next' ? ++C : --C) %N).fadeIn();
}); // close click function
}); // close main function
var content = jSONtexts.texts;
$(document).ready(function () {
$("#content0").html(content[0].content);
$("#content1").html(content[1].content);
$("#content2").html(content[2].content);
$("#content3").html(content[3].content);
$("#content4").html(content[4].content);
$("#content5").html(content[5].content);
$("#content6").html(content[6].content);
$("#content7").html(content[7].content);
$("#content8").html(content[8].content);
});
In my html I have divs set up as containers for the particular json data that I want to be presented. It's rudimentary right now, but the user clicks 'next' or 'previous' and a different section of the json loads into the visible div.
What I need is to be able to save what div is showing (maybe using the 'C' variable?) - into a cookie, and load that div when the user returns. I've tried using js.cookie.js, and it's quite possible that I'm using it wrong, Here's what I'm trying:
$( window ).unload(function() {
Cookies.set('pageState', 'C');
}); //close cookie function
But that doesn't seem to be working. It breaks my json loading when I try to put it anywhere in the .js file that would be relevant to the C variable.
I'm stumped. I've looked everywhere on google, and everything that people are saying to try breaks my json function. Help please!
If someone has any ideas I would be eternally grateful!
Thanks
Sam
Cookie is not a best practice to save these data, as cookies will be send with all requests.
Use need to use HTML5 localStorage to save data at client side.
http://www.w3schools.com/html/html5_webstorage.asp
Made demo for the same
document.getElementById("textInput").value = localStorage.getItem("pageState");
window.addEventListener("unload", function() {
localStorage.setItem("pageState", document.getElementById("textInput").value);
});
<input id="textInput" type="text" />
Demo : http://jsfiddle.net/kishoresahas/vvkdge2q/
as #KishoreSahas already suggested in the comments, I would suggest you to use localStorage instead of cookies.
You could store what you need like this
localStorage.setItem("veryimportantdata", "INeedThisLater");
and get it back later like this
var data = localStorage.getItem("veryimportantdata");
console.log(data); // prints out "INeedThisLater"

Angularjs - Resize bootstrap modal after modal is shown

I am still fairly new to angularjs and am currently porting a existing spa javascript application to the angularjs framework. I am using the ui-bootstrap directive for creating bootstrap modals. I am trying to re-position the modal in the middle of the screen once the modal is displayed on the screen. With jQuery that was a easy task, just grab the modal element after calling:
$('#modal').modal('show')
But I can't seem to figure out the correct way to do this using angular. My first thought was to catch bootstrap events. But it turns out those are not fired according to
Here
and
Here
I tried creating a custom directive, but in the link function the element was defined but was not visible on the screen yet. I need a way to trigger some resize code once the modal is visible.
I also tried accessing the $modalStack.getTop(), but I end up having the same issue. There is no way to know when $modalStack.getTop().value.modalDomEl is actually resolved and showing on the screen.
I also tried the following, but the opened promise is resolved before the modal is actually showing on the screen.
modalInstance.opened.then(function(t){
//$modalStack.getTop()
});
How do you accomplish this using angular?
So I ended up taking what #user2943490 recommended and tweaked it a little bit for my use case.
I created a directive that I added to the Modal Template. Inside I check every 100ms to see if the modal-content class exists. If the class exists we know that the modal has bee added to the DOM. Once I perform my logic, I cancel the $interval check.
return {
link: function(scope, element, attrs){
var checkInterval = $interval(checkDOM, 100);
function checkDOM(){
var $content = element.find('.modal-content');
if($content.length){
//We know if $content.length > 0 Then the modal-content class exists on the screen.
$interval.cancel(checkInterval);
}
}
element.on('$destroy', function(){
$interval.cancel(checkInterval);
});
You should use CSS to position the modal as a first option. This avoids all issues around the timing of when specific elements get rendered and stays in line with Angular's spirit of using data binding rather than manual DOM manipulation to build your UI.
You won't find many things in the Angular world that give you an "element rendered" event or similar. It's just not the recommended way to do things.
If you absolutely cannot use CSS, then use a $timeout within the opened promise, and wait a short time (50ms is probably fine) before executing your repositioning logic.
modalInstance.opened.then(function(t){
$timeout(function () {
// reposition it
}, 50);
});
You should have used modal.rendered instead of modal.opened. No need for a link function or interval checks or anything else.
modalInstance.rendered.then(function () {
$('.modal-content').css({ 'width': $(document).width() - 100 + 'px' });
});

Polymer function call but no result

Old Question: How can I call a Polymer Function? (check edits, I don't want to cram code in here)
Rewrite:
I have a <core-scaffold> that I want to call the togglePanel() function. (This sits in project_root/index.html.) I do this using:
<core-icon-button onclick="document.querySelector('core-scaffold').togglePanel();"
icon="drawer></core-icon-button>
In Chrome's Inspector, I can see this causes no errors, but it doesn't do anything on-screen. My code calls this function in project_root/bower_components/core-scaffold/core-scaffold.html:
togglePanel: function() {
this.$.drawerPanel.togglePanel();
}
Which in turn calls this function in project_root/bower_components/core-drawer-panel/core-drawer-panel.html:
togglePanel: function() {
this.selected = this.selected === 'main' ? 'drawer' : 'main';
}
I am either to naive and unexperienced to see the problem, or have a terrible complex bug. Any help would be appreciated!
I ran into the problem as well. The issue is that the closeDrawer(), openDrawer(), and togglePanel() are only usable when size of your screen is less than the value of responsiveWidth.
I think the logic is that if you have the screen real estate you would always want to show the drawer. Of course this could be tweaked by extending core-drawer-panel and making a custom core-scaffold implementation.
You can directly fetch the element using query selector and call its method on onclick just like other html pages
<button onclick="document.querySelector('core-drawer-panel').togglePanel();">toggle drawer</button>
Change the published attribute in core-drawer-panel.html forceNarrow=true See # Call function on polymer navigation drawer panel

Categories

Resources