load a cshtml file (razor) in the iframe - javascript

I have in my Layout page (Menu + Iframe)
and i want to load a cshtml files (view pages) in the iframe after the click in the menu.
the goal is not to load the entire Layout page
I tried this way:
<ul id="qm0" class="qmmc">
<li><a class="qmparent" >FILES</a>
<ul class="rgauche">
<li>#Html.ActionLink("USERS","getUsers")</li>
<li><a id="disconnect">Deconnexion</a></li>
</ul>
</li>
</ul>
but it loads the entire layout page
I had this idea from another ASP.NET project that uses javascript to load a .aspx page in the iframe after the click on the menu
<ul id="qm0" class="qmmc">
<li><a class="qmparent" >FILES</a>
<ul class="rgauche">
<li><a id="getuser">USERS</a></li>
<li><a id="disconnect">Deconnexion</a></li>
</ul>
</li>
</ul>
$(function () {
$('#getuser').click(function () {
document.getElementById('myIframe').src = "users.aspx";
return false;
});
});
Any ideas ?

You have to point the "src" attribute of the iframe to a controller action that returns the view.
For ex.
Action that returns the partial view without layout
public PartialViewResult IframeAction()
{
return PartialView();
}
Javascript
$('#getuser').click(function ()
{
document.getElementById('myIframe').src
= "/IframeController/IframeAction";
return false;
});

Load the view thru an action method. In this view, set the Layout value to null so that it wont use the layour defined in viewstart.cshtml
#{
Layout=null;
}
<p>some partial view content</p>
EDIT :
Not quite sure what you want to achieve. But If you want to update the Iframe content inside the Layout you can do like this
Assuming your Layout.cshtml is like this
<head>
//Load jQuery library
</head>
<body>
#Html.ActionLink("List", "GetUsers", "Users", null, new { #class = "iframable" })
<iframe id="ifrm" style="width:500px; height:200px; border:1px solid black;">
</iframe>
#RenderBody()
<script type="text/javascript">
$(function () {
$(".iframable").click(function (e) {
e.preventDefault();
var item = $(this);
$("#ifrm").attr('src', item.attr("href"));
});
});
</script>
Now have the GetUsers action method in your Users controller
public ActionResult GetUsers()
{
return View();
}
and make sure in the GetUsers.cshtml view, the layout is set to null
#{
Layout=null;
}
<p>some partial view content</p>

you need a different layout for the page you are loading within the iframe.
Then, within this page, you can do
#{
Layout = "YourLayout.cshtml";
}
By default all your cshtml views are using the layout provided in the _ViewStart.cshtml
EDIT
You can use the following concept:
<iframe name="my_frame"></iframe>
#Html.ActionLink("Users", "GetUsers", null, new { target = "my_frame" })
You give your iframe a name, and then use the name as the target for your action link. Thats the simplest solution. if you prefer, you can also use jquery click handler, as provided in one of the other answers.

Related

Horizontal drop-down menu Umbraco

I'm using Umbraco and I want my drop-down menu to display horizontal like this:
Right now my drop down menu is like this:
The problem is that I don't know how to do this in Umbraco
Here is my code:
MainNavigation code:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{ var home = CurrentPage.Site(); }
#if (home.Children.Any())
{
#* Get the first page in the children *#
var naviLevel = home.Children.First().Level;
#* Add in level for a CSS hook *#
<ul class="level-#naviLevel">
#* For each child page under the home node *#
#foreach (var childPage in home.Children)
{
if (childPage.Children.Any())
{
<li class="has-child #(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
#if (childPage.DocumentTypeAlias == "Huvudmeny")
{
<span>#childPage.Name</span>
#childPages(childPage.Children)
}
else
{
#childPage.Name
}
</li>
}
else
{
<li class="#(childPage.IsAncestorOrSelf(CurrentPage) ? "selected" : null)">
#childPage.Name
</li>
}
}
</ul>
}
#helper childPages(dynamic pages)
{
#* Ensure that we have a collection of pages *#
if (pages.Any())
{
#* Get the first page in pages and get the level *#
var naviLevel = pages.First().Level;
#* Add in level for a CSS hook *#
<ul class="sublevel level-#(naviLevel)">
#foreach (var page in pages)
{
<li>
#page.Name
#* if the current page has any children *#
#if (page.Children.Any())
{
#* Call our helper to display the children *#
#childPages(page.Children)
}
</li>
}
</ul>
}
}
The above code is included in my master page through this code:
<nav>
#{ Html.RenderPartial("MainNavigation"); }
</nav>
js
// Navigation
$('#toggle').click(function(){
$('.has-child').removeClass('selected');
$('nav').toggleClass('open');
$('.cross').toggleClass('open');
});
$('.has-child').click(function(){
if ( window.innerWidth < 768 ) {
if ( $( this ).hasClass('selected')){
$('.has-child').removeClass('selected');
} else {
$('.has-child').removeClass('selected');
$(this).toggleClass('selected');
}
}
});
Can anyone give me advice on how to make the drop down menu horizontal?
So described in the comment. The problem can be fixed with CSS as shown in the fiddle
This is what I would call a fix. But the way I would think is the proper way, would be to create a CSS class instead of override the bootstrap CSS.
When overriding the bootstap class, you also create a problem. if you would like to use two navbar's and the one needs the horizontal dropdown menu while the other needs the default CSS. The CSS override would effect both. But if you create a class you could use it on only the one element.
Hope this makes sense. Hard to spell check it from the mobile.

