Resize iframe - do have access to external url code - iframe

I have seen lots of questions about resizing iframes but all of those do not have access to the external url. In this case I do. I can insert a script into the head tag. I was trying to use this script inserted into the main page header containing the iframe (i know the opening and closing frame tags are wrong - it would not let me leave them in:
iframe id="frame-one" scrolling="no" frameborder="0" src="yoursitehereexample" onload="FrameManager.registerFrame(this)" /iframe
and this the js in the header (linked FrameManager.js file)
var FrameManager =
{
currentFrameId : '',
currentFrameHeight : 0,
lastFrameId : '',
lastFrameHeight : 0,
resizeTimerId : null,
init : function()
{
if (FrameManager.resizeTimerId == null)
{
FrameManager.resizeTimerId = window.setInterval(FrameManager.resizeFrames, 500);
}
},
resizeFrames : function()
{
FrameManager.retrieveFrameIdAndHeight();
if ((FrameManager.currentFrameId != FrameManager.lastFrameId) ||
(FrameManager.currentFrameHeight != FrameManager.lastFrameHeight))
{
var iframe = document.getElementById(FrameManager.currentFrameId.toString());
if (iframe == null) return;
iframe.style.height = FrameManager.currentFrameHeight.toString() + "px";
FrameManager.lastFrameId = FrameManager.currentFrameId;
FrameManager.lastFrameHeight = FrameManager.currentFrameHeight;
window.location.hash = '';
}
},
retrieveFrameIdAndHeight : function()
{
if (window.location.hash.length == 0) return;
var hashValue = window.location.hash.substring(1);
if ((hashValue == null) || (hashValue.length == 0)) return;
var pairs = hashValue.split('&');
if ((pairs != null) && (pairs.length > 0))
{
for(var i = 0; i < pairs.length; i++)
{
var pair = pairs[i].split('=');
if ((pair != null) && (pair.length > 0))
{
if (pair[0] == 'frameId')
{
if ((pair[1] != null) && (pair[1].length > 0))
{
FrameManager.currentFrameId = pair[1];
}
}
else if (pair[0] == 'height')
{
var height = parseInt(pair[1]);
if (!isNaN(height))
{
FrameManager.currentFrameHeight = height;
FrameManager.currentFrameHeight += 15;
}
}
}
}
}
},
registerFrame : function(frame)
{
var currentLocation = location.href;
var hashIndex = currentLocation.indexOf('#');
if (hashIndex > -1)
{
currentLocation = currentLocation.substring(0, hashIndex);
}
frame.contentWindow.location = frame.src + '?frameId=' + frame.id + '#' + currentLocation;
}
};
window.setTimeout(FrameManager.init, 300);
Then...I put this in the framed page header ResizeFrame.js as a link:
//orig frame mgr script
$.getScript("http://www.yoursitehereexamle.com/js/FrameManager.js", function(){
});
// external heights load
function publishHeight()
{
if (window.location.hash.length == 0) return;
var frameId = getFrameId();
if (frameId == '') return;
var actualHeight = getBodyHeight();
var currentHeight = getViewPortHeight();
if (Math.abs(actualHeight - currentHeight) > 15)
{
var hostUrl = window.location.hash.substring(1);
hostUrl += "#";
hostUrl += 'frameId=' + frameId;
hostUrl += '&';
hostUrl += 'height=' + actualHeight.toString();
window.top.location = hostUrl;
}
}
function getFrameId()
{
var qs = parseQueryString(window.location.href);
var frameId = qs["frameId"];
var hashIndex = frameId.indexOf('#');
if (hashIndex > -1)
{
frameId = frameId.substring(0, hashIndex);
}
return frameId;
}
function getBodyHeight()
{
var height;
var scrollHeight;
var offsetHeight;
if (document.height)
{
height = document.height;
}
else if (document.body)
{
if (document.body.scrollHeight)
{
height = scrollHeight = document.body.scrollHeight;
}
if (document.body.offsetHeight)
{
height = offsetHeight = document.body.offsetHeight;
}
if (scrollHeight && offsetHeight)
{
height = Math.max(scrollHeight, offsetHeight);
}
}
return height;
}
function getViewPortHeight()
{
var height = 0;
if (window.innerHeight)
{
height = window.innerHeight - 18;
}
else if ((document.documentElement) && (document.documentElement.clientHeight))
{
height = document.documentElement.clientHeight;
}
else if ((document.body) && (document.body.clientHeight))
{
height = document.body.clientHeight;
}
return height;
}
function parseQueryString(url)
{
url = new String(url);
var queryStringValues = new Object();
var querystring = url.substring((url.indexOf('?') + 1), url.length);
var querystringSplit = querystring.split('&');
for (i = 0; i < querystringSplit.length; i++)
{
var pair = querystringSplit[i].split('=');
var name = pair[0];
var value = pair[1];
queryStringValues[name] = value;
}
return queryStringValues;
}
// window load
window.onload = function(event)
{
window.setInterval(publishHeight, 300);
}
But no luck on getting it to work - can anyone see where I went wrong. The iframe still appears but does not scale. Many Thanks!

Here is my code to resize an iframe with an external website. You need insert a code into the parent (with iframe code) page and in the external website as well, so, this won't work with you don't have access to edit the external website.
local (iframe) page: just insert a code snippet
remote (external) page: you need a "body onload" and a "div" that holds all contents. And body needs to be styled to "margin:0"
Local:
<IFRAME STYLE="width:100%;height:1px" SRC="http://www.remote-site.com/" FRAMEBORDER="no" BORDER="0" SCROLLING="no" ID="estframe"></IFRAME>
<SCRIPT>
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
eventer(messageEvent,function(e) {
if (e.data.substring(0,3)=='frm') document.getElementById('estframe').style.height = e.data.substring(3) + 'px';
},false);
</SCRIPT>
You need this "frm" prefix to avoid problems with other embeded codes like Twitter or Facebook plugins. If you have a plain page, you can remove the "if" and the "frm" prefix on both pages (script and onload).
Remote:
You need jQuery to accomplish about "real" page height. I cannot realize how to do with pure JavaScript since you'll have problem when resize the height down (higher to lower height) using body.scrollHeight or related. For some reason, it will return always the biggest height (pre-redimensioned).
<BODY onload="parent.postMessage('frm'+$('#master').height(),'*')" STYLE="margin:0">
<SCRIPT SRC="path-to-jquery/jquery.min.js"></SCRIPT>
<DIV ID="master">
your content
</DIV>
So, parent page (iframe) has a 1px default height. The script inserts a "wait for message/event" from the iframe. When a message (post message) is received and the first 3 chars are "frm" (to avoid the mentioned problem), will get the number from 4th position and set the iframe height (style), including 'px' unit.
The external site (loaded in the iframe) will "send a message" to the parent (opener) with the "frm" and the height of the main div (in this case id "master"). The "*" in postmessage means "any source".
Hope this helps. Sorry for my english.

Related

Asp.net Telerik script issue

I have a line of code which comes inside a Telerik.Web.UI.Webresource.axd file which breaks something in my custom code.
dataBind:function(){if(this._virtualization&&!this._virtualization._isDataBinding&&((this.get_allowPaging()&&this._dataSource.length>this.get_pageSize())||(!this.get_allowPaging()&&this._dataSource.length>this._virtualization._itemsPerView))){this._virtualization._startIndex=null;
this._virtualization.set_bindingType("Client");
this._virtualization.set_cachedData(this._dataSource);
this._virtualization.set_virtualItemCount(this._dataSource.length);
this._virtualization.select();
return;
}
**Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0],"rgGroupHeader"),function(i){i.parentNode.removeChild(i)**;
});
I would like to know if it is possible to prevent the below line of code to be executed
Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0],"rgGroupHeader"),function(i){i.parentNode.removeChild(i)**;
You can override the dataBind method of RadGrid which will allow you to customize it:
<script>
Telerik.Web.UI.GridClientSideBinding.prototype.dataBind = function () {
// Virtualization
if (this._virtualization && !this._virtualization._isDataBinding &&
((this.get_allowPaging() && this._dataSource.length > this.get_pageSize()) ||
(!this.get_allowPaging() && this._dataSource.length > this._virtualization._itemsPerView))) {
this._virtualization._startIndex = null;
this._virtualization.set_bindingType("Client");
this._virtualization.set_cachedData(this._dataSource);
this._virtualization.set_virtualItemCount(this._dataSource.length);
this._virtualization.select();
return;
}
Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0], "rgGroupHeader"), function (element) {
element.parentNode.removeChild(element);
});
Array.forEach($telerik.getElementsByClassName(this.get_element().tBodies[0], "rgFooter"), function (element) {
element.parentNode.removeChild(element);
});
var noRecordsItem = $telerik.getElementByClassName(this.get_element(), "rgNoRecords");
if (noRecordsItem) {
if (this._dataSource.length > 0) {
noRecordsItem.style.display = "none";
} else {
noRecordsItem.style.display = "";
this._setPagerVisibility(this._data.PagerAlwaysVisible);
}
}
var dataItems = this.get_dataItems();
var columns = this.get_columns();
var i, l1, l2;
var tableElement = ($telerik.isOpera) ? this.get_element() : this.get_element().tBodies[0];
if (this._dataSource.length < dataItems.length || tableElement.rows.length == 1) {
for (i = 0, l1 = dataItems.length; i < l1; i++) {
dataItems[i].set_visible(false);
dataItems[i].get_element().style.display = "none";
}
this._cacheDataItems();
}
this._dataBind(this._dataSource);
var firstSelection = true;
// When YahooStyleScrolling is used in RadGrid and user
//scrolls down, select multiple rows using shift + down arrow key,
//the selection is not persisted on next page load
if (this._owner._keyboardNavigationProperties) {
firstSelection = this._owner._keyboardNavigationProperties.firstSelection;
}
var owner = $find(this._owner.get_id());
if (owner._getPositionedDataItems) {
owner._getPositionedDataItems(true);
}
if (this._owner._keyboardNavigationProperties) {
this._owner._keyboardNavigationProperties.firstSelection = firstSelection;
}
this._fixRowsClassNames();
this._owner.raise_dataBound(Sys.EventArgs.Empty);
for (i = 0, l2 = columns.length; i < l2; i++) {
var isVisible = false;
if (columns[i].get_element().style.visibility != "hidden" && (columns[i].Display == null || columns[i].Display == true) &&
(columns[i]._data.Display == null || columns[i]._data.Display)) {
isVisible = true;
}
if (!isVisible) {
this.hideColumn(i);
}
}
if (this.get_id() == this._owner._masterClientID) {
var grid = $find(this._owner.get_id());
if (grid._scrolling) {
this._owner._scrolling.setHeaderAndFooterDivsWidth();
grid._scrolling._initializeVirtualScrollPaging(true);
}
}
}
</script>

