Creating a New Element in Place of an Existing one - javascript

I've been creating a calender box widget (one of those little div-popups that allows you to select a date).
All's pretty much done on it short of one feature: When you create the object, you send it a field (the field that will contain the date); because of a (really) weird set of requirements, this field cannot have an easily readable format (YYYYMMddhhmmss) and so my script hides the field, and drops a div with similar styling in its place. I haven't found a way to neatly drop a div in as a sibling to the field AND right next to it (as opposed to appended at the end of the parent).
How can I take a field by ID as an argument, hide it, and drop a div in it's place at the same location?
If I could drop it, in the HTML, directly after the field, I could copy it's CSS over to the DIV (or a new field, even) and no one would be the wiser; references to the old field would still be valid, and humans could easily read the new field, but as is, the best solution I've found is to have the object take two parameters, one for the target field and one for the target div. It's not ideal.
jsFiddle: Full Project (I'm so, so, SO incredibly sorry for the widget's name. It's bad even by pun standards.)
jsFiddle: Simplified Example (Includes chosen answer)
PS:
I only have one real goal in this project: to minimize dependencies. This widget is replacing an old one my company used for ages which, over time, accumulated a dozen and a half modifications (each in different files) and needed at least as many style sheets and existing plugins. No one really knew what was going on with it. As is this one needs only jQuery, no other scripts, no other style sheets...
...I'd like to keep it that way...

http://api.jquery.com/after/
$('yourelement').hide().after(newDiv)

Related

Get access to other elements from widget inside form view

Odoo 13.
I got two float fields: time_given and timer.
I have created a widget for 'timer' field. My widget works as real-time clock or some sort of timer. The problem I have encountered is that I want to change the style of 'time_given' field based on the following condition:
((time_given - timer) <= 30 sec) i.e less than 30 seconds left
To change the style of the field the widget attached to is pretty easy, but I am not sure hot to get access to other field elements in the form view I need and make some visual manipulations with them if needed.
I was able to get access to other field elements, change their style and add some text but the it is not a proper way.
this.__parentedParent.__parentedChildren
I get array of objects, then I loop through it and look for the field needed. After I found my target field element I am able to play with it.
For example:
$field_name.addClass('text-danger')
The way above works pretty fine but again as I said before, this is definitely not a proper way.
I was trying to find the right field element and add class to it by the following way:
$("[name='field_name']").addClass('text-danger')
It found the element, but did not add the class 'text-danger'.
I was trying my best by googling and reading the source code, but failed.
enter image description here
I have managed to solve this issue. Just used core.bus.trigger method mentioned in the official documentation.
P.s. In case if you are still interested how I did this in more details, just let me know in the comments section below.

How to create a dynamic/modular 3-piece form input with html, JavaScript, and Bootstrap

I had no success researching this problem, so apologies for my difficulty in concisely describing it.
Basically, I'm building a website where users can submit "recipes," by way of html form > php. I wanted a way then for users to dynamically add or subtract steps or ingredients (I've seen this on other sites, but I couldn't find a simple pure js solution).
Anyway, I built something akin to what I wanted (example here, JavaScript here), but I'm not convinced it's such a great solution. To retrieve the form info, the php code basically loops through the materials' and steps' ids until it's reached the last one.
Although this solution works, I've run into 2 more problems:
The first is that the text for each input is saved in a js array each time the user types--that way new inputs can be added or removed without losing the text. However, when a new input element is created, if this previous text was too long, it is cut off.
The second is that for the ingredients section, I'd like to have a element where users can only choose standardized measurements (ie mg, g, kg...) and then another for a numeric quantity. I've tried Bootstrap's input-group classes, but the spacing turns out very odd and doesn't work at all on mobile. Is there a better way to accomplish this? This also thoroughly complicates the my original solution, since there will now be 3x as many inputs.

javascript iterate through dom looking for specific aria-label

I've spent hours on this one.
My company is forced to use a non-user-friendly 3rd party website. We only use IE11. My job is to use javascript and jquery to customize the screen and make things a little easier for our users. I use a bookmarklet to insert <script> tags into IE and reference a .js file saved locally.
This website uses hundreds of input text fields but we only need a handful of them. So, I want to highlight input text fields on the screen.
Some fields have ID's some only have Name. For the most part, this works:
$(document.getElementById('s_3_1_18_0').toggleClass("highlightField");
$(document.getElementsByName('s_3_1_19_0')[0]).toggleClass("highlightField");
HighlightField simply adds CSS background-color: yellow !important
The problem is, this 3rd party app changes the ID and the Name in bizarre ways. One day, the name will be 's_3_1_19_0', the next it will be 's_3_2_48_0'. So highlighting using this method is not stable.
However, these fields have an area-label that stays constant. I'm wondering how to use javascript or jquery to iterate through each text box, looking for a specific aria-label. For example, the "valid to" field has a bizarre name that changes all the time but it's aria-label is always "Valid To".
Can anyone please help me with this?
You can find the input with the aria-label "Valid To" by searching for
$(document).find('input').attr('aria-label', 'Valid To');
I recommend being a little bit more specific than $(document), though. That searches the entire doc.
You can use jquery to get the list of all aria-label attributes and use a switch case to perform what you need. Something like this
switch ($(this).attr('aria-label')) {
case 'label1': {
//do something
break;
}
}

Efficiently rendering a large number of "select" elements

I'm writing a web application that displays a large number of rows of data (~2000 at present), each of which has a drop-down "select" element with ~100 options. Any of those options can be selected by default. I'm generating all the actual DOM elements client-side. My problem: rendering this beast takes ~4 seconds on my relatively recent machine, which is really suboptimal. I know the problem is specifically with all the select elements, because replacing them with a bit of static text or a single-option list causes render time to be nigh imperceptible.
The vanilla code, minus failed experiments (see below) is here.
Avoiding the suggestions of "paginate your data" and "don't have so many options in a select", what is the most efficient way I can write my append / render code, assuming I do have a legitimate reason to display that much data and have that many options? For my purposes, Firefox is the only platform I care about.
Things I have tried:
Using an async loop to append rows to the table (slower than a regular loop, and oddly didn't render the intermediate results)
Building up a string that represents the body of the table and inserting it into the DOM in a single call (almost identical performance)
Instead of inserting the entire options list, inserting a single-option "select" element, and then populating the entire list when the "select" element gains focus (presumably because someone is trying to change it). This was actually pretty high-performing for the initial render, but then populating the element with the full list caused some weird behavior, losing focus and never actually being able to "open" the select element.
Right now my default assumption is that the third option is the way to go, and I need to figure out how to do some bookkeeping about what has already been populated. But my suspicion is that there is a plainly better / faster / more idiomatic way to do this. Is there?
Yes, I would "lazily" generate and/or populate the dropdowns.
That is, only create and populate the dropdowns when the user clicks on them, as probably almost all of the dropdowns in the 2000 rows will never be used right?
Perhaps a select element might not be the best UI here too, but instead some kind of HTML menu like so: https://jqueryui.com/menu/ that is created, populated and displayed only when the user clicks on some kind of button to display it.

Gradually opening html form

A little web design dilemma: I have a form with a lot of options, mainly radio buttons but not only.
I want the form to open up gradually, meaning at the beginning only two radio buttons are visible, and after the user picks one, more options appear under the chosen radio button. If the user then switches the pick, the page updates and shows the options under the new pick.
This happens on several levels, say 4 or 5 levels, and at the end there is a submit button that submits only certain inputs according to the branches the user chose. Also some of the branches have identical components even though the initial choice was different.
These are the options I could think of:
Build the complete form in the html body and use jquery to hide and show them according to the choices of the user. This means I have to write sections that repeat themselves twice.
Write nothing in the body, and append new elements when the user makes certain choices. This means the JavaScript is more complicated, because I have to make sure nothing appends twice.
Write an HTML skeleton of the form, and use append to fill it. Then use jquery to show and hide elements. This has none of the disadvantages but seems a bit unaesthetic.
Which one should I pick? Any better ideas?
It really comes down to your knowledge of javascript. The cleanest way would be to append to form using javascript. This way you can avoid having duplicates in your form.
If you are not that familiar with javascript and don't know how to append the form, then I would use javascript to show/hide the different parts of the form.
I think using javascript to append would be the correct way, but I don't see anything really wrong with using javascript to just hide parts of the form.
Probably going to use http://wiki.jqueryui.com/w/page/12137997/Menu
or JStree (http://www.jstree.com/) which I found out about from here http://wiki.jqueryui.com/w/page/12138128/Tree

Categories