Cookies with a redirect.
If the user can't be bothered to register, then they probably can't be bothered to clear their cookies.
Cookies with a redirect.
If the user can't be bothered to register, then they probably can't be bothered to clear their cookies.
Isn't that intentional though, because browsers convert uppercase characters in the same manner?
edit: nevermind it works differently then I thought.
redirect user to generated link (e.g. for donation with value-selection)
Good idea!
And I'd abstract the idea of buttons: add buttons just like inputs and assign actions to each of them.
I was considering this, but I could not think of any buttons besides clear and submit, so I just add them to the form automatically. Is there any more you can think of?
I will be adding a custom input type too, so either way it will be possible to add your own buttons soon.
I'm not very familiar with wordpress, but searching around, it looks like their Permalink system is indeed a plugin, (what they call a "module") and it's not even turned on by default.
It would be a nice plugin I think.
@pitaj No problem! I'm having fun with it. And there's still plenty more to do.
Could I get some opinions on this so far? or some people to try it out?
Most everything is drag and drop (I'll be adding a non-drag and drop mode), all of the standard inputs work and are fully editable. Still working on the html5 inputs. Most inputs can be edited in-place or via the modal dialog by clicking the green cog. Whatever you enter/select on the actual input will be the default value, which you can clear by clicking the pink eraser. The white checkbox requires the input, the blue files clone it, and the X deletes.
The live forms are viewable at the url forms/ID or parsed into a post. There's no backend, so if you submit a forum it should just reply with an empty page with the results.
I haven't pushed it to npm, so pull it from github to try it out.
https://github.com/pitaj/nodebb-plugin-forms
Ahhh! That is one feature of forums I find super-annoying!
But anyway, my vote would be for Cookie.
Looks great!
Huh, that is weird.
I tested it, and I could only reproduce this behavior in Firefox. And in FF it happens pretty consistently, in about 1 out of 3 back presses. No errors are ever thrown.
Cool! I suggest using the settings framework. It's super easy because you just store your data as a regular object and call persist() to save it to the database.
Definitely sounds possible to me.
There are a number of ways you could 'mark' a category or topic, a button on the topic or category page, parsed in a post, selecting them through the acp, using the topics' tags.
The widget could have an array of select elements populated with the marked categories or topics you want displayed in the carousel.
For the images, you could pull the first image inside the post. Or maybe scan the post for certain words and use a related image you have uploaded in the acp.
I think they have made the best possible decision. Those other forums can be installed by a (Hosting provided) control panel without touching the command line at all. NodeBB runs on a completely different platform, they can't just make a cPanel installer afaik, which would be the best possible solution. So, they've done the next best thing and offered their own managed hosting.
I'm not saying the documentation is fantastic though, it could definitely use some improvements. (Specifically, it relies on those single command line entries to work, and doesn't give you much to go on if something derps up.) BUT, it is still much better imo then other docs I've seen for other forums when doing a non-control panel install.
Ugh, as always I over-thought the problem. I already created an attribute data-prop to store the property name, so the user can just enter the properties' attributes as an array and declare the data-prop:
<div data-key="users" data-attributes='{"data-type":"object","data-properties":[{"data-prop":"firstname"},{"data-prop":"lastname"}]}'></div>
Unnamed data-props could default to the index in the array.
I think this syntax makes more sense than entering the properties in JSON object format and guessing the order.
@frissdiegurke Ahh! Yeah, that would definitely not be good.
I'm not sure the best way to go about this though. Using a data-order array seems the best way, the user would enter an array of keys in the order they want, and we would populate/generate the fields in that order. But, I would like this to be optional, and default to listing the properties in the order they are entered in the attributes. Though, it seems impossible to retrieve just the first set of property names because of the infinite level of complexity that could be inside the object. Mayve someone could help with a good regex?
or I could separate the attributes and keys completely like:
<div data-key="users" data-attributes='{"data-type":"object","data-attributes":[{},{}],"data-keys":["firstname","lastname"]}'>
but that eliminates the nice JSON-like syntax.
Yeah, I think a good regex to pull the property names would be best. A literal data-order should still be an option too, so this would be valid:
<div data-key="users" data-attributes='{"data-type":"object","data-attributes":{"firstname":{},"lastname":{}},"data-order":["firstname","lastname"]}'>
@frissdiegurke Thanks! I agree to the terms. (I signed the CLAHub a way back) I'm glad you think it's worthy of core!
I fixed the empty check and fixed some spacing. And I removed checks for data-object. (I used that originally as the properties object parent, but switched to using data-parent cause it worked flawlessly inside an array.)
@Schamper Okay, my original implementation was too complex, so I reimplemented it as a Settings plugin. It works... better than I expected it too. (It borrows heavily from the array plugin, I copied it to start, so there may be stuff inside that's totally unnecessary.)
You can do
<div data-type="object" data-key="user" data-split="<br>" data-properties='{"firstname":"","lastname":""}'></div>
And get two text fields and a settings object that looks like:
{
user: {
firstname: "First Name",
lastname: "Last Name"
}
}
Not to special, but the magic starts if you use it inside an array:
<div data-key="users" data-attributes='{"data-type":"object","data-attributes":{"firstname":{"data-type":"textarea"},"lastname":""}}'></div>
Then you get an array of two text fields and a settings object that looks like:
{
users: [
{
firstname: "First Name",
lastname: "Last Name"
},
{
firstname: "First Name 2",
lastname: "Last Name 2"
}
]
}
Which you can then use directly as the data parameter in a template as such:
Users:<br>
<!-- BEGIN users -->
{users.lastname}, {users.firstname}<br>
<!-- END users -->
It accepts all the same syntax as the other plugins, so it's completely possible to do crazy layered stuff like:
<div data-key="users" data-attributes='{"data-type":"object","data-attributes":{"nicknames":{"data-type":"array"},"realname":"","characters":{"data-type":"object","data-attributes":{"name":"","level":{"data-type":"number"}}}}}' data-new='{"nicknames":["Poofie","Yarikins","Yari"],"realname":"Tim","character":{"name":"yariplus","level":9001}}'></div>
and get:
{
users: [
{
"nicknames":["Poofie","Yarikins","Yari"],
"realname":"Tim",
"character":{"name":"yariplus","level":9001}
}
]
}
Here's the whole plugin:
define('settings/object', function () {
var Settings = null,
SettingsObject,
helper = null;
/**
Creates a new property child-element of the object with given data and calls given callback with elements to add.
@param field Any wrapper that contains all properties of the object.
@param key The key of the object.
@param attributes The attributes to call {@link Settings.helper.createElementOfType} with or to add as
element-attributes.
@param prop The property name.
@param value The value to call {@link Settings.helper.fillField} with.
@param separator The separator to use.
@param insertCb The callback to insert the elements.
*/
function addObjectPropertyElement(field, key, attributes, prop, value, separator, insertCb) {
attributes = helper.deepClone(attributes);
var type = attributes['data-type'] || attributes.type || 'text',
element = $(helper.createElementOfType(type, attributes.tagName, attributes));
element.attr('data-parent', '_' + key);
element.attr('data-prop', prop);
delete attributes['data-type'];
delete attributes['tagName'];
for (var name in attributes) {
var val = attributes[name];
if (name.search('data-') === 0) {
element.data(name.substring(5), val);
} else if (name.search('prop-') === 0) {
element.prop(name.substring(5), val);
} else {
element.attr(name, val);
}
}
helper.fillField(element, value);
if ($('[data-parent="_' + key + '"]', field).length) {
insertCb(separator);
}
insertCb(element);
}
SettingsObject = {
types: ['object'],
use: function () {
helper = (Settings = this).helper;
},
create: function (ignored, tagName) {
return helper.createElement(tagName || 'div');
},
set: function (element, value) {
var properties = element.data('attributes') || element.data('properties'),
attributes = {},
key = element.data('key') || element.data('object') || element.data('parent'),
prop,
separator = element.data('split') || ', ';
separator = (function () {
try {
return $(separator);
} catch (_error) {
return $(document.createTextNode(separator));
}
})();
element.empty();
if (typeof value !== 'object') {
value = {};
}
if (typeof properties === 'object') {
for (prop in properties) {
attributes = properties[prop];
if (typeof attributes !== 'object') {
attributes = {};
}
addObjectPropertyElement(element, key, attributes, prop, value[prop], separator.clone(), function (el) {
element.append(el);
});
}
}
},
get: function (element, trim, empty) {
var key = element.data('key') || element.data('object') || element.data('parent'),
properties = $('[data-parent="_' + key + '"]', element),
value = {};
properties.each(function (i, property) {
property = $(property);
var val = helper.readValue(property),
prop = property.data('prop'),
empty = helper.isTrue(property.data('empty'));
if (empty || val !== void 0 && (val == null || val.length !== 0)) {
return value[prop] = val;
}
});
if (empty || values.length) {
return value;
} else {
return void 0;
}
}
};
return SettingsObject;
});
@Schamper It's kinda sloppy right now, but I'll post it after I clean it up.
@julian @Schamper Thanks! Those docs did not have an example of exactly what I wanted to do, BUT it did give me a clue, and using the helper functions I was able to achieve what I wanted. I basically have several subforms with subforms that I wanted to store as arrays of objects with arrays of objects within. The goal being to pass that object to the template renderer without doing any additional parsing.
I got it working perfectly now, thanks so much!
This seems like it should already be a feature. Am I maybe missing it somewhere?
I'd like to do like:
<div data-type="object" data-key="objname" data-attributes="{{data-type:text,data-key:text},{data-type:number,data-key:number}}"></div>
have it generate a form with a text input and a number input and get a settings object like:
{
objname: {
text: "Some inputed text",
number: 9001
}
}
I'm currently prepending the input keys and reading, parsing, and storing the object manually into settings, but the above syntax would be so much nicer.