Using multi filter datatables in asp.net MVC

I'm trying to implement the multiple filters in the datatables in asp.net, but the time I search a value, my table is not updated.
I followed the official example of the site, but it did not work. Here is the source code I'm using.
JS on VIEW
$('#students tfoot th').each( function () {
var title = $(this).text();
if (title !== "") {
$(this).html('<input type="text" class="form-control form-control-sm" style="width: 100%" placeholder="' + title + '" />');
} else {
$(this).html('<div class="text-center">-</div>');
}
} );
tabela.columns().every( function () {
var that = this;
$( 'input', this.header() ).on( 'keydown', function (ev) {
if (ev.keyCode == 13) { //only on enter keypress (code 13)
that
.search( this.value )
.draw();
}
} );
} );
ACTION on CONTROLLER
[HttpPost]
public JsonResult Listar2()
{
var search = Request.Form.GetValues("search[value]")?[0];
var list = db.Students;
if (!string.IsNullOrEmpty(search))
{
list = list.Where(m => m.name.ToLower().Contains(search.ToLower()) || m.class.ToLower().Contains(search.ToLower()));
}
var draw = Request.Form.GetValues("draw")?[0];
var start = Request.Form.GetValues("start")?[0];
var length = Request.Form.GetValues("length")?[0];
var width = length != null ? Convert.ToInt32(length) : 0;
var skip = start != null ? Convert.ToInt32(start) : 0;
var totalRecords = list.Count();
var resultFinal = list.Skip(skip).Take(width).ToList();
return Json(new
{
data = resultFinal,
draw,
recordsFiltered = totalRecords,
recordsTotal = totalRecords
});
}
I don't know what you want to accomplish. The official example uses JavaScript to sort the datatable which is inserted into HTML already. You should load all the entries first, pass them to the view and then this script should filter those entries

