Hey frenz In my mvc 3 project i need a pop up box. Actually when the user click the edit button, I need to show the Edit View page as pop up box and save the edited data in database.
Simply, I need to replace the edit view page with edit pop up box.
I know that i need to use ajax and jquery. But confuse how to implement it.
So, Any idea about this will be greatly appreciated
I have also faced such type of situation and I preferred some style sheet instead of using any 3rd party control. I am writing sample code here.
<!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>
<html>
<head>
<title>LIGHTBOX EXAMPLE</title>
<style>
.black_overlay{
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 100%;
background-color: black;
z-index:1001;
-moz-opacity: 0.8;
opacity:.80;
filter: alpha(opacity=80);
}
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 50%;
height: 50%;
padding: 16px;
border: 16px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
</style>
</head>
<body>
<p>This is the main content. To display a lightbox click <a href = “javascript:void(0)” onclick = “document.getElementById(‘light’).style.display=’block’;document.getElementById(‘fade’).style.display=’block’”>here</a></p>
<div id=”light” class=”white_content”>This is the lightbox content. <a href = “javascript:void(0)” onclick = “document.getElementById(‘light’).style.display=’none’;document.getElementById(‘fade’).style.display=’none’”>Close</a></div>
<div id=”fade” class=”black_overlay”></div>
</body>
</html>
Onclick event you need to display user control in that div. I have used json object for that. Javascript code is like this.
function ShowPopups(cntrlId, controllerName, actionName, className, id) {
var url = controllerName + "/" + cntrlId;
elementId = id;
$.ajax(
{
type: "POST",
url: "/" + controllerName + "/" + actionName,
data: "Display=" + cntrlId,
dataType: "html",
success: function (result) {
removeClass('light1');
changeClass('light1', className);
document.getElementById('light1').style.display = 'block';
document.getElementById('fade1').style.display = 'block'
$("#light1").html(result);
}
});
}
function HidePopup() {
var url = document.location.hash;
document.getElementById('fade1').style.display = 'none';
document.getElementById('light1').style.display = 'none';
document.location.hash = url;
}
// To Add and Remove class using javascript
function removeClass(elementID) {
var element = document.getElementById(elementID);
element.className = '';
}
function changeClass(elementID, newClass) {
var element = document.getElementById(elementID);
element.className += newClass;
}
you can use JQuery model dialog box(use model form) it is really simple, Here is the documentation with examples. http://jqueryui.com/demos/dialog/#modal-form
I also recommend Jquery UI model dialog still you want to try out something else here is the list of Jquery Model PopUp Samples
So many of the other tutorials don't cover how to actually edit data, only how to show the dialog. When you try to post your form, the entire window will post and change.
jQuery ui's dialog method has some funny behavior at times, and validation won't work by default unless you parse newly loaded content.
With that said, the best overall code I've found recently is this solution here to handle the ajax loading and posting.
http://nickstips.wordpress.com/2011/08/11/asp-net-mvc-ajax-dialog-form-using-jquery-ui/
Related
Hi I'm working on a custom text editor, on a linux 64 machine (if it can help).
Since the javascript "document.execCommand" has been deprecated, I'm working with "selection" and "range" and other javascript objects and functions.
I'm using an external div (as textarea) with the attribute contenteditable = true.
Everything seems fine until the text editor generate, inside the main editable div, tags like: span, ol, li ...
In Firefox (Chrome, and Opera work fine) the editor let the user write inside the tag until he press enter to go to a new line.
At this point if the user try to get back (to correct something for example) these tags are not editable anymore.
I tried to give to those tags the same attribute contenteditable = true, but no luck;
The only way I can get back and edit them is by clicking with the mouse right button.
Any idea on how I can keep all the tags "contenteditable" inside the main div?
The file I'm working on is thousands of lines long so I simplified the problem in the snipped below.
/**
the text editor object
*/
function TextEditor( args ){
this.editorId = args.editorId;
this.container = document.querySelector('#' + this.editorId );
var self = this;
this.setOrderList = function(){
document.execCommand('insertorderedlist');
}
this.initialize = function(){
if( self.textArea.innerHTML === '' ){
var div = document.createElement('div');
self.textArea.appendChild(div);
}
}
if ( this.container ) {
this.textArea = this.container.querySelector('.text-area');
this.orderedList = this.container.querySelector('#orederd-list');
this.orderedList.addEventListener('click', this.setOrderList);
this.textArea.addEventListener('focus', this.initialize);
}
}
var args = {
editorId : 'container'
}
var editor = new TextEditor( args );
<div id="container">
<div id="buttons-container">
<ul id="buttons">
<li id="orederd-list" class="button"><i class="fas fa-list-ol"></i></li>
</ul>
</div>
<div class="text-area" contenteditable="true">
</div>
</div>
I found What's the problem is.
In the main style sheet I have the following instruction:
a, li, span, h1, h2, h3, h4, h5, h6, p{
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome and Opera */}
this instruction prevent users to select text from the website.
In Browsers like Chrome, Edge, Opera... this css instruction does not work inside "contenteditable" elements, while for some reason in Firefox it does.
For those interested, the I changed for the text editor main div the instruction:
-moz-user-select: none;
into:
-moz-user-select: text;
and now everything is fine.
I'm currently using GridMvc to display a list on an Ajax view using this code:
columns.Add()
.Titled("Host").Filterable(true).Encoded(false)
.Sanitized(false)
.RenderValueAs(LogonEvents => Html.ActionLink(LogonEvents.Host,
"Computers", new { computerName = LogonEvents.Host,
userName = LogonEvents.Name,
onclick = "showPageLoadingMessage()" }));
I'd like to use buttons rather than an ActionLink but I'm not sure how to pass the values to the next view.
You could just keep it simple and apply a CSS class to the htmlAttributes object.
Html.ActionLink("Button Name", "Index", null, new { #class="classname" })
and then create a class in your stylesheet
a.classname
{
background: url(../Images/image.gif) no-repeat top left;
display: block;
width: 150px;
height: 150px;
text-indent: -9999px; /* hides the link text */
}
Or code your own HTML Helper.
Hope my Question is enough clear. I own a website.
http://khchan.byethost18.com
My problem is in the tab "Calendar", it run properly in chrome, ie. but not in fixfox.
my design is that when I hover the calendar tab. the page of calendar will show.
but in firefox, when I do that, it don't show properly. developer tool show $bookblock.bookblock is not a function. If I reload the frame, such error message will not show.
If I directly load "http://khchan.byethost18.com/cal.php
It can show properly and such error message don't appear.
so I guess may be something is not load properly. I already try add $(top.document,document).ready({function(){}); or replace the jquery library to the head or body. the problem still exist.
since the coding is very long. I only write the iframe tag.Please try to use developer tool to view my code.
I tried document.getElementById('CalF').contentWindow.location.reload();
if I already hover the calendar tab, the tab can be reload properly.
but if not, the developer tool display the same error message.
so, I think the major key to the problem is that the jquery tab affect something so that the tab "CalF" can't work properly.
.boxoff{
display: none;
}
<article class='boxoff'> //this article will be hidden until I delete the class.
<iframe id=CalF src="cal.php" style="top: 0;"></iframe>
</article>
Thanks.
iframeLoaded()
Update 2
OP explained that the iframe must be invisible initially. While this may seem an impossibility since iframes do not load when it or one of it's ancestor elements are display: none;. The key word is invisible which is a state in which the iframe is not visible.... There are three CSS properties that come to mind and one of them is actually shouldn't be used in this situation.
display: none; This is the property being used by OP and this property actually hinders the iframe's loading. The reason why is when in that state of invisibility, the iframe is not in the DOM according to Firefox's behavior.
opacity: 0; This property renders the iframe invisible as well and Firefox seems to recognize the invisible iframe just fine.
visibility: hidden; This seems to be an acceptable as well....
So try this code that I use to suppress the FOUC:
Child Page
function init(sec) {
var ms = parseFloat(sec * 1000);
setTimeout('initFadeIn()', ms);
}
function initFadeIn() {
$("body").css("visibility","visible");
$("body").fadeIn(500);
}
HTML
<body style="visibility: hidden;" onload="init(2);">
Update 1
I made an alternative solution because I hate leaving a demo that doesn't completely work★.
Ok this relies on cal.php window.onload event which is basically the slowest but the most stablest phase of loading there is.
Initially, #overlay will block any user interaction while calF is loading.
Once calF is completely loaded, it will call iframeLoaded function that's located on the parent page.
iframeLoaded will remove #overlay (I added a setTimeout for good measure but it's probably not necessary.)
I'm not that familiar with PHP syntax, so you'll have to modify the following code✶ and place it in cal.php
window.onload = function() {
parent.iframeLoaded();
}
Then on the parent page:
function iframeLoaded() {
setTimeout(function() {
$('#overlay').hide(750);
}, 1500);
}
The code above as well as the required HTML and CSS is in the snippet below.
★ Note: The code in the snippet should work, but this snippet won't of course because there's some code that needs to be on the child page. That's just a shoutout to all the downvoters out there ;-)
Snippet 1
// iframeLoaded will remove the overlay when cal.php has completely loaded
function iframeLoaded() {
setTimeout(function() {
$('#overlay').hide(750);
}, 1500); //<========[1 to 2 (1000 - 2000ms) seconds should give you plenty of time]
}
/*~~~~~~~~~~~~~~~~~~~~~~~~[Code in cal.php]~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// When everything (DOM, script, images. etc...) is loaded on cal.php, call iframeLoaded function that is on the parent's page.
window.onload = function() {
parent.iframeLoaded();
}
#overlay {
background: rgba(0, 0, 0, .3);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
#CalF {
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="overlay"></div>
<iframe id="CalF" src="http://khchan.byethost18.com/cal.php" height="100%" width="100%" frameborder="0" style="top: 0;"></iframe>
✶ Function loadedIframe() inspired by SO5788723
Snippet 2
document.getElementById('CalF').onload = function(e) {
var over = document.getElementById('overlay');
over.classList.add('hide');
}
#overlay {
background: rgba(0, 0, 0, .3);
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
.hide {
display: none;
}
#CalF {
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="overlay"></div>
<iframe id="CalF" src="http://khchan.byethost18.com/cal.php" height="100%" width="100%" frameborder="0" style="top: 0;"></iframe>
$(document).ready seems to be called too soon, based on parent page instead of iframe content.
here you have solution to a similar problem:
jQuery .ready in a dynamically inserted iframe
User makes repeated queries against database over the course of the day; each time, the results are cleared from the table and new data are injected into the table:
<tbody data-bind="foreach: MyVM.Results">
and in code before the ajax call:
MyVM.Results.removeAll();
I want to display an animated spinner of some kind while the ajax call is underway (Edit: and then also when ko is still working on creating the table rows after the ajax call returns).
EDIT: What is "the knockout way" of displaying this animation when there's a standard ajax call with fail and success callbacks, and the tbody is foreach-bound to the observableArray Results?
EDIT2: configuring the Ajax call itself in jQuery with beforeSend and complete callbacks does not solve the problem entirely because taking UI action when the ajax call itself is complete does not account for the delay of knockout's for-each binding of the data to the table. is there a knockout event that signals "binding complete"?
EDIT3: The answers are not understanding the problem. My fault for trying to make it simple and leaving out a lot of code. This has nothing to do with Ajax. Consider this very simple scenario, which is exaggerated to make the problem clearer. Let's say you have an array with a million items in it. Ajax call is already completed! Now you want to get the items in that array into a ko observableArray to which your TABLE TBODY is bound with for-each binding. This binding process itself is going to take some seconds to complete We want to hide our animation after the binding has finished and something is displaying on the HTML page. Is there a way to know that the table rows created by knockout have begun to be rendered in the UI?
I developed a custom loading animation for doing this.
<!--Preloader-->
<div id="preloader">
<div class="preloader" data-bind="visible: _isShow">
<div class="loader-content">
<img src="img/ajax-loader.gif" alt="Loading.." style="margin: 0px auto 20px auto;">
<br>
<span class="loader-txt">Loading... Please wait....</span>
</div>
<!--End of loader-content-->
</div>
<!--End of preloader-->
</div>
CSS codes
/*****************Preloader******************/
.preloader {
background: rgba(0, 0, 0, 0.9);
width: 100%;
position: fixed;
z-index: 10000;
top:0;
bottom:0;
left:0;
right:0;
}
.preloader-hidden{
visibility: hidden;
}
.preloader .loader-content {
text-align: center;
top: 50%;
margin-top: -22px;
position: absolute;
left: 50%;
margin-left: -75px;
}
.loader-txt {
font-size: 14px;
color: #fff;
vertical-align: middle;
margin-left: 15px;
}
Javascript Code for preloader viewmodel
function PreloaderViewModel() {
var self = this;
self._isShow = ko.observable(false);
self.ShowPreloader = function() {
self._isShow(true);
};
self.HidePreloader = function() {
self._isShow(false);
};
}
Register the view model as bellow
var preloaderVM;
if ($.isEmptyObject(preloaderVM)) {
preloaderVM = new PreloaderViewModel();
ko.applyBindings(preloaderVM, document.getElementById("preloader"));
preloaderVM.HidePreloader();
}
Use it in ajax call like bellow.
//Show preloader
preloaderVM.ShowPreloader();
$.ajax({
type: "GET",
dataType: "json",
url: yourServiceUrl,
data: searchdata,
success: function (data) {
//do whatever in data return from ajax call
//Hide preloader
preloaderVM.HidePreloader();
},
error: function (error) {
console.log(error.responseText);
preloaderVM.HidePreloader();
}
});
If you want to change the text showing in pre-loader by defining a property on preloaderviewModel.
ko way is to use model to drive the view.
If the standard ko bindings are not enough (for instance, if gif animation is not enough for you), create a customised ko.bindingHandlers.
An idea ko app hides all DOM manipulation inside ko.bindingHandlers.
Here is a template that I use for ajax data loading.
HTML
<!-- ko if: loading -->
<!-- show spinner -->
<!-- /ko -->
<!-- ko ifnot: loading -->
<!-- show result, your data-bind="foreach: Results" -->
<!-- /ko -->
Javascript
//assume you use self to hold 'this' pointer in viewModel constructor
self.loading = ko.observable(false);
// in your data loading action
self.loadRemoteData = function() {
//start loading
self.loading(true);
$.ajax({
// ...
success: function(data) {
// update Results(data);
},
fail: function() { ...},
complete: function() {
//finish loading
self.loading(false);
}
});
};
I found the answer. Instead of looping through the Ajax data and adding an object to the ko observableArray on each iteration, I have to pop or shift() each item off the Ajax data array and push it onto the observableArray in a custom event using trigger(). The eventhandler invokes the custom event again and again while data contains items. Thus, the UI is not blocked but table rows begin to appear immediately.
In my case, the web app is running on an intranet, and the local database can return 10,000 rows on the LAN in the blink of an eye, but it takes a good number of seconds for all 10,000 rows to be created in the HTML Table using knockout for-each binding. With the event approach, the rows start becoming visible to the user instantly.
$(document).on("PushIt", function (event, data, results) {
var item = data.shift();
var Cust = new Customer(
item["firstname"],
item["lastname"],
item["addr1"],
item["city"],
item["state"],
item["zipcode"]
)
results.push(Cust);
if (data.length > 0) {
// timeout avoids recursion-limit problems
setTimeout(function () { $(document).trigger("PushIt", [data, results]); }, 1);
}
});
Is there a way of manually loading the view from within the controller, after say some animation was triggered first? The scenario I have is the previous page content sliding up, after that the view would be updated when being off-the screen and once ready - slides back down with the new view from the new controller.
I've got already the router set up, but it just instantly replaces the view whenever the new controller is called.
Any fiddle if possible please?
Code in Controller shouldn't manipulate DOM, directives should. Here is directive to prevent preloading content of element with "src" (by browser's parser) and show content of element only after loading, and before loading show splash with spinner:
directive('onloadSrc', function($compile) {
return function(scope, element, attrs) {
element.bind('load', function() {
var parent = $compile(element[0].parentElement)(scope);
if (!element.attr('src') && attrs.onloadSrc) {
element.attr("src", attrs.onloadSrc);
// replace this dirty hardcode with your template for splash spinner
var spinner_div = $compile('<div style="z-index: 100; width: '+element.attr('width')+'px; height: '+element.attr('height')+'px; display:block; vertical-align:middle;"><img src="/img/spinner.gif" style="position: absolute; left: 50%; top: 50%; margin: -8px 0 0 -8px;"/></div>')(scope);
attrs.onloadSrc = "";
parent.prepend(spinner_div);
element.css("display", 'none');
attrs.xloading = spinner_div;
}
else {
if (attrs.xloading) {
attrs.xloading.remove();
attrs.xloading = false;
element.css("display", 'block');
}
}
}
);
}});
To use this directive, leave empty attribute src of element and fill attribute onload-src.
Angular has animations build in in unstable branch, which should perfectly fit your scenario.
Just check out http://www.nganimate.org/angularjs/tutorial/how-to-make-animations-with-angularjs.
ng-view directive has build in 'enter' and 'leave' animations.
Check you this sample: http://jsfiddle.net/nFhX8/18/ which does more less what you'd like to achieve.