Calling magnific-popup on button element instead of an anchor - magnific-popup

I'm using magnific-popup to show a form getting the contents via ajax. This code works fine:
<a href="/entry-form" class="ajax-popup-link">
<button class="green">Enter Now</button></a>
...
<script>
$('.ajax-popup-link').magnificPopup({
type: 'ajax'
});
</script>
But according to HTML5 rules a <button> tag can't be in an <a> tag.
So I changed the html code to:
<button class="green" href="/entry-form" class="ajax-popup-link">Enter Now</button>
But the magnific-popup code doesn't recognize the href attribute on the <button> element.
How should I do this?

Probably too late to initial asker, but might help someone else...
No href attribute to button, you need to use "mfp-X" class names instead.
For me "mfp-inline" did the trick, but for ajax you need probably something like this:
<button class="ajax-popup-link mfp-ajax green" data-mfp-src="#div_element">Enter Now</button>
...
$('.ajax-popup-link').magnificPopup();
(Not sure if in ajax you need this, but there is also "data-mfp-src" attr that shows where dialog div is...)

I have another solution. You can make use of magnific-popup API for popup loaded via ajax:
<button data-ajax-popup-url="URL">Изменить</button>
...
$('[data-ajax-popup-url]').click(function() {
$.ajax({
url: $(this).data('ajax-popup-url')
})
.success(function(response, textStatus, request){
var popup = $(response);
$.magnificPopup.open({
items: {
src: popup, // can be a HTML string, jQuery object, or CSS selector
type: 'inline'
}
});
});
return false;
});

Not sure how to do this with Magnific. Have you considered/Are you using a Bootstrap template? If so, it has a nice modal dialog. Simple demo here. Hope this helps!

Related

TestCafe and grabbing an element/selector when no ID or CSS is present

Hello I have a simple page of our application, the start page that has a disclaimer on it and one button. Because of the technology we are using the IDs are stripped out and obfuscated.
So the button's name is 'ok' as it appears in the page-source view below. Note no ID. Even if I put it in our code, when it is produced the ID is removed.
<div style="text-align:center;">
<input type="button" name="ok" value="Ok" width="40" onclick="swap()" />
</div>
I have the following in my TestCafe js file:
import {Selector } from 'testcafe';
import { ClientFunction } from 'testcafe';
fixture `My fixture`
.page `http://192.168.2.86/mpes/login.jsp`;
test('Disclaimer Page 1', async t => {
const okBtn = Selector('button').withAttribute('ok');
await t
.click(okBtn);
});
test('Disclaimer Page 2 -- of course tried this ', async t => {
await t
.click('ok');
});
.click('ok') -- does not work either
Tried numerous things even trying findElementByName .. but nothing works with Window vs Document and Selector vs element.
Any help would be greatly appreciated.
I have been all over looking at how to grab selectors on TestCafe docs. None seem to fit this scenario which is quite simple -- but highly problematic.
Thanks in advance.
If you want to select this element:
<input type="button" name="ok" value="Ok" width="40" onclick="swap()" />
you can use (one or more) attribute selectors like this:
input[type="button"][name="ok"]
If only one element on the page has the attribute name="ok", you can grab that single element in javascript, using document.querySelector(), like this:
const myButton = document.querySelector('input[type="button"][name="ok"]');
N.B. If multiple elements on the page have the attribute name="ok", you can grab all of them in javascript, using document.querySelectorALL().

focus to field when bootstrap modal is opened

Neither works this one:
$formTemplateModal.modal('show');
$('#form_template_name').focus();
nor a more complicated one:
$formTemplateModal.modal('show').promise().done(function() {
// #todo: does not work.
$('#form_template_name').focus();
});
field $('#form_template_name') is a input[type=text] and it surely exists and it belongs to $formTemplateModal.
The shown is changed in bootstrap 3 ,
Try this if it could help
$('#myModal').on('shown.bs.modal', function () {
$('#textareaID').focus();
})
this is more easier try using the autofocus in your tag .
<textarea id="textareaID" autofocus="" ></textarea>

Yii Framework + Infinite Scroll + Masonry Callback not working

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.

Is there a way to disconnect an event added by dojoAttachEvent

I have a dojo widget which uses a a custom-library code having a link like this in its template.
Go Back
I need to find a way to disconnect this event from my widget. The only way i know how an event can be disconnected is, using a
dojo.disconnect(handle)
I could use this if I had the event connected using dojo,connect() which returns me the handle.
However with dojoAttachEvent i don't have the event handle hence no way to disconnect it.
Note :
Changing this html is not an option for me, since this an external library i am using.
Also, I am not looking for a solution to disconnect all events.
CODE:
otherWidget.js:
dojo.provide("otherWidget");
dojo.declare("otherWidget", [], {
templateString : dojo.cache("otherWidget","templates/otherWidget.html"),
_goBack: function(){
this.destroyWidgetAndRedirect();
},
destroyWidgetAndRedirect: function(){
//Code to destory and redirect.
},
});
otherWidget.html:
<div>
Go Back
<!-- Other Widget related code -->
...
</div>
myWidget.js:
dojo.provide("myWidget");
dojo.require("otherWidget");
dojo.declare("myWidget", [], {
templateString : dojo.cache("myWidget","templates/myWidget.html"),
this.otherWidget = new otherWidget({}, dojo.byId('otherWidgetContainer'));
});
myWidget.html:
<div>
<div id="otherWidgetContainer"></div>
<!-- My Widget related code -->
...
</div>
Any thoughts..
Thanks.
Extension points can be used directly on your html, or in javascript. Suppose the widget you are using is called 'my.custom.dojowidget', and that it has an onClick extension point. I will show here the declarative way, in your html. Try this :
<div data-dojo-type="my.custom.widget">
<script type="dojo/method" data-dojo-event="onClick" data-dojo-args"evt">
dojo.stopEvent(evt);
console.debug("did this work ?");
</script>
</div>
Now this depends on the existence of the extension point... if you can't still do what you want, please post the relevant parts of your widget's code.
So... based on the sample code you posted in your edit, I think you should do the following :
<div data-dojo-type="otherWidget">
<script type="dojo/method" data-dojo-event="destroyWidgetAndRedirect" data-dojo-args="evt">
dojo.stopEvent(evt);
// do whatever custom code you want here...
</script>
</div>

jCaptcha - Refresh only image not whole page

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>