Load partial view in a modal pop-up window using jquery - partial-views

I have images that are loaded from database. When I click on an image, I want to show that image in a Modal Pop-up. My problem is that, I am not able to call the partial view from jquery. In fact, that action is not getting called from JQuery. Please help... I am a fresher. Below is my code:
_Layout.cshtml
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>_Layout</title>
#Styles.Render("~/bundle/ProfileStyle")
#Scripts.Render("~/bundle/JQuery")
#Scripts.Render("~/bundle/JQueryUI")
#Scripts.Render("~/bundle/CustomJS")
</head>
<body>
<div>
#RenderBody()
</div>
<div id="dialog">
#Html.Partial("_ProfileDetail")
</div>
</body>
</html>
Index.cshtml
#model IEnumerable<Profile.Models.TestProfile>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<div class="tableOuterBlock">
#foreach (var item in Model)
{
<div class="tableInnerBlock">
<span>
#*<a href="#Url.Action("Edit", "Profile", new {#item.upi_Id})">*#
<img id="imgOpenDialog" src="#Url.Content(#item.upi_ImgData)" alt="No Image" width="100" height="100" />
#*</a>*#
</span>
</div>
}
</div>
Partial view
#model Profile.Models.TestProfile
<div>
#if(Model != null)
{
<img id="imgOpenDialog" src="#Url.Content(#Model.upi_ImgData)" alt="No Image" width="80%" height="50%" />
}
</div>
JQuery
$(function () {
$("[id*=imgOpenDialog]").click(function () {
var imgDetail = $(this).prop("src");
$("#dialog").dialog({
autoOpen: true,
position: { my: "center" },
modal: true,
resizable: false,
open: function () {
//parameter to c# function
data: { strImg = imgDetail }
$(this).load('#Url.Action("ShowProfileDetail","Profile")');
}
});
});
});
Controller
public PartialViewResult ShowProfileDetail(string strImg)
{
strImg = strImg.Substring(strImg.IndexOf('/'));
List<TestProfile> tpList = db.TestProfiles.Where(x => x.upi_ImgData ==strImg).ToList();
TestProfile testProfile = db.TestProfiles.Find(tpList[0].upi_Id);
return PartialView("_ProfileDetail", testProfile);
}

it may be a bit late but if you check out this blog, and download his code, you will see his use of jquery to create a modal pop up from a partial view.

Related

Ionic - show splash screen until the first image loads

