How do I get Zend_Navigation to work with database defined data? - zend-framework

I've got a Zend_Navigation component I use to display breadcrumbs on a page. It currently says something like:
"Companies > Edit a Company"
when displaying the edit form. I would like to make it say something like
"Companies > Editing FooBar"
What's the best way to accomplish that?

I had the problem that I wanted to show breadcrumbs even when the parent is set to not visible. Drove me nuts until I found the reason. Your problem is not much different, I think.
I have a unique ID set with basically all links; hence, I can fetch all nodes like the following:
// in view scripts
$navObject = $this->navigation()->findOneById($id);
// now you can manipulate the object however you like
$navObject->setLabel('Editing FooBar');
You can find the node by other means, there is findOneBy() method where you have to pass the target object.
Once I printed the breadcrumbs I had to reset setVisible(false) to the old value, though. Depending on your needs you might have to reset the label, too.

Related

How to separate option values and text in drop-down form control?

Editing a simple (so far) form in Kentico 11. I am creating a drop-down. All I want to do is to have the value of each rendered option and the visible text of each option be different, like this:
<option value="CatalogNumber">Product name</option>
so that when I refer to the Value property of the drop-down I get the (in this case) CatalogNumber, but the user sees the product name. This is surely something people do every day, but I can not find anything in the doc, or on DevNet, explaining how to do it. Am I missing something so obvious that no one finds it necessary to mention?

How does one get the total number of slides?

In Articulate's Storyline product, how does one retrieve the total number of slides (or pages) in a storyfile or project?
There's not much documentation so it's kind of hard to figure out how to query common environment values like this. If we can get the total number of slides then we don't have to manually set a value for it.
One must manually set and update a variable to store the number of slides.
The most lengthy conversation on the matter seems to be found here at the Articulate forums.
In that thread the users and staff describe the need to manually define such a variable.
I asked the question on the official forum more directly here, and so far have not received a response.
Another poster at that forum mentioned using PHP to solve this problem, but unfortunately we can't add the requirement of PHP to the final product. I'm sure some server side language tricks might be used to solve this issue, but that also adds the dependency of a particular server-side language.
The Answer Mark gave is correct. So if you want to track the number of question slides in a quiz you would either hard code the value in a variable such as totalQuestions, or increment it as you go through each slide using adjust variable trigger. To call that value and display it on screen you would just add it to a text field and surround it with "%".
EG. "You have answered %Results.ScorePoints% out of %totalQuestions% questions correctly."
I find it rather pointless to hard code it since it's just as easy to put the value in the text field at the end. Using the increment method seems more logical because then you can add more question slides without having to adjust the variable or results screen each time.
I usually load frame.xml, browse for all slidelink tags and sort all slides by their Id.
Usually you get something like slideid=_player.5xoxGTW6QCh.6bmeRt3tCqP, where 5xoxGTW6QCh is the scene id and 6bmeRt3tCqP is the slide id. displaytext also gives you the slide title.
If you browse for slidetranscript and match the Id for each transcript you also get the slide notes.
Articulate 360 now has an internal (Built-in) variable for this and other counts. See Project.TotalSlides and Menu.TotalSlides
See https://community.articulate.com/series/articulate-storyline-360/articles/storyline-360-add-slide-numbers

Drupal 7 - Hide certain form fields of a content edit form depending on the content data