Listview populates on first load, but not if you visit page by clicking a link

I'm just learning Adobe Air with JQuery, and I'm using some sample code from a Sitepoint tutorial. I've encountered a rather unusual problem. If I view the page with the list view by using the "Preview in Adobe Air" option in Dreamweaver, it populates fine. If I navigate away from the page and come back to it, the listview doesn't populate, and the rest of the javascript on the page stops working.
This is the code for populating the listview:
function ListNotes() {
var notes = GetNotes();
$("#notes").empty();
var numRecords = notes.data.length;
for (i=0;i<numRecords;i++) {
$('#student-list').append("<li><a href=\"#\">"+unescape(notes.data[i].name)+" "+unescape(notes.data[i].lastseen)+"<br \/>"+unescape(notes.data[i].belt)+"<br \/>Last Session: <\/a><\/li>");
}
$('#student-list').listview('refresh');
$(".note_time a").click(function(){
var currHash = $(this).attr("href").split('/');
var id = currHash[1];
var dbQuery = new air.SQLStatement();
dbQuery.sqlConnection = db;
dbQuery.text = "DELETE FROM students WHERE id=" + id;
try {
dbQuery.execute();
} catch (error) {
air.trace("Error deleting note from DB:", error);
air.trace(error.message);
return;
}
ListNotes();
});
}
The listview goes inside a div:
<div data-role="content" data-theme="a"><ul data-role="listview" data-inset="true" id="student-list" data-filter="true"></ul></div>
There's a snippet in notes.js that populates the listview:
$(document).ready(function(){
BindEvents();
CreateMenus();
SetupDB();
ListNotes();
});
The page works fine on first loading via "Preview in Adobe Air", but doesn't work at all if you navigate to it via clicking a button inside the app. I suspect I'm missing something really obvious but would appreciate any tips.
Thanks
I would try this:
$(".note_time a").on('click', function(){
//your code here
});

Backbone/Marionette: Adding view events to a dynamically added view for a bootstrap modal