I have an app in Ionic v.1 and on page where I have a list of articles, I would like to have a splash screen until the first image is completely loaded, not sure how to do that?
This is the controller:
module.exports = angular.module('coop.controllers')
.controller('ArticlesController', function($scope, ArticleService, $state, $ionicScrollDelegate, $location, $ionicPosition, $ionicConfig) {
$scope.articles = ArticleService.all();
$scope.$on('$ionicParentView.afterEnter', function(event, data) {
$scope.videoPlaying = [];
$ionicConfig.views.swipeBackEnabled(false);
if (data.direction == 'back') {
$scope.doRefresh();
}
});
$scope.articleType = 'all';
$scope.articleFilter = function(button) {
$scope.articleType = button;
$scope.doRefresh();
};
$scope.showBulletPoint = function(which) {
return $scope.articleType == which;
}
$scope.like = function(article){
article.userLiked = !article.userLiked;
ArticleService.like(article)
};
$scope.doRefresh = function (){
var articleType = $scope.articleType ? $scope.articleType : 'all';
ArticleService[articleType]().$promise.then(function(data){
$scope.articles = data;
}).finally(function() {
$scope.$broadcast('scroll.refreshComplete');
});
};
$scope.videoPlaying = [];
$scope.playerVars = {
controls: 0,
showinfo: 0
};
$scope.playVideo = function(youtubePlayer, index) {
$scope.videoPlaying[index] = true;
youtubePlayer.playVideo();
};
$scope.$on('$ionicView.afterLeave', function(event, data) {
$scope.videoPlaying = false;
$ionicConfig.views.swipeBackEnabled(true);
//youtubePlayer.stopVideo();
});
});
And this the html:
<ion-view>
<div class="row articles-header">
<button menu-toggle="left" class="button button-icon icon ion-navicon-round"></button>
<div class="right-icons">
<!--<a class="button button-icon icon ion-ios-search-strong">
</a>-->
<a class="button button-icon" href="#" ng-click="articleFilter('all')"><i class="ion-ios-circle-filled" ng-show="showBulletPoint('all')"></i> Siste
</a>
<a class="button button-icon" href="#" ng-click="articleFilter('video')"><i class="ion-ios-circle-filled" ng-show="showBulletPoint('video')"></i> Video
</a>
<a class="button button-icon" href="#" ng-click="articleFilter('popular')"><i class="ion-ios-circle-filled" ng-show="showBulletPoint('popular')"></i> Populært
</a>
</div>
</div>
<ion-content class="articles-content">
<ion-refresher pulling-icon="false" on-refresh="doRefresh()">
</ion-refresher>
<ion-list>
<ion-item ng-repeat="article in articles" class="item-light">
<div class="article">
<a ng-if="authenticated" ng-show="article.external_media.length == 0" ui-sref="main.article({id: article.id})" nav-direction="forward" class="article-image-link">
<img class="img" src="{{ fileServer }}/imagecache/cover/{{article.cover_image}}">
<h1>{{ article.title.split(' ', 7).join(' ') }}</h1>
</a>
<a ng-if="!authenticated" ng-show="article.external_media.length == 0" ui-sref="main.articlePublic({id: article.id})" nav-direction="forward" class="article-image-link">
<img class="img" src="{{ fileServer }}/imagecache/cover/{{article.cover_image}}">
<h1>{{ article.title.split(' ', 7).join(' ') }}</h1>
</a>
<a ui-sref="main.article({id: article.id})">
<div class="iframe" ng-show="article.external_media.length > 0 && article.external_media.image != ''">
<img class="img" ng-src="{{ article.external_media[0].image }}">
<h1>{{ article.title.split(' ', 7).join(' ') }}</h1>
<div class="iframe-overlay">
<div class="play">
<img class="playButton" src="icons/playRectangle.svg"/>
</div>
</div>
</div>
</a>
</div>
<div class="row article-meta" ng-class="{ 'has-comments': article.enable_comments }">
<a ng-click="like(article)" class="subdued col col-30">
<img class="social-images" ng-src="icons/{{ article.userLiked ? 'heart' : 'heart-outline' }}.svg"/> Lik
</a>
<a ui-sref="main.article({id: article.id, gotoComments: true })" class="subdued col col-60" ng-if="article.enable_comments">
<img class="social-images" src="icons/comment.svg"/> {{ article.commentCount }} Kommentarer
</a>
<a ui-sref="main.article({id: article.id})" nav-direction="forward" class="col col-10 article-link right">
<img class="social-images" src="icons/arrow.svg"/>
</a>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
One approach is to attach an onLoad handler to the images, and when the first image (or any other specific image, all, etc) have loaded you can remove your splash screen.
To do this we'll create a directive to handle the onload event, based on this outstanding solution from Peter, combined with the $ionicLoading loader.
var app = angular.module('app', ['ionic'])
app.controller('appCtrl', function($scope, $timeout, $ionicLoading) {
// Setup the loader
$ionicLoading.show({
content: 'Loading',
animation: 'fade-in',
showBackdrop: true,
maxWidth: 200,
showDelay: 0
});
// Add a simple onLoad callback
$scope.onLoad = function (id) {
if (id === 0) {
$ionicLoading.hide();
}
}
$scope.items = [
{img: 'http://placehold.it/5000x8000/f9009a/ffffff'},
{img: 'http://placehold.it/5000x8000/f9009a/ffffff'},
{img: 'http://placehold.it/5000x8000/f9009a/ffffff'}
];
});
// The imageonload directive
app.directive('imageonload', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('load', function() {
//call the function that was passed
scope.$apply(attrs.imageonload);
});
}
};
})
Then use the directive:
<ion-item ng-repeat="item in items" href="#">
<img ng-src="{{item.img}}" imageonload="onLoad({{$index}})" id="img-{{$index}}" />
</ion-item>
When the app loads the $ionicLoading screen will be shown until the first image emits the onload event, causing the $ionicLoading screen to be removed.
For a working demo, see this Ionic Play demo.
The loading screen may only be noticeable the first time you load the demo, and on subsequent loads you might need to do a hard refresh.

Polymer conditional class derived from child component

