Buddypress Conditional Profile Fields - wordpress

Is there any way I can create custom/conditional registration/profile fields in buddypress.
I tried Googling a lot about this, but I am not getting proper solution.
The condition what I am thinking of is :
I want to create 2/3 dropdowns, suppose if 1st one contains vehicles type(car, bike,),
then the second dropdown's option should change according to what user is choosing in dropdown 1.
any help would be appreciated.
Thanks a ton in advance. :-)

Currently there is no working plugin or hack for that. I saw such thing on some sites - but this is done via JavaScript and heavily modifying of a registration page source code.

It will be little tricky unless you touch register/resgistration.php source.
you can do like this if you little familiar with jquery.
Theres a hidden field ( id "signup_profile_field_ids" ) in buddypress registration form which tells server what fields in registration form, it will look like
<input type="hidden" name="signup_profile_field_ids" id="signup_profile_field_ids" value="5,11,1,10,32">
value of that field contains field ids of the registration form.
Now, you need to select a parent field to show conditional fields. you need to know parent and conditional field ids
now use this jquery code
<script type="text/javascript">
$(function(){
var childs = new Array("Child id 1","Child id 1"); // your child fields ids
var options = new Array("Car","Bike"); // your parent field options, notice option and child number is same, which means, one child for one option
var parent = "Parent Field id"; // place you parent field id
var currentFields = new Array();
currentFields = $("#signup_profile_field_ids").val().split(','); // take all current fields ids in an array
$.each(childs, function(index,value){
$('#field_'+value).parent().hide(); // hide all child fields first
currentFields.splice(currentFields.indexOf(value),1);
});
$("#signup_profile_field_ids").val( currentFields.join() );
$('#field_'+parent).after('<div id="conditional-fields-conteiner></div>"');
$('#field_'+parent).change(function(){
var option = $(this).val();
var appendField = childs[options.indexOf(option)];
var html = $("#field_"+appendField).parent().html();
$('#conditional-fields-conteiner').html(html);
$.each(childs, function(index,value){
currentFields.splice(currentFields.indexOf(value),1);
});
currentField[] = appendField;
$("#signup_profile_field_ids").val( currentFields.join() );
});
});
</script>
This may seems complex, but this is the easiest approach. if you are planning it in membership site, dont use it. user can manupulate conditional fields simply by editing html.
Theres also a plugin for this, going to release soon. I am developing it
http://rimonhabib.com/coming-up-next-buddypress-nested-conditional-fields/

Related

Styling contact form 7

I have made a contact form with contact form 7. Due to the styling of the theme, the selectbox does not work properly.
You cannot select multiple options and you can scroll in the select box instead of it expanding as a dropdown.
Can someone help me with this?
url: https://www.lghairdressers.nl/basis-opleiding/
The issue you are facing is that the select field has multiple=true, and this is the default styling for multiple fields.
If you want to retain a dropdown list for a multiple select, you will need to convert your field using a JavaScript plugin such as a HybridDropdown field using the following script on your page,
<script type="text/javascript">
(function(){
let sel, hyd;
document.addEventListener('DOMContentLoaded', (e) => { //instantiate on document ready.
sel= document.querySelectorAll('.wpcf7-select');
sel.forEach(function(){
hyd = new HybridDropdown(this,{});
})
})
})
</script>

Include specific attribute or child-element text in breadcrumb rendering

