I am now working on one Meteor project and trying to do the below.
I have a product list page and when I click one product, I goes to product edit page.
What I want to know is how to attach product image and show it when I go back to product list page.
I know CollectionFS used for file upload, but because there is no reliable guide to show detail, I am getting trouble for it.
I added this to schema, but don't know how to show product image in list page.
Images = new FS.Collection("images", {
stores: [new FS.Store.FileSystem("images")]
});
Images.allow({
insert: function(){
return true;
},
update: function(){
return true;
},
remove: function(){
return true;
},
download: function(){
return true;
}
});
Schemas.Products = new SimpleSchema({
'name': {
type: String,
label: 'What is the name of the building?',
max: 200,
unique: true
},
'picture': {
type: String,
max: 200,
optional: true,
autoform: {
afFieldInput: {
type: 'fileUpload',
collection: 'Images',
accept: 'image/*',
label: 'Choose file'
}
}
}
});
Is there anyone can give me a direction? Please help me!
The goal in here is to show product image in product list page.
I found this really helpful wiki on CollectionFS's page. It shows how to display an already uploaded image from front-end.
CollectionFS provides an url method associated with its FS.File object. Using this method we can display the image from frontend.
Steps:
Publish Images (FS.Collection instance) from server-side.
Subscribe to the above from your client-side.
In your template-helper, return Images.find() to the template.
You can embed the result of Images.find() into the result from another collection as well. For example:
var products = Products.find().fetch();
products.forEach(function(each) {
each.file = Images.findOne({ _id: each.file });
});
return products;
Inside the template, you can display the image using:
<img src="{{this.url stores='images'}}" />
Here this refers to the FS.File instance and 'images' is the store name.
Related
I have a taxonomy called category.
I have a menu with links to each of these taxonomy items.
The Taxonomy page for each of these items has that menu and also contains a view which uses a contextual filter from the URL to filter the content of the view to content with that taxonomy term.
I wanted to Ajax load the view content when one of these menu items is clicked.
I've been able to achieve the desired result by enabling ajax on the view and using the following JavaScript.
(function ($) {
Drupal.behaviors.course_browser = {
attach: function (context, settings) {
// should only be one menu, but guard against 0, and avoid the if statement.
context.querySelectorAll(".menu--categories").forEach((menu) => {
// for each link in the menu
menu.querySelectorAll(".nav-link").forEach((link) => {
// on click
link.addEventListener("click", (event) => {
event.preventDefault();
// fetch the taxonomy term id from menu link
let tid = event.target.dataset.drupalLinkSystemPath.replace(
"taxonomy/term/",
""
);
// make the ajax call
$.ajax({
url: "/views/ajax",
type: "post",
data: {
view_name: "course_browser",
view_display_id: "block_1",
view_args: tid,
},
success: (response) => {
response.forEach((action) => {
// the response contains a number of commands; I'm not sure
if (
action.command === "insert" &&
action.method === "replaceWith"
) {
let viewElement = document.querySelector(VIEW_SELECTOR);
// update the html of the course browser
viewElement.innerHTML = action.data;
// update the url in the browser
window.history.pushState("", "", event.target.href);
// seperate function to adjust my page title
updatePageTitle(event.target.textContent);
// call drupal behaviours passing context to ensure all the other js code gets a chance to manipulate the new content
Drupal.attachBehaviors(viewElement);
}
});
},
error: function (data) {
console("An error occured fetching the course browser");
},
});
});
});
});
},
};
})(jQuery);
I'm looking for feedback on my approach here; my main concern at the moment is the way I handle the response. When I look at the response I receive something like that shown below:
0: {command: "settings", settings: {…}, merge: true}
1: {command: "add_css", data: "<link rel="stylesheet" media="all" href="/core/modules/views/css/views.module.css?qcog4i" />↵"}
2: {command: "insert", method: "append", selector: "body", data: "<script src="/core/assets/vendor/jquery/jquery.min…/js/modules/views/ajax_view.js?qcog4i"></script>↵", settings: null}
3: {command: "insert", method: "replaceWith", selector: ".js-view-dom-id-", data: "The HTML"}
As you can see, I'm manually handling the response by cherry picking the part I want and replacing the HTML of view. Based on what I've seen around Drupal, I think there should be something I can pass this response to that handles it automatically. When I look at the window object of the browser, I can see Drupal.AjaxCommands which looks like it was designed to handle this, but I'm not sure how I should be using this.
I also note that in the case I can simply pass this response to something to have those AjaxCommands executed, the selector ".js-view-dom-id-" isn't right. So I could tweak the response before I pass it, or if someone knows a way to adjust the ajax request to perhaps get the right selector, that would be ideal.
Sorry if this info is readily available somewhere...there are quiet a few resources around related to Drupal and Ajax but I haven't been able to find examples of exactly what I'm doing here, the circumstances always seem to differ enough that I can't use them.
Thanks for any help.
I have a shopping site which I'm converting to Ajax. It has a list of cart items.
On page load the PayPal button is set up correctly with the cart totals passed in. However, now that I have an Ajax cart I need to update the cart totals when the cart changes.
If I call the paypal.Button.render function again I get another button.
So I need to either delete the old button and rebuild or call something to update the totals.
Can anyone point me in the right direction?
This is my code that sets up the button.
function PayPalButton(authResult) {
// console.log(authResult);
// Render the PayPal button
paypal.Button.render({
// Set your environment
env: authResult.PayPalEnvironment, // sandbox | production
// Specify the style of the button
style: {
label: 'generic',
size: 'responsive', // small | medium | large | responsive
shape: 'rect', // pill | rect
color: 'blue', // gold | blue | silver | black
tagline: false
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: authResult.PayPalClientId,
production: authResult.PayPalClientId
},
payment: function (data, actions) {
// recover transaction value here
var carttotal = authResult.cart.FTotal - (authResult.VATApplies ? 0 : authResult.cart.VAT);
var paymentGuid = authResult.cart.PaymentGuid;
//alert(paymentGuid);
return actions.payment.create({
payment: {
transactions: [{
amount: {
total: carttotal.toString(), currency: 'GBP'
},
custom: paymentGuid.toString()
}]
}
});
},
onAuthorize: function (data, actions) {
return actions.payment.get().then(function (data) {
return actions.payment.execute().then(function () {
processPayPal(data);
});
});
}
}, '#paypal-button-container');
};
Well this works but it's ugly. Surely there must be a better way.
After updating the cart. I remove the PayButton button from the DOM and put the HTML back how it was. Then I call the routine to reconfigure the button.
$("#PayPalSection").remove();
$("#paypalButtonContainer").append('<div id="PayPalSection"><div class= "col-8 offset-2"><div id="paypal-button-container"></div></div></div>');
ConfigurePayPalButton();
This does a round trip to the DB unfortunately but I will try and write something that doesn't require that step.
I have this code:
Ext.define('storeBusiness',{
extend: 'Ext.data.Store',
autoLoad: true,
autoSync: true,
model: 'Business',
proxy: {
type: 'ajax',
api: {
read: '../crud/ler_filter.php?db='+database+'&tbl=mercados',
create: '../crud/criar.php?db='+database+'&tbl=mercados',
update: '../crud/update.php?db='+database+'&tbl=mercados',
destroy: '../crud/apagar.php?db='+database+'&tbl=mercados'
},
reader: {
type: 'json',
root: 'rows'
},
writer: {
type:'json'
}
}
});
var storeBusinessCombo = Ext.create('storeBusiness');
var storeBusiness = Ext.create('storeBusiness');
storeBusiness.add({id: 0, business: "All"});
I have 2 grids. One has storeBusiness and the other has storeProducts.
The way the work is when I click on the business grid it filters the produts grid so that it shows the products of that business.
On the business grid it has the storeBusiness that it fetches the records from a database. I want to fetch all business from the database and add one more record (named 'All') without writing it to the database.
I dont want to add 'All' to the database because in the Product's grid I want to have a combobox that has all the business (storeBusinessCombo) without the 'All' record.
Does anyone has any idea how I can do this?
(the code above isn't doing what I want, storeBusiness shows all business without the 'All' in the grid)
Important: This works if the Ext.define('storeBusiness', has a proxy that is of type: 'memory'
Two approaches come to mind:
Add the "all" record to the store after load and don't sync so the
record isn't sent to the server.
Use memory proxy, retrieve the
businesses records via Ajax request and assign them to the store via its data config.
To resolve this I have done:
Put the Ext.define('storeBusiness',{ to autoLoad: false,
Put this code:
var storeBusinessCombo = Ext.create('storeBusiness', {autoLoad: true});
var storeBusiness = Ext.create('storeBusiness');
storeBusiness.on('beforeload', function(){
storeBusiness.loadData([{id: 0, business: "All"}]);
}
And you should put
storeBusiness.load({addRecords: true});
when you want to load storeBusiness.
I'm creating a Firefox addon using jetpack (jpm with node.js) to extend the Firefox developer tools to allow editing the current page's html. (I know this feature already exists; just trying to learn the ropes).
What API do I use to access the current page's HTML? I see that there is a Debugger.Source but I'm not sure if this is correct. If so, how do I retrieve this data?
As the first answer suggests, you can get at the html source using a content script injected the page. For example, here's a very simple approach that uses the tabs module to attach a content script into the current page:
const self = require('sdk/self');
const tabs = require('sdk/tabs');
let { ActionButton } = require("sdk/ui/button/action");
let button = ActionButton({
id: "my-button-id",
label: "Get HTML Source",
icon: {
"16": "chrome://mozapps/skin/extensions/extensionGeneric.png",
"32": "chrome://mozapps/skin/extensions/extensionGeneric.png"
},
onClick: (state) => {
let worker = tabs.activeTab.attach({
contentScript: 'self.port.emit("htmlSrc", {head: document.head.outerHTML, body: document.body.outerHTML});'
});
worker.port.on('htmlSrc', (result) => {
worker.destroy(); // clean up
let src = "<html>\n"+ result.head + "\n" + result.body + "\n</html>";
require('sdk/clipboard').set(src, 'text');
});
}
});
Direct access via SDK is impossible, but you can use content scripts to read and modify the page.
I have a store being used by several charts. I get my data remotely with an ajax call. In the php script that I link it too, I'm just going to change the parameters of my query to adjust for the different charts.
Here's my idea: I pass the title of the chart's panel as a parameter to my php script. That'll tell me which chart it is.
How do I access the title of whatever chart the store is being used by?
var my_store = Ext.create('Ext.data.JsonStore', {
fields: ['project', 'accepted', 'rejected', 'deleted', 'undefined'],
proxy: {
type: 'ajax',
url: 'generate_proj.php',
extraParams: {foo: **chart.id**},
reader: {
type: 'json'
}
},
autoLoad: true,
listeners: {
beforeload: function(store,operation) {
//operation.params.foo = this.idname;
},
load: function(obj,records) {
var text = Ext.decode(obj.responseText);
Ext.each(records,function(rec) {
});
}
}
});
Here's what I've done so far. Getting the name of a single chart/panel is no problem. I want the store to be able to dynamically read the name of what's using it. How?
Somewhere, you have some code that switches between the various charts. During that code, you could do something like
activeChart.getChartStore().proxy.extraParams.foo = activeChart.getId();
where activeChart is whatever reference you have to the chart you are about to show. Then when you load the store, it'll send the correct parameter.