I'm learning Polymer;
I can't get a conditional class name to appear in my tabs (parent) component. A 'active' class should be added to a <li> element depending on the 'selected' property of a child component.
I'm not really sure my way of communicating between parent and child component is right in the first place. It is working, but it doesn't feel right..
My index.html file
<link rel="import" href="components/tabs.html">
<link rel="import" href="components/tab.html">
<ikb-tabs>
<ikb-tab heading="Tab #1">
<p>Content of the first tab</p>
</ikb-tab>
<ikb-tab heading="Tab #2" selected>
<p>Content of the second tab</p>
</ikb-tab>
</ikb-tabs>
My components/tabs.html file
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="ikb-tabs">
<template>
<style>
.active button {
color: red;
}
</style>
<nav>
<ul>
<template is="dom-repeat" items="{{tabs}}">
<li>
<button on-tap="openTab">{{item.heading}}</button>
</li>
</template>
</ul>
</nav>
<content></content>
</template>
<script>
Polymer({
is: 'ikb-tabs',
properties: {
activeTab: Number
},
ready: function () {
this.tabs = Polymer.dom(this).children;
},
openTab: function (e) {
Polymer.dom(this).children.forEach(function (tab, index) {
tab.selected = index === e.model.index;
});
}
});
</script>
</dom-module>
My components/tab.html file
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="ikb-tab" attributes="heading">
<template>
<template is="dom-if" if="{{selected}}">
<div>
<content></content>
</div>
</template>
</template>
<script>
Polymer({
is: 'ikb-tab',
properties: {
heading: String,
selected: {
type: Boolean
}
}
});
</script>
</dom-module>
I've figured it out myself, there were two main issues with my code:
Updating an Array didn't trigger an update:
Only adding, removing are replacing items in an Array triggers an update. I changed a property of an Object inside an Array. Polymer only checks the reference to that Object, that reference remained unchanged. So no change got triggered. Solution: update the Array with the set function (see code below).
Computed classes need a special syntax:
My class="{{getClassName(item.selected}}" wasn't adding any classes. I now know the correct syntax is class$="{{getClassName(item.selected)}}".
More info: https://www.polymer-project.org/1.0/docs/devguide/data-binding#native-binding
The simplified working code:
<dom-module id="ikb-tabs">
<template>
<nav>
<ul>
<template is="dom-repeat" items="{{tabs}}">
<li class$="{{getClassName(item.selected)}}">
<button on-tap="openTab">{{item.heading}}</button>
</li>
</template>
</ul>
</nav>
<div>
<content></content>
</div>
</template>
<script>
Polymer({
is: 'ikb-tabs',
properties: {
tabs: {
type: Array
}
},
ready: function () {
this.tabs = Polymer.dom(this).children;
},
openTab: function (e) {
var self = this;
this.tabs.forEach(function (tab, index) {
self.set('tabs.' + index + '.selected', index === e.model.index)
});
},
getClassName: function (isSelected) {
return isSelected ? 'active' : null;
}
});
</script>
</dom-module>

Error submitting form data using knockout and mvc