Within the author it displays a breadcrumb, and I know you can modify its display to either some other static text or localisation, but I'm wondering if it's possible to dynamically show an attribute, or execute some other context-specific xpath dynamically.
As a test I can change the breadcrumb using the localisation editor variable ${i18n()}.
cc_config.xml
<elementRenderings platform="webapp">
<render element="num" as="${i18n(test)}" annotation="${i18n(test)}"/>
translation-cc.xml
<key value="test">
<comment></comment>
<val lang="en_US">Year</val>
"Year" is actually a num element.
However, trying any other variable, even 'more static' ones like ${cf} or ${tp} simply render the variable text literally, instead of evaluating it.
cc_config.xml
<elementRenderings platform="webapp">
<render element="paragraph" as="${xpath_eval(./#eId)}" annotation="${xpath_eval(./#eId)}"/>
<render element="p" as="${tp}" annotation="${tp}"/>
(paragraphs do have an eId attribute)
As you can see, I tried using annotation; but these tooltips also simply display the variable literally.
I also fiddled and tried a bunch of xpath stuff, like #eId/.#eId//#eId, but I think there's some restriction in using the Content Completion Configuration File with respect to editor variables.
So is the thinking right but I am doing something wrong, or is it not the right way but there is some other way to affect the breadcrumb? Maybe with the schema?
The element display names in cc_config.xml file do not support most of the editor variables. Most of them, like ${cf} (current file) and ${tp} (total number of pages) don't make sense to be used when rendering the name of an element.
The xpath_eval would make sense - the display name of an element may depend on its attributes (e.g. the #id attribute), it's index in the document (e.g. 'Section 3'), etc. We have a feature request registered for this case and I added your vote to it.
As a partial workaround you can use a JS API to compute the display name of the element based on the element original name and its attributes:
goog.events.listen(workspace, sync.api.Workspace.EventType.BEFORE_EDITOR_LOADED, function(e) {
e.options.elementNameEnhancer = function(elemName, attrs) {
var displayString = elemName;
var attr = attrs['id'];
if (attr) {
displayString += ' (#' + attr.attributeValue + ')';
}
return displayString;
};
});

Need suggestions to handle view updates

In an application currently I am loading my views using routers like below
router('menu/:item', function (item) {
app.uiHandler.toggleMenuSelected('menu', item);
// The below method updates the view with selected menu item's model.
app.channel.publish('menu', item);
});
Currently each menu item shares same data object. But the master view is replaced with new html based on each menu selection.
I am thinking to have instance like below for each menu item
var ractive = new Ractive({
el: 'container', // el is same for all instances.
template: '<p> I am {{selection}}, after {{prevSelection}}!</p>',
data: { selection: 'Home', prevSelection: 'Profile' }
});
But here my doubt is as I will be invoking each instance to render the view into 'container' whenever hash is changed how to clear all the two way data bindings created when master view is replaced with new html. Please help me on this.
If I am handling in wrong way, what would be the best way to handle the same.
Note : My question might sound like stupid, but I am looking for clarification on this :)
how to clear all the two way data bindings created when master view is replaced with new html
You can use teardown() to destroy the ractive instance, but if you don't ractive will do that automatically as soon as you try to render a new instance into the same container.
That said, it's probably better to have one instance and only update the data. I.e. when the section changes call ractive.set({ selection: 'Profile', prevSelection: 'Home' }).

Subscribing to changes in a Collection but not in a template

I'm very new to meteor, so apologies if I'm missing something very basic here.
I thought it would be fun to create a very simple textpad style app to check out meteor. I took the todo app and changed the data structures to be 'folders' and 'docs' rather than 'lists' and 'todos', so I have a list of folders and when you click on the folder you get a list of the documents in that folder.
I've then added some code to show the 'content' attribute of a single 'doc' when one of the docs in the list is clicked.
I'm using ace to add some pretty print to the content of the doc (https://github.com/ajaxorg/ace). I've set ace up to work with a hidden textarea containing the plaintext version of my document, and the editor object takes this text and pretty prints it.
The problem with ace is that I don't want the template containing the ace editor to be replaced every time the contents of the doc changes (as it takes half a second to reinitialise, which is a crappy experience after every character is typed!). Instead, I want to update the textarea template and then use the ace API to tell the editor to update it's input based on what is in the textarea.
Now, this is probably the wrong way to approach the problem, but I've ended up using two templates. The first contains a textarea containing doc.contents, which is reactive to the underlying model:
<template name="doc_content">
<textarea name="editor">{{content}}</textarea>
</template>
The second one contains the 'editor' div which ace uses to display the pretty printed text.
<template name="doc_init">
<div id="editor"></div>
</template>
The idea is that the first template will update every time the user types (on all clients), and the second template is only ever re-loaded for each new doc we load.
Template.doc_content.content = function() {
var doc_id = Session.get('viewing_itemname');
if (!doc_id) {
return {};
}
var doc = Docs.findOne({_id:doc_id});
if (doc && doc.content) {
// #1 Later
var editor = Session.get('editor');
if (editor) {
editor.getSession().setValue(doc.content);
}
return doc.content;
} else {
return '';
}
};
When you enter text into the editor div I make a call to Docs.update(doc_id, {$set: {content: text}});, which updates the value in the textarea on each client. All good so far.
editor.getSession().on('change', function(){
var text = editor.getSession().getValue();
Docs.update(doc_id, {$set: {content: text}});
});
What I want to do, for all clients other than the client which made the change, is to subscribe to the change for that doc and call editor.getSession().setContent() with the text which has just been changed, taking the text from the textarea and using it to fill the editor.
I've tried to do this by making that call from the template containing the textarea (as this changes whenever the doc is updated - see #1 above). However, this puts the clients into an infinite loop because changing the value in the editor causes another call to Docs.update.
Obviously this doesn't happen when you render a template, so I'm assuming there's some magic in meteor which can prevent this happening, but I'm not sure how.
Any thoughts?
TIA!
There's a lot to absorb in your question, but if I understand correctly, you might simply be after Deps.autorun:
Deps.autorun(function () {
var doc_id = Session.get('viewing_itemname');
if (!doc_id) {
return {};
}
var doc = Docs.findOne({_id:doc_id});
// do stuff with doc
});
Deps.autorun is really useful in that it will get re-run if any of its
dependencies change. These dependencies are limited to those that are "reactive"
such as Collections and Sessions, or anything that implements the reactive API.
In your case, both Session.get and findOne are reactive so if their values
change at all, Deps.autorun will run the function again.

