I am fairly new to jquery all together. Basically what I have done is made a dynamic gallery populated from images retrieved from an ajax call. The images are appended to a unordered list and supposed to receive special css formatting specific to the image gallery, other ul lists are untouched. Everything works great, however when I view the gallery, the proper css formatting is not rendered on the images. I have searched all over stackoverflow and tried many of the options presented to similar problems including .listview('refresh'); and after an ajax complete: as well as some other solutions. Nothing is working. If I navigate away from the page and come back, the formatting is applied. Here is the following code I am working with.
Link to Gallery
$('ul#fieldList').append('<li id="albums"><img src="images/1.jpg"><h3>'+value.name+'</h3><p>'+value.description+'</p><div class="ui-li-count">'+value.count+' Images</div></li>');
onClick Function
function GetUserPhotos(albumid) {
console.log("Get User Photos Function Ran");
var get_user_photos_album_id = albumid;
var get_user_photos_client_id = window.localStorage.getItem("client_id");
var get_user_photos_user_id = window.localStorage.getItem("user_id");
console.log("Assign Variables from local storage");
var formData = {
user_id: get_user_photos_user_id,
client_id: get_user_photos_client_id,
album_id: get_user_photos_album_id
}; //Array
$.ajax({
url: "client_photos.php",
type: "POST",
data: formData,
async: "false",
success: function (data) {
$("ul#photosList li#photos").remove();
$("#test1").html('');
//data - response from server
var PhotoData = $.parseJSON(data);
console.log("PhotoData json data parsed");
$("ul#fieldList li#albums").remove();
$.each(PhotoData, function (key, value) {
$('ul#photosList').append('<li id="photos"><a rel="' + value.album + '" href="http://www.myphotoshootapp.com/cms/uploads/' + value.client_id + '/' + value.album + '/' + value.id + '.' + value.ext + '" class="swipebox" title="' + value.fullname + '""><img src="http://www.myphotoshootapp.com/cms/uploads/thumbs/' + value.client_id + '/' + value.album + '/' + value.id + '.' + value.ext + '" alt="' + value.fullname + '" /></a></li>');
});
Swipe();
},
complete: function () {
$('#ul#photosList').listview('create');
$.mobile.changePage("#Gallery1");
}
});
}
DIV Item's Are Added To
<div data-role="content">
<ul data-role="listview" data-inset="true" id="photosList">
<li id="title">Photos</li>
<div class="main" id="test1"><img src="images/ajax-loader.gif" alt="Loading..." /></div>
</ul>
</div>
And CSS
li#photos { float: left !important; width: 33.33333333% !important; }
li#photos a { display: block !important; margin: 5px !important; border: 1px solid #3c3c3c !important; }
li#photos img { display: block !important; width: 100% !important; height: auto !important; }
As I said, I am pretty new to this and learning as I go, I have learned so much from reading a lot of other questions here but this one I can not figure out. Thanks for the help.
On the first visit, a bunch of extra classes like ui-btn, ui-btn-icon-right, ui-li-has-arrow, ui-li, ui-li-has-thumb, ui-btn-up-c are being added and the second time, only my normal formatting is applied.
First Visit
This image shows what the css formatting looks like on the first page visit
Here's Image
Second Visit
This image shows what the css formatting looks like when I return to the page (LIKE ITS SUPPOSED TO)
Here's Image
Related
I have on page with multiple iframes.
All these iframes have the same source (within the same domain that the main page which contains them all; each iframe just shows eventually a different area of this very same source).
It does work well according to this solution that I've followed:
Multiple Iframes sending ONE request to the same SRC
I do have all my iframes loaded (each of them showing correctly its own area of this common page).
But in fact each and every iframe does make an independent request to the source. And the page is quite slow to load.
Hence my question in order to improve this process:
is there a way to load the first iframe (f1 in the example), and only then to load all the others ones with the very "same content" (that to say with the same page -even if each of them shows a different area of it but this part already works well). I didn't manage to do this with a "srcdoc".
Ifames id in the html are f1, f2, f3, and so on:
<iframe style="border: 0px none; height: 1000px; width: 1000px; margin-left: -107px; margin-top: -547px; " id="f1" scrolling="no" src="MYSOURCE.html" >
</iframe>
`
`
<iframe style="border: 0px none; height: 1000px; width: 1000px; margin-left: -107px; margin-top: -685px; " id="f3" scrolling="no" srcdoc="" src="" >
and so on...
The first function waits for the first iframe to be loaded. Then the second one try to fill up the next ones with the same source page.
FuncOL = new Array();
function StkFunc(Obj) {
FuncOL[FuncOL.length] = Obj;
}
function loadingpageinf1(){
let oldDoc = f1.contentDocument;
let timer = setInterval(() => {
if (f1.contentDocument == oldDoc) return;
f1.contentDocument.addEventListener('DOMContentLoaded', () => {
f1.contentDocument.body.prepend('Hello, world!');
});
clearInterval(timer);
}, 100);
}
StkFunc(loadingpageinf1);
function Multipleiframes(){
var frames=window.frames;
for (var i=2; i<4; i++){
var frame="f"+i;
document.getElementById(frame).srcdoc = document.getElementById(f1).srcdoc ;
}
}
StkFunc(Multipleiframes);
window.onload = function() {
for(i=0; i<FuncOL.length; i++)
{FuncOL[i]();}
}
Thanks for your help.
you could send an ajax/fetch request to get the html page and render the html inside each of your iframe in response. that's one way to do it.
fetch('your_page.html')
.then(function(response) {
return response.text()
})
.then(function(html) {
var parser = new DOMParser();
var doc = parser.parseFromString(html, "text/html");
//you can iterate iframes and assign innerHTL
})
.catch(function(err) {
console.log('Failed to fetch page: ', err);
});
or you can also create blob url and assign it to iframe's src
Sorry if this is a bit of a newby question. I'm trying to create a login page that has a background image, while the rest of my pages do not. I've used ng-style but I can't get the property to update on page changes.
in my index.html:
<body ng-app="myApp" ng-style="bodyStyle" ng-controller="bodyController">
//content
</body
bodycontroller:
var image="http://momentumbooks.com.au/wp-content/uploads/2013/06/space.jpg";
if ($location.path() === '/login') {
$scope.bodyStyle = {background: "url(" + image + ") no-repeat center center fixed"};
} else{
$scope.bodyStyle={background: ""}
}
Obviously this doesn't work because the function is only called once. I've tried using rootScope, but I can't seem to use rootScope properties in ng-style (and everywhere i look, people are advising against using rootScope for this purpose). How do I create a dynamic background? Also i'd prefer not to use a controller on my body tag, if possible.
update
The main problem i'm having is that the background image does not update when changing paths. The image is set in bodycontroller, and when logging in and changing paths it is not changed.
Per suggestion I could write a service, I've used them before but only through getters and setters, so I assume i can create a service that sends a call to a controller? Looking something like this:
<body ng-app="myApp" ng-style="bodyStyle" ng-controller="bodyController">
//content
</body
bodycontroller
var image=??;
$scope.bodyStyle = {background: "url(" + image + ") no-repeat center
some service
.service('backgroundService', function (image) {
var backgroundImage = image
// somhow set bodycontroller image?
});
and then somehow call the service when route is changed? I haven't found a way to inject services into my router config, which is what I think i would need for that.
So i figured out an easy way to do this with some help.
in app.js add this:
.run(function ($rootScope, $location) {
$rootScope.$on( "$routeChangeStart", function(event, next, current) {
$rootScope.bodyClass = $location.path().replace('/', '') + '-page';
});
});
and change index to:
<body ng-app="myApp" ng-class="bodyClass">
and Css:
.login-page {
background: url("someImage") no-repeat center center fixed;
}
IMO it would be easier to just toggle an ng-class based on location. So you could do something like -
if ($location.path() === '/login') {
$scope.isLogin = true;
} else{
$scope.isLogin = false;
}
then on the html
<body ng-app="myApp" ng-class="{'customBgClass' : isLogin }" ng-controller="bodyController">
Then just set everything you want on that css class
.customBgClass {
background: url("http://momentumbooks.com.au/wp-content/uploads/2013/06/space.jpg") no-repeat ce;ter center fixed;
}
Good morning all,
I have to show a 16x40 pixel image in a jqGrid column, that changes when I click
on it; at this purpose, I defined my formatter as follow:
function dataViewLink(cellValue, options, rowdata, action)
{
var chartLink = "<div style='float:left;'><img id='_addtochart" + options.rowId + "' class='ui-icon-addtochart' onclick='devToggleChartChecked(" + options.rowId + ")'></img></div>";
return chartLink;
}
and created two CSS classes with different images:
.ui-icon-addtochart
{
content: url(../images/addtochart.jpg) !important;
}
.ui-icon-removefromchart
{
content: url(../images/removefromchart.jpg) !important;
}
then, I dynamically switch these classes using jquery. Everything
works fine on chrome, but there is no way to get it working on firefox.
The images does not show on firefox.
I have already found an issue related to the 'content' attribute on firefox:
Content url does not display image on firefox browser
and tried all the suggested workarounds, but none of them worked for me.
I cannot show these images with firefox.
This little problem is driving me crazy. Does anyone have any suggestion?
Thank you very much in advanced.
Bruno
It seems I found a solution; I changed my formatter with:
function dataViewLink2(cellValue, options, rowdata, action)
{
var chartLink = "<div style='float:left;' id='_addtochart" + options.rowId + "' class='ui-icon-addtochart ui_add_dev' onclick='devToggleChartChecked(" + options.rowId + ")'></div>";
return chartLink;
}
and the CSS classes:
.ui-icon-addtochart
{
background: url(../images/addtochart.jpg);
height: 16px;
width: 144px;
}
.ui-icon-removefromchart
{
background: url(../images/removefromchart.jpg);
height: 16px;
width: 215px;
}
it works both on chrome and on firefox.
Thank you very much anyway!
Bruno
I'm trying to create a drop down list directive, with down-arrow that appears when the mouse is hovering the dropdown header or when the dropdown list is oppend, and disappears otherways.
I succeeded to do this, but if the dropdown list is closed not by selecting element or by pressing on the header list again, than the arrow isn't disappead.
(I.E. If i'm openning one list and than openning another without closing the first one, than arrow of the first list is not disappearing)
JsFiddle - http://jsfiddle.net/rpg2kill/uS4Bs/
code:
var myApp = angular.module('myApp', ['ui.bootstrap']);
function MyCtrl($scope) {
$scope.supportedList= ['Option1', 'Option2', 'Option3', 'Option4'];
$scope.selectedItem = 'Option1';
}
myApp.directive('dropDown',
function () {
return {
restrict: 'E',
replace: false,
scope: {
supportedList:'=',
selectedItem:'='
},
template:
'<div ng-mouseenter="onMouseEntered()" ng-mouseleave="onMouseLeft()">' +
'<a class="dropdown-toggle" data-toggle="dropdown" href="" ng-click="onMouseClicked()" >' +
'<img ng-style="{\'visibility\': dropDownIconVisibility}" src="http://png.findicons.com/files/icons/2222/gloss_basic/16/arrow_down.png"> </img>' + //Arrow down Icon
'<span>{{selectedItem}}</span>' +
'</a>' +
'<ul class="dropdown-menu">' +
'<li ng-repeat="item in supportedList" ng-click="onSelectedItem(item)">' +
'{{item}}' +
'</li>' +
'</ul>' +
'</div>'
,
link: function(scope, element, attrs) {
scope.dropDownIconVisibility = "hidden";
scope.dropDownIconVisibilityLocked = false;
scope.onSelectedItem = function(item) {
scope.dropDownIconVisibilityLocked = false;
scope.selectedItem = item ;
};
scope.onMouseEntered = function()
{
scope.dropDownIconVisibility = "visible";
};
scope.onMouseLeft = function()
{
if (scope.dropDownIconVisibilityLocked)
return;
scope.dropDownIconVisibility = "hidden";
};
scope.onMouseClicked = function()
{
scope.dropDownIconVisibility = "visible";
scope.dropDownIconVisibilityLocked = !scope.dropDownIconVisibilityLocked;
};
}
};
})
The code is little ugly. A better solution is to show the arrow if the mouse is hovering OR the list is openned, but I don't know how to bind angular to the state of the dropdown list.
Is there a way to binding angular to Twitter bootstrap's dropdown event?
Or is there a better way to solve this problem?
I suggest you using full CSS approach - it takes less code, it does not trigger JS evaluations, thus, it performs better (Angular is a bit slow with all its cool features). Once you go mobile - CSS will be more preferable, as supports downgrading with media queries and so on... There are too many pros!
Remove all your mouse-tracking code and add just two CSS rules and here you go:
a.dropdown-toggle img {
visibility: hidden;
}
a.dropdown-toggle:hover img {
visibility: visible;
}
I succeeded to solve the problem, unfortunately the solution is not so pretty, but at least it works.
I'll try to solve this with only CSS as madhead suggested.
The problem was that I didn't know when the user clicked outside the dropdown, that caused the dropdown popup to close but the icon was still displayed. So I attached an handler to each directive that listen on document.click event and hides the Icon.
document.addEventListener('click', function (event) {
scope.$apply(function () {
scope.hideDropdownIcon();
});
}, false);
That worked, but if I clicked on another Dropdown when the current dropdown was opened, the document.click event was not fired. So I had to create my event and attach it to $window and to call it when any dropdown is opens.
var event = new Event('hideDropDownIcon');
$window.addEventListener('hideDropDownIcon', function (e) {
scope.hideDropdownIcon();
}, false);
You can see it here:
http://jsfiddle.net/rpg2kill/uS4Bs/6/
There must be a better solution. So if you know how to do it better or by using only css, I would like to know.
Thanks.
Found CSS solution to the problem.
css is so simple instead all the js events..
The CSS:
a.dropdown-toggle img {
visibility: hidden;
}
li.ng-scope:hover img,li.ng-scope:active img,.open a img{
visibility: visible;
}
You can check this: http://jsfiddle.net/rpg2kill/HVftB/1/
I'm trying to print iframe content.
contentWindow.focus();
contentWindow.print();
This code works in IE, Firefox and Safari. But don't work in Chrome and Opera. These browsers print entire page.
I tried to use this topic How do I print an IFrame from javascript in Safari/Chrome. But it didn't help me.
Could someone help me?
This is a known bug in Opera. In addition to the above ideas for workarounds, you may want to play with something like this:
var clone=document.documentElement.cloneNode(true)
var win=window.open('about:blank');
win.document.replaceChild(clone, win.document.documentElement);
win.print();
I have not tested this but it should create a copy of the page in a popup window and print it, without having to load the content a second time from the server or loosing any DOM modifications you may want printed.
As I understand, it's impossible to implement iframe printing without opening new window.
My print function:
if ($.browser.opera || (/chrome/.test(navigator.userAgent.toLowerCase()))) {
var href = contentWindow.location.href;
href = href.indexOf("?") > -1 ? href + "&print=1" : href + "?print=1";
var printWindow = window.open(href, "printWindow", "scrollbars=yes");
printWindow.focus();
}
else {
contentWindow.focus();
contentWindow.print();
}
Also I added the following code to the end of the body (when print==1):
<script type='text/javascript'>
function invokePrint() {
if (document.readyState && document.readyState!='complete')
setTimeout(function() { invokePrint(); }, 50);
else if (document.body && document.body.innerHTML=='false')
setTimeout(function() { invokePrint(); }, 50);
else {
focus();
print();
}
}
invokePrint();
</script>
I cannot reproduce your problem with Chrome. Opera, however, does indeed still print the entire outer page when trying to only print the iframe.
I have devised a workaround and although it does work mostly, it is not 100% failsafe (amongst others because Opera wraps lines for printing; I don't know how to calculate the correct height in such cases). That said, the following code works at least reasonable (using jQuery for convenience):
if ($.browser.opera) {
var ifr = $('#youriframe');
var ifrbody = ifr.get(0).contentDocument.body;
var sheet = $([
'<style type="text/css" media="print">',
'body * {',
' display: none;',
'}',
'#youriframe {',
' border: none;',
' display: block;',
' height: ', ifrbody.scrollHeight, 'px;',
' margin: 0px;',
' padding: 0px;',
' width: ', ifrbody.scrollWidth, 'px;',
'}',
'<\/style>'
].join(''));
$('head').append(sheet);
window.print();
sheet.remove();
}
Hope this helps.
I tried above code and after making changes to the above codes I came with conclusive code as follows
var win=window.open('about:blank');
win.document.write('<html><head></head><body>');
win.document.write('<iframe frameBorder="0" align="center" src="'+window.location.href+'" onload="test()" style="width: 619px; height: 482px;"></iframe>');
win.document.write('<scr'+'ipt>function test(){window.focus();window.print()}</sc'+'ript></body></html>');
win.document.close();
if (window.focus) {win.focus()}
try this one