#model NewDemoApp.Models.DemoViewModel
#{
ViewBag.Title = "Home Page";
}
#*<script src="#Url.Content("~/Scripts/jquery-1.9.1.min.js")" type="text/javascript"></script>*#
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="#Url.Content("~/Scripts/knockout-3.3.0.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
var viewModel;
var compViewModel, userViewModel;
$(document).ready(function () {
$(".wizard-step:visible").hide();
$(".wizard-step:first").show(); // show first step
$("#back-step").hide();
var result = #Html.Raw(Json.Encode(Model));
var viewModel = new DemoViewModel(result.userViewModel);
//viewModel.userViewModel.FirstName = result.userViewModel.FirstName;
//viewModel.userViewModel.LastName = result.userViewModel.LastName;
//viewModel.userViewModel.State = result.userViewModel.State;
//viewModel.userViewModel.City = result.userViewModel.City;
ko.applyBindings(viewModel);
});
var userVM = function(){
FirstName = ko.observable(),
LastName = ko.observable(),
State = ko.observable(),
City = ko.observable()
};
function DemoViewModel(data) {
var self = this;
self.userViewModel = function UserViewModel(data) {
userVM.FirstName = data.FirstName;
userVM.LastName = data.LastName;
userVM.State = data.State;
userVM.City = data.City;
}
self.Next = function () {
var $step = $(".wizard-step:visible"); // get current step
var form = $("#myFrm");
var validator = $("#myFrm").validate(); // obtain validator
var anyError = false;
$step.find("input").each(function () {
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
if (anyError)
return false; // exit if any error found
if ($step.next().hasClass("confirm")) { // is it confirmation?
$step.hide().prev(); // hide the current step
$step.next().show(); // show the next step
$("#back-step").show();
$("#next-step").hide();
//$("#myFrm").submit();
// show confirmation asynchronously
//$.post("/wizard/confirm", $("#myFrm").serialize(), function (r) {
// // inject response in confirmation step
// $(".wizard-step.confirm").html(r);
//});
}
else {
if ($step.next().hasClass("wizard-step")) { // is there any next step?
$step.hide().next().fadeIn(); // show it and hide current step
$("#back-step").show(); // recall to show backStep button
$("#next-step").show();
}
}
}
self.Back = function () {
var $step = $(".wizard-step:visible"); // get current step
if ($step.prev().hasClass("wizard-step")) { // is there any previous step?
$step.hide().prev().fadeIn(); // show it and hide current step
// disable backstep button?
if (!$step.prev().prev().hasClass("wizard-step")) {
$("#back-step").hide();
$("#next-step").show();
}
else {
$("#back-step").show();
$("#next-step").show();
}
}
}
self.SubmitForm = function (formElement) {
$.ajax({
url: '#Url.Content("~/Complaint/Save")',
type: "POST",
data: ko.toJS(self),
done: function (result) {
var newDiv = $(document.createElement("div"));
newDiv.html(result);
},
fail: function (err) {
alert(err);
},
always: function (data) {
alert(data);
}
});
}
self.loadData = function () {
$.get({
url: '#Url.Content("~/Complaint/ViewComplaint")',
done: function (data) {
debugger;
alert(data);
self.compViewModel(data);
self.userViewModel(data);
},
fail: function (err) {
debugger;
alert(err);
},
always: function (data) {
debugger;
alert(data);
}
});
}
}
</script>
<form class="form-horizontal" role="form" id="myFrm">
<div class="container">
<div class="row">
<div class="col-md-3">
</div>
<div class="col-md-6">
<div class="wizard-step">
</div>
<div class="wizard-step" >
<h3> Step 2</h3>
#Html.Partial("UserView", Model.userViewModel)
<div class="col-md-3"></div>
<div class="col-md-6">
<input type="submit" id="submitButton" class="btn btn-default btn-success" value="Submit" data-bind="click: SubmitForm" />
</div>
<div class="col-md-3"></div>
</div>
<div class="wizard-step">
<h3> Step 3</h3>
</div>
<div class="wizard-step confirm">
<h3> Final Step 4</h3>
</div>
</div>
<div class="col-md-3"></div>
</div>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-6">
<input type="button" id="back-step" class="btn btn-default btn-success" value="< Back" data-bind="click: Back" />
<input type="button" id="next-step" class="btn btn-default btn-success" value="Next >" data-bind="click: Next" />
</div>
<div class="col-md-3"></div>
</div>
</div>
</form>
I am able to get the data from controller and bind it using knockout. There is a partial view that loads data from controller. But when submitting the updated data, I do not get the data that was updated, instead getting error that "FirstName" property could not be accessed from null reference. I just need to get pointers where I am going wrong especially the right way to create ViewModels and use them.
When you are submitting the form in self.SubmitForm function you are passing Json object which is converted from Knockout view model.
So make sure you are providing the data-bind attributes in all input tags properly. If you are using Razor syntax then use data_bind in Html attributes of input tags.
Check 2-way binding of KO is working fine. I can't be sure as you have not shared your partial view Razor code.
Refer-
http://knockoutjs.com/documentation/value-binding.html
In Chrome you can see what data you are submitting in Network tab of javascript developer console. The Json data that you are posting and ViewModel data structure you are expecting in controller method should match.
You can also change the parameters to expect FormCollection formCollection and check what data is coming from browser when you are posting.

Multiple popup windows on same page?

I have a popup window that pops up when someone click on a button. The problem is that I want to have 6 buttons that will display different content but use the same style which doesn't work for me. Here is my current code (I found it on another post a few days ago):
JSFiddle: http://jsfiddle.net/j4c7U/
CSS:
#overlay {
display:none;
position:fixed;
left:0px;
top:0px;
width:100%;
height:100%;
background:#000;
opacity:0.5;
z-index:99999;
}
#popup {
display:none;
position:fixed;
left:50%;
top:50%;
width:300px;
height:150px;
margin-top:-75px;
margin-left:-150px;
background:#FFFFFF;
border:2px solid #000;
z-index:100000;
}
HTML:
<button id="LearnMoreBtn">Learn More</button>
<div id="overlay"></div>
<div id="popup">
Popup contents here
<button id="CloseBtn">ClosePopup</button>
</div>
<div>
some other content that will be behind the popup
</div>
Javascript:
window.onload = function() {
document.getElementById("LearnMoreBtn").onclick = function(){
var overlay = document.getElementById("overlay");
var popup = document.getElementById("popup");
overlay.style.display = "block";
popup.style.display = "block";
};
document.getElementById("CloseBtn").onclick = function(){
var overlay = document.getElementById("overlay");
var popup = document.getElementById("popup");
overlay.style.display = "none";
popup.style.display = "none";
}
};
I don't know if I completely understand the problem. Here is my JSFiddle with what I believe you're asking for.
Here is the resulting HTML:
<button id="LearnMoreBtn">Learn More</button>
<button id="LearnMoreBtn2">Learn More2</button>
<div id="overlay"></div>
<div id="popup">
Popup contents here
<button id="CloseBtn">ClosePopup</button>
</div>
<div id="popup2">
Popup2 contents here
<button id="CloseBtn2">ClosePopup</button>
</div>
<div>
some other content that will be behind the popup
</div>