In Drupal 7, is there a way to change the standard edit form for a content type based on a certain content?
For example:
I have a content type with a checkbox...once it it checked and the form is saved, I do not want this checkbox to be visible anymore...therefore based on the checkboxes value in the Database I want to hide form fields when showing the form.
I am building a small specific project site, where a company wants to add projects, and their customers are supposed to follow certain steps (upload some content, provide information etc.), and also should be able to check off certain requirements, and once these are checked off, they should not be visible/editable to them.
Also the displayed form fields should depend on an user's role, and then FURTHER be limited depending on the content's database entries.
Is there a module, which could achieve this behaviour? "rules" and "field/permissions" come close to what I need, but are not sufficient. Or did I just miss the option to change a form field's accessibility based on conditions?
What I need is some place to define a logic like "IF (VALUEOF(CHECKBOX_1) == TRUE) THEN DO_NOT_SHOW(CHECKBOX_1)"
hook_form_alter is the way to do this, as explained by Mihaela, but what options do you have inside that function?
If you want just to disable field (it will be visible, but user can't change it) you can do it like this:
$form['field_myfield']['#disabled'] = TRUE;
And if you want it to be hidden, but to keep value it has before editing the way to do that is:
$form['field_myfield']['#access'] = FALSE;
I.e. hiding it (somewhere I saw someone suggesting that):
hide($form['field_myfield']);
really hides the field, but after that, when form is saved this field has empty value, validation fails, etc, so that's not a good way to do this. Hiding makes sense only if you want to print separately that field later, at some other place.
function your_module_form_alter(&$form, &$form_state, $form_id){
switch($form_id) {
case 'nameOfTheNode_node_form':
//your code here. check the value from from_state.
break;
}
}
In this case, I use module Conditional Fields https://www.drupal.org/project/conditional_fields
For example: If my Dependees field has a value, Dependent field can be visible/invisible, enabled/disabled, required/optional, checked/unchecked

Find CURRENTLY selected <option> with XPath

What's the correct XPath syntax to check if an option element is currently selected, or just to get the selected option element from a select element, on an open page with which the user, and JavaScript, may have interacted? Is this even possible with XPath, or does it lack the ability to look at DOM properties?
I can't find any documentation on this, and have (speculatively) tried:
//option[#selected=true]
//option[#selected="selected"]
//option[#selected]
but none of these work; they simply don't match any elements.
(In case it matters, I've tried this both using the $x function in the Chrome developer console, and using the find_elements_by_xpath method in Selenium for Python.)
Short answer: it's not possible.
Longer answer: XPath can look at HTML attributes, but it can't look at DOM properties. Selecting an <option> element in a <select> changes the selected property of the <option> to true, and also changes the value property of its parent <select> element, but it doesn't affect the attributes of either, so it is invisible to XPath.
To find <option> elements that have the selected attribute set, which is often how a page author might determine which option is initially selected, you can use //option[#selected]. But this does not find the currently selected <option>; changes that the user makes to the selection are invisible to XPath. There's no guarantee it will even find the initially selected option, since it's possible that the page author didn't put the selected attribute on any elements and either let the browser select the first option by default or had some JavaScript select the initial option via the selected property.
The multiple other answers here claiming that a selector like //option[#selected] can detect selection changes made by the user after the page loads are simply completely wrong.
Of course, if you're able to use CSS selectors instead of XPath selectors, then option:checked will do the job.
The problem could be the " (double quotes).
//select/option[#selected='selected'] - Will match the selected option, i am using this successfully.
//select/option[#selected='selected' and #value='specific value'] - Will only match the selected option if it has a 'specific value', i'm also using this.
If you are still having trouble, it could be an entirely different problem, perhaps there is no option node. I hope this helps.
I think we can use a knowledge from #Mark's answer and account that. Let's just find a node which HAS desired attribute:
tree.xpath('//select/option[#selected]/text()')[0].strip()
I tried "//option[#selected=''] and it has worked for me.
it is able to highlight the selected option within Page objects model.
I would try //option[#selected='true']
i.e. driver.findElements(By.xpath("//option[#selected='true']")).getText();

MVC Html.textbox/dropdown/whatever won't refresh on postback

OK, let's start with the Html.Textbox. It is supposed to contain text read from a file. The file read is based on what the user picks from a dropdown list.
The first time it is fine. The user picks a value from the dropdown list. The controller uses that value to read some text from a file, and returns that text to the view via the view model. Everything is fine.
THen the user picks another value from the dropdown list. The controller reads a new value from a file and returns it via the view model. Debugging to the LINE BEFORE THE HTML.TEXTBOX is set in the view shows that the model contains the correct value. However, the textbox itself still shows the PREVIOUS value when the page displays!
If I switch from Html.Textbox to a plain input, type="text" html control, everything works fine. That's not so hard, but the same thing happens with my dropdown list -- I can't set the selected value in code. It always reverts to whatever was chosen last. Rendering a "select" tag with a dynamically-generated option list is a pain. I would love to be able to use Html.Dropdown.
What am I missing here?? This is such a simple thing in webforms!
When you post a form, the values that are posted are put into ModelState. When the HtmlHelper renders an html iunput element, e.g. Html.TextBoxFor(x => x.FirstName), it'll search various locations to get the value for the textbox... ModelState is before ViewData.Model in the list of locations. So there for, the previously posted value will appear in your textbox.
To fix this you could clear the ModelState value or update the ModelState value. BUT I would kinda view that as a hacky way of getting around the problem.
The real issue has more to do with the flow of the posts and requests. I would personally look into that and maybe implement the PRG (Post Redirect Get) pattern.
HTHs,
Charles
Following on from what Charles/Charlino said:
Model binding updates the ModelState object, which contains validation and model binding errors that are collected during model binding.
Inside an action method, model binding has occurred already to update the model, and generated the ModelState object. If you now update the value on the model inside the action, you must also manually update the model state (since the helpers use it to generate their HTML). Below is an example:
model.CaptchaIsValid = CaptchaService.ValidateAndExpireCaptcha(model.CaptchaAttempt);
if (!model.CaptchaIsValid)
{
ModelState.AddModelError("CaptchaAttempt", "Incorrect - please try again");
}
// I'll clear the value on each attempt, to force them to re-enter a CAPTCHA.
model.CaptchaAttempt = string.Empty;
// Since I updated the model, I must create a new ValueProvider result...
ValueProviderResult clearedValue = new ValueProviderResult(
model.CaptchaAttempt,
model.CaptchaAttempt,
CultureInfo.CurrentCulture);
// ... and update the ModelState's value.
ModelState.SetModelValue("CaptchaAttempt", clearedValue);
The biggest issue I see here is that you are trying to do a postback within MVC. That model is really not supported, and is actually way more trouble than it is worth (as it seems you are finding out). I would recommend using Ajax to update the contents of the dropdown dynamically.