PhantomJS order iframe

How can I get the iframes on the page? I want to get an external options(width, height, id, src) and inner HTML.
It's all I can get only if the iframes on the page are not dynamically added. If they are dynamically added, the order of the IFRAME in the DOM and in the frameid (switchToFrame(frameid)) differs, and I can not compare them.
HTML:
<iframe src="iframe.php?id=1"></iframe>
<iframe src="iframe.php?id=2"></iframe>
<div id="dynamic_iframe"></div>
<div id="dynamic_iframe2"></div>
<iframe src="iframe.php?id=3"></iframe>
<script>
var el = document.createElement("iframe");
el.src = 'iframe.php?id=21';
document.getElementById('dynamic_iframe').appendChild(el);
var el = document.createElement("iframe");
el.src = 'iframe.php?id=22';
document.getElementById('dynamic_iframe2').appendChild(el);
</script>
PhantomJS:
getAllIFramesFromPage = function(page){
return page.evaluate(function() {
var matches = document.querySelectorAll('iframe');
ifames = [];
for(var i = 0; i < matches.length; ++i){
ifames.push(matches[i].src);
}
return ifames;
});
};
out:
iframe.php?id=1
iframe.php?id=2
iframe.php?id=21
iframe.php?id=22
iframe.php?id=3
PhantomJS:
var cnt = page.framesCount;
for(var i = 0; i < cnt; i++){
page.switchToFrame(i);
console.log(page.framePlainText);
page.switchToMainFrame();
}
out:
1
2
3
21
22
I was able to get out of a problem like this:
When I pass all the iframe into the DOM I put in them hidden value
page.switchToMainFrame();
page.evaluate(function() {
var matches = document.querySelectorAll('iframe');
ifames = [];
for(var i = 0; i < matches.length; ++i){
var iframeWindow = matches[i].contentWindow || matches[i].contentDocument.parent;
var frmBody = iframeWindow.document.getElementsByTagName("body")[0].frame_id = i;
}
});
Already inside an iframe I can get this value as follows:
var cnt = this.page.framesCount;
for(var i = 0; i < cnt; i++){
page.switchToFrame(i);
frameIndex = this.page.evaluate(function() {
if (document.getElementsByTagName("body")[0].frame_id !== undefined){
return document.getElementsByTagName("body")[0].frame_id;
}
return false;
});
this.page.switchToParentFrame();
}