MVC2 ajax partial view does not register jquery scripts

I have my page where i have ajax call to display form.
My code works when the register the code for form but not from postback (validation error in controller).
any idea how to fix this?
My container page has:
Scripts:
<%= Html.JQuery() %>
<script src="../../../../Scripts/jquery.ui.core.js" type="text/javascript"></script>
<script src="../../../../Scripts/jquery.ui.datepicker.min.js" type="text/javascript"></script>
<script src="../../../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../../../Scripts/MicrosoftMvcAjax.js" type="text/javascript">/script>
<script src="../../../../Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>
<script type="text/javascript">
function registerStuff() {
//this gets triggered when onsuccess is called
$("#date").datepicker({ dateFormat: 'dd/mm/yy' });
$("#sla").datepicker();
}
</script>
Content:
<%= Ajax.AjaxButton("New action", "CreateWorkFlowAction", new {
controller = "CaseWorkFlow" }, new AjaxOptions() { UpdateTargetId =
"divTableContainer", HttpMethod = "Get", OnSuccess =
"registerStuff"})%>
<div id="divTableContainer">
response will appear here
</div>
my form looks like
<script type="text/javascript">
function RegisterJs() {
$("#date").datepicker({ dateFormat: 'dd/mm/yy' });
$("#sla").datepicker({ dateFormat: 'dd/mm/yy' });
}
</script>
<% Html.EnableClientValidation(); %>
<% using (Ajax.BeginForm("CreateWorkFlowAction", new AjaxOptions() { UpdateTargetId = "divTableContainer", HttpMethod = "Post" }))
{%>
<%= Html.ValidationSummary() %>
<fieldset>
<div>
<label for="title">
Title</label>
<%= Html.TextBoxFor(x=>x.Title) %>
</div>
<div>
<label for="SLA">
SLA(Due Date)</label>
<%= Html.TextBoxFor(x => x.SelectSlaDate, new { id = "sla", #Value = string.Empty} )%>
</div>
<div>
<label for="date">
Date</label>
<%= Html.TextBoxFor(x => x.SelectDate, new { id = "date", #Value = string.Empty})%>
</div>
<div>
<button type="submit">Save action</button>
</div>
</fieldset>
<% } %>
the problem is
i have found the solution to my question.
I have to reregister my javascript inside of a partial view.
this means that i had to update add register scripts into the parent page to which i will insert partial view.
and therfore if my view page contains partial view i had to move
function registerStuff() {
//this gets triggered when onsuccess is called
$("#date").datepicker({ dateFormat: 'dd/mm/yy' });
$("#sla").datepicker();
}
to the index page.
After on success call this function "registerStuff" from my oncomplete,
and after then everything is working like charm
hope this helps to you too