I almost figure this out, can anyone tell me as to why my $.unblock never executes?
$(document).ready(function () {
$('#somedropdown').change(function () {
$.blockUI({
css: {
border: 'none',
padding: '15px',
backgroundColor: '#000',
'-webkit-border-radius': '10px',
'-moz-border-radius': '10px',
opacity: '.5',
color: '#fff'
}
});
var dropdownvalue = $('#somedropdown').val();
var xaml1obj = document.getElementById("Xaml1");
$.getScript(xaml1obj.Content.scriptableObject.InitializeSomething(dropdownvalue), function () { $.unblockUI(); });
});
});
The solution to this was to call unblock method from the managed code (C# to javascript).
In other words, when you make a selection you call block, do your work (i.e. call server, etc) and then call unblock at the end. The calls to block and unblock are made from managed code (c#) but the actual work is performed in the javascript (because this is jQuery)
Related
I am attempting to re-create the solution seen here for keeping a session alive by using an HTTPHandler and making an AJAX call to it.
The solution does not appear to have worked, and when I tried to debug it by adding an alert(); just before the $.get(); the alert(); never got fired off. I copied and pasted the code from the example, so I'm not missing a semicolon or something. I even set an alert(); before the setTimeout(); and that one worked!
function setHeartbeat() {
alert("I get here!");
setTimeout("heartbeat()", 300000); // every 5 min
}
function heartbeat() {
alert("I never seem to fire off!");
$.get(
"/SessionHeartbeat.ashx",
null,
function(data) {
setHeartbeat();
},
"json"
);
}
Any thoughts?
Both slon and Hans Kesting were right one the money.
The working javascript is:
$(document).ready(function () {
//alert("Document is ready.");
// set the initial call
setHeartbeat();
function setHeartbeat() {
//alert("setHeartbeat");
setInterval(function () {
heartbeat();
}, 10000); // every 10 sec
}
function heartbeat() {
//alert("heartbeat");
$.get(
"/SessionHeartbeat.ashx",
null,
function(data) {
setHeartbeat();
},
"json"
);
}
});
Thank you both!
I'm trying to scrape products with color and size variations.
Every variation is a form and to get the next variation I'm clicking on radio button and it is doing a form submit action on each click.
I have tried to click it using
1. “casper.getElementsInfo(element)[0].click();”
2. “document.querySelectorAll(element)[2].click();”
3. “casper.thenClick('element');”
4. “casper.evaluate(function(){document.querySelectorAll(element)[2].click();});”
After every click I'm doing a casper wait for 8 seconds !
So here is my problem Casperjs is getting error after clicking the next color/size
var casper = require('casper').create({
viewportSize: {
width: 1920,
height: 1080
},
pageSettings: {
loadImages: false,
loadPlugins: false
}
});
casper.then(function () {
self.thenOpen("https://scubapro.johnsonoutdoors.com/fins/fins/seawing-nova-fin-full-foot", function () {
casper.then(function () {
var varitoinCount = document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input').length;
var i = 0;
casper.repeat(varitoinCount + 1, function () {
try {
document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input')[i].click();
casper.log('we got to anhoter variatoin ...' + i);
} catch (error) {
console.log(error);
}
i++;
});
});
});
});
try {
casper.run();
} catch (e) {
consol.log("Error..... " + e);
}
(TypeError: undefined is not a constructor )
And btw when I'm doing the same thing in a console it works fine
You have to understand that accessing DOM is not possible in Casper environment. You should switch to browser environment to execute your DOM selectors by using Casper's evaluate method. Basically it used to get some information from within browser or to manually do some actions with javascript. To understand it you have a whole section dedicated for that in official documentation.
That being said, I amended your code to properly click on different color variation inputs.
var casper = require('casper').create({
viewportSize: {
width: 1920,
height: 1080
},
pageSettings: {
loadImages: false,
loadPlugins: false
}
});
casper
.start()
.thenOpen("https://scubapro.johnsonoutdoors.com/fins/fins/seawing-nova-fin-full-foot", function () {
var varitoinCount = this.evaluate(function() {
return document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input').length;
});
var i = 0;
this.repeat(varitoinCount + 1, function() {
this.evaluate(function(iterator) {
document.querySelectorAll('div#edit-attributes-field-swatch-taxonomy > div input')[i].click();
}, i);
i++;
})
});
try {
casper.run();
} catch (e) {
console.log("Error..... " + e);
}
However it still doesn't change the color since website(for some reason) needs to take 2 clicks to change the color and I suggest that you throw in some waitFor functions to be sure that color has changed.
In Facebook react.js, you can compose component within component, or maybe mix and match.
I'm wondering if twitter flight can do the same thing. if so, can anyone gives me an example?
this is what I have so far:
define(function (require) {
var defineComponent = require('flight/lib/component'),
infoInput = require('component/info_input');
return defineComponent(inputSection, infoInput);
function inputSection () {
this.after('initialize', function() {
infoInput.doSomehting();
});
};
});
and my info_input.js is defined below:
define(function (require) {
var defineComponent = require('flight/lib/component');
return defineComponent(infoInput);
function infoInput() {
this.after('initialize', function() {
});
this.doSomething = function() {
alert('I will do something');
};
};
});
This is what mixins are for.
Flight Components are enriched mixins.
From doc/component_api.md
It comes with a set of basic functionality such as event handling and Component registration. Each Component definition mixes in a set of custom properties which describe its behavior.
Read more about Components.
So the answer to your question is Yes.
I guess that what you are doing is legit, although I've never done it before.
I'd rather move the shared logic to a Mixin or attach the two components to the same element and let them talk via events:
component/input_section.js
this.after('initialize', function () {
this.trigger('uiSomethingRequired');
});
component/info_input.js
this.after('initialize', function () {
this.on('uiSomethingRequired', this.doSomething);
});
Solution mentioned by G.G above works!
We may go a step ahead to trigger events on restricted scope instead of document:
component/input_section.js
this.after('initialize', function () {
this.$node.closest(this.attr.parentClass).trigger('uiSomethingRequired');
});
component/info_input.js
this.after('initialize', function () {
this.on(this.$node.closest(this.attr.parentClass), 'uiSomethingRequired', this.doSomething);
});
I'm developing a keno game. When the user presses the start button a Meteor.Call() executes everything for that card pick. Including updating the user balance. I have a setTimeout for the winning numbers, so that they display over a period of about 20 seconds. The problem is that when the call is made, the balance updates instantly, and then the numbers start displaying with the delay. I not familiar with how to solve this. I appreciate any help.
server-side:
Meteor.methods({
process: function(){
// generate numbers
// update user balance
}
});
client-side:
Template.keno.events({
'click #start' : function(){
Meteor.call('process',function(err,numbers){
//setTimeout on displaying numbers
// as setTimeout displays numbers, balance already updated. I need to delay
// the balance update, until all numbers are displayed.
// otherwise, the player see that they won before all numbers come out.
});
}
});
** Update **
The only help I need is to understand how to make a variable like {{balance}} unreactive, until I finish the setTimeout, and then have it update. Should I be using sessions? Should I not use a template variable and instead, insert the balance with jquery? It's just a simple solution, the difficulty is that I don't know what function / method I'm looking for that can help me turn off the reactivity for a set amount of time, and then update, after the Meteor.call() for then numbers finishes it's setTimeout.
If I understand your situation correctly, you need the template {{balance}} expression to be set at a time you decide vs. when the collection gets a result from the server. So you could use Session to set a value when you like. Below is an example:
<body>
{{> game}}
</body>
<template name="game">
<button id="process">Process</button>
<div>{{firstNumber}}</div>
<div>{{secondNumber}}</div>
<div>balance: {{balance}}</div>
</template>
if (Meteor.isClient) {
Template.game.events({
'click #process': function (e, tmpl) {
Meteor.call('process', function (err, result) {
Session.set('firstNumber', result[0]);
setTimeout(function () {
Session.set('secondNumber', result[1]);
Session.set('balance', result[0] + result[1]);
}, 2000);
});
}
});
Template.game.helpers({
firstNumber: function () { return Session.get('firstNumber'); },
secondNumber: function () { return Session.get('secondNumber'); },
balance: function () { return Session.get('balance'); }
});
}
if (Meteor.isServer) {
function randomNumber () {
return Math.floor(Math.random() * 100);
}
Meteor.methods({
process: function () {
return [randomNumber(), randomNumber()];
}
});
}
Try to wrap your Meteor.call() inside the setTimeout() itself, like:
Template.keno.events({
'click #start' : function(){
setTimeout(function(){
Meteor.call('process',function(){
//do something.
});
}, 20000);
}
});
Maybe the solution is to use reactivity on a duplicated collection :
You set your main collection on server side only.
You create another collection on the client side that will be a duplicate collection but used only for display
Then you pusblish the main collection to the client.
On the client side, you set all required observer on it that will replicate all modification on the duplicated collection. But this way you can manage animation or any other wished features. All actions on client side will do call on server-side but it won't affect immediatly the templates because the templates only use the duplicated collections.
I hope it will help you.
OK, so I threw this demo together in 5 mins, works though.
Here's the demo: http://keno-test.meteor.com/
Of course it needs LOT's more work, but the delayed thing works.
HTML:
<head>
<title>keno-test</title>
</head>
<body>
{{> hello}}
</body>
<template name="hello">
<input id="callCardThing" type="button" value="Start card-thing" />
<h1>Here are the cards!</h1>
<ul>
{{#each cards}}
<li>{{value}}</li>
{{/each}}
</ul>
</template>
JS:
Cards = new Meteor.Collection('cards');
if (Meteor.isClient) {
Deps.autorun(function () {
Meteor.subscribe("cards");
});
Template.hello.events({
"click #callCardThing": function (event) {
Meteor.call("doCardThingOnServer");
}
});
Template.hello.helpers({
cards: function () {
return Cards.find({});
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
Meteor.publish("cards", function () {
return Cards.find({});
});
});
Meteor.methods({
doCardThingOnServer: function () {
// I remove all the cards every time just for the demo…
Cards.remove({});
var numberOfcards = 10;
var counter = Meteor.setInterval(function () {
Cards.insert({value: 'whatever! no: '+numberOfcards });
numberOfcards--;
if (numberOfcards < 1) Meteor.clearInterval(counter);
}, 1500);
}
});
}
Ok, so how about conditional {{balance}} rendering?
var shouldRender = false;
setTimeout(function () {
shouldRender = true;
}, 2000);
Template.template_name.shouldRender = function () {
return shouldRender;
}
{{#if shouldRender}}
{{>balance}}
{{/if}}
Have a look at the Atmosphere animation package : https://atmosphere.meteor.com/package/animation!
I've just done this package to explore one way of doing animation on database reactivity.
You have to register a cursor and the template to animate. There is a project that will show you how to do that.
I hope it will help you.
I have made an custom collapsible fieldset control in asp.net. I use jquery to add the toggle effects. The control works perfectly but when i am using my fieldsets inside an updatepanel, afer a postback i loose my jquery logic because of the document.ready.
Now i have read about the new Live() function of Jquery but i don't get it working. What do i do wrong? Has someone the answer??
Thanks a lot
My Jquery code is:
$(document).ready(function() {
$.fn.collapse = function(options) {
var defaults = { closed: false }
settings = $.extend({}, defaults, options);
return this.each(function() {
var obj = $(this);
obj.find("legend").addClass('SmartFieldSetCollapsible').live("click", function() {
if (obj.hasClass('collapsed')) {
obj.removeClass('collapsed').addClass('SmartFieldSetCollapsible'); }
$(this).removeClass('collapsed');
obj.children().next().toggle("slow", function() {
if ($(this).is(":visible")) {
obj.find("legend").addClass('SmartFieldSetCollapsible');
obj.removeAttr("style");
obj.css({ padding: '10px' });
obj.find(".imgCollapse").css({ display: 'none' });
obj.find(".imgExpand").css({ display: 'inline' });
}
else {
obj.css({ borderLeftColor: 'transparent', borderRightColor: 'transparent', borderBottomColor: 'transparent', borderWidth: '1px 0px 0px 0px', paddingBottom: '0px' });
obj.find(".imgExpand").css({ display: 'none' });
obj.find(".imgCollapse").css({ display: 'inline' });
}
});
});
if (settings.closed) {
obj.addClass('collapsed').find("legend").addClass('collapsed');
obj.children().filter("p,img,table,ul,div,span,h1,h2,h3,h4,h5").css('display', 'none');
}
});
};
});
$(document).ready(function() {
$("fieldset.SmartFieldSetCollapsible").collapse();
});
The problem is that you are doing more then just a plain selector for your live selection
From api.jquery.com
"DOM traversal methods are not fully supported for finding elements to send to .live(). Rather, the .live() method should always be called directly after a selecton"
if (obj.hasClass('collapsed')) {
obj.removeClass('collapsed').addClass('SmartFieldSetCollapsible'); }
$(this).removeClass('collapsed');
First you want to remove the class an add another class if it has the class collapsed, an then you remove the class collapsed. I don't know if it affects the working of the system but it is worth to try.
Does the function work if you just use .click (when the field aren't updated)?
Traversing is the issue. You can solve it with a simple selection.
var obj = $(this),
obj.find("legend").addClass('SmartFieldSetCollapsible');
$('legend.SmartFieldSetCollapsible').live('click.collapsible', function(e){