I've got a Marionette layout and for demo purposes the html looks like:
<header id="header-region" class="page-title"></header>
<section id="template-content" class="full-section">
<div id="error-messages" class="fade main-section"><!-- errors --></div>
<div id="content-region"> </div>
</section>
Its layout view's regions are:
regions: {
header: "#header-region",
content: "#content-region"
}
Up until now, I've had any given page's modal html inside the page's template html which would be contained in the content region.
I have an idea to now create a separate region for modals to be shown in.
Changing things to look like this:
Template:
<section id="template-content" class="full-section">
<div id="error-messages" class="fade main-section"><!-- errors --></div>
<div id="content-region"> </div>
<div id="modal-region"></div>
</section>
And the region:
regions: {
header: "#header-region",
content: "#content-region",
modal: "#modal-region"
}
So I'd like to be able to do something like this:
// Controller
define([], function(){
initialize: function(){},
showHeaderView: function(){
this.HeaderView = new HeaderView();
this.layout.header.show(this.HeaderView);
},
showContentView: function(){
// this.BodyView's template used to contain the modal html
this.BodyView = new BodyView();
this.layout.content.show(this.BodyView);
},
showModalView: function(){
this.ModalView = new ModalView();
this.layout.modal.show(this.ModalView);
}
});
This works and renders the modal properly but the modal's events are lost because they were originally set by this.BodyView.
The modal has a checkbox that on change runs a function that is on this.BodyView but I want to bind the events for this.ModalView from this.BodyView.
How can I accomplish that? I've tried making this.ModalView's el the same as this.BodyView's but that breaks things. I've tried to use delegateEvents as well but with no luck.
This screencast does exactly what you want: http://www.backbonerails.com/screencasts/building-dialogs-with-custom-regions
Code is here: https://github.com/brian-mann/sc01-dialogs
If you are having the HeaderView as ItemView(or CollectionView/CompositeView) in it, you can instantiate it with passing arguments like
new HeaderView({events:{
"click .x" : function(){} // your function in-line or reference
});
So same applies to ModalView.

Pull down to refresh in Kendo-UI, text overlaps showing both "release" and "pull" labels

I have a problem with the pull down refresh. It works the first time, but then if I change to a different view, then come back to the original view, the Pull to refresh and Release to refresh text seem to get duplicated and overlapped on itself. I am "hardcoding" the datasource's data here, I don't want to use the transport ajax.
I am trying to manually update the data in the setOptions pull method, instead of letting Kendo update it via ajax. The actual data update works. There are no Javascript errors and I get the same result in Chrome and Firefox.
First time works:
After moving to another view, then back to this view, then pulling down:
My view code is:
<div id="subitem-view" data-role="view" data-show="showSubItems">
<div data-role="header">
<div data-role="navbar">
</div>
</div>
<ul id="subItemList" class="itemList">
</ul>
<script id="subItemTemplate" type="text/x-kendo-template">
#:Name#
</script>
</div>
Javascript:
function showSubItems(e) {
var subItems = new kendo.data.DataSource({
data: [
{ Name : "Test1" },
{ Name : "Test2" }
]
});
e.view.element.find("#subItemList").kendoMobileListView({
dataSource: subItems,
pullToRefresh: true,
template: kendo.template($("#subItemTemplate").html())
});
if (typeof (e.view.scroller.pull) == "undefined") {
e.view.scroller.setOptions({
pull: function () {
console.log("pull event...");
subItems.data([
{ Name : "Test1 Updated" },
{ Name : "Test2 Updated" }
]);
setTimeout(function () { e.view.scroller.pullHandled(); }, 400);
}
});
}
}
You're initializing your Kendo UI Mobile ListView on every View show which leads to unpredictable results, like recreating the pull to refresh labels. You should do it in the Init event only.

Detect change in hash value of URL using JavaScript

I'm working on a simple application which is single page based (due to project restrictions) and has dynamic content. I understand the dynamic content alright but what I don't understand is how to set-up a script that changes the html of a div when the hash value in the URL changes.
I need a JavaScript script to work as such:
Url: http://foo.com/foo.html div contents: <h1>Hello World</h1>
Url: http://foo.com/foo.html#foo div contents: <h1>Foo</h1>
How would this work?
Please help! Thanks.
You can listen to the hashchange event:
$(window).on('hashchange',function(){
$('h1').text(location.hash.slice(1));
});
personally, I'd use sammy which gives you the flexibility to template the hashtag (add placeholders and be able to read them back). e.g.
<script src="/path/to/jquery.js"></script>
<script src="/path/to/sammy.js"></script>
<script>
$(function(){
// Use sammy to detect hash changes
$.sammy(function(){
// bind to #:page where :page can be some value
// we're expecting and can be retrieved with this.params
this.get('#:page',function(){
// load some page using ajax in to an simple container
$('#container').load('/partial/'+this.params['page']+'.html');
});
}).run();
});
</script>
Load foo.html
Load bar.html
An example can be found here: http://jsfiddle.net/KZknm/1/
Suppose we have list of items, each items has a hash tag as #id
const markup = `
<li>
<a class="results__link" href="#${recipe.recipe_id}">
<figure class="results__fig">
<img src="${recipe.image_url}" alt="${limitRecipeTitle(recipe.title)}">
</figure>
<div class="results__data">
<h4 class="results__name">${recipe.title}</h4>
<p class="results__author">${recipe.publisher}</p>
</div>
</a>
</li>
`;
Now when a user click on any of those list item or reload (http://localhost:8080/#47746) an item with hash tag, hash event will be fired. To recive the fired hash event we must register hash event listener in our app.js
//jquery:
['hashchange', 'load'].forEach(event => $(window).on(event, controlRecipe));
//js:
['hashchange', 'load'].forEach(event => window.addEventListener(event, controlRecipe));
catch the id in your controlRecipe function
const controlRecipe = async ()=>{
//jq
const id = $(window)..location.hash.replace('#','');
//js
const id = window.location.hash.replace('#','');
if(id){
//console.log(id);
state.recipe = new Recipe(id);
try {
await state.recipe.getRecipe();
state.recipe.calcTime();
state.recipe.calcServings();
console.log(state.recipe);
} catch (error) {
alert(error);
}
}
}

Categories