Jump to content
Marco Ro

Change label position in Inputfield

Recommended Posts

Hi,

I need to change the position of the label tag. In all render the input field look like this:

<div class="Inputfield" id="">
  <label class="InputfieldHeader" for="...">Email</label>
  <div class="InputfieldContent">
    <input id="..." name="..." class="..." type="" maxlength="512" autocomplete="off">
  </div>
</div>

I would like move the label tag inside the InputfieldContent after the input tag.

I try to work around the render hook, but didn't found a solution, and also I'm not sure is this the way. 

How can I do it?

Thank you.

Share this post


Link to post
Share on other sites

Hi Marco Ro,

51 minutes ago, Marco Ro said:

I need to change the position of the label tag. In all render the input field look like thisI would like move the label tag inside the InputfieldContent after the input tag.

Just move it where you want to have it:

<div class="Inputfield" id="">
  <div class="InputfieldContent">
    <input id="42" name="..." class="..." type="" maxlength="512" autocomplete="off">
	<label class="InputfieldHeader" for="42">Email</label>
  </div>
</div>	

Through the for attribute you assign the label to the wanted input element, refering to its id (here 42).

That said, you should consider to avoid additional div elements and just use the semantic elements:

    <input id="42" name="..." class="Inputfield" type="" maxlength="512" autocomplete="off">
	<label for="42">Email</label>

This might be sufficient - of course that depends on your special use case...

 

Share this post


Link to post
Share on other sites

Thank you @ottogal, yes this could be a solution, but I have make one like of code for every input. I will like have this render for all the input. For this reason I was thinking of a hook solution on Inputfield. 

 

Share this post


Link to post
Share on other sites

@Marco Ro Why do you want to change that? And what's the situation? Do you use PW's inputfield form to create forms in the frontend? Do you want to re-style the labels and/or input fields? Maybe there's a CSS solution? Or is this even something from FormBuilder?

Share this post


Link to post
Share on other sites

Hi @dragan thank you, yes I need this for make a re-style of css, I use the field in the module LoginRegister and Padloper, all of these render directly the Inputfield.

I can't find a solution only with the css, I need to move the tag label because it has to work inside the InputfieldContent. I need move the text label inside the input, when write inside the input the label text will be smaller and move across the InputfieldContent box. 

I try to use the appendTo(), but without using a unique ID or class it doesn't work well. I also try to use the placeholder attribute, but doesn't work like we would like.

I never use the FormBuilder module, I read that is very nice module and sure I can make every contact form that I need, included the login form, but in this way I have also to write all the system for the login form like the registration, the forget password etc.. Also I probably I can't use FormBuilder with Padloper module. 

There are no way to move the label inside the InputfieldContent? 


 

 

 

Share this post


Link to post
Share on other sites

@Marco Ro If you would draw a little sketch, and show exactly what you want to do, and how it's supposed to look like visually (it's still not clear to me from your description), maybe there is a way with CSS only. And perhaps also show what it looks out now, out of the box, for comparison.

e.g. if all you want is to place the label on the left, and the input on the right, you could do it easily with flexbox: https://codepen.io/dragan1700/pen/JjdRYVE

Share this post


Link to post
Share on other sites

@Marco Ro, you can use InputfieldWrapper::setMarkup() to customise the markup of inputfields.

See the defaultMarkup property as a starting point for what can be customised:

/**
 * Markup used during the render() method - customize with InputfieldWrapper::setMarkup($array)
 *
 */
