I am experienced Java/C++ programmer, but totally new to Drupal/PHP.
Short question:
How do I refresh all the blocks in my page, based on the input to a particular block?
Exact Scenario:
I am looking to create a website with display and behaviour similar to http://www.google.com/finance. I have started creating a custom module for this in Drupal 7, So we want to have:
a top input block where users can enter a particular company's name.
a main block which starts with general content (e.g. tables plus latest news about the economy etc). As soon as a company is selected in block 1, this changes to news and tables about the chosen company.
a side graph block displaying some relevant graphs etc. Again, when no company is chosen, this could display the general graphs (e.g. S&P, Dow Jones, NASDAQ), and when a company is chosen, this displays the details for the chosen company.
The way I see it, the website works in a "current context" for the user. So, perhaps I can set a session level variable in Drupal, and refresh all blocks based on the current value of this variable?
However, I am not sure how to achieve this, and what is the best way to do this? (AJAX? Taxonomy?)
Any pointer, hints, suggestions, examples, sample code are most welcome.
This is how I would approach this problem based on how you have described it. The majority of the functionality being handled by the Views module.
I'm assuming you have the following setup:
A Taxonomy vocabulary called "companies" which has company names as
terms.
A Content Type called "News", which has news information about
companies. Most importantly it will need a taxonomy field where you
can select which companies it is related to (lets call this field "company_reference")
A Content Type called "Tables"(?). I'm not sure what information you
want in your "tables", but again it's most important that is has a
taxonomy field to reference companies. (can be the same field "company_reference")
The Majority of the functionality you are looking for can be built using the Views module.
I would create a View (let's call it "Company Data"). the view is going to have three different displays, each of type "block".
Display 1: Input Block
Set the display name to something meaningful, say "user_input_block"
For this block, leave FORMAT settings as they are.
For the FIELDS settings, just have "Content: Title" (does not
really matter for this block).
For the FILTER CRITERIA settings, add a filter and select your
"company_reference" field, set it to auto-complete, expose the filter
to visitors and (under the "more" section) change its Filter Identity
to "company".
For the PAGER settings set it to display a specific number of items and set it to '1'. (this will limit the data this block retrieves)
Under the Advanced section change the "Machine Name" so comething meaningful, say "user_input_block"
Still in the Advanced section click on "Theme: Information". this will display a list of the different custom template files you can have for this view. For "Display Output" write down the last template suggestion in the list, it will be something like "views-view--company-data--user-input-block.tpl.php" ("views-view--{your view name}--{your display name}.tpl.php"). Click on "Display Output" and copy the PHP it lists. (this is the views default PHP for the view).
In a text editor/IDE (whatever you use) paste the copied PHP code and save it in your custom theme with the template name you wrote down. Edit the PHP and either comment out or remove the section that says "<?php if ($rows): ?>...<?php endif; ?>" (this will remove the returned content from the display)
So to review the view display that was just created will (using the custom template) display a block with just a field that as the user is entering a company name it will autocomplete. It will then submit the form and pass it as a GET variable to the current url (www.yoursite.com/yourpage?company=users company").
Display 2: ** Main Block**
Set the display name to something meaningful , say "company_news".
Set the FORMAT settings to which ever you like (or leave as is)
For the FILTER CRITERIA add a "Content:type" filter and select your "News" and "Tables" content types.
In the Advanced section click "add" next to "Contextual Filters". )A contextual filter is passed in the URL, we are going to be grabbing the value that was passed from the Input block.) Select "Content: field_company_reference" as the field and click "Apply"
for the "when the Filter value is Not available" section select "provide default value"
for the "Type" select "PHP code" and the PHP code will be something like this "return isset($_GET['company']) ? $_GET['company']:false;"
for the "When the filter is available of a default is provided", check "Specify validation criteria", set "Validator" to "Taxonomy term", check the "Companies" vocabulary and for "Filter value type select "Term name converted to Term ID"
for "action to take if filter value does not validate" select "display all results"
To review, this view display will display a block that lists "news" and "tables" content. If the GET variable "company" is passed (from the input block) then the content of this block will be filtered to display only content that is associated to that block.
Display 3: ** Graph Block**
I'm not exactly sure what data you want to display in this block (or rather where it would be coming from) but if you set it up like how I described setting up the Main Block it will filter by company (use the same contextual filter and content that has the company taxonomy reference field).
The one difference with this approach is that it requires the page to be reloaded when a user enters a company into the input block. If you want to avoid this then you could make the following changes;
for the main block and graph blocks instead of using a contextual filter use a regular filter for the Company reference field (same settings as were setup in the input block). For both these blocks under the Advanced section, set "Use AJAX" to "Yes", and use custom CSS to hide the exposed filters from view.
with a custom module (or with your custom theme) that adds additional JS to the page. Have the JS triggered by the field in the input block, when a user enters a value into it, the JS copies that value into the exposed (but hidden) field for the other blocks, triggering Drupal to reload them via AJAX with the passed filter.
I haven't tested any of this and it is just theoretical based on my knowledge of Drupal, but it should start you out on the right path.
Related
I am looking to hide/show some fields depending upon user selection on another field. So a user can select among four wheeler/two wheeler. If user selects four wheeler from a dropdown he is shown different set of fields and for two wheeler different set of fields . As there are many common fields I am looking to use same content type for both content type
What I have tried so far is
Theme_name_form_alter hook in theme_name.theme file
As well as hook_form_FORM_ID_alter
None seems to be working for me
while Conditional Field module still is in development on Drupal 8 So
Field Formatter Condition Module could be a good choice.
Simple conditions and actions
Hide source field when target field is empty. Hide source field when
target field is not empty. Hide source field when the current user has
specific roles. Hide source field on specific pages. Hide source field
when target field contains a specific string. Hide source field when
target field doesn't contain a specific string. Hide link field if
title is empty. Hide date field if smaller/greater then today/custom
date. Hide if content from author Hide if checkbox is checked (in
current dev version)
Module conditional fields is still dev for Drupal 8 but should work:
https://www.drupal.org/project/conditional_fields
And in case "Conditional fields" is not working for you maybe "Paragraphs" can jump in as replacement. It's stable at least.
https://www.drupal.org/project/paragraphs
Not exactly what you were asking for, but can do the job.
I'm working on a plugin that allows the user to create "page/post types", customize the type style, then tag a page/post with that type. All of this works. My problem is this plugin also needs to allow them to attach widgets to said type.
I have no way of knowing how many "types" there are at any time.
The plugin works like this:
User creates types (cat, dog, mouse)
User specifies things like background colors, link colors, etc. for a type
User specifies widgets for that type
When the page/post is viewed the page detects if it has a type. If it does it pulls in all the relavent data to that type.
Everything works PERFECT.
I know I have to register a sidebar but I can't registe for each type since I have no idea how many there are and the user can create and delete at their whim.
My plan:
Register a sidebar called "custom sidebar"
Create a page that mimics the "Widgets" page
Allow the user to add widgets there on the "custom sidebar"
The plugin stores data for the sidebar based on the "type"'s id
I can't really use another plugin since the sidebar function has to meld right into my plugin. I'm not even sure this will work or even where to start. Any push in the right direction would be great!
I created a single sidebar and added an option for each widget where the user selects the meta option. The page get the needed meta data and compares it to each widget in the special sidebar. If the meta matches it shows that widget.
I've just started using D7 and was trying to set up a system where people can add a couple types of content and associate one with the other via nodereference.
I only want users to be able to see and work with their own content.
To achieve this in D6 I used a view for nodereference.
In D6 I used argument : user: uid and if there is no arg, it uses the user id of the logged in user. This would return all of the content that was authored by the user.
I haven't been able to figure out how to do this in Views 3?
got it:
you first need to add a User relationship, then you will see new filters and contextual filters - one of which is "current user" or something like that
This five minute video shows how to do it, as well: http://nodeone.se/sv/node/684
With contextual filters you can also display the list as a tab on each user page (as shown in the screencast).
If you're interested in a list that always shows the current user's posts, you can use a standard filter instead – there is a "current user" filter available.
Edited: The original link is broken. I'm not sure which video it was, but it could be one of the following (which all deal with this topic).
https://vimeo.com/22276809 Video guide
https://vimeo.com/33588889 Exercise description
https://vimeo.com/33588956 Exercise solution
For drupal 7
Steps for doing as the above question are
Create a new content view and limit it to the content type you want.
Uncheck "Create a page" and check "Create a block." Select the format you want; I recommend an HTML list of linked titles. Click "Continue & edit."
Add a contextual filter for "Content: Author uid."
Under "When the filter value is not available," select "Provide a default value," and select "User ID from URL" from the dropdown. Because blocks don't understand contextual filters very well, the view won't work properly without this default value, and all posts of the given content type will show on all user pages (not just the user's own posts).
Under "When the filter value is available or a default is provided," check "Specify validation criteria" and select "Basic validation" as the validator. Select "Hide view" from the dropdown.
Save your view.
Assuming that you created a block display, the block will now be available on the Blocks page. Go there and open it.
Set your block to display on all user pages (/user/*) in the correct region. Save the block.
Your block should now appear on all user pages, showing the content written by each user.
Source
I'm using drupal 7. I created a view for displaying nodes of a specific content type (e.g. products). When viewing the page, I want only those products displayed which were created by the user (currently shows all products).
I would like to do it without using a url filter so the url would be simply:
/myproducts
Use the filter "User: Current". If that doesn't work, try with a relationship
With the Advanced Help module you can see "Example to filter content by the current logged-in user": http:// yoursite /help/views/example-filter-by-current-user
And there said:
Creating the relationship
In order to have access to the author of the content, it is important to create a relationship between the current content type, and users.
Under Advanced in the right column, select add next to Relationships.
Select Content: Author and click on Add and configure relationships. Leave the settings as they are and click on Apply (all displays).
You now have access to the user data related to the content you are viewing.
Filtering the view
Now you need to filter the view to display only content authored by the current user. This >data is now available for the content because you have created the relationship in the step >above.
Next to Filter criteria click on add to add a new filter to your view.
Filter the list of fields by selecting User next to Filter at the top. You now have more >fields than before due to the relationship you created.
Select User: Current from the list and click on Add and configure filter criteria.
Since this field is only visible due to the relationship you created, author will already be selected under Relationship. This shows that the relationship you created is being used for the filter field.
Select Yes under Is the logged in user, and click on Apply (all displays).
If you have authored content of the type Blog Post, you should now see a list of those posts under the preview section at the bottom.
Saving & testing the view
Here's what I used to make it work.
Under relationships, add content:author
Under contextual relationship, add user: authentication name and relationship: author (or whatever you called your relationship).
And if you want to be even more sure, add to filter: user current and add relationship.
I'm working with Drupal 6 to create a feed collecting site. I import the original feeds via the feeds module and copy their tags. But I also want to assign a category (terms from second taxonomy) according to the author name to be able to divide the content in a unified way.
I want to use the rules module (rules-6.x-1.2) to assign these categories upon import. I use the following steps:
ON event Content is going to be saved
IF textual comparison ([node:author-name], TheAuthorName)
DO Modify node taxonomy terms (saved content, permanently, add the selected terms)
I select the terms to be added as "-none selected-" for tags and "TheCategory" for categories.
Now, when I import the feed, the category "TheCategory" is added to the content, but the tags vanish.
This happens also if I select "Replace existing terms with selected ones" or "Replace terms within same vocabulary" for the action. Upon editing, always the radio button of "add …" is selected, regardless of what I entered previously. And yes, I clicked on "save".
Is this the right way to do what I want? Why isn't it working? Could I do this with another module maybe (I don't need rules for anything else …)?
Thanks for your help!
Ok, so I found out that the right trigger to do this is "new content is created" (which I somehow couldn't get to work beforehand).
So, I ran the rules module in debug mode and found that the rule was triggered, the filter returned TRUE and the modify node taxonomy action was successfully accomplished. But the taxonomy was entirely unchanged.
I played around a little and postponed a "save content" action on the newly created content. Turns out, this fixed the problem and now everything works as I intended.
Still, there are some flaws:
I checked "permanently apply changes", but it did not do anything.
I unchecked "permanently apply changes", but upon editing again, the box was checked again (probably the setting was not saved to begin with)
The same holds true for the radio buttons for the type of "modify node taxonomy" action which was obviously not saved
Maybe this can help someone.