I'm using jCaptcha (http://jcaptcha.sourceforge.net/) on our website. The problem is sometimes it's very difficult to read the image. So, we are planning to provide a button named 'REFRESH' next to the jcaptcha image and upon clicking REFRESH button, it has to refresh only the jcaptcha image not the entire page/portlet. How can we do that?
This is how I solved it using JQuery, it will replace the image. The alert() is just there to show off the new filename and can of course be removed. The code is using the jquery plugin in grails but shows what to do in jquery to refresh the image.
<div>
<jcaptcha:jpeg name="captchaImage"/>
Refresh captcha
<jq:jquery>
$("#refreshCaptcha").click(function() {
$("#captchaImage").fadeOut(500, function() {
var captchaURL = $("#captchaImage").attr("src");
captchaURL = captchaURL.replace(captchaURL.substring(captchaURL.indexOf("=")+1, captchaURL.length), Math.floor(Math.random()*9999999999));
alert(captchaURL);
$("#captchaImage").attr("src", captchaURL);
});
$("#captchaImage").fadeIn(300);
});
</jq:jquery>
</div>
Make this changes in JSP :
<img src="jcaptcha" id="captcha_image"/> Refresh
Add the Javascript function like :
function reloadCaptcha(){
var d = new Date();
$("#captcha_image").attr("src", "jcaptcha?"+d.getTime());
}
You would have to load the image and the refresh button into . Than you should be able to refresh just the iframe. But the I don't know how you are performing your validation so.
Set an id for the img tag and let it call a javascript function:
<img src="jcaptcha.jpg" id="captchaImage"/>
javascript function:
<script type="text/javascript">
function refresh()
{
var captchaImage=document.getElementById("captchaImage");
captchaImage.src="jcaptcha.jpg";
}
</script>
this works fine because i implemented this one in my project just create one button on clicking that button it will come to below menctiond block of code like that you do
<script type="text/javascript">
function refresh()
{
var image=document.getElementById("kaptchaImage");
image.src="<%=request.getContextPath()%>/kaptcha.jpg?"+Math.floor(Math.random()*100)
}
</script>
Related
I have a Vue component I'd like to print. When the user presses a print button, a function is called which opens the component in a new window to isolate the HTML, and get the formatting right.
async openPrintDetailsDialogue() {
const prtHtml = document.getElementById('printable').innerHTML;
let stylesHtml = '';
for (const node of [...document.querySelectorAll('link[rel="stylesheet"], style')]) {
stylesHtml += node.outerHTML;
}
var newWindow = window.open('', '', 'left=0,top=0,width=800,height=900,toolbar=0,scrollbars=0,status=0');
newWindow.document.write(`<!DOCTYPE html>
<html>
<head>
${stylesHtml}
</head>
<body id="printme">
${prtHtml}
</body>
</html>`);
newWindow.document.close();
newWindow.focus();
...
I then try to print using $htmlToPaper.
...
await this.$htmlToPaper('printme');
newWindow.close();
}
However, the main window alerts Element to print #printme not found!.
I add the plugin VueHtmlToPaper in my mounted() function:
mounted() {
Vue.use(VueHtmlToPaper);
}
I've already tried passing my existing styles.css to the $htmlToPaper() call options, which changed nothing. I also have some styles in my vue file's <style scoped>, which couldn't be included in the options parameter either.
How can I get VueHtmlToPaper to "point" to newWindow?
By opening a new window you have a new separate webpage, where is no Vue Js instance. It does not work so and you will not make it work this way. You should use a Modal, change the current page or make a new page with Vue instance for printing.
I'm using the client side javascript SDK to connect to soundcloud.
now i want to block all latest tracks in a widget.
if i'm using SC.Widget('frameid') i'll get an error: Widget is not a function
so i have to implement the second script (widget api)
Whether I load the script directly from soundcloud or download it
I get the error: e is null
I tried to load the sdk before the widget api
and I also tried to load the api in document.ready but I still get the same error.
For selecting the iframe I tried to get it via ID and document.getElementbyId(..)
but that still did not work
Can someone tell me the solution?
what i'm doing wrong?
Looks like you dont reference the scripts in a proper way.
I hope this sketch points you in the right direction:
JS
(function() {
var iframe2 = document.querySelector('#widget2');
var widget2 = SC.Widget(iframe2);
var newurl = 'http://soundcloud.com/bnzlovesyou';
widget2.bind(SC.Widget.Events.READY, function() {
alert('ready');
widget2.bind(SC.Widget.Events.PLAY, function(eventData) {
alert('Playing..');
});
widget2.bind(SC.Widget.Events.PAUSE, function(eventData) {
alert('PAUSE..');
});
});
$( "#changetrack" ).click(function() {
widget2.load(newurl);
});
}());
HTML
<iframe id="widget2" width="100%" src = 'http://w.soundcloud.com/player/?url=http://soundcloud.com/barehouse_1'>
</iframe>
<div id="changetrack">Change Track / URL to my account ;)</div>
http://jsfiddle.net/iambnz/wpe2zmLh/
I know that InfiniteScroll and Masonry work well together. But I am using the Infinite Scroll Extension of Yii (called yiinfinite-scroll) and tried to apply Masonry on it. Infinite Scroll for itself works perfectly, Masonry for itself too. But after InfiniteScroll tries to load a new set of images (I've got an image page), the callback part of InfiniteScroll doesn't seem to fire, because the newly appended elements don't have any masonry code in it and appear behind the first visible items. (I know that this bug is reported often, but the solutions I found so far didn't work for me).
My structure for showing the picture looks like this:
<div class="items">
<div class="pic">...</pic>
<div class="pic">...</pic>
...
</div>
The first page load looks like this
<div class="items masonry" style="...">
<div class="pic masonry-brick" ...></div>
<div class="pic masonry-brick" ...></div>
...
</div> // everything's fine, masonry is injected into the code
After infinite scroll dynamically loads new images these look like this:
<div class="items masonry" ...></div>
<div class="pic masonry-brick" ...></div>
...
// appended pics:
<div class="pic"></div>
<div class="pic"></div>
</div> // so no masonry functionality was applied
My Masonry Code:
$(function (){
var $container = $('.items');
$container.imagesLoaded(function(){
$container.masonry({
itemSelector: '.pic',
columnWidth: 405
});
});
});
$container.infinitescroll({
// normally, the options are found here. but as I use infinitescroll as a Yii extension, the plugin is already initiated with options
}
},
// trigger Masonry as a callback
function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now they're ready
$newElems.animate({ opacity: 1 });
$container.masonry( 'appended', $newElems, true );
});
});
});
I also tried to copy and replace the current InfiniteScroll-min.js file in the extension folder by the newest one. Same effect...
Best regards,
Sebastian
Okay I found a solution. I post it here if somebody else has the same issue:
I just modified the YiinfiniteScroller Class from the Yiinfinite Scroll Yii Extension and added the callback part for Infinite Scroll which was missing:
private function createInfiniteScrollScript() {
Yii::app()->clientScript->registerScript(
uniqid(),
"$('{$this->contentSelector}').infinitescroll(".$this->buildInifiniteScrollOptions().", ".$this->callback.");"
);
}
At the beginning of the class I added the line
public $callback;
to use it later in the method.
Then you can call the Widget with an additional option callback, for example like this:
'callback' => 'function( newElements ) {
// hide new items while they are loading
var $newElems = $( newElements ).css({ opacity: 0 });
// ensure that images load before adding to masonry layout
$newElems.imagesLoaded(function(){
// show elems now theyre ready
$newElems.animate({ opacity: 1 });
$(".items").masonry( "appended", $newElems, true );
});
}',
Works like charm.
I'm having problems trying to get the unobtrusive jquery validation to work with a partial view that is loaded dynamically through an AJAX call.
I've been spending days trying to get this code to work with no luck.
Here's the View:
#model MvcApplication2.Models.test
#using (Html.BeginForm())
{
#Html.ValidationSummary(true);
<div id="res"></div>
<input id="submit" type="submit" value="submit" />
}
The Partial View:
#model MvcApplication2.Models.test
#Html.TextAreaFor(m => m.MyProperty);
#Html.ValidationMessageFor(m => m.MyProperty);
<script type="text/javascript" >
$.validator.unobtrusive.parse(document);
</script>
The Model:
public class test
{
[Required(ErrorMessage= "required field")]
public int MyProperty { get; set; }
}
The Controller:
public ActionResult GetView()
{
return PartialView("Test");
}
and finally, the javascript:
$(doument).ready(function () {
$.ajax({
url: '/test/getview',
success: function (res) {
$("#res").html(res);
$.validator.unobtrusive.parse($("#res"));
}
});
$("#submit").click(function () {
if ($("form").valid()) {
alert('valid');
return true;
} else {
alert('not valid');
return false;
}
});
The validation does not work. Even if I don't fill any information in the texbox, the submit event shows the alert ('valid').
However, if instead of loading dynamically the view, I use #Html.Partial("test", Model) to render the partial View in the main View (and I don't do the AJAX call), then the validation works just fine.
This is probably because if I load the content dynamically, the controls don't exist in the DOM yet. But I do a call to $.validator.unobtrusive.parse($("#res")); which should be enough to let the validator about the newly loaded controls...
Can anyone help ?
If you try to parse a form that is already parsed it won't update
What you could do when you add dynamic element to the form is either
You could remove the form's validation and re validate it like this:
var form = $(formSelector)
.removeData("validator") /* added by the raw jquery.validate plugin */
.removeData("unobtrusiveValidation"); /* added by the jquery unobtrusive plugin*/
$.validator.unobtrusive.parse(form);
Access the form's unobtrusiveValidation data using the jquery data method:
$(form).data('unobtrusiveValidation')
then access the rules collection and add the new elements attributes (which is somewhat complicated).
You can also check out this article on Applying unobtrusive jquery validation to dynamic content in ASP.Net MVC for a plugin used for adding dynamic elements to a form. This plugin uses the 2nd solution.
As an addition to Nadeem Khedr's answer....
If you've loaded a form in to your DOM dynamically and then call
jQuery.validator.unobtrusive.parse(form);
(with the extra bits mentioned) and are then going to submit that form using ajax remember to call
$(form).valid()
which returns true or false (and runs the actual validation) before you submit your form.
Surprisingly, when I viewed this question, the official ASP.NET docs still did not have any info about the unobtrusive parse() method or how to use it with dynamic content. I took the liberty of creating an issue at the docs repo (referencing #Nadeem's original answer) and submitting a pull request to fix it. This information is now visible in the client side validation section of the model validation topic.
add this to your _Layout.cshtml
$(function () {
//parsing the unobtrusive attributes when we get content via ajax
$(document).ajaxComplete(function () {
$.validator.unobtrusive.parse(document);
});
});
test this:
if ($.validator.unobtrusive != undefined) {
$.validator.unobtrusive.parse("form");
}
I got struck in the same problem and nothing worked except this:
$(document).ready(function () {
rebindvalidators();
});
function rebindvalidators() {
var $form = $("#id-of-form");
$form.unbind();
$form.data("validator", null);
$.validator.unobtrusive.parse($form);
$form.validate($form.data("unobtrusiveValidation").options);
}
and add
// Check if the form is valid
var $form = $(this.form);
if (!$form.valid())
return;
where you are trying to save the form.
I was saving the form through Ajax call.
Hope this will help someone.
just copy this code again in end of modal code
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
;)
I'm opening a simple modal and making an Ajax call with the following function.
function TransactionModal($id, $s) {
jQuery("#dialog").load("/chat/rejoin", { 'id': +$id, 's': +$s }, function()
{
jQuery("#dialog").modal({
overlay:80,
autoResize:false,
containerCss: {width: "490px", height: "538px"},
overlayCss: {backgroundColor:"#000"}
});
});
}
Because I have some Javascript running in the page I want to load, I need to use iframes, so the rejoin page has the following in it.
<IFRAME SRC="/chat/join/id/<?php echo $id; ?>/cid/<?php echo $cid;?>" width="500" height="535">
<!-- Alternate content for non-supporting browsers -->
Upgrade Browser to support iframes
</IFRAME>
That all works great.
The problem that I'm having is that when I click on the close button, it is resubmitting form data.
I have no idea why but it's driving me nuts.
If I refresh the page the modal goes away and doesn't resubmit.
If I click the X image to close it it does resubmit.
Please help if you have any idea why it's doing this!
function rejoinModal($id) {
var src = '/chat/join/id/'+$id ;
jQuery.modal('<iframe src="' + src + '" height="555" width="510" style="border:0">', {
containerCss:{
backgroundColor:"#000",
height:555,
width:510,
overFlow: "hidden",
},
});
}
i solved it by not calling the iframe from withing the ajax call.
it is working now.