Collapsible comments in Drupal 7

I'm using the latest Drupal 7.2 core and I have no idea how to solve my problem. I'd like to collapse all nodes comments (there's lots of them) and expose them for the user when he presses 'show comments'. I know it has something to do with the fieldsets (or maybe I'm wrong), but where, what and how ?
Every helpful answer will be appreciated.
Thanks in advance.
I wrote a begging private message to one of the contributors and he posted a working solution for collapsible comments in D7 - http://drupal.org/node/94035#comment-4674734
So i tried a bunch of ways as suggested here.
The thing I ended up doing since I was trying to basically just put all the comments stuff into a collapsible fieldset is outlined here:
Go into the Content Type -> Manage Display.
Create an empty fieldset called something like Comments (You'll need fieldset/fieldcollection modules)
Once you have the group, grab the field_groupname for later use in code.
In your theme's template.php, or whereever you have the render arrays you'll have something like this to basically add the "comments" object into the group fieldset you just created.
function mytheme_preprocess_node(&$vars, $hook){
$tempField = null;
// Copy the comments / comment form into a variable.
$tempField = $vars['content']['comments'];
// Rename some of the labels, use the markup
$tempField['#title'] = "DMS URL";
$tempField['#field_name'] = "field_comments";
$tempField[0]['#markup'] = $vars['content']['comments'];
// Add it into the group (fieldset/group name you copied)
$vars['content']['group_commentsgroup']['field_comments'] = $tempField;
}
This will basically add your comments markup into an empty fieldset/group you created using node's manage display using fieldset/fieldcollection. Also, I was using ajax_comments for this.
This is more of a tip than an answer to your problem, but our website stopped using Drupal comments since they were too basic and moved to use the free service called Disqus
After a looong time of searching For Individual Collapsible comments I found a solution, where you can put your comment replies in an individual collapsible fieldset. :)
Below code in script.js
Include the js in .info file as scripts[] = js/script.js
(function($) {$(function() {
// Hurry up and hide the comments and its replies, if present. In most browsers, this
$('.indented').hide();
// The Comment section will be turned into a toggle to
// open/close the comments
$('.comment').addClass('closed').bind('click', function() {
var $self = $(this),
$form = $self.siblings('.indented'),
speed = 250; // speed of animation, change to suit, larger = slower
if ($self.hasClass('open')) {
$self.addClass('transition').removeClass('open');
$form.hide(speed, function() {
$self.addClass('closed').removeClass('transition');
});
}
else {
$self.addClass('transition').removeClass('closed');
$form.show(speed, function() {
$self.addClass('open').removeClass('transition');
});
}
});
}); })(jQuery);

Resources