I am using redux form and pristine returns true if I don't change any entry.
The thing is one field accepts more than one entry and when I change the order of those entries in that specific field, I want to pristine to return true. Because I basically didn't change anything but the order of the entries.
Is there a way I can make that pristine return true?
Related
I ran into an odd issue when trying to modify a chef recipe. I have an attribute that contains a large hash of hashes. For each of those sub-hashes, I wanted to add a new key/value to a 'tags' hash within. In my recipe, I create a 'tags' local variable for each of those large hashes and assign the tags hash to that local variable.
I wanted to add a modification to the tags hash, but the modification had to be done at compile time since the value was dependent on a value stored in an input json. My first attempt was to do this:
tags = node['attribute']['tags']
tags['new_key'] = json_value
However, this resulted in a spec error that indicated I should use node.default, or the equivalent attribute assignment function. So I tried that:
tags = node['attribute']['tags']
node.normal['attribute']['tags']['new_key'] = json_value
While I did not have a spec error, the new key/value was not sticking.
At this point I reached my "throw stuff at a wall" phase and used the hash.merge function, which I used to think was functionally identical to hash['new_key'] for a single key/value pair addition:
tags = node['attribute']['tags']
tags.merge({ 'new_key' => 'json_value' })
This ultimately worked, but I do not understand why. What functional difference is there between the two methods that causes one to be seen as a modification of the original chef attribute, but not the other?
The issue is you can't use node['foo'] like that. That accesses the merged view of all attribute levels. If you then want to set things, it wouldn't know where to put them. So you need to lead off by tell it where to put the data:
tags = node.normal['attribute']['tags']
tags['new_key'] = json_value
Or just:
node.normal['attribute']['tags']['new_key'] = json_value
Beware of setting things at the normal level though, it is not reset at the start of each run which is probably what you want here, but it does mean that even if you remove the recipe code doing the set, the value will still be in place on any node that already ran it. If you want to actually remove things, you have to do it explicitly.
I need to create an Excel document in Ruby. My requirements are: multiple sheets, some basic formatting, ability to create hyperlinks between cells within the document and creating drop downs. I found two gems: axlsx and writeexcel which seem to offer almost everything that I want. The one mising thing is a default value for created drop downs. I ran the data validation examples for both gems and in both cases the cell containing the drop-down is empty until a human being chooses a value.
What I need is a default value displayed in the cell. So, if %w[ maybe, yes, no ] are the allowed values, then I want "maybe" to be displayed in the cell.
I read what seemed relevant parts of the documentation of both gems, but I didn't find any obvious way to say, that I want some value to be selected by default in the drop down.
I'm not emotionally attached to neither axlsx nor writeexcel, if you can suggest any other approach that will give me what I want, I'll be a happy camper.
OK, so I've found a solution to my question with writeexcel gem. I'm not sure if it's stupid or if it's obvious, but it works well enough for me. What I did is write my default value to a cell, and then add a drop down to the same cell. Below is code based on data_validate.rb example file:
#!/usr/bin/ruby -w
# -*- coding: utf-8 -*-
require 'writeexcel'
workbook = WriteExcel.new('default_dropdown.xls')
worksheet = workbook.add_worksheet
worksheet.set_column('A:A', 32)
txt = 'Select a value from a drop down list'
worksheet.write(1, 1, 'open')
worksheet.write(1, 0, txt)
worksheet.data_validation(1, 1,
{
:validate => 'list',
:source => ['open', 'high', 'close']
})
workbook.close
Either I am not using d3's selection.filter correctly, or it is buggy. I can distill the issue to a few lines. I'm in the Chrome debugger with d3 loaded. Let's start with an empty selection
d3.selectAll("nonexistant").empty()
> true
and bind some data to it.
d3.selectAll("nonexistant").data([1,2,3,4])
> [Array[4]]
Good, so it has size four. Let's check with selection.size:
d3.selectAll("nonexistant").data([1,2,3,4]).size()
> 0
Hmm, I guess that's because there are no DOM elements yet the update selection is empty since there were no previous elements. So let's make access the enter selection.
d3.selectAll("nonexistant").data([1,2,3,4]).enter()
> [Array[4]]
d3.selectAll("nonexistant").data([1,2,3,4]).enter().size()
> TypeError: undefined is not a function
d3.selectAll("nonexistant").data([1,2,3,4]).enter().append("p").size()
> 4
Not sure why the enter selection causes an error, (UPDATE: Fixed in v3.4.12) but anyway, if we try filtering using the example function in the docs,
function odds(d, i) { return i & 1; }
d3.selectAll("nonexistant").data([1,2,3,4]).filter(odds);
> [Array[0]]
d3.selectAll("nonexistant").data([1,2,3,4]).enter().filter(odds);
> []
d3.selectAll("nonexistant").data([1,2,3,4]).enter().append("p").filter(odds)
> [Array[2]]
Why is it silently filtering out all elements when there are no DOM elements bound? It does seem to be working when I already have DOM elements. But that feels pretty useless, since I don't want to create elements for data I'm discarding. Maybe if I put the filter earlier?
d3.selectAll("nonexistant").data([1,2,3,4]).filter(odds).enter().append("p").size()
> TypeError: undefined is not a function
d3.selectAll("nonexistant").data([1,2,3,4]).enter().filter(odds).append("p").size()
> TypeError: undefined is not a function
Nope. It seems the way to go is with JS's native filter on arrays:
d3.selectAll("nonexistant").data([1,2,3,4].filter(odds)).enter().append("p").size()
> 2
The d3 docs do not seem to differentiate between selections that have DOM elements bound and those that do not. It seems that I should be able to stick filter anywhere in my method chain (and call size on any selection), and get the correct result without a type error. Granted, filter also supports CSS selectors that will require DOM elements, but I'm not using them here.
What I want to know: There is a mismatch between what d3 is doing and what I expect. To what extent am I harboring misconceptions about selections and what operations are valid on them? To what extent is the documentation unclear? Does any of this behavior qualify as a bug?
From the documentation of the .enter() method:
... the entering selection only defines append, insert, select and call operators; you must use these operators to instantiate the entering nodes before modifying any content. (Enter selections also support empty to check if they are empty.)
Calling anything else doesn't produce useful results. Whether or not that's a bug, a side-effect or a feature is perhaps debatable. In almost all cases, it doesn't create any barriers, except maybe if you need to know this selection's size() to find out how many datums from the array you pass to data() didn't already have elements created.
Once you call append() on the entering selection though, it behaves well, like any normal selection. In fact, append() is returning a new selection, so it !== the return value of enter().
That's when you can also check the size() of this selection, so really it only counts as an issue if you needed to know the size PRIOR to calling append().
You're correct that using the native array filter is the solution IF you don't need to even append elements where odds(d) == false.
Filter is useful when you've already created the DOM nodes (e.g. <p>s) that are bound to [1,2,3,4], and (e.g. in an event handler, when user clicks a "highlight all odds" button ) you call
d3.selectAll('p').filter(odds).css('color', 'red')
BTW, that was a really well written question.
I'm using Ruby's Hpricot gem to parse html. I'd like to remove a single node from the document for use elsewhere, but I can't find a way.
I see that I can remove an entire list of elements, using an instance of Hpricot::Elements (x = (doc/"div").remove), but I only want to remove the first instance of a given tag.
Poking around, I see the suggestion that I simply replace the element's inner text with a comment node or whitespace (x.inner_html = ''), but that prevents me making use of the node elsewhere.
What can I do?
Specs: Ruby 1.8.7, Hpricot 0.8.4
Try this!
x = (doc/"div").first
x.parent.children.delete(x) unless x.nil?
Supposing I want to query for the XPath //*[#id=$href]. How can I tell nokogiri to safely bind a value for the $href variable?
This is similar to REXML's XPath.first( node, "//*[#id=$href]", nil, {"href"=>"linktohere"})
This feature has just (a half hour ago) been added to Nokogiri, so it should appear in the next version.