In the Bricolage CMS, what is the way to check whether a story has a particular field (in this case called 'teaser') set?
Do you mean in a template? If you want to know if a story has a field in a template, you can use either the get_field() or the get_value() method. Use get_field() if you just want to know if the field is present, as it returns a Bric::Biz::Element::Field object (I assume Mason templating here):
if (my $field = $element->get_field('teaser')) {
$m->print('<p>', $field->get_value, "</p>\n");
}
If you want to know if a field has a value, you use get_value():
if (my $val = $element->get_value('teaser')) {
$m->print("<p>$val</p>\n");
}
That method will return undef if there is no field object, and the value of the field object if it exists. Note that if the value is an empty string or 0, nothing will be printed there, either.
But it's important to note that Bricolage documents are organized in a tree structure of elements. The best way to create templates is one for each container element. The above example, might be in a top-level "story" element template, where $element will be the top-level element itself. But if your "teater" field is in a subelement, say "Metadata", you'll want to create a "metadata" element template with the above code, and call it from your story element template, like so:
$burner->display_element('metadata');
See Bric::Templates for an introduction to Bricolage templating and the API.
HTH,
David
Related
I have a page where I need to display testimonials, In that page document type I have a field to assign testimonials by using page selection, so It will save the GUID of selected testimonial in the database,
I have used following code to display the description of Testimonial, But is there any other way to get the document fileds by passing the GUID,
One option I can use is write a custom macro.
{% Documents["/Page-Resource/Testimonial/Testimonial"].getValue("Description") #%}
Note: I have used the text/xml type transformation
Well it's not that easy but there is one way and that is to use loops:
r = ""; foreach (i in CMSContext.Current.Documents) {if(i.NodeGUID == "a88f82be-bb76-4b82-8faf-5253209f0f75"){r = i}}; r.Description
Notes:
Use NodeGUID or DocumentGUID based on what you store in your custom field.
Replace the hardcoded guid with something like CMSContext.Current.CurrentDocument.YourDescriptionFieldWithGuid
See the documentation if you have any doubts about K# syntax
I've built a Zend_Form_Decorator_Input class which extends Zend_Form_Decorator_Abstract, so that I could customize my form inputs -- works great. I ran into a problem in the decorate class, in trying to get the form name of the element, so as to built a unique id for each field (in case there are multiple forms with identical field names).
There is no method like this: Zend_Form_Element::getForm(); It seems Zend_Form_Decorator_Abstract doesn't have this ability either. Any ideas?
I don't think changing the id from the decorator is the right approach. At the time the decorator is called the element already has been rendered. Thus changing the id would have no effect to the source code. Additionally, as you already have pointed out, the relation between a form and its elements is unidirectional, i.e. (to my best knowledge) there is no direct way to access the form from the element.
So far the bad news.
The good news is, that there actually is a pretty easy solution to your problem: The Zend_Form option elementsBelongTo. It prevents that the same ID is assigned to two form elements that have the same name but belong to different forms:
$form1 = new Zend_Form(array('elementsBelongTo' => 'form1'));
$form1->addElement('Text', 'text1');
$form2 = new Zend_Form(array('elementsBelongTo' => 'form2'));
$form2->addElement('Text', 'text1');
Although both forms have a text field named 'text1', they have different ids: 'form1-text1' and 'form2-text1'. However, there is a major drawback to this: This also changes the name elements in such a way that they are in the format formname[elementname]. Therefore $this->getRequest()->getParam('formname') will return an associative array containing the form elements.
How can I change a href attribute value using watir-webdriver without using js/jquery?
I can get an attribute value:
#browser.frames[2].div(:id,"mid-2").link(:class,"btn-lrg").attribute_value("href")
But I also need to change a bit of the href attribute value.
I think that the only way to modify the link is to use javascript. The code is quite maintainable since the element is retrieved using watir.
#Get the first link (or any element you want)
element = browser.frame.link
#Check element's initial attribute
puts element.attribute_value('href')
#=> "page_a.html"
#Execute javascript to change the attribute
script = "return arguments[0].href = 'page_b.html'"
browser.execute_script(script, element)
#Check that the attribute has changed
puts element.attribute_value('href')
#=> "page_b.html"
I have text box in which your adds values in comma separated values. Once the form is post I want to check each of CSV value against database table that if each one of them exist already. If so then I want to throw error message otherwise that is fine.
How can I implement this?
What you need is a custom validator. you can either do it extending Zend_Validate_Abstract or you can simply use a callback validator.
To do so, you need to add this to your element:
$elem = new Zend_Form_Element_Text('elem_name');
$elem->setLabel('Label Name:')
->setRequired(true)
->addValidator('callback', true, array('callback' => array($this, 'functionName')));
$this->addElement($elem);
And in the same class (usually your form is in a class that extends Zend_Form), you add this method:
public function functionName($csvString) {
// stuff here using explode(',', $csvString)
// foreach() to iterate over the result and match against the db each $value
}
See explode() for more information.
However, if your form element is going to be called more than once, and in different forms, then I don't recommend you to use a callback, but you'd better write your own validator, the theory remains the same though. Take a look here for more information about how to write validators.
I really doubt that this can be achieved directly just using Zend_Validate_Db_RecordExists. I think the best solution would be to create a custom validator for this purpose. Something that would take your value then explode it based on a , $valueArray = explode(',', $value); and then for each $valueArray check if the element exists in the db. This shouldn't be too hard. If you dont have idea about custom validators this might be helpful.
Does anyone know of an easy way, using jQuery, to select all <select> elements whose val() attribute yields a certain value?
I'm trying to do some validation logic and would like to just select all those elements with a single selector, then apply a warning class to each of their parents. This I know how to do once I select all the elements, but I didn't see a selector that handles this case.
Am I going to have to select all of the <select> elements into a selector, then iterate through them and check each of their values? I was hoping there would be a simpler way.
Thanks.
Why doesn't select[value=x] work? Well firstly because <select> doesn't actually have a value attribute. There is not a single value of a select box: there may be no selected options (there shouldn't normally be, but there can be in at least IE), and, in a <select multiple>, there can be any number of selected options.
Even input[value=x] doesn't work, even though <input> does have a value attribute. Well, it does work, it just doesn't do what you think. It fetches the value of the value="..." attribute in the HTML, not the current value you have entered into the form. The value="..." attribute actually corresponds to the defaultValue property and not value.
Similarly, option[value=x][selected] doesn't work because it is checking the <option selected> attribute from the HTML source (selected attribute -> defaultSelected property) and not the current selectedness of the option (selected property not attribute) - which might have changed since the page was loaded.
Except in IE, which gets the value, selected etc form attributes wrong.
Except (again): Tesserex's example may seem to work, and the reason for that is that that it's using a non-standard jQuery-specific selector, :has. This causes the native querySelectorAll methods of modern browsers to fail, and consequently jQuery falls back to its own (native JavaScript, slow) selector engine instead. This selector engine has a bug where it confuses properties for attributes, allowing [value=x] to do what you expected, and not fail like it should! (Update: this is probably no longer the case in newer jQuery versions.)
Summary: form field state checking and selectors don't mix. Apart from these issues, you also have to worry about escaping issues - for example, what if the value you want to test against contains quotes or square brackets?
So instead, yes, you should check it manually. For example using a filter:
$('select').filter(function() {
return $(this).val()==='the target value';
}).parent().addClass('warning');
(There is a value property in HTML5 and supported by modern browsers, that when you read it gives you the value of the first selected <option>. jQuery's val() is safe to use here because it provides the same method of getting the first selected option even on browsers that don't support this.)
The existing answers don't work on select tags, but I found something that does. Ask for a select that has a selected option.
$("select:has(option[value=blah]:selected)")
You can use :
$("select[value=X]");
where X is the value against which you want to check the select's value.
Attribute selectors Is what you're looking for I believe.
Something like $+('element[attribute="value"]')
See also:
*= anywhere
^= starts with
$= ends with
~= contains word
etc.
You can create a change event that puts the value in a custom attribute on the select element whenever the value changes. You can then use a simple selector to find all of the select elements that have that value. For example:
$("select").on("change", function (e) {
var $select = $(e.currentTarget);
$select.attr("select-value", $select.val());
});
And then you can do this:
var $matches = $("select[select-value='" + searchVal + "']");
$matches will have all of your matching selects.
This is a lot easier than having to iterate through elements. Remember to set select-value to the initial value when rendering the page so you don't need to trigger a change event for each select so the select-value is set.