I want to make a selection in an iframe at the editor and transferring the selection to the element where it will be displayed at the saved page. How do I get the data from the iFrame back to the registered block ?
How do I store these data ?
My current not working code:
blocks.registerBlockType('XXX/XX-block', {
stringToUpdate: {
type: 'string',
},
edit: function(props) {
return (el(components.FocusableIframe, {
src: "https:///....my-iframe.php"
},
}
}),
save: function(props) {
return (el('div', {
className: 'stringToUpdate'
}, 'stringToUpdate'))
}
Related
I'm working on a gatsby site using gatsby-source-wordpress to source posts for the blog. However, if any of the WordPress posts do not include a featured image this causes the build to fail. I understand that this is expected behavior.
Here is the build error I am seeing:
29 | {posts.map(({ node: post }, index) => (
30 | <li key={post.id} {...post}>
> 31 | <Img fixed={post.featured_media.localFile.childImageSharp.fixed} />
| ^
32 | <p>
33 | <Link to={`/insights/${post.slug}`}>
34 | {post.title}
WebpackError: TypeError: Cannot read property 'localFile' of null
This is caused by the resulting query, which is returning a null result in the second node because there is no featured image on the post:
{
"data": {
"allWordpressPost": {
"edges": [
{
"node": {
"id": "28ec9054-5b05-5f94-adcb-dcbfc14659b1",
"featured_media": {
"id": "f12d613b-e544-560b-a86f-cd0a7f87801e",
"localFile": {
"id": "7fca2893-ff80-5270-9765-d17d3dc21ac2",
"url": "https://www.mycustomdomain.com/wp-content/uploads/2020/01/some-featured-image.jpg"
}
}
}
},
{
"node": {
"id": "91a236ed-39d5-5efc-8bed-290d8344b660",
"featured_media": null
}
}
]
}
}
}
How I would like to fix:
As an ideal solution, I would like to use schema customization to set a default image if there is no featured image in WordPress. But I am at a total loss how to correctly do so. I am working from this documentation to guide me, but I'm just not getting my head wrapped around it properly.
A similar working example:
Tag data is similar to featured images in that the query returns null if the post has no tags. However I am able to set a default undefined tag using createResolvers like so:
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
wordpress__POST: {
tags: {
resolve(source, args, context, info) {
const { tags } = source
if (tags === null || (Array.isArray(tags) && !tags.length)) {
return [
{
id: 'undefined',
name: 'undefined',
slug: 'undefined',
}
]
} else {
return info.originalResolver(source, args, context, info)
}
},
},
},
}
createResolvers(resolvers)
}
And this works as shown in the following query results:
{
"data": {
"allWordpressPost": {
"edges": [
{
"node": {
"id": "28ec9054-5b05-5f94-adcb-dcbfc14659b1",
"tags": [
{
"id": "undefined"
}
]
}
},
{
"node": {
"id": "91a236ed-39d5-5efc-8bed-290d8344b660",
"tags": [
{
"id": "50449e18-bef7-566a-a3eb-9f7990084afb"
},
{
"id": "8635ff58-2997-510a-9eea-fe2b88f30781"
},
{
"id": "97029bee-4dec-5198-95af-8464393f71e3"
}
]
}
}
]
}
}
}
What I tried for images (isn't working...)
When it comes to nested nodes and image files I'm at a total loss. I am heading in the following direction based on this article and this code example, but so far it isn't working:
exports.createResolvers = ({
actions,
cache,
createNodeId,
createResolvers,
store,
reporter,
}) => {
const { createNode } = actions
const resolvers = {
wordpress__POST: {
featured_media: {
type: `File`,
resolve(source, args, context, info) {
return createRemoteFileNode({
url: 'https://www.mycustomdomain.com/wp-content/uploads/2017/05/placeholder.png',
store,
cache,
createNode,
createNodeId,
reporter,
})
},
},
},
}
createResolvers(resolvers)
}
I realize the above code does not have an if else statement, so the expectation is that all featured images would be replaced by the placeholder image. However the resulting GraphQL query is unaffected (as shown at top).
Can anyone point me in the right direction here? I can't seem to wrap my head around what information I can find out there.
WebpackError: TypeError: Cannot read property 'localFile' of null
'localFile' of null means that nulled is a parent of localfile - featured_media ... you can see that in results:
"featured_media": null
... so you're trying to fix localfile while you should work on featured_media level
why?
You can easily render conditionally [in react] what you need (placeholde, component) on nulled nodes ... why at all you're trying to fix graphql response?
I'm using datatable , I need to disable the export buttons(Excel, PDF) when the grid having the empty rows.
How can we handle the datatable export buttons click actions?
I have done the grid initialization as below.
I don't know how to handle the datatable export buttons(PDF, Excel).
Can you please help me how to fix this.
Update:
And I have one more issue that when user click on the Excel or PDF button then the grid columns width is collapsing.
I need even user click on the Excel or PDF buttons the grid column width should not change. How can we achieve this?
After exporting the data in to excel, columns are not auto adjusted in the excel.
How can we make the columns(After export datatable data into excel) auto adjusted?
var buttonCommon = {
exportOptions: {
format: {
body: function(data, column, row, node) {
return data;
}
}
}
};
var dataTableObj = {
"processing": true,
"destroy": true,
"scrollX": true,
"columns": [{
"data": "CollegeName",
"width":"30%"
}, {
"data": "AffiliatedTo",
"width":"15%"
}, {
"data": "TPOName",
"width":"20%"
}, {
"data": "Phone",
}, {
"data": "Website",
"bSortable": false
}],
dom: 'lBfrtip',
buttons: [
$.extend( true, {}, buttonCommon, {
extend: 'excelHtml5',
title: 'Colleges',
} ),
{
extend: 'pdf',
title: 'Colleges'
}
],
fnRowCallback: function(nRow, aData, iDisplayIndex) {
//Some code
return nRow;
}
};
var dataTbl = $('#tblColleges').DataTable(dataTableObj);
I don't know how far following solution makes sense but it was resolved my issue.
I need to disable the export buttons(Excel, PDF) when the grid having
the empty rows. How can we handle the datatable export buttons click
actions?
here I have done with the datatables action property.
buttons: [{
extend: 'excelHtml5',
title: 'Colleges',
action: function(e, dt, button, config) {
if (this.data().length > 0) {
$.fn.dataTable.ext.buttons.excelHtml5.action(e, dt, button, config);
$scope.hasAlert = 0;
$scope.$apply();
} else {
$scope.hasAlert = 2;
$scope.alertMsg = __APP_MESSAGE__.GridEmptyMsg;
$scope.$apply();
}
}
}, {
extend: 'pdf',
title: 'Colleges',
action: function(e, dt, button, config) {
if (this.data().length > 0) {
$.fn.dataTable.ext.buttons.pdfHtml5.action(e, dt, button, config);
$scope.hasAlert = 0;
$scope.$apply();
} else {
$scope.hasAlert = 2;
$scope.alertMsg = __APP_MESSAGE__.GridEmptyMsg;
$scope.$apply();
}
}
},
]
This solution has worked for me put it in fnDrawCallback function
$(tableName).dataTable({
"fnDrawCallback":function () {
var table = $(tableName).DataTable();
if (table.data().length === 0)
table.buttons('.buttons-html5').disable();
else
table.buttons('.buttons-html5').enable();
}
});
The easiest way to handle the datatable export buttons click actions is to create your own button and trigger the datatable export button on the click of your button.
This way you will handle the click actions of your created button:
$('#exportBtn').on('click', function () {
dataTbl.button(0).trigger();
});
You can remove dom: 'lBfrtip' to hide the original datatable button.
Some of my Fullcalendar events have links. The links point to either public webpages, pdf documents or webpages which are restricted access.
I would like to add a class to format the links to add an icon, based on url string.
If the url contains:
"pdf" addclass "fc-pdf"
"restricted" addclass "fc-lock"
I assume it should be with and eventRender... but I'm having trouble find the right syntax. Can someone help me with this?
http://jsfiddle.net/lbriquet/oez9Ltym/
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'listDay,listWeek,month'
},
views: {
listDay: {
buttonText: 'list day'
},
listWeek: {
buttonText: 'list week'
}
},
defaultView: 'listDay',
defaultDate: '2016-09-12',
navLinks: true, // can click day/week names to navigate views
events: [{
title: 'Conference (website)',
start: '2016-09-11',
end: '2016-09-13',
url: "https://www.ted.com/talks"
}, {
title: 'Meeting (download document)',
start: '2016-09-12T10:30:00',
end: '2016-09-12T12:30:00',
url: "http://storage.ted.com/tedx/manuals/tedx_speaker_guide.pdf"
}, {
title: 'Lunch',
start: '2016-09-12T12:00:00'
}, {
title: 'Meeting (members only)',
start: '2016-09-12T14:30:00',
url: "http://www.dictionary.com/browse/restricted"
}, {
title: 'Happy Hour',
start: '2016-09-12T17:30:00'
}, {
title: 'Dinner',
start: '2016-09-12T20:00:00'
}],
eventRender: function eventRender(event, element, view) {
}
});
The way I got this to work was by adding a type to the events simply because I think it would be easier than dealing with regex that might not always work. So events don't need a type but they can have a type pdf, restricted or whatever else you need. In eventRender I added the following:
eventRender: function eventRender(event, element, view) {
if(typeof event.type !== 'undefined') {
if(event.type === 'pdf') {
element.addClass('fc-pdf');
} else if(event.type === 'restricted') {
element.addClass('fc-lock');
}
}
}
A check to see if the type is provided or not and then if statements for adding the class based on the type. I also had to make a small change to the css selector, changing a.fc-lock to .fc-lock a to allow it to display properly. Here is the JS Fiddle showing this.
$('#container').highcharts('Map', {
title : {
text : 'Highmaps basic demo'
},
subtitle : {
text : 'Source map: Africa'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
min: 0
},
series : [{
data : data,
mapData: Highcharts.maps['custom/africa'],
joinBy: 'hc-key',
name: 'Random data',
states: {
hover: {
color: '#BADA55'
}
},
dataLabels: {
enabled: true,
format: '{point.name}'
}
}]
});
});
http://jsfiddle.net/gh/get/jquery/1.11.0/highslide-software/highcharts.com/tree/master/samples/mapdata/custom/africa
I am using this fiddle and I want to get the country name on click event on the country. Anybody can help me with the example or link to the API of this? I read the API but could not find, I guess I am missing some point.
thanks in advance
Pretty simple, just add this:
plotOptions:{
series:{
point:{
events:{
click: function(){
alert(this.name);
}
}
}
}
}
The this in the point scope represents the clicked point, therfore you have access to it's properties.
http://jsfiddle.net/farz5vq2/
So I have a route that sets my template
Router.route('audit', {
path: '/audit/:audit_id/',
template: 'audit',
data: function() {
if (this.ready()) {
audit_obj = Audits.findOne({_id: this.params.audit_id});
lineitems = LineItems.find(JSON.parse(audit.query));
return {
audit_obj: audit_obj,
lineitems: lineitems
}
}
},
waitOn: function () {
return [
Meteor.subscribe('lineitems', this.params.audit_id),
Meteor.subscribe('audits')
]
}
}
Now, when my user takes certain actions on the page rendered by the audit template, I would like to update the audit object and also update the data context that the page is running with. Is this possible?
Something like:
Template.audit.events({
'click .something-button': function() {
// update the data context for the current audit template.
current_context.audit_obj.something = 'new something';
}
});
Yes:
Router.route('audit', {
path: '/audit/:audit_id/',
template: 'audit',
onRun: function() {
Session.set('audit', Audits.findOne(this.params.audit_id));
Session.set('lineitems', LineItems.find(JSON.parse(audit.query)).fetch());
}
data: function() {
if (this.ready()) {
return {
audit_obj: Session.get('audit'),
lineitems: Session.get('lineitems')
}
}
},
waitOn: function () {
return [
Meteor.subscribe('lineitems', this.params.audit_id),
Meteor.subscribe('audits')
]
}
}
and
Template.audit.events({
'click .something-button': function() {
// update the data context for the current audit template.
Session.set('audit', {..});
}
});
But you'll need to decide how to handle changes that come from the server, and may interfere with changes on the front end. So a better approach might be to leave the first part of the code (router) as is:
Router.route('audit', {
path: '/audit/:audit_id/',
template: 'audit',
data: function() {
if (this.ready()) {
return {
audit_obj: Audits.findOne(this.params.audit_id),
lineitems: LineItems.find(JSON.parse(audit.query))
}
}
},
waitOn: function () {
return [
Meteor.subscribe('lineitems', this.params.audit_id),
Meteor.subscribe('audits')
]
}
}
and just change the front end to update the collection:
Template.audit.events({
'click .something-button': function() {
// update the data context for the current audit template.
Audits.update( this.data.audit_obj._id, {..} );
}
});
Of course, that will update the data on the server, too.