[PdfTron 5.2]
I have a PDF form with text and date fields. I want to find the date fields.
I can get the actions of the field with getActions().
field.getActions()
returns
{"F":[{"yc":"JavaScript","Gt":"AFDate_FormatEx(\"dd.mm.yyyy\");"}],
"K":[{"yc":"JavaScript","Gt":"...);","ey":null}]}
As you can see, the date is in actions.F[0].Gt. But checking actions.F[0].Gt
for "AFDate" seems wrong, that's too low-level.
Is there a better API function to find out, that I have a date field?
Thank you.
You are correct. The Gt property is obfuscated and minified which is volatile and not meant to be used. If you require an API, you should refer to our documentation. Everything should be available there except a few (one of which will be used below), but feel free to contact us if you do need help!
Unfortunately, there is no API currently to get that type. From my limited understanding, the "type" of a field is determined by the attached actions and not simply a specific type or flag. This suggests all fields are just text fields with special formatting actions to make it look and feel like its a date or numeric field.
In this case, you will have to check the formatting action (F) as you have already noticed for the date formatting function (AFDate_FormatEx). To get the JavaScript from that action, you should use the javascript property on the action which was not in the documentation. However, you can see it if you console log the action.
Here is an example:
const dateActionJs = /.+:"AFDate_FormatEx\(.*/;
instance.docViewer.on('annotationsLoaded', () => {
const annotations = annotManager.getAnnotationsList();
annotations.forEach(annot => {
const actions = annot.getField().getActions();
if (actions.F && actions.F[0] && actions.F[0].javascript && dateActionJs.test(actions.F[0].javascript)) { // F = Format Action
console.log('Found Date');
}
});
});
Let me know if this helps!
EDIT: You can search for AFDate instead of AFDate_FormatEx which will be sufficient.
I have created an XPage with the following: Started by creating a custom layout control using the Application Layout. I aded the layout control to the xpage and then dropped in a Dynamic Content Control. I configured the control as follows:
<xe:dynamicContent id="dynamicContent1" defaultFacet="GovernanceReviews"
useHash="true">
<xp:this.facets>
<xc:ccViewDocumentTemplates xp:key="DocumentTemplates"></xc:ccViewDocumentTemplates>
<xc:ccViewGovProcurementReviews xp:key="GovProcurementReviews"></xc:ccViewGovProcurementReviews>
<xc:ccViewGovRevReporting xp:key="GovRevReporting"></xc:ccViewGovRevReporting>
<xc:ccViewGovRevWOCompleted xp:key="GovRevWOCompleted"></xc:ccViewGovRevWOCompleted>
<xc:ccViewGovernanceReviews xp:key="GovernanceReviews"></xc:ccViewGovernanceReviews>
<xc:ccViewProfilesByType xp:key="ProfilesByType"></xc:ccViewProfilesByType>
<xc:ccViewProfilesWithTargetCompl xp:key="ProfilesWithTargetCompl"></xc:ccViewProfilesWithTargetCompl>
<xc:ccViewLastUpdated xp:key="LastUpdated"></xc:ccViewLastUpdated>
<xc:ccViewUserGuide xp:key="UserGuide"></xc:ccViewUserGuide>
<xc:ccViewTracking xp:key="Tracking"></xc:ccViewTracking>
</xp:this.facets>
</xe:dynamicContent>
Then I dropped in a navigator control in the left column and created BasicLeafNodes to correspond to the dynamic content control I used the href property and used the #content="" to display the correct content.
This works just fine, but I am having problems figuring out how to make the selections in the navigator highlight when they are selected. I know I need to compute the Selectd property,but I can't figure out how to get the xp:key value so I can compare it to the SubmitValue. I know this is probably something simple, but I can't figure it out.
Can someone please enlighten me.
Thanks,
MJ
ADDED 03/26/2014 - I have a feeling that it has something to do with Using the href property of the Dynamic Content Control to perform the content switching. I know that makes the BasicLeafNodes Links. So, not sure how the Navigator records which link is being executed and how to capture that.
MJ
Add a value is the submitValue property
And in the onItemClick Event
Assign the submitted value to a viewScope variable
viewScope.Selected=context.getSubmittedValue()
And finally check if the viewScope variable equals your item submit value in the selected property. This needs to be calculated
if(viewScope.Selected="byCategory"){
return true
}else{
return false
}
The following is working for me:
if(viewScope.Selected == "byCategory"){
return true
} else{
return false
}
An equality test must be made with two equal symbols (or three). One equal symbol evidently always returns true.
I did it by jQuery. Just put the following code to the custom control, which contains navigator.
$( function() {
if (window.location.hash.length > 0) {
select()
}
});
$(window).on('hashchange', function() {
select();
});
function select() {
$(".lotusColLeft .lotusMenu .lotusBottomCorner li").removeClass(
"lotusSelected")
$(".lotusColLeft .lotusMenu .lotusBottomCorner li a")
.filter(
function() {
return window.location.hash.indexOf($(this).attr(
'href')) > -1
}).parent().addClass("lotusSelected")
}
I'm using the search portlet in certain areas of my website, but I'd like to restrict the results to only search for a specific content type: for example only search the news items, or only show Faculty Staff Directory profiles.
I know you can do this after you get to the ##search form through that "filter" list, but is there a way to start with the filter on, so that the "Live Search" results only show the relevant results (i.e. only news items or only profiles).
I suspect you know it already, but just to be sure: You can globally define which types should be allowed to show up in searchresults in the navigations-settings of the controlpanel, and then export and include the relevant parts to your product's GS-profile-propertiestool.xml.
However, if you would like to have some types excluded only in certain sections, you can customize Products.CMFPlone/skins/plone_scripts/livesearch_reply, which already filters the types, to only show "friendly_types" around line 38 (version 4.3.1) and add a condition like this:
Edit:
I removed the solution to check for the absolute_url of the context, because the context is actually the livesearch_reply in this case, not the current section-location. Instead the statement checks now, if the referer is our section:
REQUEST = context.REQUEST
current_location = REQUEST['HTTP_REFERER']
location_to_filter = '/fullpath/relative/to/siteroot/sectionId'
url_to_filter = str(portal_url) + location_to_filter
types_to_filter = ['Event', 'News Item']
if current_location.find(url_to_filter) != -1 or current_location.endswith(url_to_filter):
friendly_types = types_to_filter
else:
friendly_types = ploneUtils.getUserFriendlyTypes()
Yet, this leaves the case open, if the user hits the Return- or Enter-key or the 'Advanced search...'-link, landing on a different result-page than the liveresults have.
Update:
An opportunity to apply the filtering to the ##search-template can be to register a Javascript with the following content:
(function($) {
$(document).ready(function() {
// Let's see, if we are coming from our special section:
if (document.referrer.indexOf('/fullpath/relative/to/siteroot/sectionId') != -1) {
// Yes, we have the button to toggle portal_type-filter:
if ($('#pt_toggle').length>0) {
// If it's checked we uncheck it:
if ($('#pt_toggle').is(':checked')) {
$('#pt_toggle').click();
}
// If for any reason it's not checked, we check and uncheck it,
// which results in NO types to filter, for now:
else {
$('#pt_toggle').click();
$('#pt_toggle').click();
}
// Then we check types we want to filter:
$("input[value='Event']").click();
$("input[value='News Item']").click();
}
}
})
})(jQuery);
Also, the different user-actions result in different, inconsistent behaviours:
Livesearch accepts terms which are not sharp, whereas the ##search-view only accepts sharp terms or requires the user to know, that you can append an asterix for unsharp results.
When hitting the Enter/Return-key in the livesearch-input, the searchterm will be transmitted to the landing-page's (##search) input-element, whilst when clicking on 'Advanced search...' the searchterm gets lost.
Update:
To overcome the sharp results, you can add this to the JS right after the if-statement:
// Get search-term and add an asterix for blurry results:
var searchterm = decodeURI(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURI('SearchableText').replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")) + '*';
// Insert new searchterm in input-text-field:
$('input[name=SearchableText]').val(searchterm);
Update2:
In this related quest, Eric Brehault provides a better solution for passing the asterix during submit: Customize Plone search
Of course you can also customize the target of advanced-search-link in livesearch_reply, respectively in the JS for ##search, yet this link is rather superfluous UI-wise, imho.
Also, if you're still with Archetypes and have more use-cases for pre-filtered searchresults depending on the context, I can recommend to have a look at collective.formcriteria, which allows to define search-criteria via the UI. I love it for it's generic and straightforward plone-ish approach: catalogued indizi and collections. In contradiction to eea.facetednavigation it doesn't break accessibility and can be enhanced progressively with some live-search-js-magic with a little bit of effort, too. Kudos to Ross Patterson here! Simply turn a collection (old-style) into a searchform by changing it's view and it can be displayed as a collection-portlet, as well. And you can decide which criteria the user should be able to change or not (f.e. you hide the type-filter and offer a textsearch-input).
Watch how the query string changes when you use the filter mechanism on the ##search page. You're simply adding/subtracting catalog query criteria.
You may any of those queries in hidden fields in a search form. For example:
<form ...>
....
<input type="hidden" name="portal_type" value="Document" />
</form>
The form on the query string when you use filter is complicated a bit by its record mechanism, which allows for some min/max queries. Simple filters are much easier.
I have fixed row numbers to 10 for my subgrids, but if reccount is less than 10 I would want to adjust height subgrid to "auto" or "100%".
So here is my code for this subgrid :
// SUBGRID FOURTH LEVEL
var subgrid_table_id = subgrid_id+"_d",
pager_id = "p_"+subgrid_table_id;
$("#"+subgrid_id).append("<table id='"+subgrid_table_id+"' class='scroll'></table><div id='"+pager_id+"' class='scroll'></div>");
$("#"+subgrid_table_id).jqGrid({
url:"sg31b.php?id="+row_id+"&clt="+clt,
datatype: "json",
idPrefix:"sgd_",
colNames: ['Id','Article','Désignation','Marque','Equivalence'],
colModel: [
{name:'e.id',index:'e.id',hidden:true},
{name:'a.code',index:'a.code', width:100},
{name:'a.descr',index:'a.descr', width:450},
{name:'k.code',index:'k.code', width:80},
{name:'e.equiv',index:'e.equiv',width:100}
],
pager: pager_id,
sortname: 'a.code',
hiddengrid:true,
scroll:true,
height:230,
rowNum:10,
autowidth:true,
caption:'4 - EQUIVALENCE ARTICLES',
gridComplete:function(){
sortDataCol(this);
if($("#"+subgrid_id+"_d").jqGrid('getGridParam','records') < $("#"+subgrid_id+"_d").jqGrid('getGridParam','rowNum')){
$("#"+subgrid_id+"_d").jqGrid('setGridHeight','100%');
}else{
$("#"+subgrid_id+"_d").jqGrid('setGridParam',[{npage:1}]).jqGrid('setGridHeight',230);
}
}
});
$("#"+subgrid_table_id).jqGrid('navGrid',"#"+pager_id,{search:false,add:false,edit:false,del:false});
$("#"+subgrid_table_id).jqGrid('filterToolbar',{stringResult: true,searchOnEnter : false});
fullInputCss();
and the snapshot of result for less than 10 filtered rows :
Now if I press Backspace in search field to obtain more rows, it seems that search doesn't fire because Firebug doesn't show any trace of request :
If I delete added 'setGridHeight' lines in gridcomplete, all runs fine !
I think that one more time I'm wrong in my coding and understanding how jqGrid runs.
Please could someone give me some way to solve this trouble ?
Many thanks in advance. Have a nice day. JiheL
I suppose that the origin of the problem could be id duplicates on your page. Just now I wrote the answer on another your question where I described the problem detailed.
Current implementation of jqGrid (version 4.4.5) has problem in the code of filterToolbar which constructs id for input fields of the filter toolbar based on the following rule:
id="gs_" + cm.name
(see the line of code). It means that the id of the input field for the column a.code will be gs_a.code for every subgrid which you use. So you can have id duplicates.
So I recommend you redesign the naming concept in your code. You can use for example
name: row_id + "a_code", index: "a.code"
In the way the value like "a.code" will be still send during sorting of the grid, but you will have no id duplicates. In some scenarios (is you use repeatitems: false in jsonReader) you could need to use additional jsonmap attribute, but you don't need it in you current code.
Currently, when one searches for an item, the quick search also brings up any bundles that contain items that fit the search criteria. How would I stop this?
A solution that filters out all bundled items from search results all together would be fine too.
UPDATE
I don't want the items to show in either the catalogue or search, but am using them as upsell items. This seems to leave two options:
I could amend the search results controller to omit bundled items (the method I was asking about), or
I could change the Upsell.php script to include "Don't show individually" items.
The second is perhaps easier? Currently the filter applied is:
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_itemCollection);
How would I change this so it shows don't show individually items?
Apologies for the incomplete initial question.
Second Update:
Ok, I've added
->setVisibility(null)
and it already has
->addStoreFilter()
But there is no change.
Essentially, if I don't have either of:
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_itemCollection);
Then I get the following error:
SELECT 1 AS status, e.entity_id, e.type_id, e.attribute_set_id, price_index.price, price_index.tax_class_id, price_index.final_price, IF(price_index.tier_price IS NOT NULL, LEAST(price_index.min_price, price_index.tier_price), price_index.min_price) AS minimal_price, price_index.min_price, price_index.max_price, price_index.tier_price, e.name, e.short_description, e.sku, e.price, e.special_price, e.special_from_date, e.special_to_date, e.manufacturer, e.manufacturer_value, e.small_image, e.thumbnail, e.news_from_date, e.news_to_date, e.tax_class_id, e.url_key, e.required_options, e.image_label, e.small_image_label, e.thumbnail_label, e.price_type, e.weight_type, e.price_view, e.shipment_type, e.links_purchased_separately, e.links_exist, e.is_imported, e.rc_manufacturer, e.rc_manufacturer_value, e.rc_vehicle, e.rc_vehicle_value, e.rc_assembly_type, e.rc_assembly_type_value, e.surface_type, e.surface_type_value, e.rc_drive, e.rc_drive_value, e.rc_scale, e.rc_scale_value, e.rc_motor_type, e.rc_motor_type_value, e.rc_engine_start_type, e.rc_engine_start_type_value, e.rc_engine_size, e.rc_engine_size_value, e.rc_form_factor, e.rc_form_factor_value, e.rc_frequency, e.rc_frequency_value, e.rc_gear_material, e.rc_gear_material_value, e.rc_operation, e.rc_operation_value, e.rc_torque_6v, e.rc_torque_6v_value, e.rc_speed_6v, e.rc_speed_6v_value, e.rc_bearing_type, e.rc_bearing_type_value, e.rc_waterproofing, e.rc_waterproofing_value, e.rc_battery_application, e.rc_battery_application_value, e.rc_input_supply, e.rc_input_supply_value, e.rc_power_output_amps, e.rc_power_output_amps_value, e.rc_power_output_watts, e.rc_power_output_watts_value, e.rc_lead_connector_type, e.rc_lead_connector_type_value, e.rc_gear_pitch, e.rc_gear_pitch_value, e.rc_nitro_content, e.rc_nitro_content_value, e.rc_exhaust_type, e.rc_exhaust_type_value, e.rc_engine_starter_type, e.rc_engine_starter_type_value, e.rc_head_fitting, e.rc_head_fitting_value, e.rc_temperature_rating, e.rc_temperature_rating_value, e.rc_oil_type, e.rc_oil_type_value, e.rc_container_size, e.rc_container_size_value, e.rc_class, e.rc_class_value, e.rc_paint_application, e.rc_paint_application_value, e.rc_size, e.rc_size_value, e.rc_colour, e.rc_colour_value, e.rc_pack_contents, e.rc_pack_contents_value, e.rc_spare_part_type, e.rc_spare_part_type_value, e.rc_oil_weight, e.rc_oil_weight_value, e.rc_glue_type, e.rc_glue_type_value, e.rc_usage, e.rc_usage_value, e.rc_tool_type, e.rc_tool_type_value, e.rc_engine_spare_type, e.rc_engine_spare_type_value, e.rc_tune_up_type, e.rc_tune_up_type_value, e.rc_bearing_pack_type, e.rc_bearing_pack_type_value, e.rc_driver_type, e.rc_driver_type_value, e.rc_nut_type, e.rc_nut_type_value, e.rc_plane_type, e.rc_plane_type_value, e.rc_boat_type, e.rc_boat_type_value, e.pre_order, e.pre_order_value, e.msrp_enabled, e.msrp_display_actual_price_type, e.msrp, links.link_id, link_attribute_position_int.value AS position FROM catalog_product_flat_1 AS e
INNER JOIN catalog_product_index_price AS price_index ON price_index.entity_id = e.entity_id AND price_index.website_id = '1' AND price_index.customer_group_id = 0
INNER JOIN catalog_product_link AS links ON links.linked_product_id = e.entity_id AND links.link_type_id = 4
LEFT JOIN catalog_product_link_attribute_int AS link_attribute_position_int ON link_attribute_position_int.link_id = links
I've also tried the following, but get the error:
Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_itemCollection);
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this->_itemCollection);
Thanks for the help.
Based on your updated question:
If you are not using Enterprise Edition TargetRule or some other module which automates upsells (i.e. the upsells are defined explicitly by the admin), then likely the simplest approach is that which you've specified - rewrite the Upsell block to not add the visibility filter. As a guess, to be optimal you may want to call setVisibility(null) and addStoreFilter() on the collection to trigger normal limiting behavior.
EDIT: Original answer below
Admin > Catalog > Manage Products grid
Choose "Bundle Product" from the filters area at the top, click "Search"
Click "Select All"
Select "Update Attributes" from the mass action block's "Action" dropdown, click "Submit"
Change the "Visibility" attribute to "Catalog"
I solved it by modifying the custom module so that I didn't need to worry about this. It may be of some use as it involved using:
$collection->addAttributeToFilter('type_id', array('neq' => 'bundle'));
Which just excludes all bundle items from a collection.