static protected $defaultMarkup = array(
	'list' => "<ul {attrs}>{out}</ul>",
	'item' => "<li {attrs}>{out}</li>", 
	'item_label' => "<label class='InputfieldHeader ui-widget-header{class}' for='{for}'>{out}</label>",
	'item_label_hidden' => "<label class='InputfieldHeader InputfieldHeaderHidden ui-widget-header{class}'><span>{out}</span></label>",
	'item_content' => "<div class='InputfieldContent ui-widget-content{class}'>{out}</div>", 
	'item_error' => "<p class='InputfieldError ui-state-error'><i class='fa fa-fw fa-flash'></i><span>{out}</span></p>",
	'item_description' => "<p class='description'>{out}</p>", 
	'item_head' => "<h2>{out}</h2>", 
	'item_notes' => "<p class='notes'>{out}</p>",
	'item_detail' => "<p class='detail'>{out}</p>", 
	'item_icon' => "<i class='fa fa-fw fa-{name}'></i> ",
	'item_toggle' => "<i class='toggle-icon fa fa-fw fa-angle-down' data-to='fa-angle-down fa-angle-right'></i>", 
	// ALSO: 
	// InputfieldAnything => array( any of the properties above to override on a per-Inputifeld basis)
	);

There are still some limitations (e.g. item_label is always rendered before item_content) but you can get closer to what you want like so:

InputfieldWrapper::setMarkup([
	'list' => "<div {attrs}>{out}</div>",
	'item' => "<div {attrs}><div class='InputfieldContent'>{out}</div></div>",
	'item_label' => "<label class='{class}' for='{for}'>{out}</label>",
	'item_content' => "{out}",
	'item_toggle' => "",
]);

$form = $modules->InputfieldForm;

$f = $modules->InputfieldText;
$f->name = 'greeting';
$f->label = 'Greeting';
$form->add($f);

$f = $modules->InputfieldSubmit;
$form->add($f);

echo $form->render();

2020-02-20_082322.png.d90ea96f0f7fedb903c143a7a257e45f.png

 

11 hours ago, Marco Ro said:

I need move the text label inside the input, when write inside the input the label text will be smaller and move across the InputfieldContent box. 

If I understand right you don't really need to change the markup to do this. The label element can never literally be inside the input element, but you can position it overlaying the input using CSS with the default markup.