Iterate through the model object in javascript (foreach and <text>)

As going through the site i got how to access the model in javascript and how to loop it in javascript.
i am using text tag to access the item in a model. when i use i am not able to add break.
#foreach (var item in Model.ArrayDetails)
{
var checklower = false;
var checkUpper = false;
var loopentered = false;
<text>
if(#item.Id ==1)
{
if(#item.LowerBound <= obj.value)
{
loopentered=true;
checklower=true;
}
if(loopentered)
{
alert(#item.UpperBound <= obj.value);
if(#item.UpperBound <= obj.value)
{
checkUpper = true;
}
}
if(checkUpper && checklower)
{
***// here i want to add break statement(if i add javascript wont work)***
}
}
</text>
}
Can some one suggest me how can solve this.
Don't write this soup. JSON serialize your model into a javascript variable and use this javascript variable to write your javascript code. Right now you have a terrible mixture of server side and client side code.
Here's what I mean in practice:
<script type="text/javascript">
// Here we serialize the Model.ArrayDetails into a javascript array
var items = #Html.Raw(Json.Encode(Model.ArrayDetails));
// This here is PURE javascript, it could (AND IT SHOULD) go into
// a separate javascript file containing this logic to which you could
// simply pass the items variable
for (var i = 0; i < items.length; i++) {
var item = items[i];
var checklower = false;
var checkUpper = false;
var loopentered = false;
if (item.Id == 1) {
if (item.LowerBound <= obj.value) {
loopentered = true;
checklower = true;
}
if (loopentered) {
alert(item.UpperBound <= obj.value);
if(item.UpperBound <= obj.value) {
checkUpper = true;
}
}
if (checkUpper && checklower) {
break;
}
}
}
</script>
and after moving the javascript into a separate file your view will simply become:
<script type="text/javascript">
// Here we serialize the Model.ArrayDetails into a javascript array
var items = #Html.Raw(Json.Encode(Model.ArrayDetails));
myFunctionDefinedIntoASeparateJavaScriptFile(items);
</script>

Not able to maintain checkbox during pagination using jQuery

I have 4 buttons for pagination(first,move next,move back and last).
I am trying to maintain checkbox during pagination. The problem is that
when I select any checkbox and then go to next page and then come back to the same page, it doesn't show previously checked checkbox, but as soon as click on next page, before going to next page it shows value checked.
Here is my code, can anyone guide me where I am doing wrong?
$(function() {
toggleSelectBtnOnCheck();
});
function toggleSelectBtnOnCheck() {
debugger;
//Register checkbox click handler to be called when Ajax requests complete.
$('#contentDiv').ajaxComplete(function() {
$('.tdHeadForCheckboxRadioButton').append('<input class="search" onclick="checkUnchekAllCheckboxes(this);" type="checkbox"/>');
$('.afirst, .aprev, .anext, .alast, .search:checkbox').click(function() {
var selectedVal = $(this).closest('td');
var selectClaim = selectedVal.next().text();
var selectSuffix = selectedVal.next().next().text();
var ClaimSuffix = selectClaim + '|' + selectSuffix + ',';
if ($(this).is(':checked')) {
document.getElementById('hdnChkClaim').value += ClaimSuffix;
} else if ($('#hdnChkClaim').val().indexOf(ClaimSuffix) != -1) {
$('#hdnChkClaim').val($('#hdnChkClaim').val().replace(ClaimSuffix, ''));
}
alert($('#hdnChkClaim').val());
if (jQuery(this).attr("href") != "") {
//button.disable($('span.btnSelect'));
var SelectedItemsCheckboxID = [];
if ($('#hdnChkClaim').val() != '') {
debugger;
if (ClaimSuffix.indexOf(',') != -1) {
ClaimSuffix = ClaimSuffix.substr(0, ClaimSuffix.length - 1); //remove last ','
}
SelectedItemsCheckboxID = $('#hdnChkClaim').val().split(',');
for (i = 0; i < SelectedItemsCheckboxID.length; i++) {
var claimDetails = SelectedItemsCheckboxID[i].split('|');
a = claimDetails[0];
b = claimDetails[1];
$('tr').filter(function(index) {
var columns = $(this).children('td');
alert(columns.eq(1).text() === a && columns.eq(2).text() === b);
return columns.eq(1).text() === a && columns.eq(2).text() === b;
}).find('input:checkbox').attr("checked", true);
;
}
}
if ($('.search:checkbox:checked').length > 0) {
button.enable($('span.btnSelect'));
} else {
button.disable($('span.btnSelect'));
}
}
});
});
}
You have to use the hidden field , when user select a checkbox , add it to hidden field like comma separated Ids , when every page is moved because of pagination check if any of the id in the current page is belong to the hidden field if yes mark them to checked.

Resources