pug nested content in input - node.js

Hi I'm trying to create nested mixins which can display bootstrap radio button in pug
mixin input(textinput)
label.btn.btn-secondary
input(type="radio" name="options" id="option1" autocomplete="off")= textinput
mixin btn-toggle-group(textinput)
.btn-group(data-toggle="button")
+btn-toggle-group
+input('coca')
+input('pepsi')
+input('orangina')
+input('lemonade')
but it gives me error with input is a self closing element but it contains nested content

The error is due to trying to make textinput a TextNode child of a radio button via = which obviously has to fail.
If one wants to render a next sibling text node, there is the | operator (pipe) and interpolation. But one also can go with just another html element like span. Bothe variants are provided with the example code.
One should keep in mind that a radio button (especially within a radio group) that does not feature a value is of almost no use. It might be useful, assigning textinput to the radio button's value attribute too.
One also should avoid passing id or class attributes directly into a tag, one instead should append each of it either by # for ids or by . for class names.
And last, for one wants to append all the labeled radio controls to the btn-group classified div element, one needs to mark this by a carefully indented block keyword.
mixin input(textinput)
label.btn.btn-secondary
input#option1(type='radio' name='options' autocomplete='off' value=textinput)
// span.label= textinput
// span= textinput
| #{textinput}
mixin btn-toggle-group(textinput)
.btn-group(data-toggle='button')
block
+ btn-toggle-group
+ input('coca')
+ input('pepsi')
+ input('orangina')
+ input('lemonade')
The above provided sanitized and tested code now does work as intended.
And reading the pug documentation (attributes, interpolation, mixins, inheritance/templates/blocks, ) does help too.

Related

How to get list of widgets in pyqt?

I am designing a interface with QtDesigner and editing its functionalities with PyQt. One of the widgets that i created has several pushButtons and i want them all to have the property Checkable = True.
So currently what i am doing is:
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
uic.loadUi('./my_widget.ui', self)
self.pushButton_X.setCheckable(True)
self.pushButton_Y.setCheckable(True)
self.pushButton_Z.setCheckable(True)
self.pushButton_ETC.setCheckable(True)
self.show()
Is there any way i can do something like:
pushbuttons_list = self.get_all_pushbuttons()
for i in pushbuttons_list:
i.setCheckable(True)
?
Im trying the answers to this question but i keep getting
> File "./testing_class.py", line 12, in __init__
items = (self.layout.itemAt(i) for i in range(self.layout.count()))
AttributeError: 'builtin_function_or_method' object has no attribute 'count'
Your example failed because all Qt properties can be accessed by calling the attribute (see the parentheses used for self.layout()):
items = (self.layout().itemAt(i) for i in range(self.layout().count()))
Note that this will only get access to the layout items, not the widgets they might (or might not) contain. For this, using comprehensions will only complicate things unnecessarily, as one-liners should be used only as long as they keep the code readable; the comprehension above is already complex enough, and since you will need to cycle through all items anyway, there's little use in it. Just use a for loop, which is far more readable:
for i in range(self.layout().count()):
widget = self.layout().itemAt(i).widget()
if isinstance(widget, QPushButton):
widget.setCheckable(True)
Note that if you have several buttons that you want checkable and you are doing this only to avoid manually setting the checkable property for all of them, you can just use the extended selection mode that is common for all UI elements that allow selection by keeping pressed Ctrl when clicking multiple objects.
The property editor will automatically show all common properties for the selected widgets, and apply the changed property to all of them.
Another option is to use findChildren():
for button in self.findChildren(QPushButton, Qt.FindDirectChildrenOnly):
button.setCheckable(True)
The Qt.FindDirectChildrenOnly flag is required whenever you have complex layouts that have nested widgets containing other buttons, if you remove that you will find any push button that exists inside the window (or the widget referenced as self).
Finally, buttons can be part of a QButtonGroup, which can also be created in Designer. Just select all buttons (as explained above), right click on one of them and select "Assign to button group", and then:
for button in self.buttonGroup.buttons():
button.setCheckable(True)
Note that the self.buttonGroup above is the object name assigned by Designer, if you change it or you create more than one, ensure that the reference matches it.