.Inputfield { position:relative; }
.InputfieldHeader { position:absolute; left:5px; top:3px; font-size:12px; text-transform:uppercase; }
input[type=text] { padding:17px 5px 5px; border:1px solid #ccc; }
.InputfieldSubmit { margin-top:20px; }

2020-02-20_083451.png.abc9ad1ecc91a0af49300ddbc295db4d.png

If you want to change the label styling when the input is focused you can use some JS to add a class to the parent .Inputfield element when its child input is focused.

Share this post


Link to post
Share on other sites

Hi @Robin S and @dragan, sorry fro the late reply. 

Ok thank you! It's very nice, I can also use $defaultClasses to add class and not use jquery. 

About the css I find a solution and the result is very beautiful.

1455807302_Schermata2020-02-20alle08_37_15.png.9a467d51d32392442bc3402e7673ddcf.png

Thank you so much.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By cosmicsafari
      Hi all,
      I have need to dynamically set InputFieldMultiSelect to  selected on page load based on the status of some items within a database table.
      However I keep running into issues when trying to do this via InputfieldSelect::setOptionAttributes()
      https://processwire.com/api/ref/inputfield-select/set-option-attributes/
      Going by the above it sounds like it should be pretty straight forward, and for certain values it seems to work but not when I wanted to set it to 'selected'.
      For example:
      $f->setOptionAttributes(1030,['foo' => 'test']); The above works as I would have wanted, in that it updates the option with the value 1030, to include the attribute foo="test"
      But the same code above edited to the following:
      $f->setOptionAttributes(1030,['selected' => 'selected']); Doesn't seem to do anything?
      I assume I'm missing something or trying to implement the 'selected' wrongly but I'm not sure how else I should approach this, any advice would be much appreciated.
       
    • By MarkE
      I'm looking for an inputfield module that might allow the entry and evaluation of a conditional expression (following php syntax).
      My use case is an admin function for writing pro-forma emails/letters where some components of the pro-forma are dependent on conditions determined by an admin user. The pro-forma is then cloned for use and the relevant components are included depending on the runtime value of the conditions. The conditions usually include hanna codes as the items to be compared. This is implemented in a parent-child structure, where the main mail body is in the parent and each child then has a condition (textarea) field and a body textarea field for the optional text relating to that condition.
      As an interim solution on my dev machine, I am just using eval() to evaluate the conditions, but I really don't want to use this in the live environment. My idea is to use an approach similar to that for hanna codes to store the php and render it. This would be (somehow) wrapped in a new inputfield module (extending InputfieldTextarea?) with an evaluate() method that would return true or false as appropriate. It would be placed inside a try...except structure to catch syntax errors etc.
      It seemed to me that this might be quite a useful utility module and that someone might have developed something similar, but I can't find anything. Does anyone have any pointers, or will I need to start from scratch? If the latter, then I'd appreciate some help along the way as I am a bit of a novice in these matters.
    • By jonatan
      collapsedNoLocked field not showing
      Hi all, ☺️
      I'm a 21 years old 👨‍🦱, danish 🇩🇰, hobby-designer-and-web-stuff-maker and very excited and eager processwire beginner, or "noob" 🐣 if you wish.
      So far I've been fascinated by the very satisfyingly simple and yet powerfull magic ✨ of PW (once you get the hang of it) and the awesome feeling of the strong PW community 🦄🌈☀️❤️! The huge work done by @ryan and all of the other amazing PW people is just so inspiring! I actually really have a hard time understanding why Processwire isn't the most used CMS in the world... or at least just a way more commonly known one!
       
      But now I've encountered a small bump on the road and I'd lovingly appreciate if one of you lovely PW forum members could maybe help me out!
      ❓Problem:
      So I have a problem with the collapsed-constant: https://processwire.com/api/ref/inputfield/#pwapi-methods-collapsed-constants 
      - It's not showing my field when I apply it.
      (I've funnily enough found this old git pull from 2014 which documents the "Locked" state being added as a field -> input -> visibility option: https://github.com/ryancramerdesign/ProcessWire/pull/457 – it also shows the relevant code implementations to the core) 
       
      📝 What I wish to do:
       is to 👀 display some data from a 📦 module (InstagramBasicDisplayApi) in the ⌨️ page editor when editing a page ("About me") using the template (About.php) - So the only possible way to do that as far as for what I've been able to come up with with my restricted PW (end eh.. php) –knowledge was to add a custom field type to the (About.php) template...
      I've set up a custom field using https://modules.processwire.com/modules/mystique/ :
      site/modules/configs/Mystique.php:
      <?php namespace ProcessWire; $modules = wire("modules"); $instagram = $modules->get("InstagramBasicDisplayApi"); $data = array('username'=>''); $account = $instagram->getUserAccount($data["username"]); $username = isset($account["username"]) ? $account["username"] : ""; $at_instausername = "@" . $username; /** * Resource : Instagram account */ return [ 'title' => __('Instagram account'), 'fields' => [ 'window_title' => [ 'label' => __(' '), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'collapsed' => '0', 'placeholder' => __($at_instausername), ] ] ]; - Basically:
      I'm getting the instagram-username, pulling it from the module "InstagramBasicDisplayApi",  And then I'm using it as the 'placeholder' value for the field, resulting in this:  - Which is actually what I want... almost...
      – The thing is, I would like it to be locked, so that it's not possible to overwrite the 'placeholder' value, but so that the inputfield actually does not take any input but just informatively displays the data...
      so what I do is that I just change 'collapsed' to '7' = 'collapsedNoLocked':
      'collapsed' => '7', , right, and that would be it?
      But unfortunately no...
      When I do I get this:
       
       - I can't figure out why? I'd supposed that the 'placeholder' value would just show, but non-editable?
      A "workaround" is to just set it to back to 0, then manually type in "@sasha_lindegaard" and then press save, and then set it to 7, and I have what I want:

      - But that's not really what I wish, as it displays the data (the instagram username) statically (from what I've typed into the field and have saved) and not dynamically (from the instagram module database) as wished for...
      – also, it's still collapsable? Why so?... 🤔
       
      Any ideas for how I might get my "INSTAGRAM" field to display the username from the instagram module's database dynamically, not as editable placeholder text in a editable/open input field but just as non-editable/locked text?
      I hope that I've made my problem clear enough but if I've failed to provide enough info please don't hesitate to request for more! 🙂 
      Thanks a thousand times in advance!
      All the best,
      Jonatan R.
    • By MarkE
      I had a need to interactively update the page choices in a multi-choice page select field. I chose to do this with a general-purpose piece of jQuery. By combining it with a InputfieldPage::getSelectablePages hook, you can get the trigger field to alter the selectable pages interactively.  I have also found this to be useful in a number of other situations - e.g. updating a RuntimeMarkup field for changes on a page. There may be more elegant ways of achieving this (I'm open to suggestions), but in case it is useful to others, I'll post it here. Hopefully the comments in the script are self-explanatory and describe how to use it. Note that there are several console.log statements to help with debugging, which you can remove once happy with its operation.
      Happy to answer any questions (if I can 😉 ). Also, if anyone can explain how to get it working fully with checbox/toggle ad radio buttons, I would be grateful.
      /* Script to refresh a form content when an element gets changed To work across all admin pages, this script needs to be loaded in admin.php – add the line $config->scripts->add($config->urls->templates . "scripts/form-update.js"); before the final require in templates/admin.php. Typical use is to modify other elements based on a select drop-down change The trigger element can have the following data attributes assigned to it (typically set these with $myInputfield->attr() in a module or hook): * data-action="form-update" : Required to run the script. * data-update-target="#myid1" : Required - the element to change. Note that this should not be the whole form, otherwise .find(target) will not find it. * data-confirm="Some confirmation text": Optional - if you want to show a confirmation before the update, this holds the text to display. If absent, there will be no confirmation dialogue. If the user chooses ‘cancel’, the script will revert the change and terminate. * data-alert="Some alert text": Optional – if you want to warn the user that the update cannot happen for some reason (the script will then revert the change and terminate). * data-cache="#myid2" : Optional - if you want to cache the (changed) value, this element stores it. * data-cache-prefix="Some prefix string" : Optional (requires data-cache) - a prefix to prepend the value stored in the cache This currently works with the following trigger elements: * select options * select page (single and multiple) * page list select (single and multiple) * asm select * page autocomplete (but note that data attributes must be set in the wrapper element - e.g. $myInputfield->wrapAttr() ) * checkboxes (set attributes in wrapper as above) but not with: * toggle * checkbox * radio buttons (These partly work - the attributes need to be in the wrapper -, but doesn't work completely as wrapper 'value' attribute is not updated by PW (always 0) ) NOTE: If you are using this with other js scripts (e.g. in a module) that listen for events in the target, you must use event delegation (e.g. $(document).on("change","#myid", function(){}); NOT $("#myid").onchange(function(){}); ) because #myid is dynamic if it is inside the target) */ $(document).on('focusin', '[data-action="form-update"]', function(){ // get the value before the element is changed console.log("Saving value " + $(this).val()); $(this).data('val', $(this).val()); }).on('change','[data-action="form-update"]', function(event){ var prev = $(this).data('val'); var current = $(this).val(); console.log("Prev value " + prev); console.log("New value " + current); // if trigger element has data-confirm attribute, confirm or revert and exit var confirmText = $(this).data('confirm'); if (confirmText) { if (!confirm(confirmText)) { $(this).val(prev); return; } } // if trigger element has data-alert attribute, show alert and exit var alertText = $(this).data('alert'); if (alertText) { alert(alertText); $(this).val(prev); return; } // cache the value before proceeding (if data-cache set) var cache = $(this).data('cache'); var cachePrefix = ($(this).data('cache-prefix')) ? $(this).data('cache-prefix') : ''; $(cache).val(cachePrefix + current); var $form = $(this).closest('form'); var target = $(this).data('update-target'); console.log("Target is " + target); var method = $form.attr('method'); var action = $form.attr('action'); var data = $form.serialize(); var encodedName; // .serialize() will omit select elements that do not have a 'null' option (e.g. asm select, page list select) // or checkboxes with nothing selected // so find them and add empty parameters to the data string, otherwise the page field will not be updated $($form.find('select, input').each(function(index){ console.log('Select element no. ' + index + ' with name ' + $(this).attr("name") + ' has serialize = ' + $(this).serialize()); encodedName = encodeURI($(this).attr("name")) if (data.search(encodedName) === -1) { data += ('&' + encodeURI($(this).attr("name")) + '='); } })); console.log("Submitted data: " + data); if (!method) method = 'get'; if (!action) action = window.location.href; // If you want to fade the affected inputfields then assign the loading class to their wrappers with method wrapClass(loading) $(target).find('.loading').css({ display: 'block', opacity: 0.2 }).animate({ opacity: 1 }, 5000); // then send your request $.ajax(action, { type: method, // type used, not method, for older versions of jquery data: data, // you can also add an error handler here if required, in case the server returns an error on the request success: function (data) { // Initial ajax just returns an array with message. Need to GET the form data. $.ajax(window.location.href, { type: 'GET', cache: false, success: function (data) { // then just take the target, and replace it with the target div from the returned data console.log("Returned data: " + data); console.log("Updating html with: " + $(data).find(target).html()); $(target).html($(data).find(target).html()); } }); } }); });  
    • By gebeer
      Hello all,
      sharing my new module FieldtypeImageReference. It provides a configurable input field for choosing any type of image from selectable sources. Sources can be: 
      a predefined folder in site/templates/ and/or a  page (and optionally its children) and/or the page being edited and/or any page on the site CAUTION: this module is under development and not quite yet in a production-ready state. So please test it carefully.
      UPDATE: the new version v2.0.0 introduces a breaking change due to renaming the module. If you have an older version already installed, you need to uninstall it and install the latest master version.
      Module and full description can be found on github https://github.com/gebeer/FieldtypeImageReference
      Install from URL: https://github.com/gebeer/FieldtypeImageReference/archive/master.zip
      Read on for features and use cases.
      Features
      Images can be loaded from a folder inside site/templates/ or site/assets Images in that folder can be uploaded and deleted from within the inputfield Images can be loaded from other pages defined in the field settings Images can be organized into categories. Child pages of the main 'image source page' serve as categories mages can be loaded from any page on the site From the API side, images can be manipulated like native ProcessWire images (resizing, cropping etc.), even the images from a folder Image thumbnails are loaded into inputfield by ajax on demand Source images on other pages can be edited from within this field. Markup of SVG images can be rendered inline with `echo $image->svgcontent` Image names are fully searchable through the API $pages->find('fieldname.filename=xyz.png'); $pages->find('fieldname.filename%=xy.png'); Accidental image deletion is prevented. When you want to delete an image from one of the pages that hold your site-wide images, the module searches all pages that use that image. If any page contains a reference to the image you are trying to delete, deletion will be prevented. You will get an error message with links to help you edit those pages and remove references there before you can finally delete the image. This field type can be used with marcrura's Settings Factory module to store images on settings pages, which was not possible with other image field types When to use ?
      If you want to let editors choose an image from a set of images that is being used site-wide. Ideal for images that are being re-used across the site (e.g. icons, but not limited to that).
      Other than the native ProcessWire images field, the images here are not stored per page. Only references to images that live on other pages or inside a folder are stored. This has several advantages:
      one central place to organize images when images change, you only have to update them in one place. All references will be updated, too. (Provided the name of the image that has changed stays the same) Installation and setup instructions can be found on github.
      Here's how the input field looks like in the page editor:

      If you like to give it a try, I'm happy to hear your comments or suggestions for improvement. Install from URL: https://github.com/gebeer/FieldtypeImageReference/archive/master.zip
      Eventually this will go in the module directory, too. But it needs some more testing before I submit it. So I'd really appreciate your assistance.
      Thanks to all who contributed their feedback and suggestions which made this module what it is now.
       
×
×
  • Create New...