get the outer element (LIST) to render anything other than a div

Is it possible to get List (or any other component from RV) to render itself like an UL>LI list or specifically like React Bootstraps ListGroup.
Currently I can not see an option to get the outer element (LIST) to render anything other than a DIV.
So my use case is really that each row should be a ListGroupItem (e.g. li with BS classes applied) and the container should be a ListGroup component.
Short answer: No. This is not supported.
Longer answer: List (like Table) uses a Grid internally. In order for windowing to work, Grid needs 2 wrapper elements around its cells. (Check out the source here. I also made a presentation slide about how it works, if you're interested, here.) Lists (ol, ul) only have 1 wrapper element.

Form does not postback when submit is clicked, jade, node.js

I have a form created with jade, it does not postback when submit button is clicked.
I have looked at many similar problems, I tried the solutions, which include ensuring that the input fields all have a 'name', I have made sure all the input field have a name but the form still does not post back, here it is
//views/users/new.jade
h1 New User
form(action="/users", method="POST")
p
label(for="username") Username
input#username(name="username")
p
label(for="name") Name
input#name(name="name")
p
label(for="bio") Bio
textarea#bio(name="bio")
p
input(type="submit",value="Create")
The post handler is this
//routes/users
module.exports=function(app){
app.post('/users',function(req,res){
if(users[req.body.username]){ //Check if user exists
res.send('Confllict, 409')
}else
{
//add to users list
users[req.body.username]=req.body;
res.redirect('/users');
}
});
};
Jade uses indention to show what content goes between the tags
p
this is inside the p tags
also there is shorthand
p this is also in the tag
in your original code you are telling Jade that there is a p tag then the next line is outside the p tags.
This is an easy problem to run into if you aren't careful with indentation using Pug (previously Jade). I realize this is an old question, and it has several hits so perhaps this answer will shed some light for new Pug users.
The problem with the OP's code is the Form does not know how to post without a button, and the Submit button doesn't know where to post to without being associated with the Form. Why? Indentation.
Jade and Pug tips for success:
They produce html, so it helps to think in html layouts when developing the template (would you put text outside of your p element? Of course not).
Pug uses indentation to form layout and element hierarchy.
Html Forms must enclose the elements that are to be associated or bound to it.
A Submit Button does nothing unless you define an event handler.
Forms define a destination in their definition, which a button type element can leverage.
In the code listed by the OP, every Pug element is left-aligned. This puts all elements at the same level, so there is no hierarchy or nesting. Since there is no other event handler explicitly defined for the Submit button, nothing happens when it is clicked, despite the form having an action and a valid method.
To fix this, the Input (submit button) can be nested inside the Form.
Reworking the code to include indented hierarchy will enable the POST to function as expected (removed all the other elements for readability):
h1 New User
form(action="/users", method="POST")
label(for="username") Username
input#username(name="username")
label(for="name") Name
input#name(name="name")
label(for="bio") Bio
textarea#bio(name="bio")
input(type="submit",value="Create")
The resulting form won't be a pretty, but it will function:
The Form has an action and method.
All dependent elements are indented.
The input has a type of Submit and is child to the form.
Of course, a server must have a binding at the address to receive the data in order to do anything with it.

How can we use ONLY client side script for "hide/whens"?

I am working on a large, worldwide application, which includes access from areas of low bandwidth. As such, I want to use a minimum of SSJS or partial refreshes for all the complex hide/when calculations. Here is what I have so far for a simple "hide/when":
A Yes/No radio button, with CSJS to show a panel ("Yes") or hide the
panel ("No").
The panel has a formTable inside it, and the values are shown or hidden, as per #1.
In the XPage's onClientLoad, the following code is run:
// "getRadioValue" is a simple script to return the value of a radio button
var v_value = getRadioValue("#{id:radioButton}");
v_div = '#{javascript:getClientId("radioButtonPanel")}';
// show or hide div simply use dojo to change the display of the panel
if (v_value == 'Yes') {
showDiv(v_div);
} else {
hideDiv(v_div);
};
For a new document, the onClientLoad script will hide the "radioButtonPanel" successfully. Changing the radio button to "Yes" will show the radioButtonPanel, just as clicking "No" will hide it. It works great! :-)
Once the document is saved and reopened in read mode, though, the onClientLoad CSJS event should read the saved value in the document, and decide to show the panel or not. When the document is opened in edit mode, the onClientLoad fires, reads the radioButton value and successfully shows or hides the panel.
This is what I've tried so far, to get it to work in read mode:
In CSJS, using "#{javascript:currentDocument.getItemValueString('radioButton'}" to get the value,
Doing some calculations in the "rendered" or "visible" properties, but that's SSJS and, if hidden, prevents any of the "show/hideDiv" CSJS visibility style changes.
Adding an old fashioned "div" to compute the style (which is what I used to do before XPages), but since I can't do pass-thru html any more, I can't seem to get a CSJS calculation for the style. Ideally, I can do something like this:
<div id="radioButtonPanel" style="<ComputedValue>">
Where the ComputedValue would read the back end value of the document, and decide to add nothing or "display:none".
Note that I don't want to use viewScopes, since this long form would need many of them for all the other hide/when's.
Is there any way to make this 100% CSJS? I feel like I'm very close, but I wonder if there's something I'm just missing in this whole process.
First, rather than computing style, I'd recommend computing the CSS class instead -- just define a class called hidden that applies the display:none; rule. Then toggling visibility becomes as simple as a call to dojo.addClass or dojo.removeClass.
Second, I see that you're using the #{id:component} syntax to get the client ID of the radio button but using SSJS to get the client ID of the panel. Use the id: syntax for both; this is still just a server-side optimization, but if there are many instances of these calculations, it adds up. Similarly, replace #{javascript:currentDocument.getItemValueString('radioButton'} with #{currentDocument.radioButton}. Both will return the same value, but the latter will be faster.
Finally, any attribute of a pass-thru tag (any component with no namespace, like xp: or xc:) can still be computed, but you'll need to populate the expression by hand, since the editor doesn't know which attributes for valid for these tags, and therefore doesn't provide a graphical expression editor. So if the ideal way to evaluate the initial display is by wrapping the content in a div, the result might look something like this:
<div class="#{javascript:return (currentDocument.getValue('radioButton') == 'Yes' ? 'visible' : 'hidden');}">
<xp:panel>
...
</xp:panel>
</div>

XPages disableOutput tag issue

Has anyone experienced an issue with disableOutputTag property where if you disable output tag for a computed field control inside a repeat control and have ssjs computed content inside that tag, it won't compute the content? Is disableOutputtag property only meant to work with static content inside a repeat control or is it a bug?
I don't know whether its a bug or not, but you can emulate the behavior of disableOutputTag by removing the ID attribute from and setting the disableTheme attribute to true. Maybe this helps you in short term.
EDIT: You can refer here for more information.
Not only does this happen when placing the xp:Text control inside a repeat but in also when you create a new XPage, add a xp:text onto it and define its value like:
<xp:text value="This is a test" disableOutputTag="true"/>
In the above example the xp:text will disappear. This is not what you would have expected. I would expect that only the value would be visible on the rendered page. But I think I can explain why this happens. Since there are no tags defined (disableoutputtag) somewhere in the rendered of this component it states that it should not generate anything. Because it can not bind its id to 'nothing' and so on.
Anyway, I could not think of a scenario where I would like to render plain text without any surrounding tags. It should at least be surrounded by a span or paragraph (<p>) tag so you can style it. And an ID would be nice so I can change the contents with a partial refresh.

Resources